]> git.ipfire.org Git - people/ms/linux.git/commitdiff
Merge tag 'riscv-for-linus-5.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Jun 2022 18:45:47 +0000 (13:45 -0500)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Jun 2022 18:45:47 +0000 (13:45 -0500)
Pull RISC-V fixes from Palmer Dabbelt:

 - A fix for the PolarFire SOC's device tree

 - A handful of fixes for the recently added Svpmbt support

 - An improvement to the Kconfig text for Svpbmt

* tag 'riscv-for-linus-5.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: Improve description for RISCV_ISA_SVPBMT Kconfig symbol
  riscv: drop cpufeature_apply_feature tracking variable
  riscv: fix dependency for t-head errata
  riscv: dts: microchip: re-add pdma to mpfs device tree

600 files changed:
Documentation/ABI/testing/sysfs-ata
Documentation/ABI/testing/sysfs-devices-system-cpu
Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator
Documentation/admin-guide/hw-vuln/index.rst
Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst [new file with mode: 0644]
Documentation/admin-guide/kernel-parameters.txt
Documentation/arm/tcm.rst
Documentation/arm64/sme.rst
Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt
Documentation/devicetree/bindings/display/arm,malidp.yaml
Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml
Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml
Documentation/devicetree/bindings/display/msm/dsi-phy-20nm.yaml
Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml
Documentation/devicetree/bindings/display/msm/dsi-phy-common.yaml
Documentation/devicetree/bindings/hwmon/ti,tmp401.yaml
Documentation/devicetree/bindings/hwmon/vexpress.txt
Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml
Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml
Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
Documentation/devicetree/bindings/phy/phy-stih407-usb.txt
Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt
Documentation/devicetree/bindings/pinctrl/ralink,mt7620-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/ralink,rt305x-pinctrl.yaml
Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml
Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
Documentation/devicetree/bindings/regulator/vexpress.txt
Documentation/devicetree/bindings/usb/dwc3-st.txt
Documentation/devicetree/bindings/usb/ehci-st.txt
Documentation/devicetree/bindings/usb/ohci-st.txt
Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
Documentation/driver-api/hte/hte.rst [moved from Documentation/hte/hte.rst with 100% similarity]
Documentation/driver-api/hte/index.rst [moved from Documentation/hte/index.rst with 100% similarity]
Documentation/driver-api/hte/tegra194-hte.rst [moved from Documentation/hte/tegra194-hte.rst with 100% similarity]
Documentation/driver-api/index.rst
Documentation/features/core/cBPF-JIT/arch-support.txt
Documentation/features/core/eBPF-JIT/arch-support.txt
Documentation/features/core/generic-idle-thread/arch-support.txt
Documentation/features/core/jump-labels/arch-support.txt
Documentation/features/core/thread-info-in-task/arch-support.txt
Documentation/features/core/tracehook/arch-support.txt
Documentation/features/debug/KASAN/arch-support.txt
Documentation/features/debug/debug-vm-pgtable/arch-support.txt
Documentation/features/debug/gcov-profile-all/arch-support.txt
Documentation/features/debug/kcov/arch-support.txt
Documentation/features/debug/kgdb/arch-support.txt
Documentation/features/debug/kmemleak/arch-support.txt
Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
Documentation/features/debug/kprobes/arch-support.txt
Documentation/features/debug/kretprobes/arch-support.txt
Documentation/features/debug/optprobes/arch-support.txt
Documentation/features/debug/stackprotector/arch-support.txt
Documentation/features/debug/uprobes/arch-support.txt
Documentation/features/debug/user-ret-profiler/arch-support.txt
Documentation/features/io/dma-contiguous/arch-support.txt
Documentation/features/locking/cmpxchg-local/arch-support.txt
Documentation/features/locking/lockdep/arch-support.txt
Documentation/features/locking/queued-rwlocks/arch-support.txt
Documentation/features/locking/queued-spinlocks/arch-support.txt
Documentation/features/perf/kprobes-event/arch-support.txt
Documentation/features/perf/perf-regs/arch-support.txt
Documentation/features/perf/perf-stackdump/arch-support.txt
Documentation/features/sched/membarrier-sync-core/arch-support.txt
Documentation/features/sched/numa-balancing/arch-support.txt
Documentation/features/seccomp/seccomp-filter/arch-support.txt
Documentation/features/time/arch-tick-broadcast/arch-support.txt
Documentation/features/time/clockevents/arch-support.txt
Documentation/features/time/context-tracking/arch-support.txt
Documentation/features/time/irq-time-acct/arch-support.txt
Documentation/features/time/virt-cpuacct/arch-support.txt
Documentation/features/vm/ELF-ASLR/arch-support.txt
Documentation/features/vm/PG_uncached/arch-support.txt
Documentation/features/vm/THP/arch-support.txt
Documentation/features/vm/TLB/arch-support.txt
Documentation/features/vm/huge-vmap/arch-support.txt
Documentation/features/vm/ioremap_prot/arch-support.txt
Documentation/features/vm/pte_special/arch-support.txt
Documentation/filesystems/netfs_library.rst
Documentation/index.rst
Documentation/networking/ip-sysctl.rst
Documentation/networking/phy.rst
Documentation/process/changes.rst
Documentation/usb/usbmon.rst
MAINTAINERS
Makefile
arch/arm/boot/dts/at91-sama5d3_ksz9477_evb.dts
arch/arm/include/asm/xen/xen-ops.h [new file with mode: 0644]
arch/arm/mm/dma-mapping.c
arch/arm/xen/enlighten.c
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/virt.h
arch/arm64/include/asm/xen/xen-ops.h [new file with mode: 0644]
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/mte.c
arch/arm64/kvm/arch_timer.c
arch/arm64/kvm/arm.c
arch/arm64/kvm/fpsimd.c
arch/arm64/kvm/hyp/nvhe/mem_protect.c
arch/arm64/kvm/hyp/nvhe/sys_regs.c
arch/arm64/kvm/vgic/vgic-mmio-v2.c
arch/arm64/kvm/vgic/vgic-mmio-v3.c
arch/arm64/kvm/vgic/vgic-mmio.c
arch/arm64/kvm/vgic/vgic-mmio.h
arch/arm64/kvm/vmid.c
arch/arm64/mm/dma-mapping.c
arch/arm64/net/bpf_jit_comp.c
arch/arm64/tools/gen-sysreg.awk
arch/loongarch/Kconfig
arch/loongarch/include/asm/hardirq.h
arch/loongarch/include/asm/percpu.h
arch/loongarch/include/asm/smp.h
arch/loongarch/include/asm/timex.h
arch/loongarch/kernel/acpi.c
arch/loongarch/kernel/cacheinfo.c
arch/loongarch/kernel/irq.c
arch/loongarch/kernel/process.c
arch/loongarch/kernel/setup.c
arch/loongarch/kernel/smp.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/thread_info.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace/ptrace-fpu.c
arch/powerpc/kernel/ptrace/ptrace.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kexec/crash.c
arch/powerpc/mm/nohash/kaslr_booke.c
arch/powerpc/platforms/powernv/Makefile
arch/powerpc/platforms/pseries/papr_scm.c
arch/riscv/kvm/vmid.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/mm/init.c
arch/um/drivers/virt-pci.c
arch/x86/Kconfig
arch/x86/hyperv/hv_init.c
arch/x86/hyperv/ivm.c
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/mshyperv.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/nospec-branch.h
arch/x86/include/asm/uaccess.h
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/tdp_iter.c
arch/x86/kvm/mmu/tdp_iter.h
arch/x86/kvm/mmu/tdp_mmu.c
arch/x86/kvm/svm/avic.c
arch/x86/kvm/svm/nested.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/vmx/vmx.h
arch/x86/kvm/x86.c
arch/x86/kvm/xen.h
arch/x86/mm/mem_encrypt.c
arch/x86/mm/mem_encrypt_amd.c
arch/x86/xen/enlighten_hvm.c
arch/x86/xen/enlighten_pv.c
block/bfq-iosched.c
block/bio.c
block/blk-mq-sched.c
block/blk-mq.c
block/kyber-iosched.c
block/mq-deadline.c
certs/.gitignore
certs/Makefile
certs/blacklist_hashes.c
certs/extract-cert.c
crypto/Kconfig
crypto/Makefile
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-transport.c
drivers/ata/pata_octeon_cf.c
drivers/base/cpu.c
drivers/base/init.c
drivers/char/Kconfig
drivers/char/hw_random/virtio-rng.c
drivers/char/lp.c
drivers/char/random.c
drivers/clocksource/hyperv_timer.c
drivers/gpio/gpio-crystalcove.c
drivers/gpio/gpio-dln2.c
drivers/gpio/gpio-dwapb.c
drivers/gpio/gpio-merrifield.c
drivers/gpio/gpio-sch.c
drivers/gpio/gpio-wcove.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
drivers/gpu/drm/amd/amdgpu/imu_v11_0.c
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
drivers/gpu/drm/amd/amdgpu/nv.c
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
drivers/gpu/drm/amd/amdkfd/kfd_crat.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h
drivers/gpu/drm/amd/display/include/ddc_service_types.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h
drivers/gpu/drm/ast/ast_dp.c
drivers/gpu/drm/ast/ast_dp501.c
drivers/gpu/drm/ast/ast_drv.h
drivers/gpu/drm/ast/ast_main.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/ast/ast_post.c
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
drivers/gpu/drm/bridge/ti-sn65dsi83.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_mic.c
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
drivers/gpu/drm/i915/gt/intel_gt.c
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c
drivers/gpu/drm/i915/gt/intel_gt_sysfs.h
drivers/gpu/drm/i915/gt/intel_gt_types.h
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
drivers/gpu/drm/i915/i915_sysfs.c
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/imx/ipuv3-crtc.c
drivers/gpu/drm/panfrost/panfrost_drv.c
drivers/gpu/drm/panfrost/panfrost_job.c
drivers/gpu/drm/panfrost/panfrost_job.h
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_device.c
drivers/gpu/drm/ttm/ttm_resource.c
drivers/hid/hid-hyperv.c
drivers/hv/channel_mgmt.c
drivers/hv/hv_kvp.c
drivers/hv/vmbus_drv.c
drivers/hwmon/asus-ec-sensors.c
drivers/hwmon/occ/common.c
drivers/idle/intel_idle.c
drivers/input/joystick/Kconfig
drivers/input/misc/soc_button_array.c
drivers/input/mouse/bcm5974.c
drivers/md/dm-core.h
drivers/md/dm-log.c
drivers/md/dm-raid.c
drivers/md/dm-rq.c
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/md.c
drivers/md/md.h
drivers/md/raid5-ppl.c
drivers/misc/atmel-ssc.c
drivers/misc/eeprom/at25.c
drivers/mmc/core/block.c
drivers/mmc/host/sdhci-pci-gli.c
drivers/net/amt.c
drivers/net/dsa/lantiq_gswip.c
drivers/net/dsa/mv88e6xxx/serdes.c
drivers/net/dsa/realtek/rtl8365mb.c
drivers/net/ethernet/altera/altera_tse_main.c
drivers/net/ethernet/amd/au1000_eth.c
drivers/net/ethernet/amd/au1000_eth.h
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-platform.c
drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
drivers/net/ethernet/broadcom/bgmac-bcma.c
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_ptp.c
drivers/net/ethernet/intel/ice/ice_ptp.h
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_virtchnl.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/dev.c
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
drivers/net/ethernet/mellanox/mlx5/core/en/params.c
drivers/net/ethernet/mellanox/mlx5/core/en_common.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h
drivers/net/ethernet/netronome/nfp/flower/conntrack.c
drivers/net/ethernet/netronome/nfp/flower/match.c
drivers/net/ethernet/netronome/nfp/nfp_net_sriov.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
drivers/net/ethernet/xilinx/xilinx_axienet.h
drivers/net/ethernet/xilinx/xilinx_axienet_main.c
drivers/net/phy/dp83867.c
drivers/net/phy/mdio_bus.c
drivers/net/usb/ax88179_178a.c
drivers/nfc/nfcmrvl/usb.c
drivers/nfc/st21nfca/se.c
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/platform/mellanox/Kconfig
drivers/platform/mellanox/nvsw-sn2201.c
drivers/platform/mips/Kconfig
drivers/platform/x86/barco-p50-gpio.c
drivers/platform/x86/gigabyte-wmi.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/intel/hid.c
drivers/platform/x86/intel/pmc/core.c
drivers/platform/x86/intel/pmt/crashlog.c
drivers/scsi/ipr.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/pmcraid.c
drivers/scsi/sd.c
drivers/scsi/vmw_pvscsi.h
drivers/staging/olpc_dcon/Kconfig
drivers/staging/r8188eu/core/rtw_xmit.c
drivers/staging/r8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
drivers/tty/goldfish.c
drivers/tty/n_gsm.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/serial_core.c
drivers/usb/cdns3/cdnsp-ring.c
drivers/usb/dwc2/hcd.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/u_ether.c
drivers/usb/gadget/udc/lpc32xx_udc.c
drivers/usb/host/xhci.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/io_usbvend.h
drivers/usb/serial/option.c
drivers/vdpa/mlx5/net/mlx5_vnet.c
drivers/vdpa/vdpa_user/vduse_dev.c
drivers/vhost/vdpa.c
drivers/vhost/vringh.c
drivers/virtio/Kconfig
drivers/virtio/virtio.c
drivers/virtio/virtio_mmio.c
drivers/virtio/virtio_pci_modern_dev.c
drivers/watchdog/gxp-wdt.c
drivers/xen/Kconfig
drivers/xen/Makefile
drivers/xen/grant-dma-iommu.c [new file with mode: 0644]
drivers/xen/grant-dma-ops.c [new file with mode: 0644]
drivers/xen/grant-table.c
drivers/xen/xlate_mmu.c
fs/9p/cache.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_addr.c
fs/9p/vfs_inode.c
fs/afs/callback.c
fs/afs/dir.c
fs/afs/dir_edit.c
fs/afs/dir_silly.c
fs/afs/dynroot.c
fs/afs/file.c
fs/afs/fs_operation.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/super.c
fs/afs/volume.c
fs/afs/write.c
fs/attr.c
fs/ceph/addr.c
fs/ceph/cache.c
fs/ceph/cache.h
fs/ceph/caps.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/snap.c
fs/ceph/super.c
fs/ceph/super.h
fs/ceph/xattr.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/fscache.c
fs/cifs/fscache.h
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/sess.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/ext2/dir.c
fs/ext2/inode.c
fs/fs-writeback.c
fs/inode.c
fs/io_uring.c
fs/netfs/buffered_read.c
fs/netfs/internal.h
fs/netfs/objects.c
fs/nfsd/filecache.c
fs/quota/dquot.c
fs/zonefs/super.c
include/asm-generic/Kbuild
include/asm-generic/platform-feature.h [new file with mode: 0644]
include/drm/drm_atomic.h
include/drm/ttm/ttm_resource.h
include/linux/backing-dev.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/cpu.h
include/linux/crc-itu-t.h
include/linux/libata.h
include/linux/mm_types.h
include/linux/netfs.h
include/linux/platform-feature.h [new file with mode: 0644]
include/linux/random.h
include/linux/serial_core.h
include/linux/sunrpc/xdr.h
include/linux/vdpa.h
include/linux/virtio_config.h
include/linux/visorbus.h [deleted file]
include/linux/vmalloc.h
include/linux/workqueue.h
include/linux/xarray.h
include/net/flow_offload.h
include/net/inet_connection_sock.h
include/net/inet_hashtables.h
include/net/ipv6.h
include/net/netfilter/nf_tables.h
include/net/netfilter/nf_tables_offload.h
include/net/sock.h
include/trace/events/workqueue.h
include/uapi/linux/io_uring.h
include/uapi/linux/tls.h
include/xen/arm/xen-ops.h [new file with mode: 0644]
include/xen/grant_table.h
include/xen/xen-ops.h
include/xen/xen.h
init/Kconfig
kernel/Makefile
kernel/auditsc.c
kernel/bpf/btf.c
kernel/cfi.c
kernel/dma/debug.c
kernel/dma/swiotlb.c
kernel/entry/kvm.c
kernel/platform-feature.c [new file with mode: 0644]
kernel/reboot.c
kernel/trace/bpf_trace.c
kernel/workqueue.c
lib/Kconfig
lib/Makefile
lib/crc-itu-t.c
lib/crypto/Kconfig
lib/iov_iter.c
lib/memneq.c [moved from crypto/memneq.c with 100% similarity]
lib/vsprintf.c
lib/xarray.c
mm/backing-dev.c
mm/filemap.c
mm/huge_memory.c
mm/readahead.c
mm/usercopy.c
mm/vmalloc.c
net/ax25/af_ax25.c
net/core/flow_offload.c
net/dccp/proto.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_hashtables.c
net/ipv4/ip_gre.c
net/ipv4/tcp.c
net/ipv4/xfrm4_protocol.c
net/ipv6/ip6_output.c
net/ipv6/seg6_hmac.c
net/ipv6/seg6_local.c
net/l2tp/l2tp_ip6.c
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_offload.c
net/netfilter/nft_nat.c
net/openvswitch/actions.c
net/openvswitch/conntrack.c
net/sunrpc/xdr.c
net/sunrpc/xprtrdma/svc_rdma_rw.c
net/tls/tls_main.c
net/unix/af_unix.c
net/xdp/xsk.c
net/xdp/xsk_queue.h
scripts/Makefile.build
scripts/check-local-export
scripts/gdb/linux/config.py
scripts/nsdeps
scripts/sign-file.c
security/keys/trusted-keys/trusted_tpm2.c
security/selinux/hooks.c
sound/hda/hdac_device.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/cs35l36.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l56.c
sound/soc/codecs/cs53l30.c
sound/soc/codecs/es8328.c
sound/soc/codecs/nau8822.c
sound/soc/codecs/nau8822.h
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/fsl_sai.c
sound/soc/intel/boards/sof_cirrus_common.c
sound/soc/qcom/lpass-platform.c
sound/soc/sof/sof-audio.c
sound/soc/sof/sof-client-ipc-msg-injector.c
sound/usb/pcm.c
sound/usb/quirks-table.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/asm/msr-index.h
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
tools/testing/selftests/bpf/progs/freplace_global_func.c [new file with mode: 0644]
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/dirty_log_perf_test.c
tools/testing/selftests/kvm/include/perf_test_util.h
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/include/x86_64/vmx.h
tools/testing/selftests/kvm/lib/perf_test_util.c
tools/testing/selftests/kvm/lib/x86_64/perf_test_util.c [new file with mode: 0644]
tools/testing/selftests/kvm/lib/x86_64/processor.c
tools/testing/selftests/kvm/lib/x86_64/vmx.c
tools/testing/selftests/kvm/max_guest_memory_test.c
tools/testing/selftests/kvm/x86_64/hyperv_clock.c
tools/testing/selftests/kvm/x86_64/mmu_role_test.c
tools/testing/selftests/net/.gitignore
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/bind_bhash_test.c [deleted file]
tools/testing/selftests/net/bpf/Makefile
tools/testing/selftests/netfilter/nft_nat.sh
tools/testing/selftests/wireguard/qemu/Makefile
tools/testing/selftests/wireguard/qemu/init.c
tools/testing/selftests/wireguard/qemu/kernel.config
virt/kvm/kvm_main.c

index 2f726c91475223b8263ba6b1a319649bf9e48a14..3daecac48964feb54193286f75e7a2acf516d5dc 100644 (file)
@@ -107,13 +107,14 @@ Description:
                                described in ATA8 7.16 and 7.17. Only valid if
                                the device is not a PM.
 
-               pio_mode:       (RO) Transfer modes supported by the device when
-                               in PIO mode. Mostly used by PATA device.
+               pio_mode:       (RO) PIO transfer mode used by the device.
+                               Mostly used by PATA devices.
 
-               xfer_mode:      (RO) Current transfer mode
+               xfer_mode:      (RO) Current transfer mode. Mostly used by
+                               PATA devices.
 
-               dma_mode:       (RO) Transfer modes supported by the device when
-                               in DMA mode. Mostly used by PATA device.
+               dma_mode:       (RO) DMA transfer mode used by the device.
+                               Mostly used by PATA devices.
 
                class:          (RO) Device class. Can be "ata" for disk,
                                "atapi" for packet device, "pmp" for PM, or
index 2ad01cad7f1c8286530a7a959aaf655b990a6c98..bcc974d276dc4521367b3a12038526f1cc49e166 100644 (file)
@@ -526,6 +526,7 @@ What:               /sys/devices/system/cpu/vulnerabilities
                /sys/devices/system/cpu/vulnerabilities/srbds
                /sys/devices/system/cpu/vulnerabilities/tsx_async_abort
                /sys/devices/system/cpu/vulnerabilities/itlb_multihit
+               /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
 Date:          January 2018
 Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
 Description:   Information about CPU vulnerabilities
index 42214b4ff14a1372dcbf9822c8c192725366ed56..90596d8bb51c0ad7c866f60fb9b6d5cf46093e0d 100644 (file)
@@ -26,6 +26,6 @@ Description:  Read/write the current state of DDR Backup Mode, which controls
                     DDR Backup Mode must be explicitly enabled by the user,
                     to invoke step 1.
 
-               See also Documentation/devicetree/bindings/mfd/bd9571mwv.txt.
+               See also Documentation/devicetree/bindings/mfd/rohm,bd9571mwv.yaml.
 Users:         User space applications for embedded boards equipped with a
                BD9571MWV PMIC.
index 8cbc711cda9359a9e99cc62f51a02e46fb65b0d0..4df436e7c4177996cb5a7f02b0dfc136c7d41d21 100644 (file)
@@ -17,3 +17,4 @@ are configurable at compile, boot or run time.
    special-register-buffer-data-sampling.rst
    core-scheduling.rst
    l1d_flush.rst
+   processor_mmio_stale_data.rst
diff --git a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
new file mode 100644 (file)
index 0000000..9393c50
--- /dev/null
@@ -0,0 +1,246 @@
+=========================================
+Processor MMIO Stale Data Vulnerabilities
+=========================================
+
+Processor MMIO Stale Data Vulnerabilities are a class of memory-mapped I/O
+(MMIO) vulnerabilities that can expose data. The sequences of operations for
+exposing data range from simple to very complex. Because most of the
+vulnerabilities require the attacker to have access to MMIO, many environments
+are not affected. System environments using virtualization where MMIO access is
+provided to untrusted guests may need mitigation. These vulnerabilities are
+not transient execution attacks. However, these vulnerabilities may propagate
+stale data into core fill buffers where the data can subsequently be inferred
+by an unmitigated transient execution attack. Mitigation for these
+vulnerabilities includes a combination of microcode update and software
+changes, depending on the platform and usage model. Some of these mitigations
+are similar to those used to mitigate Microarchitectural Data Sampling (MDS) or
+those used to mitigate Special Register Buffer Data Sampling (SRBDS).
+
+Data Propagators
+================
+Propagators are operations that result in stale data being copied or moved from
+one microarchitectural buffer or register to another. Processor MMIO Stale Data
+Vulnerabilities are operations that may result in stale data being directly
+read into an architectural, software-visible state or sampled from a buffer or
+register.
+
+Fill Buffer Stale Data Propagator (FBSDP)
+-----------------------------------------
+Stale data may propagate from fill buffers (FB) into the non-coherent portion
+of the uncore on some non-coherent writes. Fill buffer propagation by itself
+does not make stale data architecturally visible. Stale data must be propagated
+to a location where it is subject to reading or sampling.
+
+Sideband Stale Data Propagator (SSDP)
+-------------------------------------
+The sideband stale data propagator (SSDP) is limited to the client (including
+Intel Xeon server E3) uncore implementation. The sideband response buffer is
+shared by all client cores. For non-coherent reads that go to sideband
+destinations, the uncore logic returns 64 bytes of data to the core, including
+both requested data and unrequested stale data, from a transaction buffer and
+the sideband response buffer. As a result, stale data from the sideband
+response and transaction buffers may now reside in a core fill buffer.
+
+Primary Stale Data Propagator (PSDP)
+------------------------------------
+The primary stale data propagator (PSDP) is limited to the client (including
+Intel Xeon server E3) uncore implementation. Similar to the sideband response
+buffer, the primary response buffer is shared by all client cores. For some
+processors, MMIO primary reads will return 64 bytes of data to the core fill
+buffer including both requested data and unrequested stale data. This is
+similar to the sideband stale data propagator.
+
+Vulnerabilities
+===============
+Device Register Partial Write (DRPW) (CVE-2022-21166)
+-----------------------------------------------------
+Some endpoint MMIO registers incorrectly handle writes that are smaller than
+the register size. Instead of aborting the write or only copying the correct
+subset of bytes (for example, 2 bytes for a 2-byte write), more bytes than
+specified by the write transaction may be written to the register. On
+processors affected by FBSDP, this may expose stale data from the fill buffers
+of the core that created the write transaction.
+
+Shared Buffers Data Sampling (SBDS) (CVE-2022-21125)
+----------------------------------------------------
+After propagators may have moved data around the uncore and copied stale data
+into client core fill buffers, processors affected by MFBDS can leak data from
+the fill buffer. It is limited to the client (including Intel Xeon server E3)
+uncore implementation.
+
+Shared Buffers Data Read (SBDR) (CVE-2022-21123)
+------------------------------------------------
+It is similar to Shared Buffer Data Sampling (SBDS) except that the data is
+directly read into the architectural software-visible state. It is limited to
+the client (including Intel Xeon server E3) uncore implementation.
+
+Affected Processors
+===================
+Not all the CPUs are affected by all the variants. For instance, most
+processors for the server market (excluding Intel Xeon E3 processors) are
+impacted by only Device Register Partial Write (DRPW).
+
+Below is the list of affected Intel processors [#f1]_:
+
+   ===================  ============  =========
+   Common name          Family_Model  Steppings
+   ===================  ============  =========
+   HASWELL_X            06_3FH        2,4
+   SKYLAKE_L            06_4EH        3
+   BROADWELL_X          06_4FH        All
+   SKYLAKE_X            06_55H        3,4,6,7,11
+   BROADWELL_D          06_56H        3,4,5
+   SKYLAKE              06_5EH        3
+   ICELAKE_X            06_6AH        4,5,6
+   ICELAKE_D            06_6CH        1
+   ICELAKE_L            06_7EH        5
+   ATOM_TREMONT_D       06_86H        All
+   LAKEFIELD            06_8AH        1
+   KABYLAKE_L           06_8EH        9 to 12
+   ATOM_TREMONT         06_96H        1
+   ATOM_TREMONT_L       06_9CH        0
+   KABYLAKE             06_9EH        9 to 13
+   COMETLAKE            06_A5H        2,3,5
+   COMETLAKE_L          06_A6H        0,1
+   ROCKETLAKE           06_A7H        1
+   ===================  ============  =========
+
+If a CPU is in the affected processor list, but not affected by a variant, it
+is indicated by new bits in MSR IA32_ARCH_CAPABILITIES. As described in a later
+section, mitigation largely remains the same for all the variants, i.e. to
+clear the CPU fill buffers via VERW instruction.
+
+New bits in MSRs
+================
+Newer processors and microcode update on existing affected processors added new
+bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate
+specific variants of Processor MMIO Stale Data vulnerabilities and mitigation
+capability.
+
+MSR IA32_ARCH_CAPABILITIES
+--------------------------
+Bit 13 - SBDR_SSDP_NO - When set, processor is not affected by either the
+        Shared Buffers Data Read (SBDR) vulnerability or the sideband stale
+        data propagator (SSDP).
+Bit 14 - FBSDP_NO - When set, processor is not affected by the Fill Buffer
+        Stale Data Propagator (FBSDP).
+Bit 15 - PSDP_NO - When set, processor is not affected by Primary Stale Data
+        Propagator (PSDP).
+Bit 17 - FB_CLEAR - When set, VERW instruction will overwrite CPU fill buffer
+        values as part of MD_CLEAR operations. Processors that do not
+        enumerate MDS_NO (meaning they are affected by MDS) but that do
+        enumerate support for both L1D_FLUSH and MD_CLEAR implicitly enumerate
+        FB_CLEAR as part of their MD_CLEAR support.
+Bit 18 - FB_CLEAR_CTRL - Processor supports read and write to MSR
+        IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]. On such processors, the FB_CLEAR_DIS
+        bit can be set to cause the VERW instruction to not perform the
+        FB_CLEAR action. Not all processors that support FB_CLEAR will support
+        FB_CLEAR_CTRL.
+
+MSR IA32_MCU_OPT_CTRL
+---------------------
+Bit 3 - FB_CLEAR_DIS - When set, VERW instruction does not perform the FB_CLEAR
+action. This may be useful to reduce the performance impact of FB_CLEAR in
+cases where system software deems it warranted (for example, when performance
+is more critical, or the untrusted software has no MMIO access). Note that
+FB_CLEAR_DIS has no impact on enumeration (for example, it does not change
+FB_CLEAR or MD_CLEAR enumeration) and it may not be supported on all processors
+that enumerate FB_CLEAR.
+
+Mitigation
+==========
+Like MDS, all variants of Processor MMIO Stale Data vulnerabilities  have the
+same mitigation strategy to force the CPU to clear the affected buffers before
+an attacker can extract the secrets.
+
+This is achieved by using the otherwise unused and obsolete VERW instruction in
+combination with a microcode update. The microcode clears the affected CPU
+buffers when the VERW instruction is executed.
+
+Kernel reuses the MDS function to invoke the buffer clearing:
+
+       mds_clear_cpu_buffers()
+
+On MDS affected CPUs, the kernel already invokes CPU buffer clear on
+kernel/userspace, hypervisor/guest and C-state (idle) transitions. No
+additional mitigation is needed on such CPUs.
+
+For CPUs not affected by MDS or TAA, mitigation is needed only for the attacker
+with MMIO capability. Therefore, VERW is not required for kernel/userspace. For
+virtualization case, VERW is only needed at VMENTER for a guest with MMIO
+capability.
+
+Mitigation points
+-----------------
+Return to user space
+^^^^^^^^^^^^^^^^^^^^
+Same mitigation as MDS when affected by MDS/TAA, otherwise no mitigation
+needed.
+
+C-State transition
+^^^^^^^^^^^^^^^^^^
+Control register writes by CPU during C-state transition can propagate data
+from fill buffer to uncore buffers. Execute VERW before C-state transition to
+clear CPU fill buffers.
+
+Guest entry point
+^^^^^^^^^^^^^^^^^
+Same mitigation as MDS when processor is also affected by MDS/TAA, otherwise
+execute VERW at VMENTER only for MMIO capable guests. On CPUs not affected by
+MDS/TAA, guest without MMIO access cannot extract secrets using Processor MMIO
+Stale Data vulnerabilities, so there is no need to execute VERW for such guests.
+
+Mitigation control on the kernel command line
+---------------------------------------------
+The kernel command line allows to control the Processor MMIO Stale Data
+mitigations at boot time with the option "mmio_stale_data=". The valid
+arguments for this option are:
+
+  ==========  =================================================================
+  full        If the CPU is vulnerable, enable mitigation; CPU buffer clearing
+              on exit to userspace and when entering a VM. Idle transitions are
+              protected as well. It does not automatically disable SMT.
+  full,nosmt  Same as full, with SMT disabled on vulnerable CPUs. This is the
+              complete mitigation.
+  off         Disables mitigation completely.
+  ==========  =================================================================
+
+If the CPU is affected and mmio_stale_data=off is not supplied on the kernel
+command line, then the kernel selects the appropriate mitigation.
+
+Mitigation status information
+-----------------------------
+The Linux kernel provides a sysfs interface to enumerate the current
+vulnerability status of the system: whether the system is vulnerable, and
+which mitigations are active. The relevant sysfs file is:
+
+       /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
+
+The possible values in this file are:
+
+  .. list-table::
+
+     * - 'Not affected'
+       - The processor is not vulnerable
+     * - 'Vulnerable'
+       - The processor is vulnerable, but no mitigation enabled
+     * - 'Vulnerable: Clear CPU buffers attempted, no microcode'
+       - The processor is vulnerable, but microcode is not updated. The
+         mitigation is enabled on a best effort basis.
+     * - 'Mitigation: Clear CPU buffers'
+       - The processor is vulnerable and the CPU buffer clearing mitigation is
+         enabled.
+
+If the processor is vulnerable then the following information is appended to
+the above information:
+
+  ========================  ===========================================
+  'SMT vulnerable'          SMT is enabled
+  'SMT disabled'            SMT is disabled
+  'SMT Host state unknown'  Kernel runs in a VM, Host SMT state unknown
+  ========================  ===========================================
+
+References
+----------
+.. [#f1] Affected Processors
+   https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html
index 8090130b544b0701237a7b657a29c83c000a60f4..2522b11e593f2397840d59541f9befcebed505b1 100644 (file)
 
                        protected: nVHE-based mode with support for guests whose
                                   state is kept private from the host.
-                                  Not valid if the kernel is running in EL2.
 
                        Defaults to VHE/nVHE based on hardware support. Setting
                        mode to "protected" will disable kexec and hibernation
                                               srbds=off [X86,INTEL]
                                               no_entry_flush [PPC]
                                               no_uaccess_flush [PPC]
+                                              mmio_stale_data=off [X86]
 
                                Exceptions:
                                               This does not have any effect on
                                Equivalent to: l1tf=flush,nosmt [X86]
                                               mds=full,nosmt [X86]
                                               tsx_async_abort=full,nosmt [X86]
+                                              mmio_stale_data=full,nosmt [X86]
 
        mminit_loglevel=
                        [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
                        log everything. Information is printed at KERN_DEBUG
                        so loglevel=8 may also need to be specified.
 
+       mmio_stale_data=
+                       [X86,INTEL] Control mitigation for the Processor
+                       MMIO Stale Data vulnerabilities.
+
+                       Processor MMIO Stale Data is a class of
+                       vulnerabilities that may expose data after an MMIO
+                       operation. Exposed data could originate or end in
+                       the same CPU buffers as affected by MDS and TAA.
+                       Therefore, similar to MDS and TAA, the mitigation
+                       is to clear the affected CPU buffers.
+
+                       This parameter controls the mitigation. The
+                       options are:
+
+                       full       - Enable mitigation on vulnerable CPUs
+
+                       full,nosmt - Enable mitigation and disable SMT on
+                                    vulnerable CPUs.
+
+                       off        - Unconditionally disable mitigation
+
+                       On MDS or TAA affected machines,
+                       mmio_stale_data=off can be prevented by an active
+                       MDS or TAA mitigation as these vulnerabilities are
+                       mitigated with the same mechanism so in order to
+                       disable this mitigation, you need to specify
+                       mds=off and tsx_async_abort=off too.
+
+                       Not specifying this option is equivalent to
+                       mmio_stale_data=full.
+
+                       For details see:
+                       Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
+
        module.sig_enforce
                        [KNL] When CONFIG_MODULE_SIG is set, this means that
                        modules without (valid) signatures will fail to load.
index b256f97838839a98ed86dde227660617b8e283fc..1dc6c39220f98a77b3c898142b40b548e0c98917 100644 (file)
@@ -34,7 +34,7 @@ CPU so it is usually wise not to overlap any physical RAM with
 the TCM.
 
 The TCM memory can then be remapped to another address again using
-the MMU, but notice that the TCM if often used in situations where
+the MMU, but notice that the TCM is often used in situations where
 the MMU is turned off. To avoid confusion the current Linux
 implementation will map the TCM 1 to 1 from physical to virtual
 memory in the location specified by the kernel. Currently Linux
index 8ba677b87e90f78caa7a612b5704c15936df67b6..937147f58cc5429471ce527bb38de5dd0b226366 100644 (file)
@@ -371,7 +371,7 @@ The regset data starts with struct user_za_header, containing:
 Appendix A.  SME programmer's model (informative)
 =================================================
 
-This section provides a minimal description of the additions made by SVE to the
+This section provides a minimal description of the additions made by SME to the
 ARMv8-A programmer's model that are relevant to this document.
 
 Note: This section is for information only and not intended to be complete or
index be66f1e8b54761325082e056020cad578f9b79d6..7c331bfbe370eb5c61c0ef6a11afd022039c9dc4 100644 (file)
@@ -45,7 +45,7 @@ description: |
   The case where SH and SP are both 1 is likely not very interesting.
 
 maintainers:
-  - Luca Ceresoli <luca@lucaceresoli.net>
+  - Luca Ceresoli <luca.ceresoli@bootlin.com>
 
 properties:
   compatible:
index 73470ecd1f12f282755101bd0460359a815c2904..ce91a919769761c9e6f27dfc6f7019eada48d6df 100644 (file)
@@ -16,7 +16,7 @@ has been processed. See [2] for more information on the brcm,l2-intc node.
 firmware. On some SoCs, this firmware supports DFS and DVFS in addition to
 Adaptive Voltage Scaling.
 
-[2] Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt
+[2] Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.yaml
 
 
 Node brcm,avs-cpu-data-mem
index 795a08ac9f128065308015418c4ccbf32be7276e..2a17ec6fc97c02a8e2a9fae82cbef3b9d6928f31 100644 (file)
@@ -71,11 +71,6 @@ properties:
       - description: number of output lines for the green channel (G)
       - description: number of output lines for the blue channel (B)
 
-  arm,malidp-arqos-high-level:
-    $ref: /schemas/types.yaml#/definitions/uint32
-    description:
-      integer describing the ARQoS levels of DP500's QoS signaling
-
   arm,malidp-arqos-value:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
@@ -113,7 +108,7 @@ examples:
         clocks = <&oscclk2>, <&fpgaosc0>, <&fpgaosc1>, <&fpgaosc1>;
         clock-names = "pxlclk", "mclk", "aclk", "pclk";
         arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
-        arm,malidp-arqos-high-level = <0xd000d000>;
+        arm,malidp-arqos-value = <0xd000d000>;
 
         port {
             dp0_output: endpoint {
index b41991eaa454a73bbda90bf8436b22efacc35c30..d3c3e4b078971d9fd41f04b16ca507a34eb7827b 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DPU dt properties for SC7180 target
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 description: |
   Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
index 6e417d06fc79092a9c9b6b5a8972d03984bb1b45..f427eec3d3a45fdd617d638b7ef7dd9f34c4f1b0 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DPU dt properties for SC7280
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 description: |
   Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates
index 1a42491efdbcb3b07c861d7343d3c20018e6ecb3..2bb8896beffc69611d8102c23c029dc26641bb1d 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DPU dt properties for SDM845 target
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 description: |
   Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
index 7095ec3c890dadd55229f19f3a399b4b956db596..880bfe930830c4cf754f8697b33bcca6b8db84ea 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DSI controller
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 allOf:
   - $ref: "../dsi-controller.yaml#"
index 2d5a766d028f1a05205310ead1b8b6b9ec730945..716f921e3532ecd79216479a29c4f9e61de59dfd 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DSI 10nm PHY
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 allOf:
   - $ref: dsi-phy-common.yaml#
index 81dbee4803c0b5ed4912cf0e63a5b956135bb5fe..1342d74ecfe0f2a9655cd233055ccab0e04d8a94 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DSI 14nm PHY
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 allOf:
   - $ref: dsi-phy-common.yaml#
index b8de785ce8156f9a8801d490b57ee3e353a8505f..9c1f9140c731b9693078fa7a80638fa27dd96a6e 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DSI 20nm PHY
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 allOf:
   - $ref: dsi-phy-common.yaml#
index 69eecaa64b187bf03e66fb79968804c14c2bb0b3..3d8540a06fe22a4865f9d45b2bcc3b8e009a646f 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm Display DSI 28nm PHY
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 allOf:
   - $ref: dsi-phy-common.yaml#
index 502bdda902354d5de4eddb1f322e7d549132dd60..76d40f7933ddea5c34bb894d8d7ce030288f56ea 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Description of Qualcomm Display DSI PHY common dt properties
 
 maintainers:
-  - Krishna Manikandan <mkrishn@codeaurora.org>
+  - Krishna Manikandan <quic_mkrishn@quicinc.com>
 
 description: |
   This defines the DSI PHY dt properties which are common for all
index fe0ac08faa1a7065762616b7babd90318327eb1d..0e8ddf0ad7890dce61b1e14c9417b7aad85869d1 100644 (file)
@@ -40,9 +40,8 @@ properties:
       value to be used for converting remote channel measurements to
       temperature.
     $ref: /schemas/types.yaml#/definitions/int32
-    items:
-      minimum: -128
-      maximum: 127
+    minimum: -128
+    maximum: 127
 
   ti,beta-compensation:
     description:
index 9c27ed694bbbf29f8e96e286855799879e0f26b7..4a4df4ffc460be8001588bbaae6785cd4e4d4e57 100644 (file)
@@ -9,7 +9,7 @@ Requires node properties:
        "arm,vexpress-power"
        "arm,vexpress-energy"
 - "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg
-  (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
+  (see Documentation/devicetree/bindings/arm/vexpress-config.yaml
   for more details)
 
 Optional node properties:
diff --git a/Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml b/Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml
new file mode 100644 (file)
index 0000000..be1539d
--- /dev/null
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/xen,grant-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xen specific IOMMU for virtualized devices (e.g. virtio)
+
+maintainers:
+  - Stefano Stabellini <sstabellini@kernel.org>
+
+description:
+  The Xen IOMMU represents the Xen grant table interface. Grant mappings
+  are to be used with devices connected to the Xen IOMMU using the "iommus"
+  property, which also specifies the ID of the backend domain.
+  The binding is required to restrict memory access using Xen grant mappings.
+
+properties:
+  compatible:
+    const: xen,grant-dma
+
+  '#iommu-cells':
+    const: 1
+    description:
+      The single cell is the domid (domain ID) of the domain where the backend
+      is running.
+
+required:
+  - compatible
+  - "#iommu-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    iommu {
+        compatible = "xen,grant-dma";
+        #iommu-cells = <1>;
+    };
index c7cfa6c2cd81ca7777d616d8aa7b7b36090a5d92..935d63d181d9ed4fa839f85eaf6111b6cd02fed2 100644 (file)
@@ -150,7 +150,6 @@ allOf:
           description: 5 memory controller channels and 1 for stream-id registers
 
         reg-names:
-          maxItems: 6
           items:
             - const: sid
             - const: broadcast
@@ -170,7 +169,6 @@ allOf:
           description: 17 memory controller channels and 1 for stream-id registers
 
         reg-names:
-          minItems: 18
           items:
             - const: sid
             - const: broadcast
@@ -202,7 +200,6 @@ allOf:
           description: 17 memory controller channels and 1 for stream-id registers
 
         reg-names:
-          minItems: 18
           items:
             - const: sid
             - const: broadcast
index 74a6867d3c826503fe4c996324d92647347e177b..edac14af101e5b1ce9e18182e9de7f13305e90cb 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: MAX77714 PMIC with GPIO, RTC and watchdog from Maxim Integrated.
 
 maintainers:
-  - Luca Ceresoli <luca@lucaceresoli.net>
+  - Luca Ceresoli <luca.ceresoli@bootlin.com>
 
 description: |
   MAX77714 is a Power Management IC with 4 buck regulators, 9
index b672202fff4e424ada684c9d3f12ed91fb54853a..5ecdac9de484b530192a360c80f2e2ce2eb800f9 100644 (file)
@@ -75,7 +75,6 @@ examples:
       sd-uhs-sdr104;
       sdhci,auto-cmd12;
       interrupts = <0x0 0x26 0x4>;
-      interrupt-names = "sdio0_0";
       clocks = <&scmi_clk 245>;
       clock-names = "sw_sdio";
     };
@@ -94,7 +93,6 @@ examples:
       non-removable;
       bus-width = <0x8>;
       interrupts = <0x0 0x27 0x4>;
-      interrupt-names = "sdio1_0";
       clocks = <&scmi_clk 245>;
       clock-names = "sw_sdio";
     };
index c79639e9027edda13973349694ba10300d45e55b..3ee7588865585783b442f60f821052d7fa01bf4c 100644 (file)
@@ -56,6 +56,9 @@ properties:
       - const: core
       - const: axi
 
+  interrupts:
+    maxItems: 1
+
   marvell,xenon-sdhc-id:
     $ref: /schemas/types.yaml#/definitions/uint32
     minimum: 0
@@ -145,7 +148,6 @@ allOf:
           items:
             - description: Xenon IP registers
             - description: Armada 3700 SoC PHY PAD Voltage Control register
-          minItems: 2
 
         marvell,pad-type:
           $ref: /schemas/types.yaml#/definitions/string
index ddff9233b15955f6fc5220b865930d917ed8449f..34dd1cc67124689da3560ad8b01f441017c8f617 100644 (file)
@@ -55,7 +55,6 @@ properties:
     maxItems: 1
 
   apple,sart:
-    maxItems: 1
     $ref: /schemas/types.yaml#/definitions/phandle
     description: |
       Reference to the SART address filter.
index de6a706abcdbe900fda70080f76bc9214c1400f1..35f03df001304b0ab7e42cd140d047f8198a862b 100644 (file)
@@ -9,7 +9,7 @@ Required properties:
 - resets               : list of phandle and reset specifier pairs. There should be two entries, one
                          for the whole phy and one for the port
 - reset-names          : list of reset signal names. Should be "global" and "port"
-See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
+See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml
 See: Documentation/devicetree/bindings/reset/reset.txt
 
 Example:
index 60dc27834e1df7f05336bc27fe08245b486b91dc..b078009ed509dfda7a69aa24c03e4bcfb7ac8d71 100644 (file)
@@ -8,7 +8,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 title: Qualcomm QMP USB3 DP PHY controller
 
 maintainers:
-  - Manu Gautam <mgautam@codeaurora.org>
+  - Wesley Cheng <quic_wcheng@quicinc.com>
 
 properties:
   compatible:
index 0ab3dad3f1213b711c1362266623cac7afc92bc7..d68ab49345b8fd77ceb71100d50ac508b511c575 100644 (file)
@@ -8,7 +8,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 title: Qualcomm QUSB2 phy controller
 
 maintainers:
-  - Manu Gautam <mgautam@codeaurora.org>
+  - Wesley Cheng <quic_wcheng@quicinc.com>
 
 description:
   QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets.
index 1ce251de08557a95036098b3475691fbed0183b4..7a0e6a9854da2360dc87922468becc33301573da 100644 (file)
@@ -7,7 +7,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 title: Qualcomm Synopsys Femto High-Speed USB PHY V2
 
 maintainers:
-  - Wesley Cheng <wcheng@codeaurora.org>
+  - Wesley Cheng <quic_wcheng@quicinc.com>
 
 description: |
   Qualcomm High-Speed USB PHY
index cbcbd31e3ce850bf9d3cd501027350991bfefaf4..939cb5b6ffeacc195f639ba5204bc98b5dbf1cbb 100644 (file)
@@ -27,7 +27,7 @@ Required properties:
 - pins: List of pins. Valid values of pins properties are: gpio0, gpio1.
 
 First 2 properties must be added in the RK805 PMIC node, documented in
-Documentation/devicetree/bindings/mfd/rk808.txt
+Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
 
 Optional properties:
 -------------------
index 4d820df24b89f2a386a52cf073cfd66b8d31bc51..6f17f39916400cbc2a786c2548709d21ced74d6a 100644 (file)
@@ -32,31 +32,37 @@ patternProperties:
           groups:
             description: The pin group to select.
             enum: [
+              # common
+              i2c, spi, wdt,
+
               # For MT7620 SoC
-              ephy, i2c, mdio, nd_sd, pa, pcie, rgmii1, rgmii2, spi, spi refclk,
-              uartf, uartlite, wdt, wled,
+              ephy, mdio, nd_sd, pa, pcie, rgmii1, rgmii2, spi refclk,
+              uartf, uartlite, wled,
 
               # For MT7628 and MT7688 SoCs
-              gpio, i2c, i2s, p0led_an, p0led_kn, p1led_an, p1led_kn, p2led_an,
+              gpio, i2s, p0led_an, p0led_kn, p1led_an, p1led_kn, p2led_an,
               p2led_kn, p3led_an, p3led_kn, p4led_an, p4led_kn, perst, pwm0,
-              pwm1, refclk, sdmode, spi, spi cs1, spis, uart0, uart1, uart2,
-              wdt, wled_an, wled_kn,
+              pwm1, refclk, sdmode, spi cs1, spis, uart0, uart1, uart2,
+              wled_an, wled_kn,
             ]
 
           function:
             description: The mux function to select.
             enum: [
+              # common
+              gpio, i2c, refclk, spi,
+
               # For MT7620 SoC
-              ephy, gpio, gpio i2s, gpio uartf, i2c, i2s uartf, mdio, nand, pa,
-              pcie refclk, pcie rst, pcm gpio, pcm i2s, pcm uartf, refclk,
-              rgmii1, rgmii2, sd, spi, spi refclk, uartf, uartlite, wdt refclk,
+              ephy, gpio i2s, gpio uartf, i2s uartf, mdio, nand, pa,
+              pcie refclk, pcie rst, pcm gpio, pcm i2s, pcm uartf,
+              rgmii1, rgmii2, sd, spi refclk, uartf, uartlite, wdt refclk,
               wdt rst, wled,
 
               # For MT7628 and MT7688 SoCs
-              antenna, debug, gpio, i2c, i2s, jtag, p0led_an, p0led_kn,
+              antenna, debug, i2s, jtag, p0led_an, p0led_kn,
               p1led_an, p1led_kn, p2led_an, p2led_kn, p3led_an, p3led_kn,
               p4led_an, p4led_kn, pcie, pcm, perst, pwm, pwm0, pwm1, pwm_uart2,
-              refclk, rsvd, sdxc, sdxc d5 d4, sdxc d6, sdxc d7, spi, spi cs1,
+              rsvd, sdxc, sdxc d5 d4, sdxc d6, sdxc d7, spi cs1,
               spis, sw_r, uart0, uart1, uart2, utif, wdt, wled_an, wled_kn, -,
             ]
 
index 425401c542696b4929ce2e31aa6d071ecf2dcf08..f602a5d6e13a66da7f18f0bcb5ed1eaf235db110 100644 (file)
@@ -33,32 +33,29 @@ patternProperties:
           groups:
             description: The pin group to select.
             enum: [
+              # common
+              i2c, jtag, led, mdio, rgmii, spi, spi_cs1, uartf, uartlite,
+
               # For RT3050, RT3052 and RT3350 SoCs
-              i2c, jtag, mdio, rgmii, sdram, spi, uartf, uartlite,
+              sdram,
 
               # For RT3352 SoC
-              i2c, jtag, led, lna, mdio, pa, rgmii, spi, spi_cs1, uartf,
-              uartlite,
-
-              # For RT5350 SoC
-              i2c, jtag, led, spi, spi_cs1, uartf, uartlite,
+              lna, pa
             ]
 
           function:
             description: The mux function to select.
             enum: [
+              # common
+              gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, led, mdio,
+              pcm gpio, pcm i2s, pcm uartf, rgmii, spi, spi_cs1, uartf,
+              uartlite, wdg_cs1,
+
               # For RT3050, RT3052 and RT3350 SoCs
-              gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, mdio, pcm gpio,
-              pcm i2s, pcm uartf, rgmii, sdram, spi, uartf, uartlite,
+              sdram,
 
               # For RT3352 SoC
-              gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, led, lna, mdio,
-              pa, pcm gpio, pcm i2s, pcm uartf, rgmii, spi, spi_cs1, uartf,
-              uartlite, wdg_cs1,
-
-              # For RT5350 SoC
-              gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, led, pcm gpio,
-              pcm i2s, pcm uartf, spi, spi_cs1, uartf, uartlite, wdg_cs1,
+              lna, pa
             ]
 
         required:
index 675b9b26d2337f3694fbecd2e411ac753070203c..f23dcc50793e04474e318df76f1672babac9b877 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Maxim Integrated MAX77976 Battery charger
 
 maintainers:
-  - Luca Ceresoli <luca@lucaceresoli.net>
+  - Luca Ceresoli <luca.ceresoli@bootlin.com>
 
 description: |
   The Maxim MAX77976 is a 19Vin / 5.5A, 1-Cell Li+ battery charger
index 12ed98c28aaa5acfd9c291fd21eaf4fa4556062d..dbe78cd4adba58776abac0a1eb7286254715b64d 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: The Qualcomm PMIC VBUS output regulator driver
 
 maintainers:
-  - Wesley Cheng <wcheng@codeaurora.org>
+  - Wesley Cheng <quic_wcheng@quicinc.com>
 
 description: |
   This regulator driver controls the VBUS output by the Qualcomm PMIC.  This
index d775f72487aa35758c082f9c38234e4dd36d8a9a..1c2e92c7831eabd867b1fb58c3398695775f4a61 100644 (file)
@@ -4,7 +4,7 @@ Versatile Express voltage regulators
 Requires node properties:
 - "compatible" value: "arm,vexpress-volt"
 - "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg
-  (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
+  (see Documentation/devicetree/bindings/arm/vexpress-config.yaml
   for more details)
 
 Required regulator properties:
index bf73de0d5b4af1fbaba0919029a19a13cc83357c..4aa368447b1e8c995a93cf9e238b5e6ad372d010 100644 (file)
@@ -13,7 +13,7 @@ Required properties:
  - resets      : list of phandle and reset specifier pairs. There should be two entries, one
                  for the powerdown and softreset lines of the usb3 IP
  - reset-names : list of reset signal names. Names should be "powerdown" and "softreset"
-See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
+See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml
 See: Documentation/devicetree/bindings/reset/reset.txt
 
  - #address-cells, #size-cells : should be '1' if the device has sub-nodes
index 065c91d955ad159a1ff4cbd75d26ff86f0e52c0e..d6f2bdee20fc2b376c1a57fc7a729d41591039ba 100644 (file)
@@ -17,7 +17,7 @@ See: Documentation/devicetree/bindings/clock/clock-bindings.txt
  - resets              : phandle + reset specifier pairs to the powerdown and softreset lines
                          of the USB IP
  - reset-names         : should be "power" and "softreset"
-See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
+See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml
 See: Documentation/devicetree/bindings/reset/reset.txt
 
 Example:
index 44c998c16f85bfbfa4814fffb8dc3d344c14a3de..1c735573abc03af0a31271e58cc80bc6af6446be 100644 (file)
@@ -15,7 +15,7 @@ See: Documentation/devicetree/bindings/clock/clock-bindings.txt
 
  - resets              : phandle to the powerdown and reset controller for the USB IP
  - reset-names         : should be "power" and "softreset".
-See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
+See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml
 See: Documentation/devicetree/bindings/reset/reset.txt
 
 Example:
index e336fe2e03cca766d372267f8d5bfd17c60b2faa..749e1963ddbb8dd9e535033a1f7365ffd6618751 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm SuperSpeed DWC3 USB SoC controller
 
 maintainers:
-  - Manu Gautam <mgautam@codeaurora.org>
+  - Wesley Cheng <quic_wcheng@quicinc.com>
 
 properties:
   compatible:
index 6bb20b4554d7e9bfa08465445f70bb30d6749a94..0496773a3c4d870a50f1c96369dd469332731c7f 100644 (file)
@@ -143,6 +143,9 @@ patternProperties:
     description: ASPEED Technology Inc.
   "^asus,.*":
     description: AsusTek Computer Inc.
+  "^atheros,.*":
+    description: Qualcomm Atheros, Inc. (deprecated, use qca)
+    deprecated: true
   "^atlas,.*":
     description: Atlas Scientific LLC
   "^atmel,.*":
index cbcf19f514114534be0749f01fae7c785046059a..ed6c1ca80dcc4ed7f37518c9b1aef5dab6e4a67c 100644 (file)
@@ -64,7 +64,6 @@ if:
 then:
   properties:
     clocks:
-      minItems: 2
       items:
         - description: High-frequency oscillator input, divided internally
         - description: Low-frequency oscillator input
index d76a60d95b58876ee856d5f76fdd44bf639795ad..a6d525cd9fc458daac26b935d9c2ddc36333a799 100644 (file)
@@ -108,6 +108,7 @@ available subsections can be seen below.
    xilinx/index
    xillybus
    zorro
+   hte/index
 
 .. only::  subproject and html
 
index 10482dee8703c6ec127e92c9150d7605121cf29c..a053667a7a8c12b2d0afabd6fce219888a32f637 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index bcefb5afc7d6548b27cf7cb4bec5b003e25eb3c6..c0bb9c92937f0dbe675ec51e7b7a2fb11fd49ed9 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index d80d99449ac153d4e6bffb9bc97f0cfd43e12642..c9bfff292816a43b81797e0bbb4d4b763a0e0795 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: |  ok  |
     |        ia64: |  ok  |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 53eab154925d558af80d069c8481ccb4f9760bf3..35e2a44b1448b8bdb27b2f26d243a34def7c6ef4 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 94926451afb90cc05c6c084f20078c8dabad9531..9b3e2ce12b440f8557341c9b74e7dacdc7f92ba2 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index b4274b8141b673cd2dfcc8647fbe2d41768763c5..9c7ffec5d51d5d4a73d7637dd98924c3a260bdfc 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: |  ok  |
     |        ia64: |  ok  |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index c15bb4b21b6fd6ac5c6305f23e5f0a9f978b75a6..2fd5fb6f5f236561e006f2df53cd12d1645aba7b 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index 4c31fc92a3124d64228996c688219cdd997a4057..c45711e55c7bffbc3f18efbd75c9fdf74c164519 100644 (file)
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: |  ok  |
     |        s390: |  ok  |
index d7a5ac4bc1fef11839fd272ade09406771e5c9a3..502c1d40964887377609d26549124bab30313c2f 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: |  ok  |
     |        mips: |  ok  |
@@ -24,7 +25,7 @@
     |        s390: |  ok  |
     |          sh: |  ok  |
     |       sparc: | TODO |
-    |          um: | TODO |
+    |          um: |  ok  |
     |         x86: |  ok  |
     |      xtensa: | TODO |
     -----------------------
index 136e14c2b6039d8f04c191e9abb96bd38a4f7b06..afb90bebded236b88e9f9fc23a450d53f2b6bd65 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 5b3f3d8ae46228b146d6361ebeebfa4ba976bbe6..04120d278c221e96540d350b0fa80e031877460d 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: |  ok  |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: |  ok  |
     |        mips: |  ok  |
index 7a2eab4fdf9d99146bfbb3f3b8f797283fe8603b..e487c356ab206fcb7747377f0224f4f948545ad0 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: |  ok  |
     |        mips: |  ok  |
index db02ab19413866e45dfe149ede68682cd97b07b7..b3697f4c806e8ffbf8f83a53d4f4bbdce2560fca 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index ec186e7deebc7624df465916781cfbb2b5f4c3a0..452385ac9e067bb6773068d8b9a16d48c5a6ba92 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: |  ok  |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 4b7865e693f6027ea31d03565e163c2777df7dc0..daecf046e72b4efb3c30bd819cad82f126bd792e 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: |  ok  |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 5d9befa041c73df4b80c14223aabf4353d7ec20d..adb1bd055bfdd9c84faefcb19c7e9aea61390417 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index d97fd38460e69021fe8fc83ba8d9e4a21d4793ed..ddcd7161d14ce127a30a6cc2d5090d809940d3fa 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index d30e3475904ec103a3df46fd7a506e606a61e9a6..25121200f9f9e23c363abe37400c73a0cdb7d3e9 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 9ae1fa2eb27cba537f365f30fbd851f7e5a72a2d..f2fcff8e77b79fc0d967efad7dfb6d456256aaf5 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index 9e09988eb6545e54a299bf92d4b729a8f2c8cebd..95e485c87e36dde14a5f379a81120d39422c65d4 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: |  ok  |
     |        mips: |  ok  |
index 5c4ec316dbac0f6b8fb079b1a2ca76b568a97774..8b1a8d9e1c797da54146704952c55b92b03a98e2 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index 65007c1ac44f64ed935134e8d124a4ff25ac01a8..ab69e8f56a37756cb086c455ee1dd0619d8b1769 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: |  ok  |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: |  ok  |
     |        mips: |  ok  |
index 20056670fb09e989d8405da750d6cf7e60c2e033..0bfb72a08d82dabb577873a78793376ebf8f5754 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
@@ -20,7 +21,7 @@
     |    openrisc: |  ok  |
     |      parisc: | TODO |
     |     powerpc: |  ok  |
-    |       riscv: | TODO |
+    |       riscv: |  ok  |
     |        s390: | TODO |
     |          sh: | TODO |
     |       sparc: |  ok  |
index 707514faac7be41e58365518a278611038400994..d2f2201febc8f3ad423fb2c15642b304691adee7 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 9f31ce9b9f2a479eecbef1a33802dfcef2d29308..0d0647b067624bf2026139527539dd59b821d9cb 100644 (file)
@@ -7,12 +7,13 @@
     |         arch |status|
     -----------------------
     |       alpha: | TODO |
-    |         arc: | TODO |
+    |         arc: |  ok  |
     |         arm: |  ok  |
     |       arm64: |  ok  |
     |        csky: |  ok  |
     |     hexagon: |  ok  |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index f148c4329c7adb0774f693f820278b484044d88c..13c297bbf05cc4b2a9bc952be59d40ea0517278f 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 32c88b6a910cfd5977938b1a463cac5217f62c38..931687eec67196731053e45812cb5a76ceb6589d 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index d82a1f0cdc9104a11918badec41b0a42528d7f6a..336d728b8a455f5b96e36252295ba389cffbb712 100644 (file)
@@ -36,6 +36,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index 2687564e5fa876956f1bb203ee05f68b68715eac..76d01211837238e74ba0a013cd4889cce073e567 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ..  |
     |     hexagon: |  ..  |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: |  ..  |
     |  microblaze: |  ..  |
     |        mips: | TODO |
index 1b4109199e9d1cb7cc2e32aa0c87eaf8fa18887e..a86b8b1f3d10ac5db24c077fe11f253277d14ce2 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 27327256bd058730bf78d0a3bb95df61a3d7a46f..364169f00ee2f626bbc48f43ab39ab0ca904a097 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index b9a4bda2c8f55416b53aaee5f4e2e9b8e8799256..6ea274790e471e72aa931ea485d109e0f9ca409e 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: |  ok  |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: |  ok  |
     |        mips: |  ok  |
index 4aa51c9fa32b0512398f4a1b0df238a8ad43c6ff..c9e0a16290e68ee57c0307b9b1a79e73291d4ddd 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 0306ece41faae75d4c7be8b946494a6532cd8aa2..fd17d8de5ef1e2e38a9758c65b187f51fa14339f 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: |  ..  |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 5d64e40c0092ebd3eb11f32f14742ab2406dbcbd..1a859ac05e9ef02b8d50abc086184c815277f933 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ok  |
     |     hexagon: | TODO |
     |        ia64: |  ok  |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 92c9db24a6a39f820fc37d7d0a8da5dfd730d529..b1229953391b2c3ee21445d04e748ec11005b206 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 7424fea37614b3061e9099947658694a806c72cd..02f325fbfcd0d2819a0d7ba26822e2f695d61d60 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: |  ok  |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index 60985067626b0a24f738f39324e1c1176463667e..9bfff977ef55bff9dff1914053df03d665cf2dc7 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: |  ..  |
     |     hexagon: |  ..  |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: |  ..  |
     |  microblaze: |  ..  |
     |        mips: |  ok  |
index f2dcbec6020ea5e0c3335db0ef15c9228df4c1f5..039e4e91ada33c576ae6111e1ad65172c55bc22a 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: |  ..  |
     |  microblaze: |  ..  |
     |        mips: | TODO |
index 680090df03e1918abc47f60ec5292af2714028c3..13b4940e0c3a7190f60e3a3fdbe54f2e938db43c 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: | TODO |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: | TODO |
index 205a90e820501b49eb9422a31c5c4d862464071c..b01bf7bca3e6d9e9038eeef28c413e584dba3d83 100644 (file)
@@ -13,6 +13,7 @@
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
index 9f16d6e4e11e0acdf79be4416c4ebceeb593a6c6..fc3687b5e89bf03b78da59b22fe5b7969964cc7c 100644 (file)
     |        csky: | TODO |
     |     hexagon: | TODO |
     |        ia64: | TODO |
+    |       loong: |  ok  |
     |        m68k: | TODO |
     |  microblaze: | TODO |
     |        mips: |  ok  |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: |  ok  |
     |        s390: |  ok  |
index a80a59941d2fe19b94680664b88fcb7214ecdeb2..4d19b19bcc0867a834f81498f73727eac2030508 100644 (file)
@@ -37,30 +37,31 @@ The network filesystem helper library needs a place to store a bit of state for
 its use on each netfs inode it is helping to manage.  To this end, a context
 structure is defined::
 
-       struct netfs_i_context {
+       struct netfs_inode {
+               struct inode inode;
                const struct netfs_request_ops *ops;
-               struct fscache_cookie   *cache;
+               struct fscache_cookie *cache;
        };
 
-A network filesystem that wants to use netfs lib must place one of these
-directly after the VFS ``struct inode`` it allocates, usually as part of its
-own struct.  This can be done in a way similar to the following::
+A network filesystem that wants to use netfs lib must place one of these in its
+inode wrapper struct instead of the VFS ``struct inode``.  This can be done in
+a way similar to the following::
 
        struct my_inode {
-               struct {
-                       /* These must be contiguous */
-                       struct inode            vfs_inode;
-                       struct netfs_i_context  netfs_ctx;
-               };
+               struct netfs_inode netfs; /* Netfslib context and vfs inode */
                ...
        };
 
-This allows netfslib to find its state by simple offset from the inode pointer,
-thereby allowing the netfslib helper functions to be pointed to directly by the
-VFS/VM operation tables.
+This allows netfslib to find its state by using ``container_of()`` from the
+inode pointer, thereby allowing the netfslib helper functions to be pointed to
+directly by the VFS/VM operation tables.
 
 The structure contains the following fields:
 
+ * ``inode``
+
+   The VFS inode structure.
+
  * ``ops``
 
    The set of operations provided by the network filesystem to netfslib.
@@ -78,19 +79,17 @@ To help deal with the per-inode context, a number helper functions are
 provided.  Firstly, a function to perform basic initialisation on a context and
 set the operations table pointer::
 
-       void netfs_i_context_init(struct inode *inode,
-                                 const struct netfs_request_ops *ops);
+       void netfs_inode_init(struct netfs_inode *ctx,
+                             const struct netfs_request_ops *ops);
 
-then two functions to cast between the VFS inode structure and the netfs
-context::
+then a function to cast from the VFS inode structure to the netfs context::
 
-       struct netfs_i_context *netfs_i_context(struct inode *inode);
-       struct inode *netfs_inode(struct netfs_i_context *ctx);
+       struct netfs_inode *netfs_node(struct inode *inode);
 
 and finally, a function to get the cache cookie pointer from the context
 attached to an inode (or NULL if fscache is disabled)::
 
-       struct fscache_cookie *netfs_i_cookie(struct inode *inode);
+       struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx);
 
 
 Buffered Read Helpers
@@ -137,8 +136,9 @@ Three read helpers are provided::
 
        void netfs_readahead(struct readahead_control *ractl);
        int netfs_read_folio(struct file *file,
-                          struct folio *folio);
-       int netfs_write_begin(struct file *file,
+                            struct folio *folio);
+       int netfs_write_begin(struct netfs_inode *ctx,
+                             struct file *file,
                              struct address_space *mapping,
                              loff_t pos,
                              unsigned int len,
@@ -158,9 +158,10 @@ The helpers manage the read request, calling back into the network filesystem
 through the suppplied table of operations.  Waits will be performed as
 necessary before returning for helpers that are meant to be synchronous.
 
-If an error occurs and netfs_priv is non-NULL, ops->cleanup() will be called to
-deal with it.  If some parts of the request are in progress when an error
-occurs, the request will get partially completed if sufficient data is read.
+If an error occurs, the ->free_request() will be called to clean up the
+netfs_io_request struct allocated.  If some parts of the request are in
+progress when an error occurs, the request will get partially completed if
+sufficient data is read.
 
 Additionally, there is::
 
@@ -208,8 +209,7 @@ The above fields are the ones the netfs can use.  They are:
  * ``netfs_priv``
 
    The network filesystem's private data.  The value for this can be passed in
-   to the helper functions or set during the request.  The ->cleanup() op will
-   be called if this is non-NULL at the end.
+   to the helper functions or set during the request.
 
  * ``start``
  * ``len``
@@ -294,6 +294,7 @@ through which it can issue requests and negotiate::
 
        struct netfs_request_ops {
                void (*init_request)(struct netfs_io_request *rreq, struct file *file);
+               void (*free_request)(struct netfs_io_request *rreq);
                int (*begin_cache_operation)(struct netfs_io_request *rreq);
                void (*expand_readahead)(struct netfs_io_request *rreq);
                bool (*clamp_length)(struct netfs_io_subrequest *subreq);
@@ -302,7 +303,6 @@ through which it can issue requests and negotiate::
                int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
                                         struct folio *folio, void **_fsdata);
                void (*done)(struct netfs_io_request *rreq);
-               void (*cleanup)(struct address_space *mapping, void *netfs_priv);
        };
 
 The operations are as follows:
@@ -310,7 +310,12 @@ The operations are as follows:
  * ``init_request()``
 
    [Optional] This is called to initialise the request structure.  It is given
-   the file for reference and can modify the ->netfs_priv value.
+   the file for reference.
+
+ * ``free_request()``
+
+   [Optional] This is called as the request is being deallocated so that the
+   filesystem can clean up any state it has attached there.
 
  * ``begin_cache_operation()``
 
@@ -384,11 +389,6 @@ The operations are as follows:
    [Optional] This is called after the folios in the request have all been
    unlocked (and marked uptodate if applicable).
 
- * ``cleanup``
-
-   [Optional] This is called as the request is being deallocated so that the
-   filesystem can clean up ->netfs_priv.
-
 
 
 Read Helper Procedure
index 8f9be0e658b4d6b32af016e5948e737fc697690c..67036a05b771f7757e385f729d09cb513ddd14eb 100644 (file)
@@ -137,7 +137,6 @@ needed).
    scheduler/index
    mhi/index
    peci/index
-   hte/index
 
 Architecture-agnostic documentation
 -----------------------------------
index 04216564a03cb5951e82a8eb96ffcbd62a76af70..9f41961d11d526e2006fe2e823cfdabd06e88b72 100644 (file)
@@ -2925,6 +2925,43 @@ plpmtud_probe_interval - INTEGER
 
        Default: 0
 
+reconf_enable - BOOLEAN
+        Enable or disable extension of Stream Reconfiguration functionality
+        specified in RFC6525. This extension provides the ability to "reset"
+        a stream, and it includes the Parameters of "Outgoing/Incoming SSN
+        Reset", "SSN/TSN Reset" and "Add Outgoing/Incoming Streams".
+
+       - 1: Enable extension.
+       - 0: Disable extension.
+
+       Default: 0
+
+intl_enable - BOOLEAN
+        Enable or disable extension of User Message Interleaving functionality
+        specified in RFC8260. This extension allows the interleaving of user
+        messages sent on different streams. With this feature enabled, I-DATA
+        chunk will replace DATA chunk to carry user messages if also supported
+        by the peer. Note that to use this feature, one needs to set this option
+        to 1 and also needs to set socket options SCTP_FRAGMENT_INTERLEAVE to 2
+        and SCTP_INTERLEAVING_SUPPORTED to 1.
+
+       - 1: Enable extension.
+       - 0: Disable extension.
+
+       Default: 0
+
+ecn_enable - BOOLEAN
+        Control use of Explicit Congestion Notification (ECN) by SCTP.
+        Like in TCP, ECN is used only when both ends of the SCTP connection
+        indicate support for it. This feature is useful in avoiding losses
+        due to congestion by allowing supporting routers to signal congestion
+        before having to drop packets.
+
+        1: Enable ecn.
+        0: Disable ecn.
+
+        Default: 1
+
 
 ``/proc/sys/net/core/*``
 ========================
index d43da709bf40a25e64e05042d7af0c7bd3ef4d8e..704f31da51672e3ae4c057e8aeab6f225206f3a2 100644 (file)
@@ -104,7 +104,7 @@ Whenever possible, use the PHY side RGMII delay for these reasons:
 
 * PHY device drivers in PHYLIB being reusable by nature, being able to
   configure correctly a specified delay enables more designs with similar delay
-  requirements to be operate correctly
+  requirements to be operated correctly
 
 For cases where the PHY is not capable of providing this delay, but the
 Ethernet MAC driver is capable of doing so, the correct phy_interface_t value
index 34415ae1af1b57b661c752f0d1419c984f9e34bb..19c286c23786f17e73c5f2bf2790aa2c3da4dd4d 100644 (file)
@@ -32,6 +32,7 @@ you probably needn't concern yourself with pcmciautils.
 GNU C                  5.1              gcc --version
 Clang/LLVM (optional)  11.0.0           clang --version
 GNU make               3.81             make --version
+bash                   4.2              bash --version
 binutils               2.23             ld -v
 flex                   2.5.35           flex --version
 bison                  2.0              bison --version
@@ -84,6 +85,12 @@ Make
 
 You will need GNU make 3.81 or later to build the kernel.
 
+Bash
+----
+
+Some bash scripts are used for the kernel build.
+Bash 4.2 or newer is needed.
+
 Binutils
 --------
 
@@ -362,6 +369,11 @@ Make
 
 - <ftp://ftp.gnu.org/gnu/make/>
 
+Bash
+----
+
+- <ftp://ftp.gnu.org/gnu/bash/>
+
 Binutils
 --------
 
index b0bd510807993ce376a0d180cecf93577befb983..6d5ec1e62d0933cfd8340997889e4d6c4a058b09 100644 (file)
@@ -42,7 +42,7 @@ if usbmon is built into the kernel::
        # modprobe usbmon
        #
 
-Verify that bus sockets are present:
+Verify that bus sockets are present::
 
        # ls /sys/kernel/debug/usb/usbmon
        0s  0u  1s  1t  1u  2s  2t  2u  3s  3t  3u  4s  4t  4u
index a6d3bd9d2a8d0f3ae88339e8335015eac73cfab1..f52543aedd61e1cdcea0a1574c5e301c705c0870 100644 (file)
@@ -1507,7 +1507,7 @@ F:        drivers/clocksource/arm_arch_timer.c
 ARM HDLCD DRM DRIVER
 M:     Liviu Dudau <liviu.dudau@arm.com>
 S:     Supported
-F:     Documentation/devicetree/bindings/display/arm,hdlcd.txt
+F:     Documentation/devicetree/bindings/display/arm,hdlcd.yaml
 F:     drivers/gpu/drm/arm/hdlcd_*
 
 ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT
@@ -1542,7 +1542,7 @@ M:        Mihail Atanassov <mihail.atanassov@arm.com>
 L:     Mali DP Maintainers <malidp@foss.arm.com>
 S:     Supported
 T:     git git://anongit.freedesktop.org/drm/drm-misc
-F:     Documentation/devicetree/bindings/display/arm,komeda.txt
+F:     Documentation/devicetree/bindings/display/arm,komeda.yaml
 F:     Documentation/gpu/komeda-kms.rst
 F:     drivers/gpu/drm/arm/display/include/
 F:     drivers/gpu/drm/arm/display/komeda/
@@ -1564,7 +1564,7 @@ M:        Brian Starkey <brian.starkey@arm.com>
 L:     Mali DP Maintainers <malidp@foss.arm.com>
 S:     Supported
 T:     git git://anongit.freedesktop.org/drm/drm-misc
-F:     Documentation/devicetree/bindings/display/arm,malidp.txt
+F:     Documentation/devicetree/bindings/display/arm,malidp.yaml
 F:     Documentation/gpu/afbc.rst
 F:     drivers/gpu/drm/arm/
 
@@ -2009,7 +2009,7 @@ L:        linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 T:     git git://github.com/ulli-kroll/linux.git
 F:     Documentation/devicetree/bindings/arm/gemini.yaml
-F:     Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
+F:     Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml
 F:     Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
 F:     Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml
 F:     arch/arm/boot/dts/gemini*
@@ -3757,6 +3757,13 @@ F:       include/linux/bpf_lsm.h
 F:     kernel/bpf/bpf_lsm.c
 F:     security/bpf/
 
+BPFTOOL
+M:     Quentin Monnet <quentin@isovalent.com>
+L:     bpf@vger.kernel.org
+S:     Maintained
+F:     kernel/bpf/disasm.*
+F:     tools/bpf/bpftool/
+
 BROADCOM B44 10/100 ETHERNET DRIVER
 M:     Michael Chan <michael.chan@broadcom.com>
 L:     netdev@vger.kernel.org
@@ -6078,7 +6085,7 @@ M:        Sakari Ailus <sakari.ailus@linux.intel.com>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 T:     git git://linuxtv.org/media_tree.git
-F:     Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt
+F:     Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.yaml
 F:     drivers/media/i2c/dw9807-vcm.c
 
 DOUBLETALK DRIVER
@@ -7647,6 +7654,7 @@ F:        include/uapi/scsi/fc/
 
 FILE LOCKING (flock() and fcntl()/lockf())
 M:     Jeff Layton <jlayton@kernel.org>
+M:     Chuck Lever <chuck.lever@oracle.com>
 L:     linux-fsdevel@vger.kernel.org
 S:     Maintained
 F:     fs/fcntl.c
@@ -9081,7 +9089,7 @@ HTE SUBSYSTEM
 M:     Dipen Patel <dipenp@nvidia.com>
 S:     Maintained
 F:     Documentation/devicetree/bindings/timestamp/
-F:     Documentation/hte/
+F:     Documentation/driver-api/hte/
 F:     drivers/hte/
 F:     include/linux/hte.h
 
@@ -10739,6 +10747,7 @@ W:      http://kernelnewbies.org/KernelJanitors
 
 KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
 M:     Chuck Lever <chuck.lever@oracle.com>
+M:     Jeff Layton <jlayton@kernel.org>
 L:     linux-nfs@vger.kernel.org
 S:     Supported
 W:     http://nfs.sourceforge.net/
@@ -10863,7 +10872,6 @@ F:      arch/riscv/include/asm/kvm*
 F:     arch/riscv/include/uapi/asm/kvm*
 F:     arch/riscv/kvm/
 F:     tools/testing/selftests/kvm/*/riscv/
-F:     tools/testing/selftests/kvm/riscv/
 
 KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
 M:     Christian Borntraeger <borntraeger@linux.ibm.com>
@@ -11257,6 +11265,7 @@ M:      Damien Le Moal <damien.lemoal@opensource.wdc.com>
 L:     linux-ide@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git
+F:     Documentation/ABI/testing/sysfs-ata
 F:     Documentation/devicetree/bindings/ata/
 F:     drivers/ata/
 F:     include/linux/ata.h
@@ -12696,7 +12705,6 @@ L:      netdev@vger.kernel.org
 S:     Supported
 W:     http://www.mellanox.com
 Q:     https://patchwork.kernel.org/project/netdevbpf/list/
-F:     drivers/net/ethernet/mellanox/mlx5/core/accel/*
 F:     drivers/net/ethernet/mellanox/mlx5/core/en_accel/*
 F:     drivers/net/ethernet/mellanox/mlx5/core/fpga/*
 F:     include/linux/mlx5/mlx5_ifc_fpga.h
@@ -13792,6 +13800,7 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
 F:     Documentation/devicetree/bindings/net/
 F:     drivers/connector/
 F:     drivers/net/
+F:     include/dt-bindings/net/
 F:     include/linux/etherdevice.h
 F:     include/linux/fcdevice.h
 F:     include/linux/fddidevice.h
@@ -15824,6 +15833,14 @@ S:     Maintained
 F:     Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.yaml
 F:     drivers/iio/chemical/pms7003.c
 
+PLATFORM FEATURE INFRASTRUCTURE
+M:     Juergen Gross <jgross@suse.com>
+S:     Maintained
+F:     arch/*/include/asm/platform-feature.h
+F:     include/asm-generic/platform-feature.h
+F:     include/linux/platform-feature.h
+F:     kernel/platform-feature.c
+
 PLDMFW LIBRARY
 M:     Jacob Keller <jacob.e.keller@intel.com>
 S:     Maintained
@@ -19220,7 +19237,7 @@ F:      arch/arc/plat-axs10x
 SYNOPSYS AXS10x RESET CONTROLLER DRIVER
 M:     Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
 S:     Supported
-F:     Documentation/devicetree/bindings/reset/snps,axs10x-reset.txt
+F:     Documentation/devicetree/bindings/reset/snps,axs10x-reset.yaml
 F:     drivers/reset/reset-axs10x.c
 
 SYNOPSYS CREG GPIO DRIVER
index c43d825a3c4c502daa53e309cf68e75ae588ed81..1a6678d817bd1ae70586cb4c1e70e9074d5f342f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 19
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Superb Owl
 
 # *DOCUMENTATION*
@@ -788,6 +788,7 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG)      := -fstack-protector-strong
 KBUILD_CFLAGS += $(stackp-flags-y)
 
 KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror
+KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds
 KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH)
 
 ifdef CONFIG_CC_IS_CLANG
@@ -805,6 +806,9 @@ endif
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
 
+# These result in bogus false positives
+KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer)
+
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS  += -fno-omit-frame-pointer -fno-optimize-sibling-calls
 else
index 443e8b02289773630ac9b53d35512b18047ed835..14af1fd6d247d42ff3729baa67c19c7503e912e9 100644 (file)
                        port@0 {
                                reg = <0>;
                                label = "lan1";
+                               phy-mode = "internal";
                        };
 
                        port@1 {
                                reg = <1>;
                                label = "lan2";
+                               phy-mode = "internal";
                        };
 
                        port@2 {
                                reg = <2>;
                                label = "lan3";
+                               phy-mode = "internal";
                        };
 
                        port@3 {
                                reg = <3>;
                                label = "lan4";
+                               phy-mode = "internal";
                        };
 
                        port@4 {
                                reg = <4>;
                                label = "lan5";
+                               phy-mode = "internal";
                        };
 
                        port@5 {
diff --git a/arch/arm/include/asm/xen/xen-ops.h b/arch/arm/include/asm/xen/xen-ops.h
new file mode 100644 (file)
index 0000000..7ebb7eb
--- /dev/null
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <xen/arm/xen-ops.h>
index 82ffac621854f863f8cb4b9b4f17621ffc83eb7a..059cce0185706871c702b3f95a5df71444ff24ed 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/dma-iommu.h>
 #include <asm/mach/map.h>
 #include <asm/system_info.h>
-#include <xen/swiotlb-xen.h>
+#include <asm/xen/xen-ops.h>
 
 #include "dma.h"
 #include "mm.h"
@@ -2287,10 +2287,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 
        set_dma_ops(dev, dma_ops);
 
-#ifdef CONFIG_XEN
-       if (xen_initial_domain())
-               dev->dma_ops = &xen_swiotlb_dma_ops;
-#endif
+       xen_setup_dma_ops(dev);
        dev->archdata.dma_ops_setup = true;
 }
 
index 07eb69f9e7df3d2cbf77719f0c3df62f232ceac7..1f9c3ba3283333b7b982025d09ebd046ae99c3c3 100644 (file)
@@ -443,6 +443,8 @@ static int __init xen_guest_init(void)
        if (!xen_domain())
                return 0;
 
+       xen_set_restricted_virtio_memory_access();
+
        if (!acpi_disabled)
                xen_acpi_guest_init();
        else
index 47a1e25e25bbc836e2c99cec064fd9dfd4ce7a09..de32152cea0484fb03ea11d6417fb410db577b68 100644 (file)
@@ -362,11 +362,6 @@ struct kvm_vcpu_arch {
        struct arch_timer_cpu timer_cpu;
        struct kvm_pmu pmu;
 
-       /*
-        * Anything that is not used directly from assembly code goes
-        * here.
-        */
-
        /*
         * Guest registers we preserve during guest debugging.
         *
index 55f998c3dc284fd3764e32928ccec98d541d870f..42ff95dba6da41a95785188df0b6e94b484c7e29 100644 (file)
 #define ID_AA64SMFR0_F32F32_SHIFT      32
 
 #define ID_AA64SMFR0_FA64              0x1
-#define ID_AA64SMFR0_I16I64            0x4
+#define ID_AA64SMFR0_I16I64            0xf
 #define ID_AA64SMFR0_F64F64            0x1
-#define ID_AA64SMFR0_I8I32             0x4
+#define ID_AA64SMFR0_I8I32             0xf
 #define ID_AA64SMFR0_F16F32            0x1
 #define ID_AA64SMFR0_B16F32            0x1
 #define ID_AA64SMFR0_F32F32            0x1
index 3c8af033a9976cdfd567a5a6086f013aa30e11dd..0e80db4327b604c3613890289fc07e01ed6df6ae 100644 (file)
@@ -113,6 +113,9 @@ static __always_inline bool has_vhe(void)
        /*
         * Code only run in VHE/NVHE hyp context can assume VHE is present or
         * absent. Otherwise fall back to caps.
+        * This allows the compiler to discard VHE-specific code from the
+        * nVHE object, reducing the number of external symbol references
+        * needed to link.
         */
        if (is_vhe_hyp_code())
                return true;
diff --git a/arch/arm64/include/asm/xen/xen-ops.h b/arch/arm64/include/asm/xen/xen-ops.h
new file mode 100644 (file)
index 0000000..7ebb7eb
--- /dev/null
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <xen/arm/xen-ops.h>
index 42ea2bd856c6059e3813d6219d754986aeca7669..79fac13ab2efc5d3ed09762f3860d6a4d67efe56 100644 (file)
@@ -1974,15 +1974,7 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 #ifdef CONFIG_KVM
 static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
 {
-       if (kvm_get_mode() != KVM_MODE_PROTECTED)
-               return false;
-
-       if (is_kernel_in_hyp_mode()) {
-               pr_warn("Protected KVM not available with VHE\n");
-               return false;
-       }
-
-       return true;
+       return kvm_get_mode() == KVM_MODE_PROTECTED;
 }
 #endif /* CONFIG_KVM */
 
index 819979398127e6f39ecddf9f62be3b27f9690a8a..aecf3071efdddfbe9301ed7984610cc2335a49ca 100644 (file)
@@ -331,7 +331,7 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  *    trapping to the kernel.
  *
  *    When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the
- *    corresponding Zn), P0-P15 and FFR are encoded in in
+ *    corresponding Zn), P0-P15 and FFR are encoded in
  *    task->thread.sve_state, formatted appropriately for vector
  *    length task->thread.sve_vl or, if SVCR.SM is set,
  *    task->thread.sme_vl.
@@ -1916,10 +1916,15 @@ void __efi_fpsimd_begin(void)
                        if (system_supports_sme()) {
                                svcr = read_sysreg_s(SYS_SVCR);
 
-                               if (!system_supports_fa64())
-                                       ffr = svcr & SVCR_SM_MASK;
+                               __this_cpu_write(efi_sm_state,
+                                                svcr & SVCR_SM_MASK);
 
-                               __this_cpu_write(efi_sm_state, ffr);
+                               /*
+                                * Unless we have FA64 FFR does not
+                                * exist in streaming mode.
+                                */
+                               if (!system_supports_fa64())
+                                       ffr = !(svcr & SVCR_SM_MASK);
                        }
 
                        sve_save_state(sve_state + sve_ffr_offset(sve_max_vl()),
@@ -1964,8 +1969,13 @@ void __efi_fpsimd_end(void)
                                        sysreg_clear_set_s(SYS_SVCR,
                                                           0,
                                                           SVCR_SM_MASK);
+
+                                       /*
+                                        * Unless we have FA64 FFR does not
+                                        * exist in streaming mode.
+                                        */
                                        if (!system_supports_fa64())
-                                               ffr = efi_sm_state;
+                                               ffr = false;
                                }
                        }
 
index 57b30bcf9f21de03bc58a6b6b133329eb8cd4c55..f6b00743c3994a19f78be4b81b52a6c570800ec3 100644 (file)
@@ -244,6 +244,11 @@ static void mte_update_gcr_excl(struct task_struct *task)
                SYS_GCR_EL1);
 }
 
+#ifdef CONFIG_KASAN_HW_TAGS
+/* Only called from assembly, silence sparse */
+void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr,
+                                __le32 *updptr, int nr_inst);
+
 void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr,
                                 __le32 *updptr, int nr_inst)
 {
@@ -252,6 +257,7 @@ void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr,
        if (kasan_hw_tags_enabled())
                *updptr = cpu_to_le32(aarch64_insn_gen_nop());
 }
+#endif
 
 void mte_thread_init_user(void)
 {
index 4e39ace073af0fa70ff255c301f869df6463ad2f..3b8d062e30ea412b148ccb6bc214b0907b3d16f2 100644 (file)
@@ -1230,6 +1230,9 @@ bool kvm_arch_timer_get_input_level(int vintid)
        struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
        struct arch_timer_context *timer;
 
+       if (WARN(!vcpu, "No vcpu context!\n"))
+               return false;
+
        if (vintid == vcpu_vtimer(vcpu)->irq.irq)
                timer = vcpu_vtimer(vcpu);
        else if (vintid == vcpu_ptimer(vcpu)->irq.irq)
index 400bb0fe2745b4549a616b717a396f4df18ed697..a0188144a122be9ea8e7673f13a98c2dbd9eae64 100644 (file)
@@ -150,8 +150,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        if (ret)
                goto out_free_stage2_pgd;
 
-       if (!zalloc_cpumask_var(&kvm->arch.supported_cpus, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&kvm->arch.supported_cpus, GFP_KERNEL)) {
+               ret = -ENOMEM;
                goto out_free_stage2_pgd;
+       }
        cpumask_copy(kvm->arch.supported_cpus, cpu_possible_mask);
 
        kvm_vgic_early_init(kvm);
@@ -2271,7 +2273,11 @@ static int __init early_kvm_mode_cfg(char *arg)
                return -EINVAL;
 
        if (strcmp(arg, "protected") == 0) {
-               kvm_mode = KVM_MODE_PROTECTED;
+               if (!is_kernel_in_hyp_mode())
+                       kvm_mode = KVM_MODE_PROTECTED;
+               else
+                       pr_warn_once("Protected KVM not available with VHE\n");
+
                return 0;
        }
 
index 3d251a4d2cf7bfdb3ed82df94d30b8d6b48a458c..6012b08ecb14e7f6464374cf780c9bf271af1cca 100644 (file)
@@ -80,6 +80,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
        vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED;
        vcpu->arch.flags |= KVM_ARM64_FP_HOST;
 
+       vcpu->arch.flags &= ~KVM_ARM64_HOST_SVE_ENABLED;
        if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
                vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
 
@@ -93,6 +94,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
         * operations. Do this for ZA as well for now for simplicity.
         */
        if (system_supports_sme()) {
+               vcpu->arch.flags &= ~KVM_ARM64_HOST_SME_ENABLED;
                if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
                        vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED;
 
index 78edf077fa3b61e9d99bcba88b8e370b8dd09bd3..1e78acf9662eb17490f2973ccd5a8831c876ee9b 100644 (file)
@@ -314,15 +314,11 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
                             enum kvm_pgtable_prot prot)
 {
-       hyp_assert_lock_held(&host_kvm.lock);
-
        return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
 }
 
 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
 {
-       hyp_assert_lock_held(&host_kvm.lock);
-
        return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
                               addr, size, &host_s2_pool, owner_id);
 }
index b6d86e423319f5cce0fda2fd191a1dc994652b88..35a4331ba5f31e6be1ebdcf8b87e65910346c023 100644 (file)
@@ -243,15 +243,9 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
        case SYS_ID_AA64MMFR2_EL1:
                return get_pvm_id_aa64mmfr2(vcpu);
        default:
-               /*
-                * Should never happen because all cases are covered in
-                * pvm_sys_reg_descs[].
-                */
-               WARN_ON(1);
-               break;
+               /* Unhandled ID register, RAZ */
+               return 0;
        }
-
-       return 0;
 }
 
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
@@ -332,6 +326,16 @@ static bool pvm_gic_read_sre(struct kvm_vcpu *vcpu,
 /* Mark the specified system register as an AArch64 feature id register. */
 #define AARCH64(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch64 }
 
+/*
+ * sys_reg_desc initialiser for architecturally unallocated cpufeature ID
+ * register with encoding Op0=3, Op1=0, CRn=0, CRm=crm, Op2=op2
+ * (1 <= crm < 8, 0 <= Op2 < 8).
+ */
+#define ID_UNALLOCATED(crm, op2) {                     \
+       Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2),     \
+       .access = pvm_access_id_aarch64,                \
+}
+
 /* Mark the specified system register as Read-As-Zero/Write-Ignored */
 #define RAZ_WI(REG) { SYS_DESC(REG), .access = pvm_access_raz_wi }
 
@@ -375,24 +379,46 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = {
        AARCH32(SYS_MVFR0_EL1),
        AARCH32(SYS_MVFR1_EL1),
        AARCH32(SYS_MVFR2_EL1),
+       ID_UNALLOCATED(3,3),
        AARCH32(SYS_ID_PFR2_EL1),
        AARCH32(SYS_ID_DFR1_EL1),
        AARCH32(SYS_ID_MMFR5_EL1),
+       ID_UNALLOCATED(3,7),
 
        /* AArch64 ID registers */
        /* CRm=4 */
        AARCH64(SYS_ID_AA64PFR0_EL1),
        AARCH64(SYS_ID_AA64PFR1_EL1),
+       ID_UNALLOCATED(4,2),
+       ID_UNALLOCATED(4,3),
        AARCH64(SYS_ID_AA64ZFR0_EL1),
+       ID_UNALLOCATED(4,5),
+       ID_UNALLOCATED(4,6),
+       ID_UNALLOCATED(4,7),
        AARCH64(SYS_ID_AA64DFR0_EL1),
        AARCH64(SYS_ID_AA64DFR1_EL1),
+       ID_UNALLOCATED(5,2),
+       ID_UNALLOCATED(5,3),
        AARCH64(SYS_ID_AA64AFR0_EL1),
        AARCH64(SYS_ID_AA64AFR1_EL1),
+       ID_UNALLOCATED(5,6),
+       ID_UNALLOCATED(5,7),
        AARCH64(SYS_ID_AA64ISAR0_EL1),
        AARCH64(SYS_ID_AA64ISAR1_EL1),
+       AARCH64(SYS_ID_AA64ISAR2_EL1),
+       ID_UNALLOCATED(6,3),
+       ID_UNALLOCATED(6,4),
+       ID_UNALLOCATED(6,5),
+       ID_UNALLOCATED(6,6),
+       ID_UNALLOCATED(6,7),
        AARCH64(SYS_ID_AA64MMFR0_EL1),
        AARCH64(SYS_ID_AA64MMFR1_EL1),
        AARCH64(SYS_ID_AA64MMFR2_EL1),
+       ID_UNALLOCATED(7,3),
+       ID_UNALLOCATED(7,4),
+       ID_UNALLOCATED(7,5),
+       ID_UNALLOCATED(7,6),
+       ID_UNALLOCATED(7,7),
 
        /* Scalable Vector Registers are restricted. */
 
index 77a67e9d3d14b947fa8e8369da4a184024bf03df..e070cda86e12ffeb12a94284cc34e93d55cf4353 100644 (file)
@@ -429,11 +429,11 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = {
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_SET,
                vgic_mmio_read_pending, vgic_mmio_write_spending,
-               NULL, vgic_uaccess_write_spending, 1,
+               vgic_uaccess_read_pending, vgic_uaccess_write_spending, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_CLEAR,
                vgic_mmio_read_pending, vgic_mmio_write_cpending,
-               NULL, vgic_uaccess_write_cpending, 1,
+               vgic_uaccess_read_pending, vgic_uaccess_write_cpending, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET,
                vgic_mmio_read_active, vgic_mmio_write_sactive,
index f7aa7bcd6fb8cdaed3272b577fa5fa15de290203..f15e29cc63ce1bf6b1dbac3502c1ea370bae1e3d 100644 (file)
@@ -353,42 +353,6 @@ static unsigned long vgic_mmio_read_v3_idregs(struct kvm_vcpu *vcpu,
        return 0;
 }
 
-static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
-                                                 gpa_t addr, unsigned int len)
-{
-       u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
-       u32 value = 0;
-       int i;
-
-       /*
-        * pending state of interrupt is latched in pending_latch variable.
-        * Userspace will save and restore pending state and line_level
-        * separately.
-        * Refer to Documentation/virt/kvm/devices/arm-vgic-v3.rst
-        * for handling of ISPENDR and ICPENDR.
-        */
-       for (i = 0; i < len * 8; i++) {
-               struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
-               bool state = irq->pending_latch;
-
-               if (irq->hw && vgic_irq_is_sgi(irq->intid)) {
-                       int err;
-
-                       err = irq_get_irqchip_state(irq->host_irq,
-                                                   IRQCHIP_STATE_PENDING,
-                                                   &state);
-                       WARN_ON(err);
-               }
-
-               if (state)
-                       value |= (1U << i);
-
-               vgic_put_irq(vcpu->kvm, irq);
-       }
-
-       return value;
-}
-
 static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
                                         gpa_t addr, unsigned int len,
                                         unsigned long val)
@@ -666,7 +630,7 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = {
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISPENDR,
                vgic_mmio_read_pending, vgic_mmio_write_spending,
-               vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 1,
+               vgic_uaccess_read_pending, vgic_v3_uaccess_write_pending, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICPENDR,
                vgic_mmio_read_pending, vgic_mmio_write_cpending,
@@ -750,7 +714,7 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = {
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISPENDR0,
                vgic_mmio_read_pending, vgic_mmio_write_spending,
-               vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4,
+               vgic_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICPENDR0,
                vgic_mmio_read_pending, vgic_mmio_write_cpending,
index 49837d3a3ef5625ba0c5e4d2fed57e362b55ffc0..997d0fce2088345891b22d45e7728412abd90f7d 100644 (file)
@@ -226,8 +226,9 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu,
        return 0;
 }
 
-unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
-                                    gpa_t addr, unsigned int len)
+static unsigned long __read_pending(struct kvm_vcpu *vcpu,
+                                   gpa_t addr, unsigned int len,
+                                   bool is_user)
 {
        u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
        u32 value = 0;
@@ -239,6 +240,15 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
                unsigned long flags;
                bool val;
 
+               /*
+                * When used from userspace with a GICv3 model:
+                *
+                * Pending state of interrupt is latched in pending_latch
+                * variable.  Userspace will save and restore pending state
+                * and line_level separately.
+                * Refer to Documentation/virt/kvm/devices/arm-vgic-v3.rst
+                * for handling of ISPENDR and ICPENDR.
+                */
                raw_spin_lock_irqsave(&irq->irq_lock, flags);
                if (irq->hw && vgic_irq_is_sgi(irq->intid)) {
                        int err;
@@ -248,10 +258,20 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
                                                    IRQCHIP_STATE_PENDING,
                                                    &val);
                        WARN_RATELIMIT(err, "IRQ %d", irq->host_irq);
-               } else if (vgic_irq_is_mapped_level(irq)) {
+               } else if (!is_user && vgic_irq_is_mapped_level(irq)) {
                        val = vgic_get_phys_line_level(irq);
                } else {
-                       val = irq_is_pending(irq);
+                       switch (vcpu->kvm->arch.vgic.vgic_model) {
+                       case KVM_DEV_TYPE_ARM_VGIC_V3:
+                               if (is_user) {
+                                       val = irq->pending_latch;
+                                       break;
+                               }
+                               fallthrough;
+                       default:
+                               val = irq_is_pending(irq);
+                               break;
+                       }
                }
 
                value |= ((u32)val << i);
@@ -263,6 +283,18 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
        return value;
 }
 
+unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
+                                    gpa_t addr, unsigned int len)
+{
+       return __read_pending(vcpu, addr, len, false);
+}
+
+unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu,
+                                       gpa_t addr, unsigned int len)
+{
+       return __read_pending(vcpu, addr, len, true);
+}
+
 static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq)
 {
        return (vgic_irq_is_sgi(irq->intid) &&
index 3fa696f198a37ab9aad81832db4b76d61bcf1ece..6082d4b66d3983495967dc02f63db8d72106b77c 100644 (file)
@@ -149,6 +149,9 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu,
 unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
                                     gpa_t addr, unsigned int len);
 
+unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu,
+                                       gpa_t addr, unsigned int len);
+
 void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
                              gpa_t addr, unsigned int len,
                              unsigned long val);
index 8d5f0506fd87f392de4792431c1fdf7c0b2c2745..d78ae63d7c15f802c3d4796d56daa5e6bde319c2 100644 (file)
@@ -66,7 +66,7 @@ static void flush_context(void)
         * the next context-switch, we broadcast TLB flush + I-cache
         * invalidation over the inner shareable domain on rollover.
         */
-        kvm_call_hyp(__kvm_flush_vm_context);
+       kvm_call_hyp(__kvm_flush_vm_context);
 }
 
 static bool check_update_reserved_vmid(u64 vmid, u64 newvmid)
index 6719f9efea093f80449d81ecab6b816c58f57ec4..6099c81b9322372b27b1c15fdc80d7a5418001a7 100644 (file)
@@ -9,9 +9,9 @@
 #include <linux/dma-map-ops.h>
 #include <linux/dma-iommu.h>
 #include <xen/xen.h>
-#include <xen/swiotlb-xen.h>
 
 #include <asm/cacheflush.h>
+#include <asm/xen/xen-ops.h>
 
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
                enum dma_data_direction dir)
@@ -52,8 +52,5 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
        if (iommu)
                iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
-#ifdef CONFIG_XEN
-       if (xen_swiotlb_detect())
-               dev->dma_ops = &xen_swiotlb_dma_ops;
-#endif
+       xen_setup_dma_ops(dev);
 }
index 8ab4035dea2742b704dc7501b0b2128320899b1e..42f2e9a8616c3095609c182e6f50defdbe862b46 100644 (file)
@@ -1478,6 +1478,7 @@ skip_init_ctx:
                        bpf_jit_binary_free(header);
                        prog->bpf_func = NULL;
                        prog->jited = 0;
+                       prog->jited_len = 0;
                        goto out_off;
                }
                bpf_jit_binary_lock_ro(header);
index 89bfb74e28de53ca186cf516fe037bde7f152083..5c55509eb43f5d33a14a880d976bbf718f76ffed 100755 (executable)
@@ -253,7 +253,7 @@ END {
        next
 }
 
-/0b[01]+/ && block = "Enum" {
+/0b[01]+/ && block == "Enum" {
        expect_fields(2)
        val = $1
        name = $2
index 80657bf83b056d4a3b27f697326ae9122112231f..1920d52653b4150571d8551b713ae1ed4a9b4b69 100644 (file)
@@ -343,6 +343,7 @@ config NR_CPUS
 
 config NUMA
        bool "NUMA Support"
+       select SMP
        select ACPI_NUMA if ACPI
        help
          Say Y to compile the kernel with NUMA (Non-Uniform Memory Access)
index befe8184aa082b1afde8452acb4d30a22cb78437..0ef3b18f89803708d6e8a96b37c9ff037cc2e264 100644 (file)
@@ -19,7 +19,7 @@ typedef struct {
        unsigned int __softirq_pending;
 } ____cacheline_aligned irq_cpustat_t;
 
-DECLARE_PER_CPU_ALIGNED(irq_cpustat_t, irq_stat);
+DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
 #define __ARCH_IRQ_STAT
 
index 34f15a6fb1e7bc55edfe10602bdd0e4682a316cc..e6569f18c6ddfcd5e8d75bde426c4e4b5a7071fe 100644 (file)
@@ -6,6 +6,7 @@
 #define __ASM_PERCPU_H
 
 #include <asm/cmpxchg.h>
+#include <asm/loongarch.h>
 
 /* Use r21 for fast access */
 register unsigned long __my_cpu_offset __asm__("$r21");
index 551e1f37c70530be48767cfd1bc63ccd158089c7..71189b28bfb2723b5a066ad6990337848c2a1baf 100644 (file)
@@ -9,10 +9,16 @@
 #include <linux/atomic.h>
 #include <linux/bitops.h>
 #include <linux/linkage.h>
-#include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/cpumask.h>
 
+extern int smp_num_siblings;
+extern int num_processors;
+extern int disabled_cpus;
+extern cpumask_t cpu_sibling_map[];
+extern cpumask_t cpu_core_map[];
+extern cpumask_t cpu_foreign_map[];
+
 void loongson3_smp_setup(void);
 void loongson3_prepare_cpus(unsigned int max_cpus);
 void loongson3_boot_secondary(int cpu, struct task_struct *idle);
@@ -25,26 +31,11 @@ int loongson3_cpu_disable(void);
 void loongson3_cpu_die(unsigned int cpu);
 #endif
 
-#ifdef CONFIG_SMP
-
 static inline void plat_smp_setup(void)
 {
        loongson3_smp_setup();
 }
 
-#else /* !CONFIG_SMP */
-
-static inline void plat_smp_setup(void) { }
-
-#endif /* !CONFIG_SMP */
-
-extern int smp_num_siblings;
-extern int num_processors;
-extern int disabled_cpus;
-extern cpumask_t cpu_sibling_map[];
-extern cpumask_t cpu_core_map[];
-extern cpumask_t cpu_foreign_map[];
-
 static inline int raw_smp_processor_id(void)
 {
 #if defined(__VDSO__)
index d3ed99a4fdbd9cb258ce43d7fc367f39db5758c8..fb41e9e7a222cb9570adc6b3909391bfed50d82d 100644 (file)
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
 
-/*
- * Standard way to access the cycle counter.
- * Currently only used on SMP for scheduling.
- *
- * We know that all SMP capable CPUs have cycle counters.
- */
-
 typedef unsigned long cycles_t;
 
 #define get_cycles get_cycles
index b16c3dea5eeb940f3f38a1824b8df5147c4ed0c9..bb729ee8a23701391283f472369c9333ea9225b0 100644 (file)
@@ -138,6 +138,7 @@ void __init acpi_boot_table_init(void)
        }
 }
 
+#ifdef CONFIG_SMP
 static int set_processor_mask(u32 id, u32 flags)
 {
 
@@ -166,15 +167,18 @@ static int set_processor_mask(u32 id, u32 flags)
 
        return cpu;
 }
+#endif
 
 static void __init acpi_process_madt(void)
 {
+#ifdef CONFIG_SMP
        int i;
 
        for (i = 0; i < NR_CPUS; i++) {
                __cpu_number_map[i] = -1;
                __cpu_logical_map[i] = -1;
        }
+#endif
 
        loongson_sysconf.nr_cpus = num_processors;
 }
index 8c9fe29e98f0094a1705f8eca7e02386e2098fca..b38f5489d0945fd56f19128cb2192ec7eea7671e 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  */
+#include <asm/cpu-info.h>
 #include <linux/cacheinfo.h>
 
 /* Populates leaf and increments to next leaf */
index 4b671d305ede77b86627cb826f2c1de031e8889f..b34b8d792aa4d2dc2f3545d881484256b650cbec 100644 (file)
@@ -22,6 +22,8 @@
 #include <asm/setup.h>
 
 DEFINE_PER_CPU(unsigned long, irq_stack);
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
 
 struct irq_domain *cpu_domain;
 struct irq_domain *liointc_domain;
@@ -56,8 +58,11 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 
 void __init init_IRQ(void)
 {
-       int i, r, ipi_irq;
+       int i;
+#ifdef CONFIG_SMP
+       int r, ipi_irq;
        static int ipi_dummy_dev;
+#endif
        unsigned int order = get_order(IRQ_STACK_SIZE);
        struct page *page;
 
index 6d944d65f6002d31bc10d63e67f18fc90b8a0c9a..bfa0dfe8b7d75753b90737a05dd82c69e8dde24c 100644 (file)
@@ -120,10 +120,12 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 /*
  * Copy architecture-specific thread state
  */
-int copy_thread(unsigned long clone_flags, unsigned long usp,
-       unsigned long kthread_arg, struct task_struct *p, unsigned long tls)
+int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
        unsigned long childksp;
+       unsigned long tls = args->tls;
+       unsigned long usp = args->stack;
+       unsigned long clone_flags = args->flags;
        struct pt_regs *childregs, *regs = current_pt_regs();
 
        childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
@@ -136,12 +138,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        p->thread.csr_crmd = csr_read32(LOONGARCH_CSR_CRMD);
        p->thread.csr_prmd = csr_read32(LOONGARCH_CSR_PRMD);
        p->thread.csr_ecfg = csr_read32(LOONGARCH_CSR_ECFG);
-       if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
+       if (unlikely(args->fn)) {
                /* kernel thread */
-               p->thread.reg23 = usp; /* fn */
-               p->thread.reg24 = kthread_arg;
                p->thread.reg03 = childksp;
-               p->thread.reg01 = (unsigned long) ret_from_kernel_thread;
+               p->thread.reg23 = (unsigned long)args->fn;
+               p->thread.reg24 = (unsigned long)args->fn_arg;
+               p->thread.reg01 = (unsigned long)ret_from_kernel_thread;
                memset(childregs, 0, sizeof(struct pt_regs));
                childregs->csr_euen = p->thread.csr_euen;
                childregs->csr_crmd = p->thread.csr_crmd;
index 185e4035811adaa052f548dbd30e3fcfe62d5994..c74860b53375a51ddab0b9ea4bf5787f7202ac38 100644 (file)
@@ -39,7 +39,6 @@
 #include <asm/pgalloc.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
-#include <asm/smp.h>
 #include <asm/time.h>
 
 #define SMBIOS_BIOSSIZE_OFFSET         0x09
@@ -349,8 +348,6 @@ static void __init prefill_possible_map(void)
 
        nr_cpu_ids = possible;
 }
-#else
-static inline void prefill_possible_map(void) {}
 #endif
 
 void __init setup_arch(char **cmdline_p)
@@ -367,8 +364,10 @@ void __init setup_arch(char **cmdline_p)
        arch_mem_init(cmdline_p);
 
        resource_init();
+#ifdef CONFIG_SMP
        plat_smp_setup();
        prefill_possible_map();
+#endif
 
        paging_init();
 }
index b8c53b755a25aa0109d85a96ce259e542077d38a..73cec62504fbef69542af392c2edc36bd849604e 100644 (file)
@@ -66,8 +66,6 @@ static cpumask_t cpu_core_setup_map;
 
 struct secondary_data cpuboot_data;
 static DEFINE_PER_CPU(int, cpu_state);
-DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
-EXPORT_PER_CPU_SYMBOL(irq_stat);
 
 enum ipi_msg_type {
        IPI_RESCHEDULE,
index be68c1f02b794b169da802fb7be41395e07df655..c2ce2e60c8f0f65f0c3ca1ad80142946b2a9d0ec 100644 (file)
@@ -223,7 +223,6 @@ config PPC
        select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
        select HAVE_HW_BREAKPOINT               if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx)
        select HAVE_IOREMAP_PROT
-       select HAVE_IRQ_EXIT_ON_IRQ_STACK
        select HAVE_IRQ_TIME_ACCOUNTING
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZMA                 if DEFAULT_UIMAGE
@@ -786,7 +785,6 @@ config THREAD_SHIFT
        range 13 15
        default "15" if PPC_256K_PAGES
        default "14" if PPC64
-       default "14" if KASAN
        default "13"
        help
          Used to define the stack size. The default is almost always what you
index 125328d1b98027e12c36c0ebd3f3dab17892cbc2..af58f1ed3952e09b067dc2ff3b87c021db95f434 100644 (file)
 
 #ifdef __KERNEL__
 
-#if defined(CONFIG_VMAP_STACK) && CONFIG_THREAD_SHIFT < PAGE_SHIFT
+#ifdef CONFIG_KASAN
+#define MIN_THREAD_SHIFT       (CONFIG_THREAD_SHIFT + 1)
+#else
+#define MIN_THREAD_SHIFT       CONFIG_THREAD_SHIFT
+#endif
+
+#if defined(CONFIG_VMAP_STACK) && MIN_THREAD_SHIFT < PAGE_SHIFT
 #define THREAD_SHIFT           PAGE_SHIFT
 #else
-#define THREAD_SHIFT           CONFIG_THREAD_SHIFT
+#define THREAD_SHIFT           MIN_THREAD_SHIFT
 #endif
 
 #define THREAD_SIZE            (1 << THREAD_SHIFT)
index 2e2a2a9bcf43f09ef4d9025c1f308d93c6c7ffe6..f91f0f29a566acf4cc3430eb84a9ead48287937c 100644 (file)
@@ -37,6 +37,8 @@ KASAN_SANITIZE_paca.o := n
 KASAN_SANITIZE_setup_64.o := n
 KASAN_SANITIZE_mce.o := n
 KASAN_SANITIZE_mce_power.o := n
+KASAN_SANITIZE_udbg.o := n
+KASAN_SANITIZE_udbg_16550.o := n
 
 # we have to be particularly careful in ppc64 to exclude code that
 # runs with translations off, as we cannot access the shadow with
index b62046bf3bb88035615f5829c35d531c9579dc37..ee043380962142e85dbc8634824b623e20da5444 100644 (file)
@@ -2158,12 +2158,12 @@ static unsigned long ___get_wchan(struct task_struct *p)
                return 0;
 
        do {
-               sp = *(unsigned long *)sp;
+               sp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
                if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD) ||
                    task_is_running(p))
                        return 0;
                if (count > 0) {
-                       ip = ((unsigned long *)sp)[STACK_FRAME_LR_SAVE];
+                       ip = READ_ONCE_NOCHECK(((unsigned long *)sp)[STACK_FRAME_LR_SAVE]);
                        if (!in_sched_functions(ip))
                                return ip;
                }
index 5dca19361316e497d676d113ea74684b37cbda37..09c49632bfe592088a78e251685ed206b5f0d9e7 100644 (file)
@@ -17,9 +17,13 @@ int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
 
 #ifdef CONFIG_PPC_FPU_REGS
        flush_fp_to_thread(child);
-       if (fpidx < (PT_FPSCR - PT_FPR0))
-               memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
-       else
+       if (fpidx < (PT_FPSCR - PT_FPR0)) {
+               if (IS_ENABLED(CONFIG_PPC32))
+                       // On 32-bit the index we are passed refers to 32-bit words
+                       *data = ((u32 *)child->thread.fp_state.fpr)[fpidx];
+               else
+                       memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
+       } else
                *data = child->thread.fp_state.fpscr;
 #else
        *data = 0;
@@ -39,9 +43,13 @@ int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
 
 #ifdef CONFIG_PPC_FPU_REGS
        flush_fp_to_thread(child);
-       if (fpidx < (PT_FPSCR - PT_FPR0))
-               memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
-       else
+       if (fpidx < (PT_FPSCR - PT_FPR0)) {
+               if (IS_ENABLED(CONFIG_PPC32))
+                       // On 32-bit the index we are passed refers to 32-bit words
+                       ((u32 *)child->thread.fp_state.fpr)[fpidx] = data;
+               else
+                       memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
+       } else
                child->thread.fp_state.fpscr = data;
 #endif
 
index 4d2dc22d4a2d54637fb1c042da1b1b5326432bcd..5d7a72b41ae7115848592b2225570583e87bd62d 100644 (file)
@@ -444,4 +444,7 @@ void __init pt_regs_check(void)
         * real registers.
         */
        BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
+
+       // ptrace_get/put_fpr() rely on PPC32 and VSX being incompatible
+       BUILD_BUG_ON(IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_VSX));
 }
index 9bb43aa53d43ec331299a2d378751b694bed609d..a6fce3106e02b73d595fee1747740b3385f1007d 100644 (file)
@@ -993,8 +993,8 @@ int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...)
  *
  * Return: A pointer to the specified errorlog or NULL if not found.
  */
-struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
-                                             uint16_t section_id)
+noinstr struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
+                                                     uint16_t section_id)
 {
        struct rtas_ext_event_log_v6 *ext_log =
                (struct rtas_ext_event_log_v6 *)log->buffer;
index d85fa9fc6f3ca4a7f12681974961308ace4a78a8..80f54723cf6d1ffa04543fb4f7d7c7a24fb82ca0 100644 (file)
@@ -224,7 +224,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
 
 /* wait for all the CPUs to hit real mode but timeout if they don't come in */
 #if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
-static void __maybe_unused crash_kexec_wait_realmode(int cpu)
+noinstr static void __maybe_unused crash_kexec_wait_realmode(int cpu)
 {
        unsigned int msecs;
        int i;
index 1f3f9fedf1bc2223a0a56a6de8bb24365051e0c5..0d04f9d5da8d2dd194cdb6be7f7d00805b9a29ee 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/cacheflush.h>
 #include <asm/kdump.h>
 #include <mm/mmu_decl.h>
-#include <generated/compile.h>
 #include <generated/utsrelease.h>
 
 struct regions {
@@ -37,10 +36,6 @@ struct regions {
        int reserved_mem_size_cells;
 };
 
-/* Simplified build-specific string for starting entropy. */
-static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@"
-               LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
-
 struct regions __initdata regions;
 
 static __init void kaslr_get_cmdline(void *fdt)
@@ -71,7 +66,8 @@ static unsigned long __init get_boot_seed(void *fdt)
 {
        unsigned long hash = 0;
 
-       hash = rotate_xor(hash, build_str, sizeof(build_str));
+       /* build-specific string for starting entropy. */
+       hash = rotate_xor(hash, linux_banner, strlen(linux_banner));
        hash = rotate_xor(hash, fdt, fdt_totalsize(fdt));
 
        return hash;
index 6488b38421999efd62dff4be1f30294cfb368559..19f0fc5c6f1b4176f208d47801366d067ba74a1c 100644 (file)
@@ -4,6 +4,7 @@
 # in particular, idle code runs a bunch of things in real mode
 KASAN_SANITIZE_idle.o := n
 KASAN_SANITIZE_pci-ioda.o := n
+KASAN_SANITIZE_pci-ioda-tce.o := n
 # pnv_machine_check_early
 KASAN_SANITIZE_setup.o := n
 
index 181b855b30509c8bf549bd246c70f4a428b6fc82..82cae08976bcdef531ceda72c7fe007767929b7d 100644 (file)
@@ -465,6 +465,9 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
        u32 available_events;
        int index, rc = 0;
 
+       if (!p->stat_buffer_len)
+               return -ENOENT;
+
        available_events = (p->stat_buffer_len  - sizeof(struct papr_scm_perf_stats))
                        / sizeof(struct papr_scm_perf_stat);
        if (available_events == 0)
index 9f764df125db9f1190249f6f3c69fac6d41e468e..6cd93995fb65e1931a5739dc19e5d58429e3fa1b 100644 (file)
@@ -97,7 +97,7 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu)
                 * We ran out of VMIDs so we increment vmid_version and
                 * start assigning VMIDs from 1.
                 *
-                * This also means existing VMIDs assignement to all Guest
+                * This also means existing VMIDs assignment to all Guest
                 * instances is invalid and we have force VMID re-assignement
                 * for all Guest instances. The Guest instances that were not
                 * running will automatically pick-up new VMIDs because will
index b1a88f6cc3494bb058b11e5ab1391c7d881ea48b..91c0b80a8bf04a6f3b1e0e3638291ef249a33a5a 100644 (file)
@@ -125,6 +125,7 @@ config S390
        select CLONE_BACKWARDS2
        select DMA_OPS if PCI
        select DYNAMIC_FTRACE if FUNCTION_TRACER
+       select GCC12_NO_ARRAY_BOUNDS
        select GENERIC_ALLOCATOR
        select GENERIC_CPU_AUTOPROBE
        select GENERIC_CPU_VULNERABILITIES
@@ -768,7 +769,6 @@ menu "Virtualization"
 config PROTECTED_VIRTUALIZATION_GUEST
        def_bool n
        prompt "Protected virtualization guest support"
-       select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
        help
          Select this option, if you want to be able to run this
          kernel as a protected virtualization KVM guest.
index d73611b35164f3a3283e2a76807026b07913f15b..495c68a4df1e9d25b98ae194d3c1095d3d29c65e 100644 (file)
@@ -32,15 +32,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += -fno-stack-protector
 KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member)
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g)
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,))
-
-ifdef CONFIG_CC_IS_GCC
-       ifeq ($(call cc-ifversion, -ge, 1200, y), y)
-               ifeq ($(call cc-ifversion, -lt, 1300, y), y)
-                       KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds)
-                       KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, array-bounds)
-               endif
-       endif
-endif
+KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds)
 
 UTS_MACHINE    := s390x
 STACK_SIZE     := $(if $(CONFIG_KASAN),65536,16384)
index 6fb6bf64326f9c9799ca48724904b2b9aac60a74..6a0ac00d5a42b45a26c0c29946a2758a02401c15 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/cma.h>
 #include <linux/gfp.h>
 #include <linux/dma-direct.h>
+#include <linux/platform-feature.h>
 #include <asm/processor.h>
 #include <linux/uaccess.h>
 #include <asm/pgalloc.h>
@@ -168,22 +169,14 @@ bool force_dma_unencrypted(struct device *dev)
        return is_prot_virt_guest();
 }
 
-#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
-
-int arch_has_restricted_virtio_memory_access(void)
-{
-       return is_prot_virt_guest();
-}
-EXPORT_SYMBOL(arch_has_restricted_virtio_memory_access);
-
-#endif
-
 /* protected virtualization */
 static void pv_init(void)
 {
        if (!is_prot_virt_guest())
                return;
 
+       platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS);
+
        /* make sure bounce buffers are shared */
        swiotlb_init(true, SWIOTLB_FORCE | SWIOTLB_VERBOSE);
        swiotlb_update_mem_attributes();
index 5c092a9153eaedcc31fe878ec40a22fd01708500..02784702318419227156d7a0b199171bc4abcb79 100644 (file)
@@ -544,6 +544,8 @@ static int um_pci_init_vqs(struct um_pci_device *dev)
        dev->cmd_vq = vqs[0];
        dev->irq_vq = vqs[1];
 
+       virtio_device_ready(dev->vdev);
+
        for (i = 0; i < NUM_IRQ_MSGS; i++) {
                void *msg = kzalloc(MAX_IRQ_MSG_SIZE, GFP_KERNEL);
 
@@ -587,7 +589,7 @@ static int um_pci_virtio_probe(struct virtio_device *vdev)
        dev->irq = irq_alloc_desc(numa_node_id());
        if (dev->irq < 0) {
                err = dev->irq;
-               goto error;
+               goto err_reset;
        }
        um_pci_devices[free].dev = dev;
        vdev->priv = dev;
@@ -604,6 +606,9 @@ static int um_pci_virtio_probe(struct virtio_device *vdev)
 
        um_pci_rescan();
        return 0;
+err_reset:
+       virtio_reset_device(vdev);
+       vdev->config->del_vqs(vdev);
 error:
        mutex_unlock(&um_pci_mtx);
        kfree(dev);
index 9783ebc4e0212b79452bc7e7b37b0d6c92eb8599..be0b95e51df663f94a5c7e4c3fc3965179d26bdc 100644 (file)
@@ -1542,7 +1542,6 @@ config X86_CPA_STATISTICS
 config X86_MEM_ENCRYPT
        select ARCH_HAS_FORCE_DMA_UNENCRYPTED
        select DYNAMIC_PHYSICAL_MASK
-       select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
        def_bool n
 
 config AMD_MEM_ENCRYPT
index 8b392b6b7b93422fd9c4a72966a59035e881e4af..3de6d8b533672bea57e9b15468de3ce835e4e76b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <asm/apic.h>
 #include <asm/desc.h>
+#include <asm/sev.h>
 #include <asm/hypervisor.h>
 #include <asm/hyperv-tlfs.h>
 #include <asm/mshyperv.h>
@@ -405,6 +406,11 @@ void __init hyperv_init(void)
        }
 
        if (hv_isolation_type_snp()) {
+               /* Negotiate GHCB Version. */
+               if (!hv_ghcb_negotiate_protocol())
+                       hv_ghcb_terminate(SEV_TERM_SET_GEN,
+                                         GHCB_SEV_ES_PROT_UNSUPPORTED);
+
                hv_ghcb_pg = alloc_percpu(union hv_ghcb *);
                if (!hv_ghcb_pg)
                        goto free_vp_assist_page;
index 2b994117581e2f19226bbc481d3d9de64021f5f3..1dbcbd9da74d445e609e2c0bcc689bf922813740 100644 (file)
@@ -53,6 +53,8 @@ union hv_ghcb {
        } hypercall;
 } __packed __aligned(HV_HYP_PAGE_SIZE);
 
+static u16 hv_ghcb_version __ro_after_init;
+
 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
 {
        union hv_ghcb *hv_ghcb;
@@ -96,12 +98,85 @@ u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
        return status;
 }
 
+static inline u64 rd_ghcb_msr(void)
+{
+       return __rdmsr(MSR_AMD64_SEV_ES_GHCB);
+}
+
+static inline void wr_ghcb_msr(u64 val)
+{
+       native_wrmsrl(MSR_AMD64_SEV_ES_GHCB, val);
+}
+
+static enum es_result hv_ghcb_hv_call(struct ghcb *ghcb, u64 exit_code,
+                                  u64 exit_info_1, u64 exit_info_2)
+{
+       /* Fill in protocol and format specifiers */
+       ghcb->protocol_version = hv_ghcb_version;
+       ghcb->ghcb_usage       = GHCB_DEFAULT_USAGE;
+
+       ghcb_set_sw_exit_code(ghcb, exit_code);
+       ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
+       ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
+
+       VMGEXIT();
+
+       if (ghcb->save.sw_exit_info_1 & GENMASK_ULL(31, 0))
+               return ES_VMM_ERROR;
+       else
+               return ES_OK;
+}
+
+void hv_ghcb_terminate(unsigned int set, unsigned int reason)
+{
+       u64 val = GHCB_MSR_TERM_REQ;
+
+       /* Tell the hypervisor what went wrong. */
+       val |= GHCB_SEV_TERM_REASON(set, reason);
+
+       /* Request Guest Termination from Hypvervisor */
+       wr_ghcb_msr(val);
+       VMGEXIT();
+
+       while (true)
+               asm volatile("hlt\n" : : : "memory");
+}
+
+bool hv_ghcb_negotiate_protocol(void)
+{
+       u64 ghcb_gpa;
+       u64 val;
+
+       /* Save ghcb page gpa. */
+       ghcb_gpa = rd_ghcb_msr();
+
+       /* Do the GHCB protocol version negotiation */
+       wr_ghcb_msr(GHCB_MSR_SEV_INFO_REQ);
+       VMGEXIT();
+       val = rd_ghcb_msr();
+
+       if (GHCB_MSR_INFO(val) != GHCB_MSR_SEV_INFO_RESP)
+               return false;
+
+       if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTOCOL_MIN ||
+           GHCB_MSR_PROTO_MIN(val) > GHCB_PROTOCOL_MAX)
+               return false;
+
+       hv_ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val),
+                            GHCB_PROTOCOL_MAX);
+
+       /* Write ghcb page back after negotiating protocol. */
+       wr_ghcb_msr(ghcb_gpa);
+       VMGEXIT();
+
+       return true;
+}
+
 void hv_ghcb_msr_write(u64 msr, u64 value)
 {
        union hv_ghcb *hv_ghcb;
        void **ghcb_base;
        unsigned long flags;
-       struct es_em_ctxt ctxt;
 
        if (!hv_ghcb_pg)
                return;
@@ -120,8 +195,7 @@ void hv_ghcb_msr_write(u64 msr, u64 value)
        ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value));
        ghcb_set_rdx(&hv_ghcb->ghcb, upper_32_bits(value));
 
-       if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt,
-                               SVM_EXIT_MSR, 1, 0))
+       if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 1, 0))
                pr_warn("Fail to write msr via ghcb %llx.\n", msr);
 
        local_irq_restore(flags);
@@ -133,7 +207,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
        union hv_ghcb *hv_ghcb;
        void **ghcb_base;
        unsigned long flags;
-       struct es_em_ctxt ctxt;
 
        /* Check size of union hv_ghcb here. */
        BUILD_BUG_ON(sizeof(union hv_ghcb) != HV_HYP_PAGE_SIZE);
@@ -152,8 +225,7 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
        }
 
        ghcb_set_rcx(&hv_ghcb->ghcb, msr);
-       if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt,
-                               SVM_EXIT_MSR, 0, 0))
+       if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 0, 0))
                pr_warn("Fail to read msr via ghcb %llx.\n", msr);
        else
                *value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax)
index 393f2bbb5e3a8405e22094e45cdef4c6953cab01..03acc823838a7e46f739ce301af252543168dcd7 100644 (file)
 #define X86_BUG_TAA                    X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
 #define X86_BUG_ITLB_MULTIHIT          X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
 #define X86_BUG_SRBDS                  X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
+#define X86_BUG_MMIO_STALE_DATA                X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
index 959d66b9be94d0230445faa642fc41e380bf5552..9217bd6cf0d14888bd2e8e7034858100934feaf1 100644 (file)
@@ -653,6 +653,7 @@ struct kvm_vcpu_arch {
        u64 ia32_misc_enable_msr;
        u64 smbase;
        u64 smi_count;
+       bool at_instruction_boundary;
        bool tpr_access_reporting;
        bool xsaves_enabled;
        bool xfd_no_write_intercept;
@@ -1046,14 +1047,77 @@ struct kvm_x86_msr_filter {
 };
 
 enum kvm_apicv_inhibit {
+
+       /********************************************************************/
+       /* INHIBITs that are relevant to both Intel's APICv and AMD's AVIC. */
+       /********************************************************************/
+
+       /*
+        * APIC acceleration is disabled by a module parameter
+        * and/or not supported in hardware.
+        */
        APICV_INHIBIT_REASON_DISABLE,
+
+       /*
+        * APIC acceleration is inhibited because AutoEOI feature is
+        * being used by a HyperV guest.
+        */
        APICV_INHIBIT_REASON_HYPERV,
+
+       /*
+        * APIC acceleration is inhibited because the userspace didn't yet
+        * enable the kernel/split irqchip.
+        */
+       APICV_INHIBIT_REASON_ABSENT,
+
+       /* APIC acceleration is inhibited because KVM_GUESTDBG_BLOCKIRQ
+        * (out of band, debug measure of blocking all interrupts on this vCPU)
+        * was enabled, to avoid AVIC/APICv bypassing it.
+        */
+       APICV_INHIBIT_REASON_BLOCKIRQ,
+
+       /*
+        * For simplicity, the APIC acceleration is inhibited
+        * first time either APIC ID or APIC base are changed by the guest
+        * from their reset values.
+        */
+       APICV_INHIBIT_REASON_APIC_ID_MODIFIED,
+       APICV_INHIBIT_REASON_APIC_BASE_MODIFIED,
+
+       /******************************************************/
+       /* INHIBITs that are relevant only to the AMD's AVIC. */
+       /******************************************************/
+
+       /*
+        * AVIC is inhibited on a vCPU because it runs a nested guest.
+        *
+        * This is needed because unlike APICv, the peers of this vCPU
+        * cannot use the doorbell mechanism to signal interrupts via AVIC when
+        * a vCPU runs nested.
+        */
        APICV_INHIBIT_REASON_NESTED,
+
+       /*
+        * On SVM, the wait for the IRQ window is implemented with pending vIRQ,
+        * which cannot be injected when the AVIC is enabled, thus AVIC
+        * is inhibited while KVM waits for IRQ window.
+        */
        APICV_INHIBIT_REASON_IRQWIN,
+
+       /*
+        * PIT (i8254) 're-inject' mode, relies on EOI intercept,
+        * which AVIC doesn't support for edge triggered interrupts.
+        */
        APICV_INHIBIT_REASON_PIT_REINJ,
+
+       /*
+        * AVIC is inhibited because the guest has x2apic in its CPUID.
+        */
        APICV_INHIBIT_REASON_X2APIC,
-       APICV_INHIBIT_REASON_BLOCKIRQ,
-       APICV_INHIBIT_REASON_ABSENT,
+
+       /*
+        * AVIC is disabled because SEV doesn't support it.
+        */
        APICV_INHIBIT_REASON_SEV,
 };
 
@@ -1300,6 +1364,8 @@ struct kvm_vcpu_stat {
        u64 nested_run;
        u64 directed_yield_attempted;
        u64 directed_yield_successful;
+       u64 preemption_reported;
+       u64 preemption_other;
        u64 guest_mode;
 };
 
index a82f603d4312d16e77b51ef404e227f2980728c3..61f0c206bff0f638fb1caeba3bb42694deb088cc 100644 (file)
@@ -179,9 +179,13 @@ int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible);
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 void hv_ghcb_msr_write(u64 msr, u64 value);
 void hv_ghcb_msr_read(u64 msr, u64 *value);
+bool hv_ghcb_negotiate_protocol(void);
+void hv_ghcb_terminate(unsigned int set, unsigned int reason);
 #else
 static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
 static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
+static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
+static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
 #endif
 
 extern bool hv_isolation_type_snp(void);
index 403e83b4adc88ea3d61337279920de39f75df6ae..d27e0581b7777ba086a772453cc52f6afacdcdeb 100644 (file)
                                                 * Not susceptible to
                                                 * TSX Async Abort (TAA) vulnerabilities.
                                                 */
+#define ARCH_CAP_SBDR_SSDP_NO          BIT(13) /*
+                                                * Not susceptible to SBDR and SSDP
+                                                * variants of Processor MMIO stale data
+                                                * vulnerabilities.
+                                                */
+#define ARCH_CAP_FBSDP_NO              BIT(14) /*
+                                                * Not susceptible to FBSDP variant of
+                                                * Processor MMIO stale data
+                                                * vulnerabilities.
+                                                */
+#define ARCH_CAP_PSDP_NO               BIT(15) /*
+                                                * Not susceptible to PSDP variant of
+                                                * Processor MMIO stale data
+                                                * vulnerabilities.
+                                                */
+#define ARCH_CAP_FB_CLEAR              BIT(17) /*
+                                                * VERW clears CPU fill buffer
+                                                * even on MDS_NO CPUs.
+                                                */
+#define ARCH_CAP_FB_CLEAR_CTRL         BIT(18) /*
+                                                * MSR_IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]
+                                                * bit available to control VERW
+                                                * behavior.
+                                                */
 
 #define MSR_IA32_FLUSH_CMD             0x0000010b
 #define L1D_FLUSH                      BIT(0)  /*
 #define MSR_IA32_MCU_OPT_CTRL          0x00000123
 #define RNGDS_MITG_DIS                 BIT(0)  /* SRBDS support */
 #define RTM_ALLOW                      BIT(1)  /* TSX development mode */
+#define FB_CLEAR_DIS                   BIT(3)  /* CPU Fill buffer clear disable */
 
 #define MSR_IA32_SYSENTER_CS           0x00000174
 #define MSR_IA32_SYSENTER_ESP          0x00000175
index acbaeaf83b61adc1f9d0e103eab18e4328047775..da251a5645b0ec25ae5eec7279684d20b26ed528 100644 (file)
@@ -269,6 +269,8 @@ DECLARE_STATIC_KEY_FALSE(mds_idle_clear);
 
 DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush);
 
+DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear);
+
 #include <asm/segment.h>
 
 /**
index 35f222aa66bfcf39fa5824350fa93d4ff79ed22d..913e593a3b45fb5de1e16170a23320bb464a0ee6 100644 (file)
@@ -439,7 +439,7 @@ do {                                                                        \
                       [ptr] "+m" (*_ptr),                              \
                       [old] "+a" (__old)                               \
                     : [new] ltype (__new)                              \
-                    : "memory", "cc");                                 \
+                    : "memory");                                       \
        if (unlikely(__err))                                            \
                goto label;                                             \
        if (unlikely(!success))                                         \
index d879a6c93609a6f655bd76f1efbb7750b68de5b7..74c62cc47a5ff35a90adc06f2653985d68700799 100644 (file)
@@ -41,8 +41,10 @@ static void __init spectre_v2_select_mitigation(void);
 static void __init ssb_select_mitigation(void);
 static void __init l1tf_select_mitigation(void);
 static void __init mds_select_mitigation(void);
-static void __init mds_print_mitigation(void);
+static void __init md_clear_update_mitigation(void);
+static void __init md_clear_select_mitigation(void);
 static void __init taa_select_mitigation(void);
+static void __init mmio_select_mitigation(void);
 static void __init srbds_select_mitigation(void);
 static void __init l1d_flush_select_mitigation(void);
 
@@ -85,6 +87,10 @@ EXPORT_SYMBOL_GPL(mds_idle_clear);
  */
 DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush);
 
+/* Controls CPU Fill buffer clear before KVM guest MMIO accesses */
+DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear);
+EXPORT_SYMBOL_GPL(mmio_stale_data_clear);
+
 void __init check_bugs(void)
 {
        identify_boot_cpu();
@@ -117,17 +123,10 @@ void __init check_bugs(void)
        spectre_v2_select_mitigation();
        ssb_select_mitigation();
        l1tf_select_mitigation();
-       mds_select_mitigation();
-       taa_select_mitigation();
+       md_clear_select_mitigation();
        srbds_select_mitigation();
        l1d_flush_select_mitigation();
 
-       /*
-        * As MDS and TAA mitigations are inter-related, print MDS
-        * mitigation until after TAA mitigation selection is done.
-        */
-       mds_print_mitigation();
-
        arch_smt_update();
 
 #ifdef CONFIG_X86_32
@@ -267,14 +266,6 @@ static void __init mds_select_mitigation(void)
        }
 }
 
-static void __init mds_print_mitigation(void)
-{
-       if (!boot_cpu_has_bug(X86_BUG_MDS) || cpu_mitigations_off())
-               return;
-
-       pr_info("%s\n", mds_strings[mds_mitigation]);
-}
-
 static int __init mds_cmdline(char *str)
 {
        if (!boot_cpu_has_bug(X86_BUG_MDS))
@@ -329,7 +320,7 @@ static void __init taa_select_mitigation(void)
        /* TSX previously disabled by tsx=off */
        if (!boot_cpu_has(X86_FEATURE_RTM)) {
                taa_mitigation = TAA_MITIGATION_TSX_DISABLED;
-               goto out;
+               return;
        }
 
        if (cpu_mitigations_off()) {
@@ -343,7 +334,7 @@ static void __init taa_select_mitigation(void)
         */
        if (taa_mitigation == TAA_MITIGATION_OFF &&
            mds_mitigation == MDS_MITIGATION_OFF)
-               goto out;
+               return;
 
        if (boot_cpu_has(X86_FEATURE_MD_CLEAR))
                taa_mitigation = TAA_MITIGATION_VERW;
@@ -375,18 +366,6 @@ static void __init taa_select_mitigation(void)
 
        if (taa_nosmt || cpu_mitigations_auto_nosmt())
                cpu_smt_disable(false);
-
-       /*
-        * Update MDS mitigation, if necessary, as the mds_user_clear is
-        * now enabled for TAA mitigation.
-        */
-       if (mds_mitigation == MDS_MITIGATION_OFF &&
-           boot_cpu_has_bug(X86_BUG_MDS)) {
-               mds_mitigation = MDS_MITIGATION_FULL;
-               mds_select_mitigation();
-       }
-out:
-       pr_info("%s\n", taa_strings[taa_mitigation]);
 }
 
 static int __init tsx_async_abort_parse_cmdline(char *str)
@@ -410,6 +389,151 @@ static int __init tsx_async_abort_parse_cmdline(char *str)
 }
 early_param("tsx_async_abort", tsx_async_abort_parse_cmdline);
 
+#undef pr_fmt
+#define pr_fmt(fmt)    "MMIO Stale Data: " fmt
+
+enum mmio_mitigations {
+       MMIO_MITIGATION_OFF,
+       MMIO_MITIGATION_UCODE_NEEDED,
+       MMIO_MITIGATION_VERW,
+};
+
+/* Default mitigation for Processor MMIO Stale Data vulnerabilities */
+static enum mmio_mitigations mmio_mitigation __ro_after_init = MMIO_MITIGATION_VERW;
+static bool mmio_nosmt __ro_after_init = false;
+
+static const char * const mmio_strings[] = {
+       [MMIO_MITIGATION_OFF]           = "Vulnerable",
+       [MMIO_MITIGATION_UCODE_NEEDED]  = "Vulnerable: Clear CPU buffers attempted, no microcode",
+       [MMIO_MITIGATION_VERW]          = "Mitigation: Clear CPU buffers",
+};
+
+static void __init mmio_select_mitigation(void)
+{
+       u64 ia32_cap;
+
+       if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
+           cpu_mitigations_off()) {
+               mmio_mitigation = MMIO_MITIGATION_OFF;
+               return;
+       }
+
+       if (mmio_mitigation == MMIO_MITIGATION_OFF)
+               return;
+
+       ia32_cap = x86_read_arch_cap_msr();
+
+       /*
+        * Enable CPU buffer clear mitigation for host and VMM, if also affected
+        * by MDS or TAA. Otherwise, enable mitigation for VMM only.
+        */
+       if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) &&
+                                             boot_cpu_has(X86_FEATURE_RTM)))
+               static_branch_enable(&mds_user_clear);
+       else
+               static_branch_enable(&mmio_stale_data_clear);
+
+       /*
+        * If Processor-MMIO-Stale-Data bug is present and Fill Buffer data can
+        * be propagated to uncore buffers, clearing the Fill buffers on idle
+        * is required irrespective of SMT state.
+        */
+       if (!(ia32_cap & ARCH_CAP_FBSDP_NO))
+               static_branch_enable(&mds_idle_clear);
+
+       /*
+        * Check if the system has the right microcode.
+        *
+        * CPU Fill buffer clear mitigation is enumerated by either an explicit
+        * FB_CLEAR or by the presence of both MD_CLEAR and L1D_FLUSH on MDS
+        * affected systems.
+        */
+       if ((ia32_cap & ARCH_CAP_FB_CLEAR) ||
+           (boot_cpu_has(X86_FEATURE_MD_CLEAR) &&
+            boot_cpu_has(X86_FEATURE_FLUSH_L1D) &&
+            !(ia32_cap & ARCH_CAP_MDS_NO)))
+               mmio_mitigation = MMIO_MITIGATION_VERW;
+       else
+               mmio_mitigation = MMIO_MITIGATION_UCODE_NEEDED;
+
+       if (mmio_nosmt || cpu_mitigations_auto_nosmt())
+               cpu_smt_disable(false);
+}
+
+static int __init mmio_stale_data_parse_cmdline(char *str)
+{
+       if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
+               return 0;
+
+       if (!str)
+               return -EINVAL;
+
+       if (!strcmp(str, "off")) {
+               mmio_mitigation = MMIO_MITIGATION_OFF;
+       } else if (!strcmp(str, "full")) {
+               mmio_mitigation = MMIO_MITIGATION_VERW;
+       } else if (!strcmp(str, "full,nosmt")) {
+               mmio_mitigation = MMIO_MITIGATION_VERW;
+               mmio_nosmt = true;
+       }
+
+       return 0;
+}
+early_param("mmio_stale_data", mmio_stale_data_parse_cmdline);
+
+#undef pr_fmt
+#define pr_fmt(fmt)     "" fmt
+
+static void __init md_clear_update_mitigation(void)
+{
+       if (cpu_mitigations_off())
+               return;
+
+       if (!static_key_enabled(&mds_user_clear))
+               goto out;
+
+       /*
+        * mds_user_clear is now enabled. Update MDS, TAA and MMIO Stale Data
+        * mitigation, if necessary.
+        */
+       if (mds_mitigation == MDS_MITIGATION_OFF &&
+           boot_cpu_has_bug(X86_BUG_MDS)) {
+               mds_mitigation = MDS_MITIGATION_FULL;
+               mds_select_mitigation();
+       }
+       if (taa_mitigation == TAA_MITIGATION_OFF &&
+           boot_cpu_has_bug(X86_BUG_TAA)) {
+               taa_mitigation = TAA_MITIGATION_VERW;
+               taa_select_mitigation();
+       }
+       if (mmio_mitigation == MMIO_MITIGATION_OFF &&
+           boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
+               mmio_mitigation = MMIO_MITIGATION_VERW;
+               mmio_select_mitigation();
+       }
+out:
+       if (boot_cpu_has_bug(X86_BUG_MDS))
+               pr_info("MDS: %s\n", mds_strings[mds_mitigation]);
+       if (boot_cpu_has_bug(X86_BUG_TAA))
+               pr_info("TAA: %s\n", taa_strings[taa_mitigation]);
+       if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
+               pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
+}
+
+static void __init md_clear_select_mitigation(void)
+{
+       mds_select_mitigation();
+       taa_select_mitigation();
+       mmio_select_mitigation();
+
+       /*
+        * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update
+        * and print their mitigation after MDS, TAA and MMIO Stale Data
+        * mitigation selection is done.
+        */
+       md_clear_update_mitigation();
+}
+
 #undef pr_fmt
 #define pr_fmt(fmt)    "SRBDS: " fmt
 
@@ -478,11 +602,13 @@ static void __init srbds_select_mitigation(void)
                return;
 
        /*
-        * Check to see if this is one of the MDS_NO systems supporting
-        * TSX that are only exposed to SRBDS when TSX is enabled.
+        * Check to see if this is one of the MDS_NO systems supporting TSX that
+        * are only exposed to SRBDS when TSX is enabled or when CPU is affected
+        * by Processor MMIO Stale Data vulnerability.
         */
        ia32_cap = x86_read_arch_cap_msr();
-       if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM))
+       if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) &&
+           !boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
                srbds_mitigation = SRBDS_MITIGATION_TSX_OFF;
        else if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
                srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR;
@@ -1116,6 +1242,8 @@ static void update_indir_branch_cond(void)
 /* Update the static key controlling the MDS CPU buffer clear in idle */
 static void update_mds_branch_idle(void)
 {
+       u64 ia32_cap = x86_read_arch_cap_msr();
+
        /*
         * Enable the idle clearing if SMT is active on CPUs which are
         * affected only by MSBDS and not any other MDS variant.
@@ -1127,14 +1255,17 @@ static void update_mds_branch_idle(void)
        if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY))
                return;
 
-       if (sched_smt_active())
+       if (sched_smt_active()) {
                static_branch_enable(&mds_idle_clear);
-       else
+       } else if (mmio_mitigation == MMIO_MITIGATION_OFF ||
+                  (ia32_cap & ARCH_CAP_FBSDP_NO)) {
                static_branch_disable(&mds_idle_clear);
+       }
 }
 
 #define MDS_MSG_SMT "MDS CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for more details.\n"
 #define TAA_MSG_SMT "TAA CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html for more details.\n"
+#define MMIO_MSG_SMT "MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.\n"
 
 void cpu_bugs_smt_update(void)
 {
@@ -1179,6 +1310,16 @@ void cpu_bugs_smt_update(void)
                break;
        }
 
+       switch (mmio_mitigation) {
+       case MMIO_MITIGATION_VERW:
+       case MMIO_MITIGATION_UCODE_NEEDED:
+               if (sched_smt_active())
+                       pr_warn_once(MMIO_MSG_SMT);
+               break;
+       case MMIO_MITIGATION_OFF:
+               break;
+       }
+
        mutex_unlock(&spec_ctrl_mutex);
 }
 
@@ -1781,6 +1922,20 @@ static ssize_t tsx_async_abort_show_state(char *buf)
                       sched_smt_active() ? "vulnerable" : "disabled");
 }
 
+static ssize_t mmio_stale_data_show_state(char *buf)
+{
+       if (mmio_mitigation == MMIO_MITIGATION_OFF)
+               return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]);
+
+       if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
+               return sysfs_emit(buf, "%s; SMT Host state unknown\n",
+                                 mmio_strings[mmio_mitigation]);
+       }
+
+       return sysfs_emit(buf, "%s; SMT %s\n", mmio_strings[mmio_mitigation],
+                         sched_smt_active() ? "vulnerable" : "disabled");
+}
+
 static char *stibp_state(void)
 {
        if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
@@ -1881,6 +2036,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
        case X86_BUG_SRBDS:
                return srbds_show_state(buf);
 
+       case X86_BUG_MMIO_STALE_DATA:
+               return mmio_stale_data_show_state(buf);
+
        default:
                break;
        }
@@ -1932,4 +2090,9 @@ ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *
 {
        return cpu_show_common(dev, attr, buf, X86_BUG_SRBDS);
 }
+
+ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA);
+}
 #endif
index c296cb1c01133e7cd195576e7ed6fa0d1df288b2..4730b0a58f24a559f3f4c5decca80589e3c64b4e 100644 (file)
@@ -1211,18 +1211,42 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
                                            X86_FEATURE_ANY, issues)
 
 #define SRBDS          BIT(0)
+/* CPU is affected by X86_BUG_MMIO_STALE_DATA */
+#define MMIO           BIT(1)
+/* CPU is affected by Shared Buffers Data Sampling (SBDS), a variant of X86_BUG_MMIO_STALE_DATA */
+#define MMIO_SBDS      BIT(2)
 
 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
        VULNBL_INTEL_STEPPINGS(IVYBRIDGE,       X86_STEPPING_ANY,               SRBDS),
        VULNBL_INTEL_STEPPINGS(HASWELL,         X86_STEPPING_ANY,               SRBDS),
        VULNBL_INTEL_STEPPINGS(HASWELL_L,       X86_STEPPING_ANY,               SRBDS),
        VULNBL_INTEL_STEPPINGS(HASWELL_G,       X86_STEPPING_ANY,               SRBDS),
+       VULNBL_INTEL_STEPPINGS(HASWELL_X,       BIT(2) | BIT(4),                MMIO),
+       VULNBL_INTEL_STEPPINGS(BROADWELL_D,     X86_STEPPINGS(0x3, 0x5),        MMIO),
        VULNBL_INTEL_STEPPINGS(BROADWELL_G,     X86_STEPPING_ANY,               SRBDS),
+       VULNBL_INTEL_STEPPINGS(BROADWELL_X,     X86_STEPPING_ANY,               MMIO),
        VULNBL_INTEL_STEPPINGS(BROADWELL,       X86_STEPPING_ANY,               SRBDS),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE_L,       X86_STEPPINGS(0x3, 0x3),        SRBDS | MMIO),
        VULNBL_INTEL_STEPPINGS(SKYLAKE_L,       X86_STEPPING_ANY,               SRBDS),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       BIT(3) | BIT(4) | BIT(6) |
+                                               BIT(7) | BIT(0xB),              MMIO),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE,         X86_STEPPINGS(0x3, 0x3),        SRBDS | MMIO),
        VULNBL_INTEL_STEPPINGS(SKYLAKE,         X86_STEPPING_ANY,               SRBDS),
-       VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPINGS(0x0, 0xC),        SRBDS),
-       VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPINGS(0x0, 0xD),        SRBDS),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPINGS(0x9, 0xC),        SRBDS | MMIO),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPINGS(0x0, 0x8),        SRBDS),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPINGS(0x9, 0xD),        SRBDS | MMIO),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPINGS(0x0, 0x8),        SRBDS),
+       VULNBL_INTEL_STEPPINGS(ICELAKE_L,       X86_STEPPINGS(0x5, 0x5),        MMIO | MMIO_SBDS),
+       VULNBL_INTEL_STEPPINGS(ICELAKE_D,       X86_STEPPINGS(0x1, 0x1),        MMIO),
+       VULNBL_INTEL_STEPPINGS(ICELAKE_X,       X86_STEPPINGS(0x4, 0x6),        MMIO),
+       VULNBL_INTEL_STEPPINGS(COMETLAKE,       BIT(2) | BIT(3) | BIT(5),       MMIO | MMIO_SBDS),
+       VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPINGS(0x1, 0x1),        MMIO | MMIO_SBDS),
+       VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPINGS(0x0, 0x0),        MMIO),
+       VULNBL_INTEL_STEPPINGS(LAKEFIELD,       X86_STEPPINGS(0x1, 0x1),        MMIO | MMIO_SBDS),
+       VULNBL_INTEL_STEPPINGS(ROCKETLAKE,      X86_STEPPINGS(0x1, 0x1),        MMIO),
+       VULNBL_INTEL_STEPPINGS(ATOM_TREMONT,    X86_STEPPINGS(0x1, 0x1),        MMIO | MMIO_SBDS),
+       VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D,  X86_STEPPING_ANY,               MMIO),
+       VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L,  X86_STEPPINGS(0x0, 0x0),        MMIO | MMIO_SBDS),
        {}
 };
 
@@ -1243,6 +1267,13 @@ u64 x86_read_arch_cap_msr(void)
        return ia32_cap;
 }
 
+static bool arch_cap_mmio_immune(u64 ia32_cap)
+{
+       return (ia32_cap & ARCH_CAP_FBSDP_NO &&
+               ia32_cap & ARCH_CAP_PSDP_NO &&
+               ia32_cap & ARCH_CAP_SBDR_SSDP_NO);
+}
+
 static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
 {
        u64 ia32_cap = x86_read_arch_cap_msr();
@@ -1296,12 +1327,27 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
        /*
         * SRBDS affects CPUs which support RDRAND or RDSEED and are listed
         * in the vulnerability blacklist.
+        *
+        * Some of the implications and mitigation of Shared Buffers Data
+        * Sampling (SBDS) are similar to SRBDS. Give SBDS same treatment as
+        * SRBDS.
         */
        if ((cpu_has(c, X86_FEATURE_RDRAND) ||
             cpu_has(c, X86_FEATURE_RDSEED)) &&
-           cpu_matches(cpu_vuln_blacklist, SRBDS))
+           cpu_matches(cpu_vuln_blacklist, SRBDS | MMIO_SBDS))
                    setup_force_cpu_bug(X86_BUG_SRBDS);
 
+       /*
+        * Processor MMIO Stale Data bug enumeration
+        *
+        * Affected CPU list is generally enough to enumerate the vulnerability,
+        * but for virtualization case check for ARCH_CAP MSR bits also, VMM may
+        * not want the guest to enumerate the bug.
+        */
+       if (cpu_matches(cpu_vuln_blacklist, MMIO) &&
+           !arch_cap_mmio_immune(ia32_cap))
+               setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
+
        if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
                return;
 
index f1bdac3f5aa8a845cb34dbb02cb3321878be8048..0e68b4c937fcd9971d5f24c943a8868618bb3fb2 100644 (file)
@@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
        }
 }
 
+static void kvm_lapic_xapic_id_updated(struct kvm_lapic *apic)
+{
+       struct kvm *kvm = apic->vcpu->kvm;
+
+       if (KVM_BUG_ON(apic_x2apic_mode(apic), kvm))
+               return;
+
+       if (kvm_xapic_id(apic) == apic->vcpu->vcpu_id)
+               return;
+
+       kvm_set_apicv_inhibit(apic->vcpu->kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED);
+}
+
 static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
 {
        int ret = 0;
@@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
 
        switch (reg) {
        case APIC_ID:           /* Local APIC ID */
-               if (!apic_x2apic_mode(apic))
+               if (!apic_x2apic_mode(apic)) {
                        kvm_apic_set_xapic_id(apic, val >> 24);
-               else
+                       kvm_lapic_xapic_id_updated(apic);
+               } else {
                        ret = 1;
+               }
                break;
 
        case APIC_TASKPRI:
@@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
                             MSR_IA32_APICBASE_BASE;
 
        if ((value & MSR_IA32_APICBASE_ENABLE) &&
-            apic->base_address != APIC_DEFAULT_PHYS_BASE)
-               pr_warn_once("APIC base relocation is unsupported by KVM");
+            apic->base_address != APIC_DEFAULT_PHYS_BASE) {
+               kvm_set_apicv_inhibit(apic->vcpu->kvm,
+                                     APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
+       }
 }
 
 void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
@@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
                        icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
                        __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
                }
+       } else {
+               kvm_lapic_xapic_id_updated(vcpu->arch.apic);
        }
 
        return 0;
index f4653688fa6db1d4bf0246e1f16188bf11612462..17252f39bd7c2ef466b1519e6c97de025f0f6562 100644 (file)
@@ -3411,7 +3411,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
                        root = mmu_alloc_root(vcpu, i << (30 - PAGE_SHIFT),
                                              i << 30, PT32_ROOT_LEVEL, true);
                        mmu->pae_root[i] = root | PT_PRESENT_MASK |
-                                          shadow_me_mask;
+                                          shadow_me_value;
                }
                mmu->root.hpa = __pa(mmu->pae_root);
        } else {
@@ -5179,7 +5179,7 @@ static void __kvm_mmu_free_obsolete_roots(struct kvm *kvm, struct kvm_mmu *mmu)
                roots_to_free |= KVM_MMU_ROOT_CURRENT;
 
        for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) {
-               if (is_obsolete_root(kvm, mmu->root.hpa))
+               if (is_obsolete_root(kvm, mmu->prev_roots[i].hpa))
                        roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
        }
 
index 6d3b3e5a5533b174ab30a5cc4c7ef12f3d26fb72..ee4802d7b36cd308c83c6966db67993613c1d5fc 100644 (file)
@@ -145,6 +145,15 @@ static bool try_step_up(struct tdp_iter *iter)
        return true;
 }
 
+/*
+ * Step the iterator back up a level in the paging structure. Should only be
+ * used when the iterator is below the root level.
+ */
+void tdp_iter_step_up(struct tdp_iter *iter)
+{
+       WARN_ON(!try_step_up(iter));
+}
+
 /*
  * Step to the next SPTE in a pre-order traversal of the paging structure.
  * To get to the next SPTE, the iterator either steps down towards the goal
index f0af385c56e035e74ce9e0d01ed2f0d2ce4c5c20..adfca0cf94d3a0cb666a6e319817474f04b32362 100644 (file)
@@ -114,5 +114,6 @@ void tdp_iter_start(struct tdp_iter *iter, struct kvm_mmu_page *root,
                    int min_level, gfn_t next_last_level_gfn);
 void tdp_iter_next(struct tdp_iter *iter);
 void tdp_iter_restart(struct tdp_iter *iter);
+void tdp_iter_step_up(struct tdp_iter *iter);
 
 #endif /* __KVM_X86_MMU_TDP_ITER_H */
index 841feaa48be5eb6425bc3c26a0af19210bfe1266..7b9265d6713101f3c1808a7eb84633a4267bbdb5 100644 (file)
@@ -1742,12 +1742,12 @@ static void zap_collapsible_spte_range(struct kvm *kvm,
        gfn_t start = slot->base_gfn;
        gfn_t end = start + slot->npages;
        struct tdp_iter iter;
+       int max_mapping_level;
        kvm_pfn_t pfn;
 
        rcu_read_lock();
 
        tdp_root_for_each_pte(iter, root, start, end) {
-retry:
                if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true))
                        continue;
 
@@ -1755,15 +1755,41 @@ retry:
                    !is_last_spte(iter.old_spte, iter.level))
                        continue;
 
+               /*
+                * This is a leaf SPTE. Check if the PFN it maps can
+                * be mapped at a higher level.
+                */
                pfn = spte_to_pfn(iter.old_spte);
-               if (kvm_is_reserved_pfn(pfn) ||
-                   iter.level >= kvm_mmu_max_mapping_level(kvm, slot, iter.gfn,
-                                                           pfn, PG_LEVEL_NUM))
+
+               if (kvm_is_reserved_pfn(pfn))
                        continue;
 
+               max_mapping_level = kvm_mmu_max_mapping_level(kvm, slot,
+                               iter.gfn, pfn, PG_LEVEL_NUM);
+
+               WARN_ON(max_mapping_level < iter.level);
+
+               /*
+                * If this page is already mapped at the highest
+                * viable level, there's nothing more to do.
+                */
+               if (max_mapping_level == iter.level)
+                       continue;
+
+               /*
+                * The page can be remapped at a higher level, so step
+                * up to zap the parent SPTE.
+                */
+               while (max_mapping_level > iter.level)
+                       tdp_iter_step_up(&iter);
+
                /* Note, a successful atomic zap also does a remote TLB flush. */
-               if (tdp_mmu_zap_spte_atomic(kvm, &iter))
-                       goto retry;
+               tdp_mmu_zap_spte_atomic(kvm, &iter);
+
+               /*
+                * If the atomic zap fails, the iter will recurse back into
+                * the same subtree to retry.
+                */
        }
 
        rcu_read_unlock();
index 54fe03714f8a6af9cc929f595d2f0b2ff86cb439..d1bc5820ea469349bedb6f61cc8d209cdb75190f 100644 (file)
@@ -291,58 +291,91 @@ void avic_ring_doorbell(struct kvm_vcpu *vcpu)
 static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source,
                                       u32 icrl, u32 icrh, u32 index)
 {
-       u32 dest, apic_id;
-       struct kvm_vcpu *vcpu;
+       u32 l1_physical_id, dest;
+       struct kvm_vcpu *target_vcpu;
        int dest_mode = icrl & APIC_DEST_MASK;
        int shorthand = icrl & APIC_SHORT_MASK;
        struct kvm_svm *kvm_svm = to_kvm_svm(kvm);
-       u32 *avic_logical_id_table = page_address(kvm_svm->avic_logical_id_table_page);
 
        if (shorthand != APIC_DEST_NOSHORT)
                return -EINVAL;
 
-       /*
-        * The AVIC incomplete IPI #vmexit info provides index into
-        * the physical APIC ID table, which can be used to derive
-        * guest physical APIC ID.
-        */
+       if (apic_x2apic_mode(source))
+               dest = icrh;
+       else
+               dest = GET_APIC_DEST_FIELD(icrh);
+
        if (dest_mode == APIC_DEST_PHYSICAL) {
-               apic_id = index;
+               /* broadcast destination, use slow path */
+               if (apic_x2apic_mode(source) && dest == X2APIC_BROADCAST)
+                       return -EINVAL;
+               if (!apic_x2apic_mode(source) && dest == APIC_BROADCAST)
+                       return -EINVAL;
+
+               l1_physical_id = dest;
+
+               if (WARN_ON_ONCE(l1_physical_id != index))
+                       return -EINVAL;
+
        } else {
-               if (!apic_x2apic_mode(source)) {
-                       /* For xAPIC logical mode, the index is for logical APIC table. */
-                       apic_id = avic_logical_id_table[index] & 0x1ff;
+               u32 bitmap, cluster;
+               int logid_index;
+
+               if (apic_x2apic_mode(source)) {
+                       /* 16 bit dest mask, 16 bit cluster id */
+                       bitmap = dest & 0xFFFF0000;
+                       cluster = (dest >> 16) << 4;
+               } else if (kvm_lapic_get_reg(source, APIC_DFR) == APIC_DFR_FLAT) {
+                       /* 8 bit dest mask*/
+                       bitmap = dest;
+                       cluster = 0;
                } else {
-                       return -EINVAL;
+                       /* 4 bit desk mask, 4 bit cluster id */
+                       bitmap = dest & 0xF;
+                       cluster = (dest >> 4) << 2;
                }
-       }
 
-       /*
-        * Assuming vcpu ID is the same as physical apic ID,
-        * and use it to retrieve the target vCPU.
-        */
-       vcpu = kvm_get_vcpu_by_id(kvm, apic_id);
-       if (!vcpu)
-               return -EINVAL;
+               if (unlikely(!bitmap))
+                       /* guest bug: nobody to send the logical interrupt to */
+                       return 0;
 
-       if (apic_x2apic_mode(vcpu->arch.apic))
-               dest = icrh;
-       else
-               dest = GET_APIC_DEST_FIELD(icrh);
+               if (!is_power_of_2(bitmap))
+                       /* multiple logical destinations, use slow path */
+                       return -EINVAL;
 
-       /*
-        * Try matching the destination APIC ID with the vCPU.
-        */
-       if (kvm_apic_match_dest(vcpu, source, shorthand, dest, dest_mode)) {
-               vcpu->arch.apic->irr_pending = true;
-               svm_complete_interrupt_delivery(vcpu,
-                                               icrl & APIC_MODE_MASK,
-                                               icrl & APIC_INT_LEVELTRIG,
-                                               icrl & APIC_VECTOR_MASK);
-               return 0;
+               logid_index = cluster + __ffs(bitmap);
+
+               if (apic_x2apic_mode(source)) {
+                       l1_physical_id = logid_index;
+               } else {
+                       u32 *avic_logical_id_table =
+                               page_address(kvm_svm->avic_logical_id_table_page);
+
+                       u32 logid_entry = avic_logical_id_table[logid_index];
+
+                       if (WARN_ON_ONCE(index != logid_index))
+                               return -EINVAL;
+
+                       /* guest bug: non existing/reserved logical destination */
+                       if (unlikely(!(logid_entry & AVIC_LOGICAL_ID_ENTRY_VALID_MASK)))
+                               return 0;
+
+                       l1_physical_id = logid_entry &
+                                        AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK;
+               }
        }
 
-       return -EINVAL;
+       target_vcpu = kvm_get_vcpu_by_id(kvm, l1_physical_id);
+       if (unlikely(!target_vcpu))
+               /* guest bug: non existing vCPU is a target of this IPI*/
+               return 0;
+
+       target_vcpu->arch.apic->irr_pending = true;
+       svm_complete_interrupt_delivery(target_vcpu,
+                                       icrl & APIC_MODE_MASK,
+                                       icrl & APIC_INT_LEVELTRIG,
+                                       icrl & APIC_VECTOR_MASK);
+       return 0;
 }
 
 static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
@@ -508,35 +541,6 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
        return ret;
 }
 
-static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu)
-{
-       u64 *old, *new;
-       struct vcpu_svm *svm = to_svm(vcpu);
-       u32 id = kvm_xapic_id(vcpu->arch.apic);
-
-       if (vcpu->vcpu_id == id)
-               return 0;
-
-       old = avic_get_physical_id_entry(vcpu, vcpu->vcpu_id);
-       new = avic_get_physical_id_entry(vcpu, id);
-       if (!new || !old)
-               return 1;
-
-       /* We need to move physical_id_entry to new offset */
-       *new = *old;
-       *old = 0ULL;
-       to_svm(vcpu)->avic_physical_id_cache = new;
-
-       /*
-        * Also update the guest physical APIC ID in the logical
-        * APIC ID table entry if already setup the LDR.
-        */
-       if (svm->ldr_reg)
-               avic_handle_ldr_update(vcpu);
-
-       return 0;
-}
-
 static void avic_handle_dfr_update(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -555,10 +559,6 @@ static int avic_unaccel_trap_write(struct kvm_vcpu *vcpu)
                                AVIC_UNACCEL_ACCESS_OFFSET_MASK;
 
        switch (offset) {
-       case APIC_ID:
-               if (avic_handle_apic_id_update(vcpu))
-                       return 0;
-               break;
        case APIC_LDR:
                if (avic_handle_ldr_update(vcpu))
                        return 0;
@@ -650,8 +650,6 @@ int avic_init_vcpu(struct vcpu_svm *svm)
 
 void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
 {
-       if (avic_handle_apic_id_update(vcpu) != 0)
-               return;
        avic_handle_dfr_update(vcpu);
        avic_handle_ldr_update(vcpu);
 }
@@ -910,7 +908,9 @@ bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
                          BIT(APICV_INHIBIT_REASON_PIT_REINJ) |
                          BIT(APICV_INHIBIT_REASON_X2APIC) |
                          BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |
-                         BIT(APICV_INHIBIT_REASON_SEV);
+                         BIT(APICV_INHIBIT_REASON_SEV)      |
+                         BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) |
+                         BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
 
        return supported & BIT(reason);
 }
@@ -946,7 +946,7 @@ out:
        return ret;
 }
 
-void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
        u64 entry;
        int h_physical_id = kvm_cpu_get_apicid(cpu);
@@ -978,7 +978,7 @@ void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true);
 }
 
-void __avic_vcpu_put(struct kvm_vcpu *vcpu)
+void avic_vcpu_put(struct kvm_vcpu *vcpu)
 {
        u64 entry;
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -997,25 +997,6 @@ void __avic_vcpu_put(struct kvm_vcpu *vcpu)
        WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
 }
 
-static void avic_vcpu_load(struct kvm_vcpu *vcpu)
-{
-       int cpu = get_cpu();
-
-       WARN_ON(cpu != vcpu->cpu);
-
-       __avic_vcpu_load(vcpu, cpu);
-
-       put_cpu();
-}
-
-static void avic_vcpu_put(struct kvm_vcpu *vcpu)
-{
-       preempt_disable();
-
-       __avic_vcpu_put(vcpu);
-
-       preempt_enable();
-}
 
 void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
 {
@@ -1042,7 +1023,7 @@ void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
        vmcb_mark_dirty(vmcb, VMCB_AVIC);
 
        if (activated)
-               avic_vcpu_load(vcpu);
+               avic_vcpu_load(vcpu, vcpu->cpu);
        else
                avic_vcpu_put(vcpu);
 
@@ -1075,5 +1056,5 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
        if (!kvm_vcpu_apicv_active(vcpu))
                return;
 
-       avic_vcpu_load(vcpu);
+       avic_vcpu_load(vcpu, vcpu->cpu);
 }
index bed5e1692cef0209457697cd96dc401139a6167f..ba7cd26f438fc8a1eb7bb87e053a7e2117d2eb3b 100644 (file)
@@ -616,6 +616,8 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)
        struct kvm_vcpu *vcpu = &svm->vcpu;
        struct vmcb *vmcb01 = svm->vmcb01.ptr;
        struct vmcb *vmcb02 = svm->nested.vmcb02.ptr;
+       u32 pause_count12;
+       u32 pause_thresh12;
 
        /*
         * Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2,
@@ -671,27 +673,25 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)
        if (!nested_vmcb_needs_vls_intercept(svm))
                vmcb02->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK;
 
+       pause_count12 = svm->pause_filter_enabled ? svm->nested.ctl.pause_filter_count : 0;
+       pause_thresh12 = svm->pause_threshold_enabled ? svm->nested.ctl.pause_filter_thresh : 0;
        if (kvm_pause_in_guest(svm->vcpu.kvm)) {
-               /* use guest values since host doesn't use them */
-               vmcb02->control.pause_filter_count =
-                               svm->pause_filter_enabled ?
-                               svm->nested.ctl.pause_filter_count : 0;
+               /* use guest values since host doesn't intercept PAUSE */
+               vmcb02->control.pause_filter_count = pause_count12;
+               vmcb02->control.pause_filter_thresh = pause_thresh12;
 
-               vmcb02->control.pause_filter_thresh =
-                               svm->pause_threshold_enabled ?
-                               svm->nested.ctl.pause_filter_thresh : 0;
-
-       } else if (!vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_PAUSE)) {
-               /* use host values when guest doesn't use them */
+       } else {
+               /* start from host values otherwise */
                vmcb02->control.pause_filter_count = vmcb01->control.pause_filter_count;
                vmcb02->control.pause_filter_thresh = vmcb01->control.pause_filter_thresh;
-       } else {
-               /*
-                * Intercept every PAUSE otherwise and
-                * ignore both host and guest values
-                */
-               vmcb02->control.pause_filter_count = 0;
-               vmcb02->control.pause_filter_thresh = 0;
+
+               /* ... but ensure filtering is disabled if so requested.  */
+               if (vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_PAUSE)) {
+                       if (!pause_count12)
+                               vmcb02->control.pause_filter_count = 0;
+                       if (!pause_thresh12)
+                               vmcb02->control.pause_filter_thresh = 0;
+               }
        }
 
        nested_svm_transition_tlb_flush(vcpu);
@@ -951,8 +951,11 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
        vmcb12->control.event_inj         = svm->nested.ctl.event_inj;
        vmcb12->control.event_inj_err     = svm->nested.ctl.event_inj_err;
 
-       if (!kvm_pause_in_guest(vcpu->kvm) && vmcb02->control.pause_filter_count)
+       if (!kvm_pause_in_guest(vcpu->kvm)) {
                vmcb01->control.pause_filter_count = vmcb02->control.pause_filter_count;
+               vmcb_mark_dirty(vmcb01, VMCB_INTERCEPTS);
+
+       }
 
        nested_svm_copy_common_state(svm->nested.vmcb02.ptr, svm->vmcb01.ptr);
 
@@ -982,7 +985,7 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
        if (svm->tsc_ratio_msr != kvm_default_tsc_scaling_ratio) {
                WARN_ON(!svm->tsc_scaling_enabled);
                vcpu->arch.tsc_scaling_ratio = vcpu->arch.l1_tsc_scaling_ratio;
-               svm_write_tsc_multiplier(vcpu, vcpu->arch.tsc_scaling_ratio);
+               __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
        }
 
        svm->nested.ctl.nested_cr3 = 0;
@@ -1387,7 +1390,7 @@ void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu)
        vcpu->arch.tsc_scaling_ratio =
                kvm_calc_nested_tsc_multiplier(vcpu->arch.l1_tsc_scaling_ratio,
                                               svm->tsc_ratio_msr);
-       svm_write_tsc_multiplier(vcpu, vcpu->arch.tsc_scaling_ratio);
+       __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
 }
 
 /* Inverse operation of nested_copy_vmcb_control_to_cache(). asid is copied too. */
index 200045f71df04e522e883e34756a71eda29f5cf5..87da90360bc76215ceb0342c612ef264b0acf1d0 100644 (file)
@@ -465,11 +465,24 @@ static int has_svm(void)
        return 1;
 }
 
+void __svm_write_tsc_multiplier(u64 multiplier)
+{
+       preempt_disable();
+
+       if (multiplier == __this_cpu_read(current_tsc_ratio))
+               goto out;
+
+       wrmsrl(MSR_AMD64_TSC_RATIO, multiplier);
+       __this_cpu_write(current_tsc_ratio, multiplier);
+out:
+       preempt_enable();
+}
+
 static void svm_hardware_disable(void)
 {
        /* Make sure we clean up behind us */
        if (tsc_scaling)
-               wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT);
+               __svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT);
 
        cpu_svm_disable();
 
@@ -515,8 +528,7 @@ static int svm_hardware_enable(void)
                 * Set the default value, even if we don't use TSC scaling
                 * to avoid having stale value in the msr
                 */
-               wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT);
-               __this_cpu_write(current_tsc_ratio, SVM_TSC_RATIO_DEFAULT);
+               __svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT);
        }
 
 
@@ -909,7 +921,7 @@ static void grow_ple_window(struct kvm_vcpu *vcpu)
        struct vmcb_control_area *control = &svm->vmcb->control;
        int old = control->pause_filter_count;
 
-       if (kvm_pause_in_guest(vcpu->kvm) || !old)
+       if (kvm_pause_in_guest(vcpu->kvm))
                return;
 
        control->pause_filter_count = __grow_ple_window(old,
@@ -930,7 +942,7 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu)
        struct vmcb_control_area *control = &svm->vmcb->control;
        int old = control->pause_filter_count;
 
-       if (kvm_pause_in_guest(vcpu->kvm) || !old)
+       if (kvm_pause_in_guest(vcpu->kvm))
                return;
 
        control->pause_filter_count =
@@ -999,11 +1011,12 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
        vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 }
 
-void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier)
+static void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier)
 {
-       wrmsrl(MSR_AMD64_TSC_RATIO, multiplier);
+       __svm_write_tsc_multiplier(multiplier);
 }
 
+
 /* Evaluate instruction intercepts that depend on guest CPUID features. */
 static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu,
                                              struct vcpu_svm *svm)
@@ -1363,13 +1376,8 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
                sev_es_prepare_switch_to_guest(hostsa);
        }
 
-       if (tsc_scaling) {
-               u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio;
-               if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
-                       __this_cpu_write(current_tsc_ratio, tsc_ratio);
-                       wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
-               }
-       }
+       if (tsc_scaling)
+               __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
 
        if (likely(tsc_aux_uret_slot >= 0))
                kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull);
@@ -1392,13 +1400,13 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                indirect_branch_prediction_barrier();
        }
        if (kvm_vcpu_apicv_active(vcpu))
-               __avic_vcpu_load(vcpu, cpu);
+               avic_vcpu_load(vcpu, cpu);
 }
 
 static void svm_vcpu_put(struct kvm_vcpu *vcpu)
 {
        if (kvm_vcpu_apicv_active(vcpu))
-               __avic_vcpu_put(vcpu);
+               avic_vcpu_put(vcpu);
 
        svm_prepare_host_switch(vcpu);
 
@@ -4255,6 +4263,8 @@ out:
 
 static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu)
 {
+       if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR)
+               vcpu->arch.at_instruction_boundary = true;
 }
 
 static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu)
index 21c5460e947aaf5b54e32cdfd1a602336bce47cf..1bddd336a27e088c16d747237e369dd3f13d73fd 100644 (file)
@@ -590,7 +590,7 @@ int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
                               bool has_error_code, u32 error_code);
 int nested_svm_exit_special(struct vcpu_svm *svm);
 void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu);
-void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier);
+void __svm_write_tsc_multiplier(u64 multiplier);
 void nested_copy_vmcb_control_to_cache(struct vcpu_svm *svm,
                                       struct vmcb_control_area *control);
 void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm,
@@ -610,8 +610,8 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb);
 int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu);
 int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu);
 int avic_init_vcpu(struct vcpu_svm *svm);
-void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
-void __avic_vcpu_put(struct kvm_vcpu *vcpu);
+void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
+void avic_vcpu_put(struct kvm_vcpu *vcpu);
 void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu);
 void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
 void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu);
index a07e8cd753ec55660f9142f283a7be81926b2d7d..3a919e49129bf5458692ea1c058f2bc28971bdf0 100644 (file)
@@ -229,6 +229,9 @@ static const struct {
 #define L1D_CACHE_ORDER 4
 static void *vmx_l1d_flush_pages;
 
+/* Control for disabling CPU Fill buffer clear */
+static bool __read_mostly vmx_fb_clear_ctrl_available;
+
 static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
 {
        struct page *page;
@@ -360,6 +363,60 @@ static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp)
        return sprintf(s, "%s\n", vmentry_l1d_param[l1tf_vmx_mitigation].option);
 }
 
+static void vmx_setup_fb_clear_ctrl(void)
+{
+       u64 msr;
+
+       if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES) &&
+           !boot_cpu_has_bug(X86_BUG_MDS) &&
+           !boot_cpu_has_bug(X86_BUG_TAA)) {
+               rdmsrl(MSR_IA32_ARCH_CAPABILITIES, msr);
+               if (msr & ARCH_CAP_FB_CLEAR_CTRL)
+                       vmx_fb_clear_ctrl_available = true;
+       }
+}
+
+static __always_inline void vmx_disable_fb_clear(struct vcpu_vmx *vmx)
+{
+       u64 msr;
+
+       if (!vmx->disable_fb_clear)
+               return;
+
+       rdmsrl(MSR_IA32_MCU_OPT_CTRL, msr);
+       msr |= FB_CLEAR_DIS;
+       wrmsrl(MSR_IA32_MCU_OPT_CTRL, msr);
+       /* Cache the MSR value to avoid reading it later */
+       vmx->msr_ia32_mcu_opt_ctrl = msr;
+}
+
+static __always_inline void vmx_enable_fb_clear(struct vcpu_vmx *vmx)
+{
+       if (!vmx->disable_fb_clear)
+               return;
+
+       vmx->msr_ia32_mcu_opt_ctrl &= ~FB_CLEAR_DIS;
+       wrmsrl(MSR_IA32_MCU_OPT_CTRL, vmx->msr_ia32_mcu_opt_ctrl);
+}
+
+static void vmx_update_fb_clear_dis(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx)
+{
+       vmx->disable_fb_clear = vmx_fb_clear_ctrl_available;
+
+       /*
+        * If guest will not execute VERW, there is no need to set FB_CLEAR_DIS
+        * at VMEntry. Skip the MSR read/write when a guest has no use case to
+        * execute VERW.
+        */
+       if ((vcpu->arch.arch_capabilities & ARCH_CAP_FB_CLEAR) ||
+          ((vcpu->arch.arch_capabilities & ARCH_CAP_MDS_NO) &&
+           (vcpu->arch.arch_capabilities & ARCH_CAP_TAA_NO) &&
+           (vcpu->arch.arch_capabilities & ARCH_CAP_PSDP_NO) &&
+           (vcpu->arch.arch_capabilities & ARCH_CAP_FBSDP_NO) &&
+           (vcpu->arch.arch_capabilities & ARCH_CAP_SBDR_SSDP_NO)))
+               vmx->disable_fb_clear = false;
+}
+
 static const struct kernel_param_ops vmentry_l1d_flush_ops = {
        .set = vmentry_l1d_flush_set,
        .get = vmentry_l1d_flush_get,
@@ -2252,6 +2309,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        ret = kvm_set_msr_common(vcpu, msr_info);
        }
 
+       /* FB_CLEAR may have changed, also update the FB_CLEAR_DIS behavior */
+       if (msr_index == MSR_IA32_ARCH_CAPABILITIES)
+               vmx_update_fb_clear_dis(vcpu, vmx);
+
        return ret;
 }
 
@@ -4553,6 +4614,8 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
        kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
 
        vpid_sync_context(vmx->vpid);
+
+       vmx_update_fb_clear_dis(vcpu, vmx);
 }
 
 static void vmx_enable_irq_window(struct kvm_vcpu *vcpu)
@@ -6547,6 +6610,7 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu)
                return;
 
        handle_interrupt_nmi_irqoff(vcpu, gate_offset(desc));
+       vcpu->arch.at_instruction_boundary = true;
 }
 
 static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu)
@@ -6771,6 +6835,11 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
                vmx_l1d_flush(vcpu);
        else if (static_branch_unlikely(&mds_user_clear))
                mds_clear_cpu_buffers();
+       else if (static_branch_unlikely(&mmio_stale_data_clear) &&
+                kvm_arch_has_assigned_device(vcpu->kvm))
+               mds_clear_cpu_buffers();
+
+       vmx_disable_fb_clear(vmx);
 
        if (vcpu->arch.cr2 != native_read_cr2())
                native_write_cr2(vcpu->arch.cr2);
@@ -6780,6 +6849,8 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
 
        vcpu->arch.cr2 = native_read_cr2();
 
+       vmx_enable_fb_clear(vmx);
+
        guest_state_exit_irqoff();
 }
 
@@ -7708,7 +7779,9 @@ static bool vmx_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
        ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
                          BIT(APICV_INHIBIT_REASON_ABSENT) |
                          BIT(APICV_INHIBIT_REASON_HYPERV) |
-                         BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
+                         BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |
+                         BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) |
+                         BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
 
        return supported & BIT(reason);
 }
@@ -8211,6 +8284,8 @@ static int __init vmx_init(void)
                return r;
        }
 
+       vmx_setup_fb_clear_ctrl();
+
        for_each_possible_cpu(cpu) {
                INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
 
index b98c7e96697a9a4925909a418831cdf5d5138b24..8d2342ede0c59d3c9a9a407743acfb713572de54 100644 (file)
@@ -348,6 +348,8 @@ struct vcpu_vmx {
        u64 msr_ia32_feature_control_valid_bits;
        /* SGX Launch Control public key hash */
        u64 msr_ia32_sgxlepubkeyhash[4];
+       u64 msr_ia32_mcu_opt_ctrl;
+       bool disable_fb_clear;
 
        struct pt_desc pt_desc;
        struct lbr_desc lbr_desc;
index e9473c7c73903a4fba783cb2c98bf04bdd63c1d7..1910e1e78b1534346cbf0fd85a35ad05c4c31003 100644 (file)
@@ -296,6 +296,8 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
        STATS_DESC_COUNTER(VCPU, nested_run),
        STATS_DESC_COUNTER(VCPU, directed_yield_attempted),
        STATS_DESC_COUNTER(VCPU, directed_yield_successful),
+       STATS_DESC_COUNTER(VCPU, preemption_reported),
+       STATS_DESC_COUNTER(VCPU, preemption_other),
        STATS_DESC_ICOUNTER(VCPU, guest_mode)
 };
 
@@ -1615,6 +1617,9 @@ static u64 kvm_get_arch_capabilities(void)
                 */
        }
 
+       /* Guests don't need to know "Fill buffer clear control" exists */
+       data &= ~ARCH_CAP_FB_CLEAR_CTRL;
+
        return data;
 }
 
@@ -4625,6 +4630,19 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
        struct kvm_memslots *slots;
        static const u8 preempted = KVM_VCPU_PREEMPTED;
 
+       /*
+        * The vCPU can be marked preempted if and only if the VM-Exit was on
+        * an instruction boundary and will not trigger guest emulation of any
+        * kind (see vcpu_run).  Vendor specific code controls (conservatively)
+        * when this is true, for example allowing the vCPU to be marked
+        * preempted if and only if the VM-Exit was due to a host interrupt.
+        */
+       if (!vcpu->arch.at_instruction_boundary) {
+               vcpu->stat.preemption_other++;
+               return;
+       }
+
+       vcpu->stat.preemption_reported++;
        if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
                return;
 
@@ -4654,19 +4672,21 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
        int idx;
 
-       if (vcpu->preempted && !vcpu->arch.guest_state_protected)
-               vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu);
+       if (vcpu->preempted) {
+               if (!vcpu->arch.guest_state_protected)
+                       vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu);
 
-       /*
-        * Take the srcu lock as memslots will be accessed to check the gfn
-        * cache generation against the memslots generation.
-        */
-       idx = srcu_read_lock(&vcpu->kvm->srcu);
-       if (kvm_xen_msr_enabled(vcpu->kvm))
-               kvm_xen_runstate_set_preempted(vcpu);
-       else
-               kvm_steal_time_set_preempted(vcpu);
-       srcu_read_unlock(&vcpu->kvm->srcu, idx);
+               /*
+                * Take the srcu lock as memslots will be accessed to check the gfn
+                * cache generation against the memslots generation.
+                */
+               idx = srcu_read_lock(&vcpu->kvm->srcu);
+               if (kvm_xen_msr_enabled(vcpu->kvm))
+                       kvm_xen_runstate_set_preempted(vcpu);
+               else
+                       kvm_steal_time_set_preempted(vcpu);
+               srcu_read_unlock(&vcpu->kvm->srcu, idx);
+       }
 
        static_call(kvm_x86_vcpu_put)(vcpu);
        vcpu->arch.last_host_tsc = rdtsc();
@@ -9833,6 +9853,7 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
                return;
 
        down_read(&vcpu->kvm->arch.apicv_update_lock);
+       preempt_disable();
 
        activate = kvm_vcpu_apicv_activated(vcpu);
 
@@ -9853,6 +9874,7 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
                kvm_make_request(KVM_REQ_EVENT, vcpu);
 
 out:
+       preempt_enable();
        up_read(&vcpu->kvm->arch.apicv_update_lock);
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv);
@@ -10422,6 +10444,13 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->arch.l1tf_flush_l1d = true;
 
        for (;;) {
+               /*
+                * If another guest vCPU requests a PV TLB flush in the middle
+                * of instruction emulation, the rest of the emulation could
+                * use a stale page translation. Assume that any code after
+                * this point can start executing an instruction.
+                */
+               vcpu->arch.at_instruction_boundary = false;
                if (kvm_vcpu_running(vcpu)) {
                        r = vcpu_enter_guest(vcpu);
                } else {
index ee5c4ae0755cddeec1db69e951bb14f28fc42c65..532a535a9e99f43c4cfadc1fbbb1192630225bf8 100644 (file)
@@ -159,8 +159,10 @@ static inline void kvm_xen_runstate_set_preempted(struct kvm_vcpu *vcpu)
         * behalf of the vCPU. Only if the VMM does actually block
         * does it need to enter RUNSTATE_blocked.
         */
-       if (vcpu->preempted)
-               kvm_xen_update_runstate_guest(vcpu, RUNSTATE_runnable);
+       if (WARN_ON_ONCE(!vcpu->preempted))
+               return;
+
+       kvm_xen_update_runstate_guest(vcpu, RUNSTATE_runnable);
 }
 
 /* 32-bit compatibility definitions, also used natively in 32-bit build */
index 11350e2fd7366fa3b850f0a24b55eced8c3b7327..9f27e14e185f339f58010d859c7941b6c8345f3e 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/swiotlb.h>
 #include <linux/cc_platform.h>
 #include <linux/mem_encrypt.h>
-#include <linux/virtio_config.h>
 
 /* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
 bool force_dma_unencrypted(struct device *dev)
@@ -87,9 +86,3 @@ void __init mem_encrypt_init(void)
 
        print_mem_encrypt_feature_info();
 }
-
-int arch_has_restricted_virtio_memory_access(void)
-{
-       return cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT);
-}
-EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access);
index e8f7953fda83a3caa353108894b60a01a0497128..f6d038e2cd8e827d1a9553486d4c16f6da59a15a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/virtio_config.h>
 #include <linux/cc_platform.h>
+#include <linux/platform-feature.h>
 
 #include <asm/tlbflush.h>
 #include <asm/fixmap.h>
@@ -242,6 +243,9 @@ void __init sev_setup_arch(void)
        size = total_mem * 6 / 100;
        size = clamp_val(size, IO_TLB_DEFAULT_SIZE, SZ_1G);
        swiotlb_adjust_size(size);
+
+       /* Set restricted memory access for virtio. */
+       platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS);
 }
 
 static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
index 517a9d8d8f94d02cb96d3ba24f2208741970675d..8b71b1dd76396f92dc1542c84dde948591599c52 100644 (file)
@@ -195,6 +195,8 @@ static void __init xen_hvm_guest_init(void)
        if (xen_pv_domain())
                return;
 
+       xen_set_restricted_virtio_memory_access();
+
        init_hvm_pv_info();
 
        reserve_shared_info();
index f33a4421e7cd6def0c956736707b5d14c3899f7d..e3297b15701c67fa648fb6085fafef5152ce879c 100644 (file)
@@ -109,6 +109,8 @@ static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc);
 
 static void __init xen_pv_init_platform(void)
 {
+       xen_set_restricted_virtio_memory_access();
+
        populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));
 
        set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info);
index 0d46cb728bbfab177eaf505b2760637ec2e27d97..e6d7e6b01a05c744c4264220b6ae7a9f48c9178b 100644 (file)
@@ -7046,6 +7046,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
        spin_unlock_irq(&bfqd->lock);
 #endif
 
+       blk_stat_disable_accounting(bfqd->queue);
        wbt_enable_default(bfqd->queue);
 
        kfree(bfqd);
@@ -7188,7 +7189,12 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
        bfq_init_root_group(bfqd->root_group, bfqd);
        bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group);
 
+       /* We dispatch from request queue wide instead of hw queue */
+       blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q);
+
        wbt_disable_default(q);
+       blk_stat_enable_accounting(q);
+
        return 0;
 
 out_free:
index f92d0223247b7ad851f82ad32b0fa4abe18b5209..51c99f2c5c90873eed4f7d480f3a5c91282b2888 100644 (file)
@@ -1747,26 +1747,6 @@ bad:
 }
 EXPORT_SYMBOL(bioset_init);
 
-/*
- * Initialize and setup a new bio_set, based on the settings from
- * another bio_set.
- */
-int bioset_init_from_src(struct bio_set *bs, struct bio_set *src)
-{
-       int flags;
-
-       flags = 0;
-       if (src->bvec_pool.min_nr)
-               flags |= BIOSET_NEED_BVECS;
-       if (src->rescue_workqueue)
-               flags |= BIOSET_NEED_RESCUER;
-       if (src->cache)
-               flags |= BIOSET_PERCPU_CACHE;
-
-       return bioset_init(bs, src->bio_pool.min_nr, src->front_pad, flags);
-}
-EXPORT_SYMBOL(bioset_init_from_src);
-
 static int __init init_bio(void)
 {
        int i;
index 9e56a69422b655ce433fd93cf534a9d0980e068d..eb3c65a2136258c65fb1bda2d818e1978146ec18 100644 (file)
@@ -564,6 +564,7 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
        int ret;
 
        if (!e) {
+               blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q);
                q->elevator = NULL;
                q->nr_requests = q->tag_set->queue_depth;
                return 0;
index e9bf950983c71cb979a6dbb61c1b25cd20200ea5..33145ba52c9606cee0d954b9674a8bd3d647a36c 100644 (file)
@@ -579,6 +579,8 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
        if (!blk_mq_hw_queue_mapped(data.hctx))
                goto out_queue_exit;
        cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask);
+       if (cpu >= nr_cpu_ids)
+               goto out_queue_exit;
        data.ctx = __blk_mq_get_ctx(q, cpu);
 
        if (!q->elevator)
@@ -2140,20 +2142,6 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
 }
 EXPORT_SYMBOL(blk_mq_run_hw_queue);
 
-/*
- * Is the request queue handled by an IO scheduler that does not respect
- * hardware queues when dispatching?
- */
-static bool blk_mq_has_sqsched(struct request_queue *q)
-{
-       struct elevator_queue *e = q->elevator;
-
-       if (e && e->type->ops.dispatch_request &&
-           !(e->type->elevator_features & ELEVATOR_F_MQ_AWARE))
-               return true;
-       return false;
-}
-
 /*
  * Return prefered queue to dispatch from (if any) for non-mq aware IO
  * scheduler.
@@ -2186,7 +2174,7 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async)
        unsigned long i;
 
        sq_hctx = NULL;
-       if (blk_mq_has_sqsched(q))
+       if (blk_queue_sq_sched(q))
                sq_hctx = blk_mq_get_sq_hctx(q);
        queue_for_each_hw_ctx(q, hctx, i) {
                if (blk_mq_hctx_stopped(hctx))
@@ -2214,7 +2202,7 @@ void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
        unsigned long i;
 
        sq_hctx = NULL;
-       if (blk_mq_has_sqsched(q))
+       if (blk_queue_sq_sched(q))
                sq_hctx = blk_mq_get_sq_hctx(q);
        queue_for_each_hw_ctx(q, hctx, i) {
                if (blk_mq_hctx_stopped(hctx))
@@ -3443,8 +3431,9 @@ static void blk_mq_exit_hctx(struct request_queue *q,
        if (blk_mq_hw_queue_mapped(hctx))
                blk_mq_tag_idle(hctx);
 
-       blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx],
-                       set->queue_depth, flush_rq);
+       if (blk_queue_init_done(q))
+               blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx],
+                               set->queue_depth, flush_rq);
        if (set->ops->exit_request)
                set->ops->exit_request(set, flush_rq, hctx_idx);
 
@@ -4438,12 +4427,14 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
        if (!qe)
                return false;
 
+       /* q->elevator needs protection from ->sysfs_lock */
+       mutex_lock(&q->sysfs_lock);
+
        INIT_LIST_HEAD(&qe->node);
        qe->q = q;
        qe->type = q->elevator->type;
        list_add(&qe->node, head);
 
-       mutex_lock(&q->sysfs_lock);
        /*
         * After elevator_switch_mq, the previous elevator_queue will be
         * released by elevator_release. The reference of the io scheduler
index 70ff2a599ef6168423d2c6edac18889279168099..8f7c745b4a57c650e14a031034e31e7a285b8763 100644 (file)
@@ -421,6 +421,8 @@ static int kyber_init_sched(struct request_queue *q, struct elevator_type *e)
 
        blk_stat_enable_accounting(q);
 
+       blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q);
+
        eq->elevator_data = kqd;
        q->elevator = eq;
 
@@ -1033,7 +1035,6 @@ static struct elevator_type kyber_sched = {
 #endif
        .elevator_attrs = kyber_sched_attrs,
        .elevator_name = "kyber",
-       .elevator_features = ELEVATOR_F_MQ_AWARE,
        .elevator_owner = THIS_MODULE,
 };
 
index 6ed602b2f80a5904892717bd2bbe19203045260a..1a9e835e816cd96d7494069d1f3767b5b29b502e 100644 (file)
@@ -642,6 +642,9 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e)
        spin_lock_init(&dd->lock);
        spin_lock_init(&dd->zone_lock);
 
+       /* We dispatch from request queue wide instead of hw queue */
+       blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q);
+
        q->elevator = eq;
        return 0;
 
index 56637aceaf81c62cfe63cfe6a10fe7e82835266b..cec5465f31c1c43f7395091902a70b1184c62e63 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
-/blacklist_hashes_checked
+/blacklist_hash_list
 /extract-cert
 /x509_certificate_list
 /x509_revocation_list
index bb904f90f13947936af42815d3ae5b01c7e97d6f..a8d628fd5f7b7aaa694db62b1d1a80ccb08b0e8d 100644 (file)
@@ -7,22 +7,22 @@ obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o c
 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o
 obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
 ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),)
-quiet_cmd_check_blacklist_hashes = CHECK   $(patsubst "%",%,$(2))
-      cmd_check_blacklist_hashes = $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(2); touch $@
 
-$(eval $(call config_filename,SYSTEM_BLACKLIST_HASH_LIST))
+$(obj)/blacklist_hashes.o: $(obj)/blacklist_hash_list
+CFLAGS_blacklist_hashes.o := -I $(obj)
 
-$(obj)/blacklist_hashes.o: $(obj)/blacklist_hashes_checked
+quiet_cmd_check_and_copy_blacklist_hash_list = GEN     $@
+      cmd_check_and_copy_blacklist_hash_list = \
+       $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) >&2; \
+       cat $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) > $@
 
-CFLAGS_blacklist_hashes.o += -I$(srctree)
-
-targets += blacklist_hashes_checked
-$(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE
-       $(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST))
+$(obj)/blacklist_hash_list: $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) FORCE
+       $(call if_changed,check_and_copy_blacklist_hash_list)
 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o
 else
 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
 endif
+targets += blacklist_hash_list
 
 quiet_cmd_extract_certs  = CERT    $@
       cmd_extract_certs  = $(obj)/extract-cert $(extract-cert-in) $@
@@ -33,7 +33,7 @@ $(obj)/system_certificates.o: $(obj)/x509_certificate_list
 $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE
        $(call if_changed,extract_certs)
 
-targets += x509_certificate_list blacklist_hashes_checked
+targets += x509_certificate_list
 
 # If module signing is requested, say by allyesconfig, but a key has not been
 # supplied, then one will need to be generated to make sure the build does not
index 344892337be0797cc713877ad64014b8cacaec20..86d66fe1134899479caab9c38824fe10d4b7d133 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "blacklist.h"
 
-const char __initdata *const blacklist_hashes[] = {
-#include CONFIG_SYSTEM_BLACKLIST_HASH_LIST
+const char __initconst *const blacklist_hashes[] = {
+#include "blacklist_hash_list"
        , NULL
 };
index f7ef7862f207cfd2cec59f8be18f61cf1fb56081..8c1fb9a70d66b8758cd8b3b89a4872debe588488 100644 (file)
 #include <openssl/err.h>
 #include <openssl/engine.h>
 
+/*
+ * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
+ *
+ * Remove this if/when that API is no longer used
+ */
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 #define PKEY_ID_PKCS7 2
 
 static __attribute__((noreturn))
index 19197469cfab3d7c6d5c10a53afbf239c88b0044..1d44893a997bafda0c2bee3c2beb2894841438f9 100644 (file)
@@ -15,6 +15,7 @@ source "crypto/async_tx/Kconfig"
 #
 menuconfig CRYPTO
        tristate "Cryptographic API"
+       select LIB_MEMNEQ
        help
          This option provides the core Cryptographic API.
 
index 43bc33e247d19ffb09613f2678a3743364b84d23..ceaaa9f34145ad316f53e46f69c824bc87b132c8 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 obj-$(CONFIG_CRYPTO) += crypto.o
-crypto-y := api.o cipher.o compress.o memneq.o
+crypto-y := api.o cipher.o compress.o
 
 obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o
 obj-$(CONFIG_CRYPTO_FIPS) += fips.o
index 40e816419f48c75d57930abccc015948c1c2551b..9601fa92950a061c5b9599799c57360da1f5450d 100644 (file)
@@ -2010,16 +2010,16 @@ retry:
        return err_mask;
 }
 
-static bool ata_log_supported(struct ata_device *dev, u8 log)
+static int ata_log_supported(struct ata_device *dev, u8 log)
 {
        struct ata_port *ap = dev->link->ap;
 
        if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR)
-               return false;
+               return 0;
 
        if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1))
-               return false;
-       return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false;
+               return 0;
+       return get_unaligned_le16(&ap->sector_buf[log * 2]);
 }
 
 static bool ata_identify_page_supported(struct ata_device *dev, u8 page)
@@ -2455,15 +2455,20 @@ static void ata_dev_config_cpr(struct ata_device *dev)
        struct ata_cpr_log *cpr_log = NULL;
        u8 *desc, *buf = NULL;
 
-       if (ata_id_major_version(dev->id) < 11 ||
-           !ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES))
+       if (ata_id_major_version(dev->id) < 11)
+               goto out;
+
+       buf_len = ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES);
+       if (buf_len == 0)
                goto out;
 
        /*
         * Read the concurrent positioning ranges log (0x47). We can have at
-        * most 255 32B range descriptors plus a 64B header.
+        * most 255 32B range descriptors plus a 64B header. This log varies in
+        * size, so use the size reported in the GPL directory. Reading beyond
+        * the supported length will result in an error.
         */
-       buf_len = (64 + 255 * 32 + 511) & ~511;
+       buf_len <<= 9;
        buf = kzalloc(buf_len, GFP_KERNEL);
        if (!buf)
                goto out;
@@ -5462,7 +5467,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
                                      const struct ata_port_info * const * ppi,
                                      int n_ports)
 {
-       const struct ata_port_info *pi;
+       const struct ata_port_info *pi = &ata_dummy_port_info;
        struct ata_host *host;
        int i, j;
 
@@ -5470,7 +5475,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
        if (!host)
                return NULL;
 
-       for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) {
+       for (i = 0, j = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
 
                if (ppi[j])
index 42cecf95a4e589bdd21444bd547aeb13a080a411..86dbb1cdfabd897221a1c4efe877a4200b140d7a 100644 (file)
@@ -2125,7 +2125,7 @@ static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf)
 
        /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
        rbuf[1] = 0xb9;
-       put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[3]);
+       put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]);
 
        for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) {
                desc[0] = cpr_log->cpr[i].num;
index ca129854a88c77a7301ece33fc9d73d3f3b218d6..c380278874990da00407353edc5a19c5c059f3de 100644 (file)
@@ -196,7 +196,7 @@ static struct {
        { XFER_PIO_0,                   "XFER_PIO_0" },
        { XFER_PIO_SLOW,                "XFER_PIO_SLOW" }
 };
-ata_bitfield_name_match(xfer,ata_xfer_names)
+ata_bitfield_name_search(xfer, ata_xfer_names)
 
 /*
  * ATA Port attributes
index 6b5ed3046b44d861677b943baa655c2aca9d8a51..35608a0cf552e3e062f4b1cadda63ca5cf00792c 100644 (file)
@@ -856,12 +856,14 @@ static int octeon_cf_probe(struct platform_device *pdev)
                                int i;
                                res_dma = platform_get_resource(dma_dev, IORESOURCE_MEM, 0);
                                if (!res_dma) {
+                                       put_device(&dma_dev->dev);
                                        of_node_put(dma_node);
                                        return -EINVAL;
                                }
                                cf_port->dma_base = (u64)devm_ioremap(&pdev->dev, res_dma->start,
                                                                         resource_size(res_dma));
                                if (!cf_port->dma_base) {
+                                       put_device(&dma_dev->dev);
                                        of_node_put(dma_node);
                                        return -EINVAL;
                                }
@@ -871,6 +873,7 @@ static int octeon_cf_probe(struct platform_device *pdev)
                                        irq = i;
                                        irq_handler = octeon_cf_interrupt;
                                }
+                               put_device(&dma_dev->dev);
                        }
                        of_node_put(dma_node);
                }
index 2ef23fce0860c5d780d41c3eb13e51ad6132da26..a97776ea9d99067bb53c21210a7818e7dae39897 100644 (file)
@@ -564,6 +564,12 @@ ssize_t __weak cpu_show_srbds(struct device *dev,
        return sysfs_emit(buf, "Not affected\n");
 }
 
+ssize_t __weak cpu_show_mmio_stale_data(struct device *dev,
+                                       struct device_attribute *attr, char *buf)
+{
+       return sysfs_emit(buf, "Not affected\n");
+}
+
 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
 static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
 static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
@@ -573,6 +579,7 @@ static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
 static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
 static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
 static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
+static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL);
 
 static struct attribute *cpu_root_vulnerabilities_attrs[] = {
        &dev_attr_meltdown.attr,
@@ -584,6 +591,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
        &dev_attr_tsx_async_abort.attr,
        &dev_attr_itlb_multihit.attr,
        &dev_attr_srbds.attr,
+       &dev_attr_mmio_stale_data.attr,
        NULL
 };
 
index d8d0fe687111a0e0cec44c388a470df8708bdf44..397eb9880cecb8ed39914880bf64e879a8c94b32 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/memory.h>
 #include <linux/of.h>
+#include <linux/backing-dev.h>
 
 #include "base.h"
 
@@ -20,6 +21,7 @@
 void __init driver_init(void)
 {
        /* These are the core pieces */
+       bdi_init(&noop_backing_dev_info);
        devtmpfs_init();
        devices_init();
        buses_init();
index 69fd31ffb8474fe3ed546f69ed244406a2dd23b9..0b6c03643ddc67962a24e77b592ae4fe80abe2e4 100644 (file)
@@ -429,28 +429,40 @@ config ADI
          driver include crash and makedumpfile.
 
 config RANDOM_TRUST_CPU
-       bool "Trust the CPU manufacturer to initialize Linux's CRNG"
+       bool "Initialize RNG using CPU RNG instructions"
+       default y
        depends on ARCH_RANDOM
-       default n
        help
-       Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or
-       RDRAND, IBM for the S390 and Power PC architectures) is trustworthy
-       for the purposes of initializing Linux's CRNG.  Since this is not
-       something that can be independently audited, this amounts to trusting
-       that CPU manufacturer (perhaps with the insistence or mandate
-       of a Nation State's intelligence or law enforcement agencies)
-       has not installed a hidden back door to compromise the CPU's
-       random number generation facilities. This can also be configured
-       at boot with "random.trust_cpu=on/off".
+         Initialize the RNG using random numbers supplied by the CPU's
+         RNG instructions (e.g. RDRAND), if supported and available. These
+         random numbers are never used directly, but are rather hashed into
+         the main input pool, and this happens regardless of whether or not
+         this option is enabled. Instead, this option controls whether the
+         they are credited and hence can initialize the RNG. Additionally,
+         other sources of randomness are always used, regardless of this
+         setting.  Enabling this implies trusting that the CPU can supply high
+         quality and non-backdoored random numbers.
+
+         Say Y here unless you have reason to mistrust your CPU or believe
+         its RNG facilities may be faulty. This may also be configured at
+         boot time with "random.trust_cpu=on/off".
 
 config RANDOM_TRUST_BOOTLOADER
-       bool "Trust the bootloader to initialize Linux's CRNG"
-       help
-       Some bootloaders can provide entropy to increase the kernel's initial
-       device randomness. Say Y here to assume the entropy provided by the
-       booloader is trustworthy so it will be added to the kernel's entropy
-       pool. Otherwise, say N here so it will be regarded as device input that
-       only mixes the entropy pool. This can also be configured at boot with
-       "random.trust_bootloader=on/off".
+       bool "Initialize RNG using bootloader-supplied seed"
+       default y
+       help
+         Initialize the RNG using a seed supplied by the bootloader or boot
+         environment (e.g. EFI or a bootloader-generated device tree). This
+         seed is not used directly, but is rather hashed into the main input
+         pool, and this happens regardless of whether or not this option is
+         enabled. Instead, this option controls whether the seed is credited
+         and hence can initialize the RNG. Additionally, other sources of
+         randomness are always used, regardless of this setting. Enabling
+         this implies trusting that the bootloader can supply high quality and
+         non-backdoored seeds.
+
+         Say Y here unless you have reason to mistrust your bootloader or
+         believe its RNG facilities may be faulty. This may also be configured
+         at boot time with "random.trust_bootloader=on/off".
 
 endmenu
index e856df7e285c73c57e6ac9334c6e03831c12b1fb..a6f3a8a2aca6d1c9091a21da56d3efea38ba74e9 100644 (file)
@@ -159,6 +159,8 @@ static int probe_common(struct virtio_device *vdev)
                goto err_find;
        }
 
+       virtio_device_ready(vdev);
+
        /* we always have a pending entropy request */
        request_entropy(vi);
 
index 0e22e3b0a04e7f621f67f919b3c00ce500f62dd6..38aad99ebb61586c9ef4f86f5347920938e96358 100644 (file)
@@ -1019,7 +1019,7 @@ static struct parport_driver lp_driver = {
 
 static int __init lp_init(void)
 {
-       int i, err = 0;
+       int i, err;
 
        if (parport_nr[0] == LP_PARPORT_OFF)
                return 0;
index b691b9d5950331257af811d7c6f50fe113b77c51..655e327d425ec34bde22f711acb5be7ded9f5f41 100644 (file)
@@ -650,7 +650,8 @@ static void __cold _credit_init_bits(size_t bits)
 
        if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
                crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
-               execute_in_process_context(crng_set_ready, &set_ready);
+               if (static_key_initialized)
+                       execute_in_process_context(crng_set_ready, &set_ready);
                wake_up_interruptible(&crng_init_wait);
                kill_fasync(&fasync, SIGIO, POLL_IN);
                pr_notice("crng init done\n");
@@ -724,9 +725,8 @@ static void __cold _credit_init_bits(size_t bits)
  *
  **********************************************************************/
 
-static bool used_arch_random;
-static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
-static bool trust_bootloader __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
+static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
+static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
 static int __init parse_trust_cpu(char *arg)
 {
        return kstrtobool(arg, &trust_cpu);
@@ -776,7 +776,7 @@ static struct notifier_block pm_notifier = { .notifier_call = random_pm_notifica
 int __init random_init(const char *command_line)
 {
        ktime_t now = ktime_get_real();
-       unsigned int i, arch_bytes;
+       unsigned int i, arch_bits;
        unsigned long entropy;
 
 #if defined(LATENT_ENTROPY_PLUGIN)
@@ -784,12 +784,12 @@ int __init random_init(const char *command_line)
        _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
 #endif
 
-       for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE;
+       for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8;
             i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) {
                if (!arch_get_random_seed_long_early(&entropy) &&
                    !arch_get_random_long_early(&entropy)) {
                        entropy = random_get_entropy();
-                       arch_bytes -= sizeof(entropy);
+                       arch_bits -= sizeof(entropy) * 8;
                }
                _mix_pool_bytes(&entropy, sizeof(entropy));
        }
@@ -798,11 +798,18 @@ int __init random_init(const char *command_line)
        _mix_pool_bytes(command_line, strlen(command_line));
        add_latent_entropy();
 
+       /*
+        * If we were initialized by the bootloader before jump labels are
+        * initialized, then we should enable the static branch here, where
+        * it's guaranteed that jump labels have been initialized.
+        */
+       if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY)
+               crng_set_ready(NULL);
+
        if (crng_ready())
                crng_reseed();
        else if (trust_cpu)
-               credit_init_bits(arch_bytes * 8);
-       used_arch_random = arch_bytes * 8 >= POOL_READY_BITS;
+               _credit_init_bits(arch_bits);
 
        WARN_ON(register_pm_notifier(&pm_notifier));
 
@@ -811,17 +818,6 @@ int __init random_init(const char *command_line)
        return 0;
 }
 
-/*
- * Returns whether arch randomness has been mixed into the initial
- * state of the RNG, regardless of whether or not that randomness
- * was credited. Knowing this is only good for a very limited set
- * of uses, such as early init printk pointer obfuscation.
- */
-bool rng_has_arch_random(void)
-{
-       return used_arch_random;
-}
-
 /*
  * Add device- or boot-specific data to the input pool to help
  * initialize it.
@@ -865,13 +861,12 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
  * Handle random seed passed by bootloader, and credit it if
  * CONFIG_RANDOM_TRUST_BOOTLOADER is set.
  */
-void __cold add_bootloader_randomness(const void *buf, size_t len)
+void __init add_bootloader_randomness(const void *buf, size_t len)
 {
        mix_pool_bytes(buf, len);
        if (trust_bootloader)
                credit_init_bits(len * 8);
 }
-EXPORT_SYMBOL_GPL(add_bootloader_randomness);
 
 #if IS_ENABLED(CONFIG_VMGENID)
 static BLOCKING_NOTIFIER_HEAD(vmfork_chain);
index ff188ab68496e0d646f5e15ea8c5b0ef2e321c83..bb47610bbd1c4ddee413a626cf8a6eed333b451a 100644 (file)
@@ -565,4 +565,3 @@ void __init hv_init_clocksource(void)
        hv_sched_clock_offset = hv_read_reference_counter();
        hv_setup_sched_clock(read_hv_sched_clock_msr);
 }
-EXPORT_SYMBOL_GPL(hv_init_clocksource);
index b55c74a5e06483e4303f5cf6586a110ba831042b..1ee62cd58582b6496f0536fa7c45e2dc0305797f 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/seq_file.h>
+#include <linux/types.h>
 
 #define CRYSTALCOVE_GPIO_NUM   16
 #define CRYSTALCOVE_VGPIO_NUM  95
@@ -110,8 +111,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)
        return reg + gpio % 8;
 }
 
-static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg,
-                                       int gpio)
+static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, int gpio)
 {
        u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0;
        int mask = BIT(gpio % 8);
@@ -140,8 +140,7 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)
        return regmap_write(cg->regmap, reg, CTLO_INPUT_SET);
 }
 
-static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio,
-                                   int value)
+static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, int value)
 {
        struct crystalcove_gpio *cg = gpiochip_get_data(chip);
        int reg = to_reg(gpio, CTRL_OUT);
@@ -168,8 +167,7 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
        return val & 0x1;
 }
 
-static void crystalcove_gpio_set(struct gpio_chip *chip,
-                                unsigned int gpio, int value)
+static void crystalcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
 {
        struct crystalcove_gpio *cg = gpiochip_get_data(chip);
        int reg = to_reg(gpio, CTRL_OUT);
@@ -185,10 +183,10 @@ static void crystalcove_gpio_set(struct gpio_chip *chip,
 
 static int crystalcove_irq_type(struct irq_data *data, unsigned int type)
 {
-       struct crystalcove_gpio *cg =
-               gpiochip_get_data(irq_data_get_irq_chip_data(data));
+       struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));
+       irq_hw_number_t hwirq = irqd_to_hwirq(data);
 
-       if (data->hwirq >= CRYSTALCOVE_GPIO_NUM)
+       if (hwirq >= CRYSTALCOVE_GPIO_NUM)
                return 0;
 
        switch (type) {
@@ -215,22 +213,20 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned int type)
 
 static void crystalcove_bus_lock(struct irq_data *data)
 {
-       struct crystalcove_gpio *cg =
-               gpiochip_get_data(irq_data_get_irq_chip_data(data));
+       struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));
 
        mutex_lock(&cg->buslock);
 }
 
 static void crystalcove_bus_sync_unlock(struct irq_data *data)
 {
-       struct crystalcove_gpio *cg =
-               gpiochip_get_data(irq_data_get_irq_chip_data(data));
-       int gpio = data->hwirq;
+       struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data));
+       irq_hw_number_t hwirq = irqd_to_hwirq(data);
 
        if (cg->update & UPDATE_IRQ_TYPE)
-               crystalcove_update_irq_ctrl(cg, gpio);
+               crystalcove_update_irq_ctrl(cg, hwirq);
        if (cg->update & UPDATE_IRQ_MASK)
-               crystalcove_update_irq_mask(cg, gpio);
+               crystalcove_update_irq_mask(cg, hwirq);
        cg->update = 0;
 
        mutex_unlock(&cg->buslock);
@@ -238,34 +234,43 @@ static void crystalcove_bus_sync_unlock(struct irq_data *data)
 
 static void crystalcove_irq_unmask(struct irq_data *data)
 {
-       struct crystalcove_gpio *cg =
-               gpiochip_get_data(irq_data_get_irq_chip_data(data));
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+       struct crystalcove_gpio *cg = gpiochip_get_data(gc);
+       irq_hw_number_t hwirq = irqd_to_hwirq(data);
 
-       if (data->hwirq < CRYSTALCOVE_GPIO_NUM) {
-               cg->set_irq_mask = false;
-               cg->update |= UPDATE_IRQ_MASK;
-       }
+       if (hwirq >= CRYSTALCOVE_GPIO_NUM)
+               return;
+
+       gpiochip_enable_irq(gc, hwirq);
+
+       cg->set_irq_mask = false;
+       cg->update |= UPDATE_IRQ_MASK;
 }
 
 static void crystalcove_irq_mask(struct irq_data *data)
 {
-       struct crystalcove_gpio *cg =
-               gpiochip_get_data(irq_data_get_irq_chip_data(data));
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+       struct crystalcove_gpio *cg = gpiochip_get_data(gc);
+       irq_hw_number_t hwirq = irqd_to_hwirq(data);
 
-       if (data->hwirq < CRYSTALCOVE_GPIO_NUM) {
-               cg->set_irq_mask = true;
-               cg->update |= UPDATE_IRQ_MASK;
-       }
+       if (hwirq >= CRYSTALCOVE_GPIO_NUM)
+               return;
+
+       cg->set_irq_mask = true;
+       cg->update |= UPDATE_IRQ_MASK;
+
+       gpiochip_disable_irq(gc, hwirq);
 }
 
-static struct irq_chip crystalcove_irqchip = {
+static const struct irq_chip crystalcove_irqchip = {
        .name                   = "Crystal Cove",
        .irq_mask               = crystalcove_irq_mask,
        .irq_unmask             = crystalcove_irq_unmask,
        .irq_set_type           = crystalcove_irq_type,
        .irq_bus_lock           = crystalcove_bus_lock,
        .irq_bus_sync_unlock    = crystalcove_bus_sync_unlock,
-       .flags                  = IRQCHIP_SKIP_SET_WAKE,
+       .flags                  = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
 static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
@@ -293,8 +298,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static void crystalcove_gpio_dbg_show(struct seq_file *s,
-                                     struct gpio_chip *chip)
+static void crystalcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
        struct crystalcove_gpio *cg = gpiochip_get_data(chip);
        int gpio, offset;
@@ -353,7 +357,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
        cg->regmap = pmic->regmap;
 
        girq = &cg->chip.irq;
-       girq->chip = &crystalcove_irqchip;
+       gpio_irq_chip_set_chip(girq, &crystalcove_irqchip);
        /* This will let us handle the parent IRQ in the driver */
        girq->parent_handler = NULL;
        girq->num_parents = 0;
index 08b9e2cf4f2d629034c39ee466df34901666f302..71fa437b491f62dd1a233d6aaa25de1fcd80e793 100644 (file)
@@ -46,7 +46,6 @@
 struct dln2_gpio {
        struct platform_device *pdev;
        struct gpio_chip gpio;
-       struct irq_chip irqchip;
 
        /*
         * Cache pin direction to save us one transfer, since the hardware has
@@ -306,6 +305,7 @@ static void dln2_irq_unmask(struct irq_data *irqd)
        struct dln2_gpio *dln2 = gpiochip_get_data(gc);
        int pin = irqd_to_hwirq(irqd);
 
+       gpiochip_enable_irq(gc, pin);
        set_bit(pin, dln2->unmasked_irqs);
 }
 
@@ -316,6 +316,7 @@ static void dln2_irq_mask(struct irq_data *irqd)
        int pin = irqd_to_hwirq(irqd);
 
        clear_bit(pin, dln2->unmasked_irqs);
+       gpiochip_disable_irq(gc, pin);
 }
 
 static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
@@ -384,6 +385,17 @@ static void dln2_irq_bus_unlock(struct irq_data *irqd)
        mutex_unlock(&dln2->irq_lock);
 }
 
+static const struct irq_chip dln2_irqchip = {
+       .name = "dln2-irq",
+       .irq_mask = dln2_irq_mask,
+       .irq_unmask = dln2_irq_unmask,
+       .irq_set_type = dln2_irq_set_type,
+       .irq_bus_lock = dln2_irq_bus_lock,
+       .irq_bus_sync_unlock = dln2_irq_bus_unlock,
+       .flags = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
 static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
                            const void *data, int len)
 {
@@ -465,15 +477,8 @@ static int dln2_gpio_probe(struct platform_device *pdev)
        dln2->gpio.direction_output = dln2_gpio_direction_output;
        dln2->gpio.set_config = dln2_gpio_set_config;
 
-       dln2->irqchip.name = "dln2-irq",
-       dln2->irqchip.irq_mask = dln2_irq_mask,
-       dln2->irqchip.irq_unmask = dln2_irq_unmask,
-       dln2->irqchip.irq_set_type = dln2_irq_set_type,
-       dln2->irqchip.irq_bus_lock = dln2_irq_bus_lock,
-       dln2->irqchip.irq_bus_sync_unlock = dln2_irq_bus_unlock,
-
        girq = &dln2->gpio.irq;
-       girq->chip = &dln2->irqchip;
+       gpio_irq_chip_set_chip(girq, &dln2_irqchip);
        /* The event comes from the outside so no parent handler */
        girq->parent_handler = NULL;
        girq->num_parents = 0;
index 04afe728e18748df88e11518b739a394a56a8bc5..c22fcaa44a614c66ee5ae0105abb71148bf09650 100644 (file)
@@ -662,10 +662,9 @@ static int dwapb_get_clks(struct dwapb_gpio *gpio)
        gpio->clks[1].id = "db";
        err = devm_clk_bulk_get_optional(gpio->dev, DWAPB_NR_CLOCKS,
                                         gpio->clks);
-       if (err) {
-               dev_err(gpio->dev, "Cannot get APB/Debounce clocks\n");
-               return err;
-       }
+       if (err)
+               return dev_err_probe(gpio->dev, err,
+                                    "Cannot get APB/Debounce clocks\n");
 
        err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks);
        if (err) {
index f3d1baeacbe97034187bb6f7138f0bf3931502f7..72ac09a597029ff87e7004c27a25020afa217b75 100644 (file)
@@ -220,10 +220,8 @@ static void mrfld_irq_ack(struct irq_data *d)
        raw_spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void mrfld_irq_unmask_mask(struct irq_data *d, bool unmask)
+static void mrfld_irq_unmask_mask(struct mrfld_gpio *priv, u32 gpio, bool unmask)
 {
-       struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d);
-       u32 gpio = irqd_to_hwirq(d);
        void __iomem *gimr = gpio_reg(&priv->chip, gpio, GIMR);
        unsigned long flags;
        u32 value;
@@ -241,12 +239,20 @@ static void mrfld_irq_unmask_mask(struct irq_data *d, bool unmask)
 
 static void mrfld_irq_mask(struct irq_data *d)
 {
-       mrfld_irq_unmask_mask(d, false);
+       struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d);
+       u32 gpio = irqd_to_hwirq(d);
+
+       mrfld_irq_unmask_mask(priv, gpio, false);
+       gpiochip_disable_irq(&priv->chip, gpio);
 }
 
 static void mrfld_irq_unmask(struct irq_data *d)
 {
-       mrfld_irq_unmask_mask(d, true);
+       struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d);
+       u32 gpio = irqd_to_hwirq(d);
+
+       gpiochip_enable_irq(&priv->chip, gpio);
+       mrfld_irq_unmask_mask(priv, gpio, true);
 }
 
 static int mrfld_irq_set_type(struct irq_data *d, unsigned int type)
@@ -329,13 +335,15 @@ static int mrfld_irq_set_wake(struct irq_data *d, unsigned int on)
        return 0;
 }
 
-static struct irq_chip mrfld_irqchip = {
+static const struct irq_chip mrfld_irqchip = {
        .name           = "gpio-merrifield",
        .irq_ack        = mrfld_irq_ack,
        .irq_mask       = mrfld_irq_mask,
        .irq_unmask     = mrfld_irq_unmask,
        .irq_set_type   = mrfld_irq_set_type,
        .irq_set_wake   = mrfld_irq_set_wake,
+       .flags          = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
 static void mrfld_irq_handler(struct irq_desc *desc)
@@ -482,7 +490,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
                return retval;
 
        girq = &priv->chip.irq;
-       girq->chip = &mrfld_irqchip;
+       gpio_irq_chip_set_chip(girq, &mrfld_irqchip);
        girq->init_hw = mrfld_irq_init_hw;
        girq->parent_handler = mrfld_irq_handler;
        girq->num_parents = 1;
index acda4c5052d38a040319f6e5734dd7050022457a..8a83f7bf4382b6349515b4d8ce957937a82a7391 100644 (file)
@@ -38,7 +38,6 @@
 
 struct sch_gpio {
        struct gpio_chip chip;
-       struct irq_chip irqchip;
        spinlock_t lock;
        unsigned short iobase;
        unsigned short resume_base;
@@ -218,11 +217,9 @@ static void sch_irq_ack(struct irq_data *d)
        spin_unlock_irqrestore(&sch->lock, flags);
 }
 
-static void sch_irq_mask_unmask(struct irq_data *d, int val)
+static void sch_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t gpio_num, int val)
 {
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct sch_gpio *sch = gpiochip_get_data(gc);
-       irq_hw_number_t gpio_num = irqd_to_hwirq(d);
        unsigned long flags;
 
        spin_lock_irqsave(&sch->lock, flags);
@@ -232,14 +229,32 @@ static void sch_irq_mask_unmask(struct irq_data *d, int val)
 
 static void sch_irq_mask(struct irq_data *d)
 {
-       sch_irq_mask_unmask(d, 0);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       irq_hw_number_t gpio_num = irqd_to_hwirq(d);
+
+       sch_irq_mask_unmask(gc, gpio_num, 0);
+       gpiochip_disable_irq(gc, gpio_num);
 }
 
 static void sch_irq_unmask(struct irq_data *d)
 {
-       sch_irq_mask_unmask(d, 1);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       irq_hw_number_t gpio_num = irqd_to_hwirq(d);
+
+       gpiochip_enable_irq(gc, gpio_num);
+       sch_irq_mask_unmask(gc, gpio_num, 1);
 }
 
+static const struct irq_chip sch_irqchip = {
+       .name = "sch_gpio",
+       .irq_ack = sch_irq_ack,
+       .irq_mask = sch_irq_mask,
+       .irq_unmask = sch_irq_unmask,
+       .irq_set_type = sch_irq_type,
+       .flags = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
 static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context)
 {
        struct sch_gpio *sch = context;
@@ -367,14 +382,8 @@ static int sch_gpio_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, sch);
 
-       sch->irqchip.name = "sch_gpio";
-       sch->irqchip.irq_ack = sch_irq_ack;
-       sch->irqchip.irq_mask = sch_irq_mask;
-       sch->irqchip.irq_unmask = sch_irq_unmask;
-       sch->irqchip.irq_set_type = sch_irq_type;
-
        girq = &sch->chip.irq;
-       girq->chip = &sch->irqchip;
+       gpio_irq_chip_set_chip(girq, &sch_irqchip);
        girq->num_parents = 0;
        girq->parents = NULL;
        girq->parent_handler = NULL;
index 16a0fae1e32ebbf1eba7572dd3ebf60434a9b433..c18b6b47384f1b8b9a3a26c3ac7c5f125e82d365 100644 (file)
@@ -299,6 +299,8 @@ static void wcove_irq_unmask(struct irq_data *data)
        if (gpio >= WCOVE_GPIO_NUM)
                return;
 
+       gpiochip_enable_irq(chip, gpio);
+
        wg->set_irq_mask = false;
        wg->update |= UPDATE_IRQ_MASK;
 }
@@ -314,15 +316,19 @@ static void wcove_irq_mask(struct irq_data *data)
 
        wg->set_irq_mask = true;
        wg->update |= UPDATE_IRQ_MASK;
+
+       gpiochip_disable_irq(chip, gpio);
 }
 
-static struct irq_chip wcove_irqchip = {
+static const struct irq_chip wcove_irqchip = {
        .name                   = "Whiskey Cove",
        .irq_mask               = wcove_irq_mask,
        .irq_unmask             = wcove_irq_unmask,
        .irq_set_type           = wcove_irq_type,
        .irq_bus_lock           = wcove_bus_lock,
        .irq_bus_sync_unlock    = wcove_bus_sync_unlock,
+       .flags                  = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
 static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
@@ -452,7 +458,7 @@ static int wcove_gpio_probe(struct platform_device *pdev)
        }
 
        girq = &wg->chip.irq;
-       girq->chip = &wcove_irqchip;
+       gpio_irq_chip_set_chip(girq, &wcove_irqchip);
        /* This will let us handle the parent IRQ in the driver */
        girq->parent_handler = NULL;
        girq->num_parents = 0;
index 67abf8dcd30ac8f995610c4309893cbbc9098562..6b6d46e29e6e8bd21dd5a3ee3789a7858c4757ce 100644 (file)
@@ -1918,9 +1918,6 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
                return -EINVAL;
        }
 
-       /* delete kgd_mem from kfd_bo_list to avoid re-validating
-        * this BO in BO's restoring after eviction.
-        */
        mutex_lock(&mem->process_info->lock);
 
        ret = amdgpu_bo_reserve(bo, true);
@@ -1943,7 +1940,6 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
 
        amdgpu_amdkfd_remove_eviction_fence(
                bo, mem->process_info->eviction_fence);
-       list_del_init(&mem->validate_list.head);
 
        if (size)
                *size = amdgpu_bo_size(bo);
@@ -2512,12 +2508,15 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
        process_info->eviction_fence = new_fence;
        *ef = dma_fence_get(&new_fence->base);
 
-       /* Attach new eviction fence to all BOs */
+       /* Attach new eviction fence to all BOs except pinned ones */
        list_for_each_entry(mem, &process_info->kfd_bo_list,
-               validate_list.head)
+               validate_list.head) {
+               if (mem->bo->tbo.pin_count)
+                       continue;
+
                amdgpu_bo_fence(mem->bo,
                        &process_info->eviction_fence->base, true);
-
+       }
        /* Attach eviction fence to PD / PT BOs */
        list_for_each_entry(peer_vm, &process_info->vm_list_head,
                            vm_list_node) {
index ede2fa56f6c90d92e19b9b02ef1c5203f24afdc1..16699158e00d8c47dc1a6908966c72fd10bb7e77 100644 (file)
@@ -594,17 +594,20 @@ int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
 int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
 {
        int r;
-       r = amdgpu_ras_block_late_init(adev, ras_block);
-       if (r)
-               return r;
 
        if (amdgpu_ras_is_supported(adev, ras_block->block)) {
                if (!amdgpu_persistent_edc_harvesting_supported(adev))
                        amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);
 
+               r = amdgpu_ras_block_late_init(adev, ras_block);
+               if (r)
+                       return r;
+
                r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
                if (r)
                        goto late_fini;
+       } else {
+               amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
        }
 
        return 0;
index 798c56214a2390180a25cfb39f04b086a62c7ce4..aebc384531ac8fc100209dae588abc5408b4d614 100644 (file)
@@ -518,6 +518,8 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
        case IP_VERSION(9, 1, 0):
        /* RENOIR looks like RAVEN */
        case IP_VERSION(9, 3, 0):
+       /* GC 10.3.7 */
+       case IP_VERSION(10, 3, 7):
                if (amdgpu_tmz == 0) {
                        adev->gmc.tmz_enabled = false;
                        dev_info(adev->dev,
@@ -540,8 +542,6 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
        case IP_VERSION(10, 3, 1):
        /* YELLOW_CARP*/
        case IP_VERSION(10, 3, 3):
-       /* GC 10.3.7 */
-       case IP_VERSION(10, 3, 7):
                /* Don't enable it by default yet.
                 */
                if (amdgpu_tmz < 1) {
index 801f6fa692e98c706b8389e1673e3b3e20f024ff..6de63ea6687eb05df55f1d1f3e32c9ddadb7cb49 100644 (file)
@@ -642,7 +642,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                            atomic64_read(&adev->visible_pin_size),
                            vram_gtt.vram_size);
                vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size;
-               vram_gtt.gtt_size *= PAGE_SIZE;
                vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size);
                return copy_to_user(out, &vram_gtt,
                                    min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0;
@@ -675,7 +674,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
 
                mem.gtt.total_heap_size = gtt_man->size;
-               mem.gtt.total_heap_size *= PAGE_SIZE;
                mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
                        atomic64_read(&adev->gart_pin_size);
                mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man);
index 2de9309a419391ffceb9496ca73a9e5a6fb2a3c7..dac202ae864dd224d14b7975d67dbfce1e9ca3d6 100644 (file)
@@ -197,6 +197,13 @@ static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf,
        if (amdgpu_ras_query_error_status(obj->adev, &info))
                return -EINVAL;
 
+       /* Hardware counter will be reset automatically after the query on Vega20 and Arcturus */
+       if (obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) &&
+           obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) {
+               if (amdgpu_ras_reset_error_status(obj->adev, info.head.block))
+                       dev_warn(obj->adev->dev, "Failed to reset error counter and error status");
+       }
+
        s = snprintf(val, sizeof(val), "%s: %lu\n%s: %lu\n",
                        "ue", info.ue_count,
                        "ce", info.ce_count);
@@ -550,9 +557,10 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev,
        if (amdgpu_ras_query_error_status(obj->adev, &info))
                return -EINVAL;
 
-       if (obj->adev->asic_type == CHIP_ALDEBARAN) {
+       if (obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) &&
+           obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) {
                if (amdgpu_ras_reset_error_status(obj->adev, info.head.block))
-                       DRM_WARN("Failed to reset error counter and error status");
+                       dev_warn(obj->adev->dev, "Failed to reset error counter and error status");
        }
 
        return sysfs_emit(buf, "%s: %lu\n%s: %lu\n", "ue", info.ue_count,
@@ -1027,9 +1035,6 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
                }
        }
 
-       if (!amdgpu_persistent_edc_harvesting_supported(adev))
-               amdgpu_ras_reset_error_status(adev, info->head.block);
-
        return 0;
 }
 
@@ -1149,6 +1154,12 @@ int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
                if (res)
                        return res;
 
+               if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) &&
+                   adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) {
+                       if (amdgpu_ras_reset_error_status(adev, info.head.block))
+                               dev_warn(adev->dev, "Failed to reset error counter and error status");
+               }
+
                ce += info.ce_count;
                ue += info.ue_count;
        }
@@ -1792,6 +1803,12 @@ static void amdgpu_ras_log_on_err_counter(struct amdgpu_device *adev)
                        continue;
 
                amdgpu_ras_query_error_status(adev, &info);
+
+               if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) &&
+                   adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) {
+                       if (amdgpu_ras_reset_error_status(adev, info.head.block))
+                               dev_warn(adev->dev, "Failed to reset error counter and error status");
+               }
        }
 }
 
@@ -2278,8 +2295,9 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev)
            !amdgpu_ras_asic_supported(adev))
                return;
 
-       if (!(amdgpu_sriov_vf(adev) &&
-               (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2))))
+       /* If driver run on sriov guest side, only enable ras for aldebaran */
+       if (amdgpu_sriov_vf(adev) &&
+               adev->ip_versions[MP1_HWIP][0] != IP_VERSION(13, 0, 2))
                return;
 
        if (!adev->gmc.xgmi.connected_to_cpu) {
index 2ceeaa4c793aec1243386b81c6fd93b08058ec8f..dc76d2b3ce52fdcb9ba1623c6ab9499dbde9da2c 100644 (file)
@@ -679,6 +679,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
 {
        struct amdgpu_vm_update_params params;
        struct amdgpu_vm_bo_base *entry;
+       bool flush_tlb_needed = false;
        int r, idx;
 
        if (list_empty(&vm->relocated))
@@ -697,6 +698,9 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
                goto error;
 
        list_for_each_entry(entry, &vm->relocated, vm_status) {
+               /* vm_flush_needed after updating moved PDEs */
+               flush_tlb_needed |= entry->moved;
+
                r = amdgpu_vm_pde_update(&params, entry);
                if (r)
                        goto error;
@@ -706,8 +710,8 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
        if (r)
                goto error;
 
-       /* vm_flush_needed after updating PDEs */
-       atomic64_inc(&vm->tlb_seq);
+       if (flush_tlb_needed)
+               atomic64_inc(&vm->tlb_seq);
 
        while (!list_empty(&vm->relocated)) {
                entry = list_first_entry(&vm->relocated,
@@ -789,6 +793,11 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
        flush_tlb |= adev->gmc.xgmi.num_physical_nodes &&
                     adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0);
 
+       /*
+        * On GFX8 and older any 8 PTE block with a valid bit set enters the TLB
+        */
+       flush_tlb |= adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 0, 0);
+
        memset(&params, 0, sizeof(params));
        params.adev = adev;
        params.vm = vm;
index 8c0a3fc7aaa6d9d01360166ce66ca06565d51da7..a4a6751b1e449208ee17db4f351c049c06dc8263 100644 (file)
@@ -1096,6 +1096,7 @@ static void gfx_v11_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd,
        dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_STS2);
        dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_DBG1);
        dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_M0);
+       dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_MODE);
 }
 
 static void gfx_v11_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
@@ -1316,7 +1317,7 @@ static void gfx_v11_0_rlc_backdoor_autoload_copy_ucode(struct amdgpu_device *ade
                memset(ptr + toc_offset + fw_size, 0, toc_fw_size - fw_size);
 
        if ((id != SOC21_FIRMWARE_ID_RS64_PFP) && (id != SOC21_FIRMWARE_ID_RS64_ME))
-               *(uint64_t *)fw_autoload_mask |= 1 << id;
+               *(uint64_t *)fw_autoload_mask |= 1ULL << id;
 }
 
 static void gfx_v11_0_rlc_backdoor_autoload_copy_toc_ucode(struct amdgpu_device *adev,
@@ -1983,7 +1984,7 @@ static int gfx_v11_0_init_csb(struct amdgpu_device *adev)
        return 0;
 }
 
-void gfx_v11_0_rlc_stop(struct amdgpu_device *adev)
+static void gfx_v11_0_rlc_stop(struct amdgpu_device *adev)
 {
        u32 tmp = RREG32_SOC15(GC, 0, regRLC_CNTL);
 
@@ -6028,6 +6029,7 @@ static void gfx_v11_0_handle_priv_fault(struct amdgpu_device *adev,
                break;
        default:
                BUG();
+               break;
        }
 }
 
index a0c0b7d9f444dde338b133134bd99c8a749ed2c9..7f4b480ae66e10be4eadde269a59fc45a86bd604 100644 (file)
@@ -638,6 +638,12 @@ static int gmc_v11_0_mc_init(struct amdgpu_device *adev)
        adev->gmc.aper_base = pci_resource_start(adev->pdev, 0);
        adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
 
+#ifdef CONFIG_X86_64
+       if ((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev)) {
+               adev->gmc.aper_base = adev->mmhub.funcs->get_mc_fb_offset(adev);
+               adev->gmc.aper_size = adev->gmc.real_vram_size;
+       }
+#endif
        /* In case the PCI BAR is larger than the actual amount of vram */
        adev->gmc.visible_vram_size = adev->gmc.aper_size;
        if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size)
index 5d2dfeff8fe5dbfdf492b992c13d6b3192229058..d63d3f2b8a161973c08365d839dda693c3810dfb 100644 (file)
@@ -299,7 +299,7 @@ static const struct imu_rlc_ram_golden imu_rlc_ram_golden_11_0_2[] =
        IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPG_PSP_DEBUG, CPG_PSP_DEBUG__GPA_OVERRIDE_MASK, 0)
 };
 
-void program_imu_rlc_ram(struct amdgpu_device *adev,
+static void program_imu_rlc_ram(struct amdgpu_device *adev,
                                const struct imu_rlc_ram_golden *regs,
                                const u32 array_size)
 {
index d2722adabd1baa4076f8877236cf036db178ba25..f3c1af5130abcbbb7b1594f648f34e899b025547 100644 (file)
@@ -535,6 +535,10 @@ void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
 {
        unsigned vmid = AMDGPU_JOB_GET_VMID(job);
 
+       amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_IH_CTRL_INTERNAL_OFFSET,
+               0, 0, PACKETJ_TYPE0));
+       amdgpu_ring_write(ring, (vmid << JPEG_IH_CTRL__IH_VMID__SHIFT));
+
        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
                0, 0, PACKETJ_TYPE0));
        amdgpu_ring_write(ring, (vmid | (vmid << 4)));
@@ -768,7 +772,7 @@ static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {
                8 + /* jpeg_v2_0_dec_ring_emit_vm_flush */
                18 + 18 + /* jpeg_v2_0_dec_ring_emit_fence x2 vm fence */
                8 + 16,
-       .emit_ib_size = 22, /* jpeg_v2_0_dec_ring_emit_ib */
+       .emit_ib_size = 24, /* jpeg_v2_0_dec_ring_emit_ib */
        .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
        .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
        .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
index 1a03baa59755762285cab56069dcc2d6e29ab663..654e43e83e2c43800974e6eba8e0de7aa0165304 100644 (file)
@@ -41,6 +41,7 @@
 #define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET                         0x4084
 #define mmUVD_JRBC_STATUS_INTERNAL_OFFSET                              0x4089
 #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET                               0x401f
+#define mmUVD_JPEG_IH_CTRL_INTERNAL_OFFSET                             0x4149
 
 #define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR                               0x18000
 
index fcf51947bb186f8575fd608342b4fa6d7d5485e9..7eee004cf3ce39ef9f6d3741ecf4ec90657961c6 100644 (file)
@@ -541,7 +541,7 @@ static void mes_v11_0_enable(struct amdgpu_device *adev, bool enable)
 
 /* This function is for backdoor MES firmware */
 static int mes_v11_0_load_microcode(struct amdgpu_device *adev,
-                                   enum admgpu_mes_pipe pipe)
+                                   enum admgpu_mes_pipe pipe, bool prime_icache)
 {
        int r;
        uint32_t data;
@@ -593,16 +593,18 @@ static int mes_v11_0_load_microcode(struct amdgpu_device *adev,
        /* Set 0x3FFFF (256K-1) to CP_MES_MDBOUND_LO */
        WREG32_SOC15(GC, 0, regCP_MES_MDBOUND_LO, 0x3FFFF);
 
-       /* invalidate ICACHE */
-       data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL);
-       data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 0);
-       data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, INVALIDATE_CACHE, 1);
-       WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data);
-
-       /* prime the ICACHE. */
-       data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL);
-       data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 1);
-       WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data);
+       if (prime_icache) {
+               /* invalidate ICACHE */
+               data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL);
+               data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 0);
+               data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, INVALIDATE_CACHE, 1);
+               WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data);
+
+               /* prime the ICACHE. */
+               data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL);
+               data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 1);
+               WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data);
+       }
 
        soc21_grbm_select(adev, 0, 0, 0, 0);
        mutex_unlock(&adev->srbm_mutex);
@@ -1044,17 +1046,19 @@ static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev)
        int r = 0;
 
        if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
-               r = mes_v11_0_load_microcode(adev, AMDGPU_MES_KIQ_PIPE);
+
+               r = mes_v11_0_load_microcode(adev, AMDGPU_MES_SCHED_PIPE, false);
                if (r) {
-                       DRM_ERROR("failed to load MES kiq fw, r=%d\n", r);
+                       DRM_ERROR("failed to load MES fw, r=%d\n", r);
                        return r;
                }
 
-               r = mes_v11_0_load_microcode(adev, AMDGPU_MES_SCHED_PIPE);
+               r = mes_v11_0_load_microcode(adev, AMDGPU_MES_KIQ_PIPE, true);
                if (r) {
-                       DRM_ERROR("failed to load MES fw, r=%d\n", r);
+                       DRM_ERROR("failed to load MES kiq fw, r=%d\n", r);
                        return r;
                }
+
        }
 
        mes_v11_0_enable(adev, true);
@@ -1086,7 +1090,7 @@ static int mes_v11_0_hw_init(void *handle)
        if (!adev->enable_mes_kiq) {
                if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
                        r = mes_v11_0_load_microcode(adev,
-                                            AMDGPU_MES_SCHED_PIPE);
+                                            AMDGPU_MES_SCHED_PIPE, true);
                        if (r) {
                                DRM_ERROR("failed to MES fw, r=%d\n", r);
                                return r;
index d016e3c3e221f80eb00e048173bac592dc4f61ca..b3fba8dea63ca868fa20da2ca08e0b3a24508713 100644 (file)
@@ -170,6 +170,7 @@ static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = {
        {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
        {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
        {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
 };
 
 static const struct amdgpu_video_codecs yc_video_codecs_decode = {
index 06b2635b142a58c0662d3b0cbc5a1e77ccc55d89..83c6ccaaa9e4e0c0130a71efa8130725efdc809d 100644 (file)
@@ -469,6 +469,7 @@ static void sdma_v5_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
        }
 }
 
+
 /**
  * sdma_v5_2_gfx_stop - stop the gfx async dma engines
  *
@@ -514,21 +515,17 @@ static void sdma_v5_2_rlc_stop(struct amdgpu_device *adev)
 }
 
 /**
- * sdma_v5_2_ctx_switch_enable_for_instance - start the async dma engines
- * context switch for an instance
+ * sdma_v5_2_ctx_switch_enable - stop the async dma engines context switch
  *
  * @adev: amdgpu_device pointer
- * @instance_idx: the index of the SDMA instance
+ * @enable: enable/disable the DMA MEs context switch.
  *
- * Unhalt the async dma engines context switch.
+ * Halt or unhalt the async dma engines context switch.
  */
-static void sdma_v5_2_ctx_switch_enable_for_instance(struct amdgpu_device *adev, int instance_idx)
+static void sdma_v5_2_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
 {
        u32 f32_cntl, phase_quantum = 0;
-
-       if (WARN_ON(instance_idx >= adev->sdma.num_instances)) {
-               return;
-       }
+       int i;
 
        if (amdgpu_sdma_phase_quantum) {
                unsigned value = amdgpu_sdma_phase_quantum;
@@ -552,68 +549,50 @@ static void sdma_v5_2_ctx_switch_enable_for_instance(struct amdgpu_device *adev,
                phase_quantum =
                        value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
                        unit  << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
-
-               WREG32_SOC15_IP(GC,
-                       sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_PHASE0_QUANTUM),
-                       phase_quantum);
-               WREG32_SOC15_IP(GC,
-                       sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_PHASE1_QUANTUM),
-                   phase_quantum);
-               WREG32_SOC15_IP(GC,
-                       sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_PHASE2_QUANTUM),
-                   phase_quantum);
        }
 
-       if (!amdgpu_sriov_vf(adev)) {
-               f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_CNTL));
-               f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
-                               AUTO_CTXSW_ENABLE, 1);
-               WREG32(sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_CNTL), f32_cntl);
+       for (i = 0; i < adev->sdma.num_instances; i++) {
+               if (enable && amdgpu_sdma_phase_quantum) {
+                       WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM),
+                              phase_quantum);
+                       WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE1_QUANTUM),
+                              phase_quantum);
+                       WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM),
+                              phase_quantum);
+               }
+
+               if (!amdgpu_sriov_vf(adev)) {
+                       f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL));
+                       f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+                                       AUTO_CTXSW_ENABLE, enable ? 1 : 0);
+                       WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
+               }
        }
+
 }
 
 /**
- * sdma_v5_2_ctx_switch_disable_all - stop the async dma engines context switch
+ * sdma_v5_2_enable - stop the async dma engines
  *
  * @adev: amdgpu_device pointer
+ * @enable: enable/disable the DMA MEs.
  *
- * Halt the async dma engines context switch.
+ * Halt or unhalt the async dma engines.
  */
-static void sdma_v5_2_ctx_switch_disable_all(struct amdgpu_device *adev)
+static void sdma_v5_2_enable(struct amdgpu_device *adev, bool enable)
 {
        u32 f32_cntl;
        int i;
 
-       if (amdgpu_sriov_vf(adev))
-               return;
-
-       for (i = 0; i < adev->sdma.num_instances; i++) {
-               f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL));
-               f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
-                               AUTO_CTXSW_ENABLE, 0);
-               WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
+       if (!enable) {
+               sdma_v5_2_gfx_stop(adev);
+               sdma_v5_2_rlc_stop(adev);
        }
-}
-
-/**
- * sdma_v5_2_halt - stop the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Halt the async dma engines.
- */
-static void sdma_v5_2_halt(struct amdgpu_device *adev)
-{
-       int i;
-       u32 f32_cntl;
-
-       sdma_v5_2_gfx_stop(adev);
-       sdma_v5_2_rlc_stop(adev);
 
        if (!amdgpu_sriov_vf(adev)) {
                for (i = 0; i < adev->sdma.num_instances; i++) {
                        f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL));
-                       f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, 1);
+                       f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1);
                        WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), f32_cntl);
                }
        }
@@ -625,9 +604,6 @@ static void sdma_v5_2_halt(struct amdgpu_device *adev)
  * @adev: amdgpu_device pointer
  *
  * Set up the gfx DMA ring buffers and enable them.
- * It assumes that the dma engine is stopped for each instance.
- * The function enables the engine and preemptions sequentially for each instance.
- *
  * Returns 0 for success, error for failure.
  */
 static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev)
@@ -769,7 +745,10 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev)
 
                ring->sched.ready = true;
 
-               sdma_v5_2_ctx_switch_enable_for_instance(adev, i);
+               if (amdgpu_sriov_vf(adev)) { /* bare-metal sequence doesn't need below to lines */
+                       sdma_v5_2_ctx_switch_enable(adev, true);
+                       sdma_v5_2_enable(adev, true);
+               }
 
                r = amdgpu_ring_test_ring(ring);
                if (r) {
@@ -813,7 +792,7 @@ static int sdma_v5_2_load_microcode(struct amdgpu_device *adev)
        int i, j;
 
        /* halt the MEs */
-       sdma_v5_2_halt(adev);
+       sdma_v5_2_enable(adev, false);
 
        for (i = 0; i < adev->sdma.num_instances; i++) {
                if (!adev->sdma.instance[i].fw)
@@ -885,8 +864,8 @@ static int sdma_v5_2_start(struct amdgpu_device *adev)
        int r = 0;
 
        if (amdgpu_sriov_vf(adev)) {
-               sdma_v5_2_ctx_switch_disable_all(adev);
-               sdma_v5_2_halt(adev);
+               sdma_v5_2_ctx_switch_enable(adev, false);
+               sdma_v5_2_enable(adev, false);
 
                /* set RB registers */
                r = sdma_v5_2_gfx_resume(adev);
@@ -910,10 +889,12 @@ static int sdma_v5_2_start(struct amdgpu_device *adev)
                amdgpu_gfx_off_ctrl(adev, false);
 
        sdma_v5_2_soft_reset(adev);
+       /* unhalt the MEs */
+       sdma_v5_2_enable(adev, true);
+       /* enable sdma ring preemption */
+       sdma_v5_2_ctx_switch_enable(adev, true);
 
-       /* Soft reset supposes to disable the dma engine and preemption.
-        * Now start the gfx rings and rlc compute queues.
-        */
+       /* start the gfx rings and rlc compute queues */
        r = sdma_v5_2_gfx_resume(adev);
        if (adev->in_s0ix)
                amdgpu_gfx_off_ctrl(adev, true);
@@ -1447,8 +1428,8 @@ static int sdma_v5_2_hw_fini(void *handle)
        if (amdgpu_sriov_vf(adev))
                return 0;
 
-       sdma_v5_2_ctx_switch_disable_all(adev);
-       sdma_v5_2_halt(adev);
+       sdma_v5_2_ctx_switch_enable(adev, false);
+       sdma_v5_2_enable(adev, false);
 
        return 0;
 }
index 3cabceee5f57aa0094349630ef8dbfd3ed2a3c5a..39405f0db824100c708b26ce71447a0f4d3bbf90 100644 (file)
@@ -1761,23 +1761,21 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = {
        .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
 };
 
-static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p,
-                               struct amdgpu_job *job)
+static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p)
 {
        struct drm_gpu_scheduler **scheds;
 
        /* The create msg must be in the first IB submitted */
-       if (atomic_read(&job->base.entity->fence_seq))
+       if (atomic_read(&p->entity->fence_seq))
                return -EINVAL;
 
        scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC]
                [AMDGPU_RING_PRIO_DEFAULT].sched;
-       drm_sched_entity_modify_sched(job->base.entity, scheds, 1);
+       drm_sched_entity_modify_sched(p->entity, scheds, 1);
        return 0;
 }
 
-static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
-                           uint64_t addr)
+static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
 {
        struct ttm_operation_ctx ctx = { false, false };
        struct amdgpu_bo_va_mapping *map;
@@ -1848,7 +1846,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
                if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
                        continue;
 
-               r = vcn_v3_0_limit_sched(p, job);
+               r = vcn_v3_0_limit_sched(p);
                if (r)
                        goto out;
        }
@@ -1862,7 +1860,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
                                           struct amdgpu_job *job,
                                           struct amdgpu_ib *ib)
 {
-       struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
+       struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
        uint32_t msg_lo = 0, msg_hi = 0;
        unsigned i;
        int r;
@@ -1881,8 +1879,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
                        msg_hi = val;
                } else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0) &&
                           val == 0) {
-                       r = vcn_v3_0_dec_msg(p, job,
-                                            ((u64)msg_hi) << 32 | msg_lo);
+                       r = vcn_v3_0_dec_msg(p, ((u64)msg_hi) << 32 | msg_lo);
                        if (r)
                                return r;
                }
index 5e9adbc71bbd3980739a87d1268974380d122aab..cbfb32b3d2352c22b334dd935673c949d762dd2b 100644 (file)
@@ -1516,6 +1516,8 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
                        num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
                        break;
                case IP_VERSION(10, 3, 3):
+               case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */
+               case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */
                        pcache_info = yellow_carp_cache_info;
                        num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
                        break;
index 8667e3df2d0b9e2885d84b4f68fca78e458a50f3..bf420045777221ecf0e6769e18c24b4418ea5bdb 100644 (file)
@@ -73,6 +73,8 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
        case IP_VERSION(4, 1, 2):/* RENOIR */
        case IP_VERSION(5, 2, 1):/* VANGOGH */
        case IP_VERSION(5, 2, 3):/* YELLOW_CARP */
+       case IP_VERSION(5, 2, 6):/* GC 10.3.6 */
+       case IP_VERSION(5, 2, 7):/* GC 10.3.7 */
        case IP_VERSION(6, 0, 1):
                kfd->device_info.num_sdma_queues_per_engine = 2;
                break;
@@ -127,6 +129,8 @@ static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd)
        case IP_VERSION(9, 4, 2): /* ALDEBARAN */
        case IP_VERSION(10, 3, 1): /* VANGOGH */
        case IP_VERSION(10, 3, 3): /* YELLOW_CARP */
+       case IP_VERSION(10, 3, 6): /* GC 10.3.6 */
+       case IP_VERSION(10, 3, 7): /* GC 10.3.7 */
        case IP_VERSION(10, 1, 3): /* CYAN_SKILLFISH */
        case IP_VERSION(10, 1, 4):
        case IP_VERSION(10, 1, 10): /* NAVI10 */
@@ -178,7 +182,9 @@ static void kfd_device_info_init(struct kfd_dev *kfd,
 
                if (gc_version < IP_VERSION(11, 0, 0)) {
                        /* Navi2x+, Navi1x+ */
-                       if (gc_version >= IP_VERSION(10, 3, 0))
+                       if (gc_version == IP_VERSION(10, 3, 6))
+                               kfd->device_info.no_atomic_fw_version = 14;
+                       else if (gc_version >= IP_VERSION(10, 3, 0))
                                kfd->device_info.no_atomic_fw_version = 92;
                        else if (gc_version >= IP_VERSION(10, 1, 1))
                                kfd->device_info.no_atomic_fw_version = 145;
@@ -368,6 +374,16 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
                        if (!vf)
                                f2g = &gfx_v10_3_kfd2kgd;
                        break;
+               case IP_VERSION(10, 3, 6):
+                       gfx_target_version = 100306;
+                       if (!vf)
+                               f2g = &gfx_v10_3_kfd2kgd;
+                       break;
+               case IP_VERSION(10, 3, 7):
+                       gfx_target_version = 100307;
+                       if (!vf)
+                               f2g = &gfx_v10_3_kfd2kgd;
+                       break;
                case IP_VERSION(11, 0, 0):
                        gfx_target_version = 110000;
                        f2g = &gfx_v11_kfd2kgd;
index 997650d597eca47d21465cfbb9c4031fb34428b0..e44376c2ecdcddd54e6e587e3e302871da1bb111 100644 (file)
@@ -296,7 +296,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
                         struct migrate_vma *migrate, struct dma_fence **mfence,
                         dma_addr_t *scratch)
 {
-       uint64_t npages = migrate->cpages;
+       uint64_t npages = migrate->npages;
        struct device *dev = adev->dev;
        struct amdgpu_res_cursor cursor;
        dma_addr_t *src;
@@ -344,7 +344,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
                                                mfence);
                                if (r)
                                        goto out_free_vram_pages;
-                               amdgpu_res_next(&cursor, j << PAGE_SHIFT);
+                               amdgpu_res_next(&cursor, (j + 1) << PAGE_SHIFT);
                                j = 0;
                        } else {
                                amdgpu_res_next(&cursor, PAGE_SIZE);
@@ -590,7 +590,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
                        continue;
                }
                src[i] = svm_migrate_addr(adev, spage);
-               if (i > 0 && src[i] != src[i - 1] + PAGE_SIZE) {
+               if (j > 0 && src[i] != src[i - 1] + PAGE_SIZE) {
                        r = svm_migrate_copy_memory_gart(adev, dst + i - j,
                                                         src + i - j, j,
                                                         FROM_VRAM_TO_RAM,
index 2ebf0132c25bfb822f5d2c36e43e2bc61e3e917b..7b332246eda3e1cb71b14c61dbaaac1aee960dd6 100644 (file)
@@ -1295,7 +1295,7 @@ svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange,
                r = amdgpu_vm_update_range(adev, vm, false, false, flush_tlb, NULL,
                                           last_start, prange->start + i,
                                           pte_flags,
-                                          last_start - prange->start,
+                                          (last_start - prange->start) << PAGE_SHIFT,
                                           bo_adev ? bo_adev->vm_manager.vram_base_offset : 0,
                                           NULL, dma_addr, &vm->last_update);
 
@@ -2307,6 +2307,8 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
 
        if (range->event == MMU_NOTIFY_RELEASE)
                return true;
+       if (!mmget_not_zero(mni->mm))
+               return true;
 
        start = mni->interval_tree.start;
        last = mni->interval_tree.last;
@@ -2333,6 +2335,7 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
        }
 
        svm_range_unlock(prange);
+       mmput(mni->mm);
 
        return true;
 }
index 70be67a56673745d5392cd50a2b61f6e23fbb89c..39b425d83bb1a5f52030d14f6bc134ef376bcf0c 100644 (file)
@@ -2812,7 +2812,7 @@ static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = {
 
 static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
 {
-       u32 max_cll, min_cll, max, min, q, r;
+       u32 max_avg, min_cll, max, min, q, r;
        struct amdgpu_dm_backlight_caps *caps;
        struct amdgpu_display_manager *dm;
        struct drm_connector *conn_base;
@@ -2842,7 +2842,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
        caps = &dm->backlight_caps[i];
        caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps;
        caps->aux_support = false;
-       max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll;
+       max_avg = conn_base->hdr_sink_metadata.hdmi_type1.max_fall;
        min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll;
 
        if (caps->ext_caps->bits.oled == 1 /*||
@@ -2870,8 +2870,8 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
         * The results of the above expressions can be verified at
         * pre_computed_values.
         */
-       q = max_cll >> 5;
-       r = max_cll % 32;
+       q = max_avg >> 5;
+       r = max_avg % 32;
        max = (1 << q) * pre_computed_values[r];
 
        // min luminance: maxLum * (CV/255)^2 / 100
index ceb34376decbdb557361121c709de915942b77a7..bca5f01da7637faabd86e36f0a24fe145ecba8a1 100644 (file)
@@ -287,8 +287,11 @@ static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base)
 
 void dcn31_init_clocks(struct clk_mgr *clk_mgr)
 {
+       uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
+
        memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
        // Assumption is that boot state always supports pstate
+       clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk;      // restore ref_dtbclk
        clk_mgr->clks.p_state_change_support = true;
        clk_mgr->clks.prev_p_state_change_support = true;
        clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
@@ -638,8 +641,14 @@ static void dcn31_set_low_power_state(struct clk_mgr *clk_mgr_base)
        }
 }
 
+int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base)
+{
+       return clk_mgr_base->clks.ref_dtbclk_khz;
+}
+
 static struct clk_mgr_funcs dcn31_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+       .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
        .update_clocks = dcn31_update_clocks,
        .init_clocks = dcn31_init_clocks,
        .enable_pme_wa = dcn31_enable_pme_wa,
@@ -719,7 +728,7 @@ void dcn31_clk_mgr_construct(
        }
 
        clk_mgr->base.base.dprefclk_khz = 600000;
-       clk_mgr->base.dccg->ref_dtbclk_khz = 600000;
+       clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
        dce_clock_read_ss_info(&clk_mgr->base);
        /*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/
        //clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(clk_mgr_internal, clk_mgr->base.base.dprefclk_khz);
index 961b10a494863e76fe80310ee99eadb036099ca3..be06fdbd0c22eb12eac13cf7bdd0e1beec5df0b9 100644 (file)
@@ -51,6 +51,8 @@ void dcn31_clk_mgr_construct(struct dc_context *ctx,
                struct pp_smu_funcs *pp_smu,
                struct dccg *dccg);
 
+int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base);
+
 void dcn31_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int);
 
 #endif //__DCN31_CLK_MGR_H__
index a2ade6e93f5e8974df98842a92eaafa637a852e5..fb4ae800e91935fc8a22b8901ab13e91eccd7721 100644 (file)
@@ -41,9 +41,7 @@
 
 #include "dc_dmub_srv.h"
 
-#if defined (CONFIG_DRM_AMD_DC_DP2_0)
 #include "dc_link_dp.h"
-#endif
 
 #define TO_CLK_MGR_DCN315(clk_mgr)\
        container_of(clk_mgr, struct clk_mgr_dcn315, base)
@@ -580,6 +578,7 @@ static void dcn315_enable_pme_wa(struct clk_mgr *clk_mgr_base)
 
 static struct clk_mgr_funcs dcn315_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+       .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
        .update_clocks = dcn315_update_clocks,
        .init_clocks = dcn31_init_clocks,
        .enable_pme_wa = dcn315_enable_pme_wa,
@@ -656,9 +655,9 @@ void dcn315_clk_mgr_construct(
 
        clk_mgr->base.base.dprefclk_khz = 600000;
        clk_mgr->base.base.dprefclk_khz = dcn315_smu_get_dpref_clk(&clk_mgr->base);
-       clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
+       clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
        dce_clock_read_ss_info(&clk_mgr->base);
-       clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);
+       clk_mgr->base.base.clks.ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);
 
        clk_mgr->base.base.bw_params = &dcn315_bw_params;
 
index fc3af81ed6c62f37449375e78f7e37a3ed94ea78..e4bb9c6193b577082d93f13e601ab975fd2e922f 100644 (file)
@@ -571,6 +571,7 @@ static void dcn316_clk_mgr_helper_populate_bw_params(
 static struct clk_mgr_funcs dcn316_funcs = {
        .enable_pme_wa = dcn316_enable_pme_wa,
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+       .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
        .update_clocks = dcn316_update_clocks,
        .init_clocks = dcn31_init_clocks,
        .are_clock_states_equal = dcn31_are_clock_states_equal,
@@ -685,7 +686,7 @@ void dcn316_clk_mgr_construct(
 
        clk_mgr->base.base.dprefclk_khz = 600000;
        clk_mgr->base.base.dprefclk_khz = dcn316_smu_get_dpref_clk(&clk_mgr->base);
-       clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
+       clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
        dce_clock_read_ss_info(&clk_mgr->base);
        /*clk_mgr->base.dccg->ref_dtbclk_khz =
        dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);*/
index dc30ac366a5053a4a4b29cf69bc5b4d429f534bd..cbc47aecd00f5eb937fab394ae91305e08efa80c 100644 (file)
@@ -114,8 +114,8 @@ static const struct dc_link_settings fail_safe_link_settings = {
 
 static bool decide_fallback_link_setting(
                struct dc_link *link,
-               struct dc_link_settings initial_link_settings,
-               struct dc_link_settings *current_link_setting,
+               struct dc_link_settings *max,
+               struct dc_link_settings *cur,
                enum link_training_result training_result);
 static void maximize_lane_settings(const struct link_training_settings *lt_settings,
                struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
@@ -2784,6 +2784,7 @@ bool perform_link_training_with_retries(
        enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
        enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0;
        struct dc_link_settings cur_link_settings = *link_setting;
+       struct dc_link_settings max_link_settings = *link_setting;
        const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
        int fail_count = 0;
        bool is_link_bw_low = false; /* link bandwidth < stream bandwidth */
@@ -2793,7 +2794,6 @@ bool perform_link_training_with_retries(
 
        dp_trace_commit_lt_init(link);
 
-
        if (dp_get_link_encoding_format(&cur_link_settings) == DP_8b_10b_ENCODING)
                /* We need to do this before the link training to ensure the idle
                 * pattern in SST mode will be sent right after the link training
@@ -2909,19 +2909,15 @@ bool perform_link_training_with_retries(
                        uint32_t req_bw;
                        uint32_t link_bw;
 
-                       decide_fallback_link_setting(link, *link_setting, &cur_link_settings, status);
-                       /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to
-                        * minimum link bandwidth.
+                       decide_fallback_link_setting(link, &max_link_settings,
+                                       &cur_link_settings, status);
+                       /* Fail link training if reduced link bandwidth no longer meets
+                        * stream requirements.
                         */
                        req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
                        link_bw = dc_link_bandwidth_kbps(link, &cur_link_settings);
-                       is_link_bw_low = (req_bw > link_bw);
-                       is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) &&
-                               (cur_link_settings.lane_count <= LANE_COUNT_ONE));
-
-                       if (is_link_bw_low)
-                               DC_LOG_WARNING("%s: Link bandwidth too low after fallback req_bw(%d) > link_bw(%d)\n",
-                                       __func__, req_bw, link_bw);
+                       if (req_bw > link_bw)
+                               break;
                }
 
                msleep(delay_between_attempts);
@@ -3309,7 +3305,7 @@ static bool dp_verify_link_cap(
        int *fail_count)
 {
        struct dc_link_settings cur_link_settings = {0};
-       struct dc_link_settings initial_link_settings = *known_limit_link_setting;
+       struct dc_link_settings max_link_settings = *known_limit_link_setting;
        bool success = false;
        bool skip_video_pattern;
        enum clock_source_id dp_cs_id = get_clock_source_id(link);
@@ -3318,7 +3314,7 @@ static bool dp_verify_link_cap(
        struct link_resource link_res;
 
        memset(&irq_data, 0, sizeof(irq_data));
-       cur_link_settings = initial_link_settings;
+       cur_link_settings = max_link_settings;
 
        /* Grant extended timeout request */
        if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) {
@@ -3361,7 +3357,7 @@ static bool dp_verify_link_cap(
                dp_trace_lt_result_update(link, status, true);
                dp_disable_link_phy(link, &link_res, link->connector_signal);
        } while (!success && decide_fallback_link_setting(link,
-                       initial_link_settings, &cur_link_settings, status));
+                       &max_link_settings, &cur_link_settings, status));
 
        link->verified_link_cap = success ?
                        cur_link_settings : fail_safe_link_settings;
@@ -3596,16 +3592,19 @@ static bool decide_fallback_link_setting_max_bw_policy(
  */
 static bool decide_fallback_link_setting(
                struct dc_link *link,
-               struct dc_link_settings initial_link_settings,
-               struct dc_link_settings *current_link_setting,
+               struct dc_link_settings *max,
+               struct dc_link_settings *cur,
                enum link_training_result training_result)
 {
-       if (!current_link_setting)
+       if (!cur)
                return false;
-       if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING ||
+       if (!max)
+               return false;
+
+       if (dp_get_link_encoding_format(max) == DP_128b_132b_ENCODING ||
                        link->dc->debug.force_dp2_lt_fallback_method)
-               return decide_fallback_link_setting_max_bw_policy(link, &initial_link_settings,
-                               current_link_setting, training_result);
+               return decide_fallback_link_setting_max_bw_policy(link, max, cur,
+                               training_result);
 
        switch (training_result) {
        case LINK_TRAINING_CR_FAIL_LANE0:
@@ -3613,28 +3612,18 @@ static bool decide_fallback_link_setting(
        case LINK_TRAINING_CR_FAIL_LANE23:
        case LINK_TRAINING_LQA_FAIL:
        {
-               if (!reached_minimum_link_rate
-                               (current_link_setting->link_rate)) {
-                       current_link_setting->link_rate =
-                               reduce_link_rate(
-                                       current_link_setting->link_rate);
-               } else if (!reached_minimum_lane_count
-                               (current_link_setting->lane_count)) {
-                       current_link_setting->link_rate =
-                               initial_link_settings.link_rate;
+               if (!reached_minimum_link_rate(cur->link_rate)) {
+                       cur->link_rate = reduce_link_rate(cur->link_rate);
+               } else if (!reached_minimum_lane_count(cur->lane_count)) {
+                       cur->link_rate = max->link_rate;
                        if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
                                return false;
                        else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
-                               current_link_setting->lane_count =
-                                               LANE_COUNT_ONE;
-                       else if (training_result ==
-                                       LINK_TRAINING_CR_FAIL_LANE23)
-                               current_link_setting->lane_count =
-                                               LANE_COUNT_TWO;
+                               cur->lane_count = LANE_COUNT_ONE;
+                       else if (training_result == LINK_TRAINING_CR_FAIL_LANE23)
+                               cur->lane_count = LANE_COUNT_TWO;
                        else
-                               current_link_setting->lane_count =
-                                       reduce_lane_count(
-                                       current_link_setting->lane_count);
+                               cur->lane_count = reduce_lane_count(cur->lane_count);
                } else {
                        return false;
                }
@@ -3642,17 +3631,17 @@ static bool decide_fallback_link_setting(
        }
        case LINK_TRAINING_EQ_FAIL_EQ:
        {
-               if (!reached_minimum_lane_count
-                               (current_link_setting->lane_count)) {
-                       current_link_setting->lane_count =
-                               reduce_lane_count(
-                                       current_link_setting->lane_count);
-               } else if (!reached_minimum_link_rate
-                               (current_link_setting->link_rate)) {
-                       current_link_setting->link_rate =
-                               reduce_link_rate(
-                                       current_link_setting->link_rate);
-                       current_link_setting->lane_count = initial_link_settings.lane_count;
+               if (!reached_minimum_lane_count(cur->lane_count)) {
+                       cur->lane_count = reduce_lane_count(cur->lane_count);
+               } else if (!reached_minimum_link_rate(cur->link_rate)) {
+                       cur->link_rate = reduce_link_rate(cur->link_rate);
+                       /* Reduce max link rate to avoid potential infinite loop.
+                        * Needed so that any subsequent CR_FAIL fallback can't
+                        * re-set the link rate higher than the link rate from
+                        * the latest EQ_FAIL fallback.
+                        */
+                       max->link_rate = cur->link_rate;
+                       cur->lane_count = max->lane_count;
                } else {
                        return false;
                }
@@ -3660,12 +3649,15 @@ static bool decide_fallback_link_setting(
        }
        case LINK_TRAINING_EQ_FAIL_CR:
        {
-               if (!reached_minimum_link_rate
-                               (current_link_setting->link_rate)) {
-                       current_link_setting->link_rate =
-                               reduce_link_rate(
-                                       current_link_setting->link_rate);
-                       current_link_setting->lane_count = initial_link_settings.lane_count;
+               if (!reached_minimum_link_rate(cur->link_rate)) {
+                       cur->link_rate = reduce_link_rate(cur->link_rate);
+                       /* Reduce max link rate to avoid potential infinite loop.
+                        * Needed so that any subsequent CR_FAIL fallback can't
+                        * re-set the link rate higher than the link rate from
+                        * the latest EQ_FAIL fallback.
+                        */
+                       max->link_rate = cur->link_rate;
+                       cur->lane_count = max->lane_count;
                } else {
                        return false;
                }
index 3960c74482be6a0f5b0e95b9d3b38353a4043d4a..817028d3c4a0c3fba75492fde1ea2632b6271e32 100644 (file)
@@ -47,7 +47,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.186"
+#define DC_VER "3.2.187"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
@@ -416,6 +416,7 @@ struct dc_clocks {
        bool p_state_change_support;
        enum dcn_zstate_support_state zstate_support;
        bool dtbclk_en;
+       int ref_dtbclk_khz;
        enum dcn_pwr_state pwr_state;
        /*
         * Elements below are not compared for the purposes of
@@ -719,6 +720,8 @@ struct dc_debug_options {
        bool apply_vendor_specific_lttpr_wa;
        bool extended_blank_optimization;
        union aux_wake_wa_options aux_wake_wa;
+       /* uses value at boot and disables switch */
+       bool disable_dtb_ref_clk_switch;
        uint8_t psr_power_use_phy_fsm;
        enum dml_hostvm_override_opts dml_hostvm_override;
 };
index 287a1066b547280b84ee350f5c4a58aa106213fc..bbc58d167c630e26071491dcfd6b0d892c25f5cc 100644 (file)
@@ -513,12 +513,10 @@ void dccg31_set_physymclk(
 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
 static void dccg31_set_dtbclk_dto(
                struct dccg *dccg,
-               int dtbclk_inst,
-               int req_dtbclk_khz,
-               int num_odm_segments,
-               const struct dc_crtc_timing *timing)
+               struct dtbclk_dto_params *params)
 {
        struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+       int req_dtbclk_khz = params->pixclk_khz;
        uint32_t dtbdto_div;
 
        /* Mode                 DTBDTO Rate       DTBCLK_DTO<x>_DIV Register
@@ -529,57 +527,53 @@ static void dccg31_set_dtbclk_dto(
         * DSC native 4:2:2     pixel rate/2      4
         * Other modes          pixel rate        8
         */
-       if (num_odm_segments == 4) {
+       if (params->num_odm_segments == 4) {
                dtbdto_div = 2;
-               req_dtbclk_khz = req_dtbclk_khz / 4;
-       } else if ((num_odm_segments == 2) ||
-                       (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
-                       (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
-                                       && !timing->dsc_cfg.ycbcr422_simple)) {
+               req_dtbclk_khz = params->pixclk_khz / 4;
+       } else if ((params->num_odm_segments == 2) ||
+                       (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
+                       (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
+                                       && !params->timing->dsc_cfg.ycbcr422_simple)) {
                dtbdto_div = 4;
-               req_dtbclk_khz = req_dtbclk_khz / 2;
+               req_dtbclk_khz = params->pixclk_khz / 2;
        } else
                dtbdto_div = 8;
 
-       if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
+       if (params->ref_dtbclk_khz && req_dtbclk_khz) {
                uint32_t modulo, phase;
 
                // phase / modulo = dtbclk / dtbclk ref
-               modulo = dccg->ref_dtbclk_khz * 1000;
-               phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
-                       dccg->ref_dtbclk_khz);
+               modulo = params->ref_dtbclk_khz * 1000;
+               phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1),
+                               params->ref_dtbclk_khz);
 
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
 
-               REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo);
-               REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase);
+               REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
+               REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
 
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLK_DTO_ENABLE[dtbclk_inst], 1);
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_ENABLE[params->otg_inst], 1);
 
-               REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1,
+               REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
                                1, 100);
 
                /* The recommended programming sequence to enable DTBCLK DTO to generate
                 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
                 * be set only after DTO is enabled
                 */
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               PIPE_DTO_SRC_SEL[dtbclk_inst], 1);
-
-               dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz;
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               PIPE_DTO_SRC_SEL[params->otg_inst], 1);
        } else {
-               REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLK_DTO_ENABLE[dtbclk_inst], 0,
-                               PIPE_DTO_SRC_SEL[dtbclk_inst], 0,
-                               DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
+               REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+                               PIPE_DTO_SRC_SEL[params->otg_inst], 0,
+                               DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
 
-               REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0);
-               REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0);
-
-               dccg->dtbclk_khz[dtbclk_inst] = 0;
+               REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+               REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
        }
 }
 
@@ -606,16 +600,12 @@ void dccg31_set_audio_dtbclk_dto(
 
                REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
                                DCCG_AUDIO_DTO_SEL, 4);  //  04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK
-
-               dccg->audio_dtbclk_khz = req_audio_dtbclk_khz;
        } else {
                REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0);
                REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0);
 
                REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
                                DCCG_AUDIO_DTO_SEL, 3);  //  03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO
-
-               dccg->audio_dtbclk_khz = 0;
        }
 }
 
index d94fd1010debcfa582f11294d0039bbfef23ff17..8b12b4111c8870a54bda0561c8d5b076720e83d9 100644 (file)
@@ -230,9 +230,7 @@ static void enc31_hw_init(struct link_encoder *enc)
        AUX_RX_PHASE_DETECT_LEN,  [21,20] = 0x3 default is 3
        AUX_RX_DETECTION_THRESHOLD [30:28] = 1
 */
-       AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110);
-
-       AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a);
+       // dmub will read AUX_DPHY_RX_CONTROL0/AUX_DPHY_TX_CONTROL from vbios table in dp_aux_init
 
        //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32;
        // Set AUX_TX_REF_DIV Divider to generate 2 MHz reference from refclk
index 789f7562cdc75efcee5b52dd2b1e08674209d5c5..d2273674e872925bbd90a174f115e91fb8995336 100644 (file)
@@ -1284,10 +1284,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                if (!context->res_ctx.pipe_ctx[i].stream)
                        continue;
-#if defined (CONFIG_DRM_AMD_DC_DP2_0)
                if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
                        return true;
-#endif
        }
        return false;
 }
index 46ce5a0ee4ec38f66159ae4df9b1133da575d891..b5570aa8e39d90e2766bb45eac2683ed7e604d1b 100644 (file)
@@ -237,6 +237,7 @@ struct clk_mgr_funcs {
                        bool safe_to_lower);
 
        int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr);
+       int (*get_dtb_ref_clk_frequency)(struct clk_mgr *clk_mgr);
 
        void (*set_low_power_state)(struct clk_mgr *clk_mgr);
 
index b2fa4de47734d3e436d219d27af6647abefdec94..c7021915bac8815d1c3182ceed1e17887888642e 100644 (file)
@@ -60,8 +60,17 @@ struct dccg {
        const struct dccg_funcs *funcs;
        int pipe_dppclk_khz[MAX_PIPES];
        int ref_dppclk;
-       int dtbclk_khz[MAX_PIPES];
-       int audio_dtbclk_khz;
+       //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */
+       //int audio_dtbclk_khz;/* TODO needs to be removed */
+       int ref_dtbclk_khz;/* TODO needs to be removed */
+};
+
+struct dtbclk_dto_params {
+       const struct dc_crtc_timing *timing;
+       int otg_inst;
+       int pixclk_khz;
+       int req_audio_dtbclk_khz;
+       int num_odm_segments;
        int ref_dtbclk_khz;
 };
 
@@ -111,10 +120,7 @@ struct dccg_funcs {
 
        void (*set_dtbclk_dto)(
                        struct dccg *dccg,
-                       int dtbclk_inst,
-                       int req_dtbclk_khz,
-                       int num_odm_segments,
-                       const struct dc_crtc_timing *timing);
+                       struct dtbclk_dto_params *dto_params);
 
        void (*set_audio_dtbclk_dto)(
                        struct dccg *dccg,
index 87972dc8443d665ee3e84083df4ae13f47519b20..ea6cf8bfce304ba3a83c11ab8212ab892f1f3ad2 100644 (file)
@@ -27,6 +27,7 @@
 #include "core_types.h"
 #include "dccg.h"
 #include "dc_link_dp.h"
+#include "clk_mgr.h"
 
 static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
 {
@@ -106,14 +107,18 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
        struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc;
        struct dccg *dccg = dc->res_pool->dccg;
        struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       int odm_segment_count = get_odm_segment_count(pipe_ctx);
+       struct dtbclk_dto_params dto_params = {0};
        enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link);
 
+       dto_params.otg_inst = tg->inst;
+       dto_params.pixclk_khz = pipe_ctx->stream->phy_pix_clk;
+       dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
+       dto_params.timing = &pipe_ctx->stream->timing;
+       dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
+
        dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst);
        dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk);
-       dccg->funcs->set_dtbclk_dto(dccg, tg->inst, pipe_ctx->stream->phy_pix_clk,
-                       odm_segment_count,
-                       &pipe_ctx->stream->timing);
+       dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
        stream_enc->funcs->enable_stream(stream_enc);
        stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst);
 }
@@ -124,9 +129,13 @@ static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
        struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
        struct dccg *dccg = dc->res_pool->dccg;
        struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       struct dtbclk_dto_params dto_params = {0};
+
+       dto_params.otg_inst = tg->inst;
+       dto_params.timing = &pipe_ctx->stream->timing;
 
        stream_enc->funcs->disable(stream_enc);
-       dccg->funcs->set_dtbclk_dto(dccg, tg->inst, 0, 0, &pipe_ctx->stream->timing);
+       dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
        dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
        dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst);
 }
index 7c9330a61ac1bcc7becb636aa746445a60dc6f80..c7bd7e216710944ab3786a17a31ed68a5c4c66b7 100644 (file)
@@ -84,7 +84,7 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
 {
        union dmub_gpint_data_register cmd;
        const uint32_t timeout = 100;
-       uint32_t in_reset, scratch, i;
+       uint32_t in_reset, scratch, i, pwait_mode;
 
        REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);
 
@@ -115,6 +115,13 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
                        udelay(1);
                }
 
+               for (i = 0; i < timeout; ++i) {
+                       REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode);
+                       if (pwait_mode & (1 << 0))
+                               break;
+
+                       udelay(1);
+               }
                /* Force reset in case we timed out, DMCUB is likely hung. */
        }
 
@@ -125,6 +132,8 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
        REG_WRITE(DMCUB_INBOX1_WPTR, 0);
        REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
        REG_WRITE(DMCUB_OUTBOX1_WPTR, 0);
+       REG_WRITE(DMCUB_OUTBOX0_RPTR, 0);
+       REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);
        REG_WRITE(DMCUB_SCRATCH0, 0);
 
        /* Clear the GPINT command manually so we don't send anything during boot. */
index 59ddc81b5a0e4756c2b4d202d1e05fa54764ecee..f6db6f89d45dc74b6c17a6c506c53a8a0df5ed00 100644 (file)
@@ -151,7 +151,8 @@ struct dmub_srv;
        DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \
        DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \
        DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \
-       DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK)
+       DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) \
+       DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS)
 
 struct dmub_srv_dcn31_reg_offset {
 #define DMUB_SR(reg) uint32_t reg;
index 73b9e0a87e5487285d39a7b2cb6fd075e3d45590..20a3d4e23f66173e910ae8adbcdd71009dd4380c 100644 (file)
@@ -127,6 +127,8 @@ struct av_sync_data {
 static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
 static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
 
+static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u";
+
 /*MST Dock*/
 static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA";
 
index 247c6e9632ba1f3f6d2ef2c8197193d17fccee39..1cb399dbc7cc89152b501f5fcd891e9957bb12ce 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef SMU_11_0_7_PPTABLE_H
 #define SMU_11_0_7_PPTABLE_H
 
+#pragma pack(push, 1)
 
 #define SMU_11_0_7_TABLE_FORMAT_REVISION                  15
 
@@ -139,7 +140,7 @@ struct smu_11_0_7_overdrive_table
     uint32_t max[SMU_11_0_7_MAX_ODSETTING];                   //default maximum settings
     uint32_t min[SMU_11_0_7_MAX_ODSETTING];                   //default minimum settings
     int16_t  pm_setting[SMU_11_0_7_MAX_PMSETTING];            //Optimized power mode feature settings
-} __attribute__((packed));
+};
 
 enum SMU_11_0_7_PPCLOCK_ID {
     SMU_11_0_7_PPCLOCK_GFXCLK = 0,
@@ -166,7 +167,7 @@ struct smu_11_0_7_power_saving_clock_table
     uint32_t count;                                           //power_saving_clock_count = SMU_11_0_7_PPCLOCK_COUNT
     uint32_t max[SMU_11_0_7_MAX_PPCLOCK];                       //PowerSavingClock Mode Clock Maximum array In MHz
     uint32_t min[SMU_11_0_7_MAX_PPCLOCK];                       //PowerSavingClock Mode Clock Minimum array In MHz
-} __attribute__((packed));
+};
 
 struct smu_11_0_7_powerplay_table
 {
@@ -191,6 +192,8 @@ struct smu_11_0_7_powerplay_table
       struct smu_11_0_7_overdrive_table               overdrive_table;
 
       PPTable_t smc_pptable;                        //PPTable_t in smu11_driver_if.h
-} __attribute__((packed));
+};
+
+#pragma pack(pop)
 
 #endif
index 7a63cf8e85ed9419fb96d10452a8280b164044d1..0116e3d04fad280bd8af3534d4ad35c7657d9529 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef SMU_11_0_PPTABLE_H
 #define SMU_11_0_PPTABLE_H
 
+#pragma pack(push, 1)
 
 #define SMU_11_0_TABLE_FORMAT_REVISION                  12
 
@@ -109,7 +110,7 @@ struct smu_11_0_overdrive_table
     uint8_t  cap[SMU_11_0_MAX_ODFEATURE];                     //OD feature support flags
     uint32_t max[SMU_11_0_MAX_ODSETTING];                     //default maximum settings
     uint32_t min[SMU_11_0_MAX_ODSETTING];                     //default minimum settings
-} __attribute__((packed));
+};
 
 enum SMU_11_0_PPCLOCK_ID {
     SMU_11_0_PPCLOCK_GFXCLK = 0,
@@ -133,7 +134,7 @@ struct smu_11_0_power_saving_clock_table
     uint32_t count;                                           //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT
     uint32_t max[SMU_11_0_MAX_PPCLOCK];                       //PowerSavingClock Mode Clock Maximum array In MHz
     uint32_t min[SMU_11_0_MAX_PPCLOCK];                       //PowerSavingClock Mode Clock Minimum array In MHz
-} __attribute__((packed));
+};
 
 struct smu_11_0_powerplay_table
 {
@@ -162,6 +163,8 @@ struct smu_11_0_powerplay_table
 #ifndef SMU_11_0_PARTIAL_PPTABLE
       PPTable_t smc_pptable;                        //PPTable_t in smu11_driver_if.h
 #endif
-} __attribute__((packed));
+};
+
+#pragma pack(pop)
 
 #endif
index 3f29f4327378c6cfb23f5c90f07c4a907004db01..478862ded0bdebbf9ac3b422e93202bcaffd9062 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef SMU_13_0_7_PPTABLE_H
 #define SMU_13_0_7_PPTABLE_H
 
+#pragma pack(push, 1)
+
 #define SMU_13_0_7_TABLE_FORMAT_REVISION 15
 
 //// POWERPLAYTABLE::ulPlatformCaps
@@ -194,7 +196,8 @@ struct smu_13_0_7_powerplay_table
     struct smu_13_0_7_overdrive_table overdrive_table;
     uint8_t padding1;
     PPTable_t smc_pptable; //PPTable_t in driver_if.h
-} __attribute__((packed));
+};
 
+#pragma pack(pop)
 
 #endif
index 1f311396b706700f5dba36c4bc4934bac348f662..04330748552869292a65433f0d19bb3a110eb804 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef SMU_13_0_PPTABLE_H
 #define SMU_13_0_PPTABLE_H
 
+#pragma pack(push, 1)
+
 #define SMU_13_0_TABLE_FORMAT_REVISION                  1
 
 //// POWERPLAYTABLE::ulPlatformCaps
@@ -109,7 +111,7 @@ struct smu_13_0_overdrive_table {
        uint8_t  cap[SMU_13_0_MAX_ODFEATURE];                     //OD feature support flags
        uint32_t max[SMU_13_0_MAX_ODSETTING];                     //default maximum settings
        uint32_t min[SMU_13_0_MAX_ODSETTING];                     //default minimum settings
-} __attribute__((packed));
+};
 
 enum SMU_13_0_PPCLOCK_ID {
        SMU_13_0_PPCLOCK_GFXCLK = 0,
@@ -132,7 +134,7 @@ struct smu_13_0_power_saving_clock_table {
        uint32_t count;                                           //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT
        uint32_t max[SMU_13_0_MAX_PPCLOCK];                       //PowerSavingClock Mode Clock Maximum array In MHz
        uint32_t min[SMU_13_0_MAX_PPCLOCK];                       //PowerSavingClock Mode Clock Minimum array In MHz
-} __attribute__((packed));
+};
 
 struct smu_13_0_powerplay_table {
        struct atom_common_table_header header;
@@ -160,6 +162,8 @@ struct smu_13_0_powerplay_table {
 #ifndef SMU_13_0_PARTIAL_PPTABLE
        PPTable_t smc_pptable;                        //PPTable_t in driver_if.h
 #endif
-} __attribute__((packed));
+};
+
+#pragma pack(pop)
 
 #endif
index 4551bc8a3ecfff4de7c254ba311be5ae922096ed..f573d582407e0b7667cc461051c18dc3b53d888d 100644 (file)
@@ -160,13 +160,12 @@ void ast_dp_launch(struct drm_device *dev, u8 bPower)
                }
 
                if (bDPExecute)
-                       ast->tx_chip_type = AST_TX_ASTDP;
+                       ast->tx_chip_types |= BIT(AST_TX_ASTDP);
 
                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
                                                        (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
                                                        ASTDP_HOST_EDID_READ_DONE);
-       } else
-               ast->tx_chip_type = AST_TX_NONE;
+       }
 }
 
 
index 204c926a18ea75809ab85883e33a1ae65a619d29..4f75a9efb610af733ecceb73b7e233da33244e88 100644 (file)
@@ -450,7 +450,7 @@ void ast_init_3rdtx(struct drm_device *dev)
                        ast_init_dvo(dev);
                        break;
                default:
-                       if (ast->tx_chip_type == AST_TX_SIL164)
+                       if (ast->tx_chip_types & BIT(AST_TX_SIL164))
                                ast_init_dvo(dev);
                        else
                                ast_init_analog(dev);
index afebe35f205e49f13fb2d08e31854ee122c53be4..a34db4380f686725a6d455b977cddff36f906dfc 100644 (file)
@@ -73,6 +73,11 @@ enum ast_tx_chip {
        AST_TX_ASTDP,
 };
 
+#define AST_TX_NONE_BIT                BIT(AST_TX_NONE)
+#define AST_TX_SIL164_BIT      BIT(AST_TX_SIL164)
+#define AST_TX_DP501_BIT       BIT(AST_TX_DP501)
+#define AST_TX_ASTDP_BIT       BIT(AST_TX_ASTDP)
+
 #define AST_DRAM_512Mx16 0
 #define AST_DRAM_1Gx16   1
 #define AST_DRAM_512Mx32 2
@@ -173,7 +178,7 @@ struct ast_private {
        struct drm_plane primary_plane;
        struct ast_cursor_plane cursor_plane;
        struct drm_crtc crtc;
-       union {
+       struct {
                struct {
                        struct drm_encoder encoder;
                        struct ast_vga_connector vga_connector;
@@ -199,7 +204,7 @@ struct ast_private {
                ast_use_defaults
        } config_mode;
 
-       enum ast_tx_chip tx_chip_type;
+       unsigned long tx_chip_types;            /* bitfield of enum ast_chip_type */
        u8 *dp501_fw_addr;
        const struct firmware *dp501_fw;        /* dp501 fw */
 };
index d770d5a23c1afeb87ffc19941ed4dc3141a7d71f..067453266897fff785fb0538a2e01d4946339497 100644 (file)
@@ -216,7 +216,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
        }
 
        /* Check 3rd Tx option (digital output afaik) */
-       ast->tx_chip_type = AST_TX_NONE;
+       ast->tx_chip_types |= AST_TX_NONE_BIT;
 
        /*
         * VGACRA3 Enhanced Color Mode Register, check if DVO is already
@@ -229,7 +229,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
        if (!*need_post) {
                jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
                if (jreg & 0x80)
-                       ast->tx_chip_type = AST_TX_SIL164;
+                       ast->tx_chip_types = AST_TX_SIL164_BIT;
        }
 
        if ((ast->chip == AST2300) || (ast->chip == AST2400) || (ast->chip == AST2500)) {
@@ -241,7 +241,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
                jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
                switch (jreg) {
                case 0x04:
-                       ast->tx_chip_type = AST_TX_SIL164;
+                       ast->tx_chip_types = AST_TX_SIL164_BIT;
                        break;
                case 0x08:
                        ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL);
@@ -254,22 +254,19 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
                        }
                        fallthrough;
                case 0x0c:
-                       ast->tx_chip_type = AST_TX_DP501;
+                       ast->tx_chip_types = AST_TX_DP501_BIT;
                }
        } else if (ast->chip == AST2600)
                ast_dp_launch(&ast->base, 0);
 
        /* Print stuff for diagnostic purposes */
-       switch(ast->tx_chip_type) {
-       case AST_TX_SIL164:
+       if (ast->tx_chip_types & AST_TX_NONE_BIT)
+               drm_info(dev, "Using analog VGA\n");
+       if (ast->tx_chip_types & AST_TX_SIL164_BIT)
                drm_info(dev, "Using Sil164 TMDS transmitter\n");
-               break;
-       case AST_TX_DP501:
+       if (ast->tx_chip_types & AST_TX_DP501_BIT)
                drm_info(dev, "Using DP501 DisplayPort transmitter\n");
-               break;
-       default:
-               drm_info(dev, "Analog VGA only\n");
-       }
+
        return 0;
 }
 
index 323af2746aa92a4830d83ddfb55747c37c6f80e1..db2010a556744f7421e2636261d3591f46e81260 100644 (file)
@@ -997,10 +997,10 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
        case DRM_MODE_DPMS_ON:
                ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT,  0x01, 0xdf, 0);
                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0);
-               if (ast->tx_chip_type == AST_TX_DP501)
+               if (ast->tx_chip_types & AST_TX_DP501_BIT)
                        ast_set_dp501_video_output(crtc->dev, 1);
 
-               if (ast->tx_chip_type == AST_TX_ASTDP) {
+               if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
                        ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON);
                        ast_wait_for_vretrace(ast);
                        ast_dp_set_on_off(crtc->dev, 1);
@@ -1012,17 +1012,17 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
                ch = mode;
-               if (ast->tx_chip_type == AST_TX_DP501)
+               if (ast->tx_chip_types & AST_TX_DP501_BIT)
                        ast_set_dp501_video_output(crtc->dev, 0);
-               break;
 
-               if (ast->tx_chip_type == AST_TX_ASTDP) {
+               if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
                        ast_dp_set_on_off(crtc->dev, 0);
                        ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
                }
 
                ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT,  0x01, 0xdf, 0x20);
                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch);
+               break;
        }
 }
 
@@ -1155,7 +1155,7 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
                ast_crtc_load_lut(ast, crtc);
 
        //Set Aspeed Display-Port
-       if (ast->tx_chip_type == AST_TX_ASTDP)
+       if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
                ast_dp_set_mode(crtc, vbios_mode_info);
 
        mutex_unlock(&ast->ioregs_lock);
@@ -1739,22 +1739,26 @@ int ast_mode_config_init(struct ast_private *ast)
 
        ast_crtc_init(dev);
 
-       switch (ast->tx_chip_type) {
-       case AST_TX_NONE:
+       if (ast->tx_chip_types & AST_TX_NONE_BIT) {
                ret = ast_vga_output_init(ast);
-               break;
-       case AST_TX_SIL164:
+               if (ret)
+                       return ret;
+       }
+       if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
                ret = ast_sil164_output_init(ast);
-               break;
-       case AST_TX_DP501:
+               if (ret)
+                       return ret;
+       }
+       if (ast->tx_chip_types & AST_TX_DP501_BIT) {
                ret = ast_dp501_output_init(ast);
-               break;
-       case AST_TX_ASTDP:
+               if (ret)
+                       return ret;
+       }
+       if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
                ret = ast_astdp_output_init(ast);
-               break;
+               if (ret)
+                       return ret;
        }
-       if (ret)
-               return ret;
 
        drm_mode_config_reset(dev);
 
index 0aa9cf0fb5c3f1eca3ac5a5cb3eedf11cfa24d3e..82fd3c8adee13339567bb58ff455bd3d8543dd88 100644 (file)
@@ -391,7 +391,7 @@ void ast_post_gpu(struct drm_device *dev)
 
                ast_init_3rdtx(dev);
        } else {
-               if (ast->tx_chip_type != AST_TX_NONE)
+               if (ast->tx_chip_types & AST_TX_SIL164_BIT)
                        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);        /* Enable DVO */
        }
 }
index b97f6e8f0f6bc6afbbcf9f0123a60f1bf75a303e..01c8b80e34ec42a9e518148be1a8b36b0ba33b37 100644 (file)
@@ -1266,6 +1266,25 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
        return 0;
 }
 
+static
+struct drm_crtc *analogix_dp_get_old_crtc(struct analogix_dp_device *dp,
+                                         struct drm_atomic_state *state)
+{
+       struct drm_encoder *encoder = dp->encoder;
+       struct drm_connector *connector;
+       struct drm_connector_state *conn_state;
+
+       connector = drm_atomic_get_old_connector_for_encoder(state, encoder);
+       if (!connector)
+               return NULL;
+
+       conn_state = drm_atomic_get_old_connector_state(state, connector);
+       if (!conn_state)
+               return NULL;
+
+       return conn_state->crtc;
+}
+
 static
 struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp,
                                          struct drm_atomic_state *state)
@@ -1446,14 +1465,16 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 {
        struct drm_atomic_state *old_state = old_bridge_state->base.state;
        struct analogix_dp_device *dp = bridge->driver_private;
-       struct drm_crtc *crtc;
+       struct drm_crtc *old_crtc, *new_crtc;
+       struct drm_crtc_state *old_crtc_state = NULL;
        struct drm_crtc_state *new_crtc_state = NULL;
+       int ret;
 
-       crtc = analogix_dp_get_new_crtc(dp, old_state);
-       if (!crtc)
+       new_crtc = analogix_dp_get_new_crtc(dp, old_state);
+       if (!new_crtc)
                goto out;
 
-       new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc);
+       new_crtc_state = drm_atomic_get_new_crtc_state(old_state, new_crtc);
        if (!new_crtc_state)
                goto out;
 
@@ -1462,6 +1483,19 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
                return;
 
 out:
+       old_crtc = analogix_dp_get_old_crtc(dp, old_state);
+       if (old_crtc) {
+               old_crtc_state = drm_atomic_get_old_crtc_state(old_state,
+                                                              old_crtc);
+
+               /* When moving from PSR to fully disabled, exit PSR first. */
+               if (old_crtc_state && old_crtc_state->self_refresh_active) {
+                       ret = analogix_dp_disable_psr(dp);
+                       if (ret)
+                               DRM_ERROR("Failed to disable psr (%d)\n", ret);
+               }
+       }
+
        analogix_dp_bridge_disable(bridge);
 }
 
index 2831f0813c3a8cd0bf9776045c029d418cfa0e1a..ac66f408b40c5afa90b8787106dbe4deb432e647 100644 (file)
@@ -577,7 +577,7 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
        ctx->host_node = of_graph_get_remote_port_parent(endpoint);
        of_node_put(endpoint);
 
-       if (ctx->dsi_lanes < 0 || ctx->dsi_lanes > 4) {
+       if (ctx->dsi_lanes <= 0 || ctx->dsi_lanes > 4) {
                ret = -EINVAL;
                goto err_put_node;
        }
index 9603193d2fa13367d971ddfd73b6651214831080..987e4b212e9fbd7f0bf65f0c42b93180af0d2729 100644 (file)
@@ -1011,9 +1011,19 @@ crtc_needs_disable(struct drm_crtc_state *old_state,
                return drm_atomic_crtc_effectively_active(old_state);
 
        /*
-        * We need to run through the crtc_funcs->disable() function if the CRTC
-        * is currently on, if it's transitioning to self refresh mode, or if
-        * it's in self refresh mode and needs to be fully disabled.
+        * We need to disable bridge(s) and CRTC if we're transitioning out of
+        * self-refresh and changing CRTCs at the same time, because the
+        * bridge tracks self-refresh status via CRTC state.
+        */
+       if (old_state->self_refresh_active &&
+           old_state->crtc != new_state->crtc)
+               return true;
+
+       /*
+        * We also need to run through the crtc_funcs->disable() function if
+        * the CRTC is currently on, if it's transitioning to self refresh
+        * mode, or if it's in self refresh mode and needs to be fully
+        * disabled.
         */
        return old_state->active ||
               (old_state->self_refresh_active && !new_state->active) ||
index 424ea23eec32a2001ec8bed8b92c02562f0f2f3e..16c539657f730cd73dcf812636870454425e701b 100644 (file)
@@ -176,15 +176,15 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
        }, {
                DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
                DRM_COMPONENT_DRIVER
-       }, {
-               DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
-               DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP),
                DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI),
                DRM_COMPONENT_DRIVER
+       }, {
+               DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
+               DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
                DRM_COMPONENT_DRIVER
index 9e06f8e2a8635e74f11172ebb4b09614ac63d66e..09ce28ee08d91564fd496b9e4db29a9cb249f79c 100644 (file)
@@ -26,6 +26,7 @@
 #include <drm/drm_print.h>
 
 #include "exynos_drm_drv.h"
+#include "exynos_drm_crtc.h"
 
 /* Sysreg registers for MIC */
 #define DSD_CFG_MUX    0x1004
@@ -100,9 +101,7 @@ struct exynos_mic {
 
        bool i80_mode;
        struct videomode vm;
-       struct drm_encoder *encoder;
        struct drm_bridge bridge;
-       struct drm_bridge *next_bridge;
 
        bool enabled;
 };
@@ -229,8 +228,6 @@ static void mic_set_reg_on(struct exynos_mic *mic, bool enable)
        writel(reg, mic->reg + MIC_OP);
 }
 
-static void mic_disable(struct drm_bridge *bridge) { }
-
 static void mic_post_disable(struct drm_bridge *bridge)
 {
        struct exynos_mic *mic = bridge->driver_private;
@@ -297,34 +294,30 @@ unlock:
        mutex_unlock(&mic_mutex);
 }
 
-static void mic_enable(struct drm_bridge *bridge) { }
-
-static int mic_attach(struct drm_bridge *bridge,
-                     enum drm_bridge_attach_flags flags)
-{
-       struct exynos_mic *mic = bridge->driver_private;
-
-       return drm_bridge_attach(bridge->encoder, mic->next_bridge,
-                                &mic->bridge, flags);
-}
-
 static const struct drm_bridge_funcs mic_bridge_funcs = {
-       .disable = mic_disable,
        .post_disable = mic_post_disable,
        .mode_set = mic_mode_set,
        .pre_enable = mic_pre_enable,
-       .enable = mic_enable,
-       .attach = mic_attach,
 };
 
 static int exynos_mic_bind(struct device *dev, struct device *master,
                           void *data)
 {
        struct exynos_mic *mic = dev_get_drvdata(dev);
+       struct drm_device *drm_dev = data;
+       struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev,
+                                                      EXYNOS_DISPLAY_TYPE_LCD);
+       struct drm_encoder *e, *encoder = NULL;
+
+       drm_for_each_encoder(e, drm_dev)
+               if (e->possible_crtcs == drm_crtc_mask(&crtc->base))
+                       encoder = e;
+       if (!encoder)
+               return -ENODEV;
 
        mic->bridge.driver_private = mic;
 
-       return 0;
+       return drm_bridge_attach(encoder, &mic->bridge, NULL, 0);
 }
 
 static void exynos_mic_unbind(struct device *dev, struct device *master,
@@ -388,7 +381,6 @@ static int exynos_mic_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct exynos_mic *mic;
-       struct device_node *remote;
        struct resource res;
        int ret, i;
 
@@ -432,16 +424,6 @@ static int exynos_mic_probe(struct platform_device *pdev)
                }
        }
 
-       remote = of_graph_get_remote_node(dev->of_node, 1, 0);
-       mic->next_bridge = of_drm_find_bridge(remote);
-       if (IS_ERR(mic->next_bridge)) {
-               DRM_DEV_ERROR(dev, "mic: Failed to find next bridge\n");
-               ret = PTR_ERR(mic->next_bridge);
-               goto err;
-       }
-
-       of_node_put(remote);
-
        platform_set_drvdata(pdev, mic);
 
        mic->bridge.funcs = &mic_bridge_funcs;
index c326bd2b444fc50cb350a2e6d3ff8184e117d97c..30fe847c6664d3d9c70ce4fd8e8fed675191764f 100644 (file)
@@ -999,7 +999,8 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
                        }
                }
 
-               err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
+               /* Reserve enough slots to accommodate composite fences */
+               err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
                if (err)
                        return err;
 
index 53307ca0eed0c873286a768bdf3ad94d32750349..51a0fe60c050d13e5ba74162b832483d7d224139 100644 (file)
@@ -785,6 +785,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 {
        intel_wakeref_t wakeref;
 
+       intel_gt_sysfs_unregister(gt);
        intel_rps_driver_unregister(&gt->rps);
        intel_gsc_fini(&gt->gsc);
 
index 8ec8bc660c8c2bbf88c551bcfac3294753b0123b..9e4ebf53379bcaf8a17afd24ec921b492b136267 100644 (file)
@@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj)
 
 static struct intel_gt *kobj_to_gt(struct kobject *kobj)
 {
-       return container_of(kobj, struct kobj_gt, base)->gt;
+       return container_of(kobj, struct intel_gt, sysfs_gt);
 }
 
 struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
@@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = {
 };
 ATTRIBUTE_GROUPS(id);
 
+/* A kobject needs a release() method even if it does nothing */
 static void kobj_gt_release(struct kobject *kobj)
 {
-       kfree(kobj);
 }
 
 static struct kobj_type kobj_gt_type = {
@@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = {
 
 void intel_gt_sysfs_register(struct intel_gt *gt)
 {
-       struct kobj_gt *kg;
-
        /*
         * We need to make things right with the
         * ABI compatibility. The files were originally
@@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt)
        if (gt_is_root(gt))
                intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));
 
-       kg = kzalloc(sizeof(*kg), GFP_KERNEL);
-       if (!kg)
+       /* init and xfer ownership to sysfs tree */
+       if (kobject_init_and_add(&gt->sysfs_gt, &kobj_gt_type,
+                                gt->i915->sysfs_gt, "gt%d", gt->info.id))
                goto exit_fail;
 
-       kobject_init(&kg->base, &kobj_gt_type);
-       kg->gt = gt;
-
-       /* xfer ownership to sysfs tree */
-       if (kobject_add(&kg->base, gt->i915->sysfs_gt, "gt%d", gt->info.id))
-               goto exit_kobj_put;
-
-       intel_gt_sysfs_pm_init(gt, &kg->base);
+       intel_gt_sysfs_pm_init(gt, &gt->sysfs_gt);
 
        return;
 
-exit_kobj_put:
-       kobject_put(&kg->base);
-
 exit_fail:
+       kobject_put(&gt->sysfs_gt);
        drm_warn(&gt->i915->drm,
                 "failed to initialize gt%d sysfs root\n", gt->info.id);
 }
+
+void intel_gt_sysfs_unregister(struct intel_gt *gt)
+{
+       kobject_put(&gt->sysfs_gt);
+}
index 9471b26752cfcfeccffc5c159d551925a3778fb6..a99aa7e8b01a631f85080f7e9da13421362887c4 100644 (file)
 
 struct intel_gt;
 
-struct kobj_gt {
-       struct kobject base;
-       struct intel_gt *gt;
-};
-
 bool is_object_gt(struct kobject *kobj);
 
 struct drm_i915_private *kobj_to_i915(struct kobject *kobj);
@@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt,
                     const char *name);
 
 void intel_gt_sysfs_register(struct intel_gt *gt);
+void intel_gt_sysfs_unregister(struct intel_gt *gt);
 struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
                                            const char *name);
 
index b06611c1d4ada19860d07be87ec5a4411bfde81e..edd7a3cf5f5f5293622a7ebfb96e146c86c4de30 100644 (file)
@@ -224,6 +224,9 @@ struct intel_gt {
        } mocs;
 
        struct intel_pxp pxp;
+
+       /* gt/gtN sysfs */
+       struct kobject sysfs_gt;
 };
 
 enum intel_gt_scratch_field {
index d078f884b5e3263258836d718843ca452255ecc9..f0d7b57b741e76f83e74b612141bfde4edf419f7 100644 (file)
@@ -156,7 +156,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
                [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
                [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
        };
-       static const struct uc_fw_platform_requirement *fw_blobs;
+       const struct uc_fw_platform_requirement *fw_blobs;
        enum intel_platform p = INTEL_INFO(i915)->platform;
        u32 fw_count;
        u8 rev = INTEL_REVID(i915);
index 8521daba212a79f740ec1e1966cdfc47e10bea13..1e2750210831308d1edd4c1c4bde4dfa3ebd77cc 100644 (file)
@@ -166,7 +166,14 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
        struct device *kdev = kobj_to_dev(kobj);
        struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
        struct i915_gpu_coredump *gpu;
-       ssize_t ret;
+       ssize_t ret = 0;
+
+       /*
+        * FIXME: Concurrent clients triggering resets and reading + clearing
+        * dumps can cause inconsistent sysfs reads when a user calls in with a
+        * non-zero offset to complete a prior partial read but the
+        * gpu_coredump has been cleared or replaced.
+        */
 
        gpu = i915_first_error_state(i915);
        if (IS_ERR(gpu)) {
@@ -178,8 +185,10 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
                const char *str = "No error state collected\n";
                size_t len = strlen(str);
 
-               ret = min_t(size_t, count, len - off);
-               memcpy(buf, str + off, ret);
+               if (off < len) {
+                       ret = min_t(size_t, count, len - off);
+                       memcpy(buf, str + off, ret);
+               }
        }
 
        return ret;
@@ -259,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
 
        device_remove_bin_file(kdev,  &dpf_attrs_1);
        device_remove_bin_file(kdev,  &dpf_attrs);
+
+       kobject_put(dev_priv->sysfs_gt);
 }
index 4f6db539571aa64d3327e577cb6cc4e026ff2f49..0bffb70b3c5f5303314aa0863590d19beae31e29 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched/mm.h>
+#include <linux/dma-fence-array.h>
 #include <drm/drm_gem.h>
 
 #include "display/intel_frontbuffer.h"
@@ -1823,6 +1824,21 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
        if (unlikely(err))
                return err;
 
+       /*
+        * Reserve fences slot early to prevent an allocation after preparing
+        * the workload and associating fences with dma_resv.
+        */
+       if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
+               struct dma_fence *curr;
+               int idx;
+
+               dma_fence_array_for_each(curr, idx, fence)
+                       ;
+               err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
+               if (unlikely(err))
+                       return err;
+       }
+
        if (flags & EXEC_OBJECT_WRITE) {
                struct intel_frontbuffer *front;
 
@@ -1832,31 +1848,23 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
                                i915_active_add_request(&front->write, rq);
                        intel_frontbuffer_put(front);
                }
+       }
 
-               if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-                       err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
-                       if (unlikely(err))
-                               return err;
-               }
+       if (fence) {
+               struct dma_fence *curr;
+               enum dma_resv_usage usage;
+               int idx;
 
-               if (fence) {
-                       dma_resv_add_fence(vma->obj->base.resv, fence,
-                                          DMA_RESV_USAGE_WRITE);
+               obj->read_domains = 0;
+               if (flags & EXEC_OBJECT_WRITE) {
+                       usage = DMA_RESV_USAGE_WRITE;
                        obj->write_domain = I915_GEM_DOMAIN_RENDER;
-                       obj->read_domains = 0;
-               }
-       } else {
-               if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-                       err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
-                       if (unlikely(err))
-                               return err;
+               } else {
+                       usage = DMA_RESV_USAGE_READ;
                }
 
-               if (fence) {
-                       dma_resv_add_fence(vma->obj->base.resv, fence,
-                                          DMA_RESV_USAGE_READ);
-                       obj->write_domain = 0;
-               }
+               dma_fence_array_for_each(curr, idx, fence)
+                       dma_resv_add_fence(vma->obj->base.resv, curr, usage);
        }
 
        if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)
index 9c8829f945b23a293dde34854b4de08f0ed47400..f7863d6dea80484497ef091efacd39d320b3f817 100644 (file)
@@ -69,7 +69,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,
        drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
                if (plane == &ipu_crtc->plane[0]->base)
                        disable_full = true;
-               if (&ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base)
+               if (ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base)
                        disable_partial = true;
        }
 
index 7fcbc2a5b6cda8f31813b90685dbe4546319a59d..087e69b98d0694b8ce1037c8df8b7277e309b9e1 100644 (file)
@@ -233,6 +233,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data,
                struct drm_file *file)
 {
        struct panfrost_device *pfdev = dev->dev_private;
+       struct panfrost_file_priv *file_priv = file->driver_priv;
        struct drm_panfrost_submit *args = data;
        struct drm_syncobj *sync_out = NULL;
        struct panfrost_job *job;
@@ -262,12 +263,12 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data,
        job->jc = args->jc;
        job->requirements = args->requirements;
        job->flush_id = panfrost_gpu_get_latest_flush_id(pfdev);
-       job->file_priv = file->driver_priv;
+       job->mmu = file_priv->mmu;
 
        slot = panfrost_job_get_slot(job);
 
        ret = drm_sched_job_init(&job->base,
-                                &job->file_priv->sched_entity[slot],
+                                &file_priv->sched_entity[slot],
                                 NULL);
        if (ret)
                goto out_put_job;
index fda5871aebe3079dd2c5ef1628762e285b2f3519..7c4208476fbd34457e3c248eed53f1a9e9a02bbb 100644 (file)
@@ -201,7 +201,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
                return;
        }
 
-       cfg = panfrost_mmu_as_get(pfdev, job->file_priv->mmu);
+       cfg = panfrost_mmu_as_get(pfdev, job->mmu);
 
        job_write(pfdev, JS_HEAD_NEXT_LO(js), lower_32_bits(jc_head));
        job_write(pfdev, JS_HEAD_NEXT_HI(js), upper_32_bits(jc_head));
@@ -435,7 +435,7 @@ static void panfrost_job_handle_err(struct panfrost_device *pfdev,
                job->jc = 0;
        }
 
-       panfrost_mmu_as_put(pfdev, job->file_priv->mmu);
+       panfrost_mmu_as_put(pfdev, job->mmu);
        panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
 
        if (signal_fence)
@@ -456,7 +456,7 @@ static void panfrost_job_handle_done(struct panfrost_device *pfdev,
         * happen when we receive the DONE interrupt while doing a GPU reset).
         */
        job->jc = 0;
-       panfrost_mmu_as_put(pfdev, job->file_priv->mmu);
+       panfrost_mmu_as_put(pfdev, job->mmu);
        panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
 
        dma_fence_signal_locked(job->done_fence);
index 77e6d0e6f612fa7c63e9d1662102e1b2e57fceb4..8becc1ba0eb95210850fc9b1b49f20d39bcc8ba1 100644 (file)
@@ -17,7 +17,7 @@ struct panfrost_job {
        struct kref refcount;
 
        struct panfrost_device *pfdev;
-       struct panfrost_file_priv *file_priv;
+       struct panfrost_mmu *mmu;
 
        /* Fence to be signaled by IRQ handler when the job is complete. */
        struct dma_fence *done_fence;
index 75d308ec173d34d0a3e47f5706868e5f491826b9..406e9c324e76a824ca0e8e0ddbfc41626d5a0b58 100644 (file)
@@ -109,11 +109,11 @@ void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo,
                return;
 
        spin_lock(&bo->bdev->lru_lock);
-       if (bo->bulk_move && bo->resource)
-               ttm_lru_bulk_move_del(bo->bulk_move, bo->resource);
+       if (bo->resource)
+               ttm_resource_del_bulk_move(bo->resource, bo);
        bo->bulk_move = bulk;
-       if (bo->bulk_move && bo->resource)
-               ttm_lru_bulk_move_add(bo->bulk_move, bo->resource);
+       if (bo->resource)
+               ttm_resource_add_bulk_move(bo->resource, bo);
        spin_unlock(&bo->bdev->lru_lock);
 }
 EXPORT_SYMBOL(ttm_bo_set_bulk_move);
@@ -689,8 +689,11 @@ void ttm_bo_pin(struct ttm_buffer_object *bo)
 {
        dma_resv_assert_held(bo->base.resv);
        WARN_ON_ONCE(!kref_read(&bo->kref));
-       if (!(bo->pin_count++) && bo->bulk_move && bo->resource)
-               ttm_lru_bulk_move_del(bo->bulk_move, bo->resource);
+       spin_lock(&bo->bdev->lru_lock);
+       if (bo->resource)
+               ttm_resource_del_bulk_move(bo->resource, bo);
+       ++bo->pin_count;
+       spin_unlock(&bo->bdev->lru_lock);
 }
 EXPORT_SYMBOL(ttm_bo_pin);
 
@@ -707,8 +710,11 @@ void ttm_bo_unpin(struct ttm_buffer_object *bo)
        if (WARN_ON_ONCE(!bo->pin_count))
                return;
 
-       if (!(--bo->pin_count) && bo->bulk_move && bo->resource)
-               ttm_lru_bulk_move_add(bo->bulk_move, bo->resource);
+       spin_lock(&bo->bdev->lru_lock);
+       --bo->pin_count;
+       if (bo->resource)
+               ttm_resource_add_bulk_move(bo->resource, bo);
+       spin_unlock(&bo->bdev->lru_lock);
 }
 EXPORT_SYMBOL(ttm_bo_unpin);
 
index a0562ab386f51f3e8380feaa5579dfda509e4896..e7147e30463789272311313359abccc2934d9436 100644 (file)
@@ -156,8 +156,12 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
 
                ttm_resource_manager_for_each_res(man, &cursor, res) {
                        struct ttm_buffer_object *bo = res->bo;
-                       uint32_t num_pages = PFN_UP(bo->base.size);
+                       uint32_t num_pages;
 
+                       if (!bo)
+                               continue;
+
+                       num_pages = PFN_UP(bo->base.size);
                        ret = ttm_bo_swapout(bo, ctx, gfp_flags);
                        /* ttm_bo_swapout has dropped the lru_lock */
                        if (!ret)
index 65889b3caf50287f54aa1e3ec8c1cea9d7b0df6c..20f9adcc3235feb62e860dc783cf855760ab47f5 100644 (file)
@@ -91,8 +91,8 @@ static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos,
 }
 
 /* Add the resource to a bulk_move cursor */
-void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
-                          struct ttm_resource *res)
+static void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
+                                 struct ttm_resource *res)
 {
        struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res);
 
@@ -105,8 +105,8 @@ void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
 }
 
 /* Remove the resource from a bulk_move range */
-void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
-                          struct ttm_resource *res)
+static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
+                                 struct ttm_resource *res)
 {
        struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res);
 
@@ -122,6 +122,22 @@ void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
        }
 }
 
+/* Add the resource to a bulk move if the BO is configured for it */
+void ttm_resource_add_bulk_move(struct ttm_resource *res,
+                               struct ttm_buffer_object *bo)
+{
+       if (bo->bulk_move && !bo->pin_count)
+               ttm_lru_bulk_move_add(bo->bulk_move, res);
+}
+
+/* Remove the resource from a bulk move if the BO is configured for it */
+void ttm_resource_del_bulk_move(struct ttm_resource *res,
+                               struct ttm_buffer_object *bo)
+{
+       if (bo->bulk_move && !bo->pin_count)
+               ttm_lru_bulk_move_del(bo->bulk_move, res);
+}
+
 /* Move a resource to the LRU or bulk tail */
 void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
 {
@@ -169,15 +185,14 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
        res->bus.is_iomem = false;
        res->bus.caching = ttm_cached;
        res->bo = bo;
-       INIT_LIST_HEAD(&res->lru);
 
        man = ttm_manager_type(bo->bdev, place->mem_type);
        spin_lock(&bo->bdev->lru_lock);
-       man->usage += res->num_pages << PAGE_SHIFT;
-       if (bo->bulk_move)
-               ttm_lru_bulk_move_add(bo->bulk_move, res);
+       if (bo->pin_count)
+               list_add_tail(&res->lru, &bo->bdev->pinned);
        else
-               ttm_resource_move_to_lru_tail(res);
+               list_add_tail(&res->lru, &man->lru[bo->priority]);
+       man->usage += res->num_pages << PAGE_SHIFT;
        spin_unlock(&bo->bdev->lru_lock);
 }
 EXPORT_SYMBOL(ttm_resource_init);
@@ -210,8 +225,16 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
 {
        struct ttm_resource_manager *man =
                ttm_manager_type(bo->bdev, place->mem_type);
+       int ret;
+
+       ret = man->func->alloc(man, bo, place, res_ptr);
+       if (ret)
+               return ret;
 
-       return man->func->alloc(man, bo, place, res_ptr);
+       spin_lock(&bo->bdev->lru_lock);
+       ttm_resource_add_bulk_move(*res_ptr, bo);
+       spin_unlock(&bo->bdev->lru_lock);
+       return 0;
 }
 
 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
@@ -221,12 +244,9 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
        if (!*res)
                return;
 
-       if (bo->bulk_move) {
-               spin_lock(&bo->bdev->lru_lock);
-               ttm_lru_bulk_move_del(bo->bulk_move, *res);
-               spin_unlock(&bo->bdev->lru_lock);
-       }
-
+       spin_lock(&bo->bdev->lru_lock);
+       ttm_resource_del_bulk_move(*res, bo);
+       spin_unlock(&bo->bdev->lru_lock);
        man = ttm_manager_type(bo->bdev, (*res)->mem_type);
        man->func->free(man, *res);
        *res = NULL;
index 978ee2aab2d4010e3bd96f0d3d8a7f9d86384c7e..e0bc731241960dc1bec7c837227d88768226b83f 100644 (file)
@@ -199,7 +199,8 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
        if (!input_device->hid_desc)
                goto cleanup;
 
-       input_device->report_desc_size = desc->desc[0].wDescriptorLength;
+       input_device->report_desc_size = le16_to_cpu(
+                                       desc->desc[0].wDescriptorLength);
        if (input_device->report_desc_size == 0) {
                input_device->dev_info_status = -EINVAL;
                goto cleanup;
@@ -217,7 +218,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
 
        memcpy(input_device->report_desc,
               ((unsigned char *)desc) + desc->bLength,
-              desc->desc[0].wDescriptorLength);
+              le16_to_cpu(desc->desc[0].wDescriptorLength));
 
        /* Send the ack */
        memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
index b60f13481bdcb21435a97bd2507ab76f1be6ee38..5b120402d4057ef9eac985db6dcf5e91fa0e22ee 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/cpu.h>
 #include <linux/hyperv.h>
 #include <asm/mshyperv.h>
+#include <linux/sched/isolation.h>
 
 #include "hyperv_vmbus.h"
 
@@ -638,6 +639,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
                 */
                if (newchannel->offermsg.offer.sub_channel_index == 0) {
                        mutex_unlock(&vmbus_connection.channel_mutex);
+                       cpus_read_unlock();
                        /*
                         * Don't call free_channel(), because newchannel->kobj
                         * is not initialized yet.
@@ -728,16 +730,20 @@ static void init_vp_index(struct vmbus_channel *channel)
        u32 i, ncpu = num_online_cpus();
        cpumask_var_t available_mask;
        struct cpumask *allocated_mask;
+       const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
        u32 target_cpu;
        int numa_node;
 
        if (!perf_chn ||
-           !alloc_cpumask_var(&available_mask, GFP_KERNEL)) {
+           !alloc_cpumask_var(&available_mask, GFP_KERNEL) ||
+           cpumask_empty(hk_mask)) {
                /*
                 * If the channel is not a performance critical
                 * channel, bind it to VMBUS_CONNECT_CPU.
                 * In case alloc_cpumask_var() fails, bind it to
                 * VMBUS_CONNECT_CPU.
+                * If all the cpus are isolated, bind it to
+                * VMBUS_CONNECT_CPU.
                 */
                channel->target_cpu = VMBUS_CONNECT_CPU;
                if (perf_chn)
@@ -758,17 +764,19 @@ static void init_vp_index(struct vmbus_channel *channel)
                }
                allocated_mask = &hv_context.hv_numa_map[numa_node];
 
-               if (cpumask_equal(allocated_mask, cpumask_of_node(numa_node))) {
+retry:
+               cpumask_xor(available_mask, allocated_mask, cpumask_of_node(numa_node));
+               cpumask_and(available_mask, available_mask, hk_mask);
+
+               if (cpumask_empty(available_mask)) {
                        /*
                         * We have cycled through all the CPUs in the node;
                         * reset the allocated map.
                         */
                        cpumask_clear(allocated_mask);
+                       goto retry;
                }
 
-               cpumask_xor(available_mask, allocated_mask,
-                           cpumask_of_node(numa_node));
-
                target_cpu = cpumask_first(available_mask);
                cpumask_set_cpu(target_cpu, allocated_mask);
 
index c698592b83e421a6e98c1701ddc76b3333710ef3..d35b60c0611486c8c909d2f8f7c730ff913df30d 100644 (file)
@@ -394,7 +394,7 @@ kvp_send_key(struct work_struct *dummy)
        in_msg = kvp_transaction.kvp_msg;
 
        /*
-        * The key/value strings sent from the host are encoded in
+        * The key/value strings sent from the host are encoded
         * in utf16; convert it to utf8 strings.
         * The host assures us that the utf16 strings will not exceed
         * the max lengths specified. We will however, reserve room
index 714d549b7b46f99878c99b7e5415643c4c988f86..547ae334e5cd83bd1c4679d6993a8089603a8245 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
+#include <linux/sched/isolation.h>
 #include <linux/sched/task_stack.h>
 
 #include <linux/delay.h>
@@ -1770,6 +1771,9 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
        if (target_cpu >= nr_cpumask_bits)
                return -EINVAL;
 
+       if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ)))
+               return -EINVAL;
+
        /* No CPUs should come up or down during this. */
        cpus_read_lock();
 
index 57e11b2bab742b05e16edd60dfb46b31e14a16bd..3633ab691662bf362baa2a1d08713144c956daea 100644 (file)
@@ -259,7 +259,7 @@ static const struct ec_board_info board_info[] = {
        },
        {
                .board_names = {
-                       "ROG CROSSHAIR VIII FORMULA"
+                       "ROG CROSSHAIR VIII FORMULA",
                        "ROG CROSSHAIR VIII HERO",
                        "ROG CROSSHAIR VIII HERO (WI-FI)",
                },
index d78f4bebc7189b2200de3dc2128d02514459f8a1..ea070b91e5b981badd923e235fa7b096354f0c21 100644 (file)
@@ -1228,10 +1228,15 @@ EXPORT_SYMBOL_GPL(occ_setup);
 
 void occ_shutdown(struct occ *occ)
 {
+       mutex_lock(&occ->lock);
+
        occ_shutdown_sysfs(occ);
 
        if (occ->hwmon)
                hwmon_device_unregister(occ->hwmon);
+       occ->hwmon = NULL;
+
+       mutex_unlock(&occ->lock);
 }
 EXPORT_SYMBOL_GPL(occ_shutdown);
 
index b9bb94bd0f67277571596166e5de722a453f5b8e..424ef470223df4d687b2609c952147299de620ec 100644 (file)
@@ -115,6 +115,18 @@ static unsigned int mwait_substates __initdata;
 #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF)
 #define MWAIT2flg(eax) ((eax & 0xFF) << 24)
 
+static __always_inline int __intel_idle(struct cpuidle_device *dev,
+                                       struct cpuidle_driver *drv, int index)
+{
+       struct cpuidle_state *state = &drv->states[index];
+       unsigned long eax = flg2MWAIT(state->flags);
+       unsigned long ecx = 1; /* break on interrupt flag */
+
+       mwait_idle_with_hints(eax, ecx);
+
+       return index;
+}
+
 /**
  * intel_idle - Ask the processor to enter the given idle state.
  * @dev: cpuidle device of the target CPU.
@@ -132,16 +144,19 @@ static unsigned int mwait_substates __initdata;
 static __cpuidle int intel_idle(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv, int index)
 {
-       struct cpuidle_state *state = &drv->states[index];
-       unsigned long eax = flg2MWAIT(state->flags);
-       unsigned long ecx = 1; /* break on interrupt flag */
+       return __intel_idle(dev, drv, index);
+}
 
-       if (state->flags & CPUIDLE_FLAG_IRQ_ENABLE)
-               local_irq_enable();
+static __cpuidle int intel_idle_irq(struct cpuidle_device *dev,
+                                   struct cpuidle_driver *drv, int index)
+{
+       int ret;
 
-       mwait_idle_with_hints(eax, ecx);
+       raw_local_irq_enable();
+       ret = __intel_idle(dev, drv, index);
+       raw_local_irq_disable();
 
-       return index;
+       return ret;
 }
 
 /**
@@ -1801,6 +1816,9 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
                /* Structure copy. */
                drv->states[drv->state_count] = cpuidle_state_table[cstate];
 
+               if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE)
+                       drv->states[drv->state_count].enter = intel_idle_irq;
+
                if ((disabled_states_mask & BIT(drv->state_count)) ||
                    ((icpu->use_acpi || force_use_acpi) &&
                     intel_idle_off_by_default(mwait_hint) &&
index 505a032e2786d2121e8019c35c849e77f4a25ee3..9dcf3f51f2dd9e4a327bb2d7aeb1431ee3acbd13 100644 (file)
@@ -402,6 +402,7 @@ config JOYSTICK_N64
 config JOYSTICK_SENSEHAT
        tristate "Raspberry Pi Sense HAT joystick"
        depends on INPUT && I2C
+       depends on HAS_IOMEM
        select MFD_SIMPLE_MFD_I2C
        help
          Say Y here if you want to enable the driver for the
index cbb1599a520e602cafb1e8ef8c96253bf718ef9d..480476121c0105dde875a1902a8a5531fa539762 100644 (file)
@@ -85,13 +85,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = {
        },
        {
                /*
-                * Lenovo Yoga Tab2 1051L, something messes with the home-button
+                * Lenovo Yoga Tab2 1051F/1051L, something messes with the home-button
                 * IRQ settings, leading to a non working home-button.
                 */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "60073"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "1051L"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "1051"),
                },
        },
        {} /* Terminating entry */
index 59a14505b9cd135d5988c0e20b661b8f171da072..ca150618d32f1863795f390b4ebf4687ea0e36c1 100644 (file)
@@ -942,17 +942,22 @@ static int bcm5974_probe(struct usb_interface *iface,
        if (!dev->tp_data)
                goto err_free_bt_buffer;
 
-       if (dev->bt_urb)
+       if (dev->bt_urb) {
                usb_fill_int_urb(dev->bt_urb, udev,
                                 usb_rcvintpipe(udev, cfg->bt_ep),
                                 dev->bt_data, dev->cfg.bt_datalen,
                                 bcm5974_irq_button, dev, 1);
 
+               dev->bt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       }
+
        usb_fill_int_urb(dev->tp_urb, udev,
                         usb_rcvintpipe(udev, cfg->tp_ep),
                         dev->tp_data, dev->cfg.tp_datalen,
                         bcm5974_irq_trackpad, dev, 1);
 
+       dev->tp_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
        /* create bcm5974 device */
        usb_make_path(udev, dev->phys, sizeof(dev->phys));
        strlcat(dev->phys, "/input0", sizeof(dev->phys));
index d21648a923ea95b7e9bbd4508721c3361354c921..54c0473a51ddec847cfa7eba66b7187ad007a4e5 100644 (file)
@@ -33,6 +33,14 @@ struct dm_kobject_holder {
  * access their members!
  */
 
+/*
+ * For mempools pre-allocation at the table loading time.
+ */
+struct dm_md_mempools {
+       struct bio_set bs;
+       struct bio_set io_bs;
+};
+
 struct mapped_device {
        struct mutex suspend_lock;
 
@@ -110,8 +118,7 @@ struct mapped_device {
        /*
         * io objects are allocated from here.
         */
-       struct bio_set io_bs;
-       struct bio_set bs;
+       struct dm_md_mempools *mempools;
 
        /* kobject and completion */
        struct dm_kobject_holder kobj_holder;
index 06f328928a7f52948eb3ac0c895cd2014faa503b..2dda05aada2312509f3aba6658e7d9d9f7fad22e 100644 (file)
@@ -415,8 +415,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
        /*
         * Work out how many "unsigned long"s we need to hold the bitset.
         */
-       bitset_size = dm_round_up(region_count,
-                                 sizeof(*lc->clean_bits) << BYTE_SHIFT);
+       bitset_size = dm_round_up(region_count, BITS_PER_LONG);
        bitset_size >>= BYTE_SHIFT;
 
        lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits);
index 5e41fbae3f6b05918d1a6c7e0471dad79f5d6051..9526ccbedafbac9ad74c413b2968a3bdc5da776d 100644 (file)
@@ -3725,7 +3725,7 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv,
        if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) {
                if (mddev->sync_thread) {
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-                       md_reap_sync_thread(mddev, false);
+                       md_reap_sync_thread(mddev);
                }
        } else if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
                return -EBUSY;
index 6087cdcaad46df50cb786fdb1f23b41efdf030a6..a83b98a8d2a993e75debd263ebefa369075c4080 100644 (file)
@@ -319,7 +319,7 @@ static int setup_clone(struct request *clone, struct request *rq,
 {
        int r;
 
-       r = blk_rq_prep_clone(clone, rq, &tio->md->bs, gfp_mask,
+       r = blk_rq_prep_clone(clone, rq, &tio->md->mempools->bs, gfp_mask,
                              dm_rq_bio_constructor, tio);
        if (r)
                return r;
index 0e833a154b31dfc87e9c1bf7713a36dd8ae596f7..bd539afbfe88f729baa10d6b0af5276fb412b10b 100644 (file)
@@ -1038,17 +1038,6 @@ static int dm_table_alloc_md_mempools(struct dm_table *t, struct mapped_device *
        return 0;
 }
 
-void dm_table_free_md_mempools(struct dm_table *t)
-{
-       dm_free_md_mempools(t->mempools);
-       t->mempools = NULL;
-}
-
-struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t)
-{
-       return t->mempools;
-}
-
 static int setup_indexes(struct dm_table *t)
 {
        int i;
index dfb0a551bd880e9da428c8c28ee9a8822278ed09..b6b25d319ef705e96654fb7974026d53f9c4f8ff 100644 (file)
@@ -136,14 +136,6 @@ static int get_swap_bios(void)
        return latch;
 }
 
-/*
- * For mempools pre-allocation at the table loading time.
- */
-struct dm_md_mempools {
-       struct bio_set bs;
-       struct bio_set io_bs;
-};
-
 struct table_device {
        struct list_head list;
        refcount_t count;
@@ -563,6 +555,10 @@ static void dm_start_io_acct(struct dm_io *io, struct bio *clone)
                unsigned long flags;
                /* Can afford locking given DM_TIO_IS_DUPLICATE_BIO */
                spin_lock_irqsave(&io->lock, flags);
+               if (dm_io_flagged(io, DM_IO_ACCOUNTED)) {
+                       spin_unlock_irqrestore(&io->lock, flags);
+                       return;
+               }
                dm_io_set_flag(io, DM_IO_ACCOUNTED);
                spin_unlock_irqrestore(&io->lock, flags);
        }
@@ -581,7 +577,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
        struct dm_target_io *tio;
        struct bio *clone;
 
-       clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->io_bs);
+       clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->mempools->io_bs);
        /* Set default bdev, but target must bio_set_dev() before issuing IO */
        clone->bi_bdev = md->disk->part0;
 
@@ -628,7 +624,8 @@ static struct bio *alloc_tio(struct clone_info *ci, struct dm_target *ti,
        } else {
                struct mapped_device *md = ci->io->md;
 
-               clone = bio_alloc_clone(NULL, ci->bio, gfp_mask, &md->bs);
+               clone = bio_alloc_clone(NULL, ci->bio, gfp_mask,
+                                       &md->mempools->bs);
                if (!clone)
                        return NULL;
                /* Set default bdev, but target must bio_set_dev() before issuing IO */
@@ -718,18 +715,18 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU)
 }
 
 static inline struct dm_table *dm_get_live_table_bio(struct mapped_device *md,
-                                                    int *srcu_idx, struct bio *bio)
+                                                    int *srcu_idx, unsigned bio_opf)
 {
-       if (bio->bi_opf & REQ_NOWAIT)
+       if (bio_opf & REQ_NOWAIT)
                return dm_get_live_table_fast(md);
        else
                return dm_get_live_table(md, srcu_idx);
 }
 
 static inline void dm_put_live_table_bio(struct mapped_device *md, int srcu_idx,
-                                        struct bio *bio)
+                                        unsigned bio_opf)
 {
-       if (bio->bi_opf & REQ_NOWAIT)
+       if (bio_opf & REQ_NOWAIT)
                dm_put_live_table_fast(md);
        else
                dm_put_live_table(md, srcu_idx);
@@ -1023,23 +1020,19 @@ static void clone_endio(struct bio *bio)
        struct dm_io *io = tio->io;
        struct mapped_device *md = io->md;
 
-       if (likely(bio->bi_bdev != md->disk->part0)) {
-               struct request_queue *q = bdev_get_queue(bio->bi_bdev);
-
-               if (unlikely(error == BLK_STS_TARGET)) {
-                       if (bio_op(bio) == REQ_OP_DISCARD &&
-                           !bdev_max_discard_sectors(bio->bi_bdev))
-                               disable_discard(md);
-                       else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
-                                !q->limits.max_write_zeroes_sectors)
-                               disable_write_zeroes(md);
-               }
-
-               if (static_branch_unlikely(&zoned_enabled) &&
-                   unlikely(blk_queue_is_zoned(q)))
-                       dm_zone_endio(io, bio);
+       if (unlikely(error == BLK_STS_TARGET)) {
+               if (bio_op(bio) == REQ_OP_DISCARD &&
+                   !bdev_max_discard_sectors(bio->bi_bdev))
+                       disable_discard(md);
+               else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
+                        !bdev_write_zeroes_sectors(bio->bi_bdev))
+                       disable_write_zeroes(md);
        }
 
+       if (static_branch_unlikely(&zoned_enabled) &&
+           unlikely(blk_queue_is_zoned(bdev_get_queue(bio->bi_bdev))))
+               dm_zone_endio(io, bio);
+
        if (endio) {
                int r = endio(ti, bio, &error);
                switch (r) {
@@ -1620,7 +1613,12 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
        ti = dm_table_find_target(ci->map, ci->sector);
        if (unlikely(!ti))
                return BLK_STS_IOERR;
-       else if (unlikely(ci->is_abnormal_io))
+
+       if (unlikely((ci->bio->bi_opf & REQ_NOWAIT) != 0) &&
+           unlikely(!dm_target_supports_nowait(ti->type)))
+               return BLK_STS_NOTSUPP;
+
+       if (unlikely(ci->is_abnormal_io))
                return __process_abnormal_io(ci, ti);
 
        /*
@@ -1722,8 +1720,9 @@ static void dm_submit_bio(struct bio *bio)
        struct mapped_device *md = bio->bi_bdev->bd_disk->private_data;
        int srcu_idx;
        struct dm_table *map;
+       unsigned bio_opf = bio->bi_opf;
 
-       map = dm_get_live_table_bio(md, &srcu_idx, bio);
+       map = dm_get_live_table_bio(md, &srcu_idx, bio_opf);
 
        /* If suspended, or map not yet available, queue this IO for later */
        if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) ||
@@ -1739,7 +1738,7 @@ static void dm_submit_bio(struct bio *bio)
 
        dm_split_and_process_bio(md, map, bio);
 out:
-       dm_put_live_table_bio(md, srcu_idx, bio);
+       dm_put_live_table_bio(md, srcu_idx, bio_opf);
 }
 
 static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob,
@@ -1876,8 +1875,7 @@ static void cleanup_mapped_device(struct mapped_device *md)
 {
        if (md->wq)
                destroy_workqueue(md->wq);
-       bioset_exit(&md->bs);
-       bioset_exit(&md->io_bs);
+       dm_free_md_mempools(md->mempools);
 
        if (md->dax_dev) {
                dax_remove_host(md->disk);
@@ -2049,48 +2047,6 @@ static void free_dev(struct mapped_device *md)
        kvfree(md);
 }
 
-static int __bind_mempools(struct mapped_device *md, struct dm_table *t)
-{
-       struct dm_md_mempools *p = dm_table_get_md_mempools(t);
-       int ret = 0;
-
-       if (dm_table_bio_based(t)) {
-               /*
-                * The md may already have mempools that need changing.
-                * If so, reload bioset because front_pad may have changed
-                * because a different table was loaded.
-                */
-               bioset_exit(&md->bs);
-               bioset_exit(&md->io_bs);
-
-       } else if (bioset_initialized(&md->bs)) {
-               /*
-                * There's no need to reload with request-based dm
-                * because the size of front_pad doesn't change.
-                * Note for future: If you are to reload bioset,
-                * prep-ed requests in the queue may refer
-                * to bio from the old bioset, so you must walk
-                * through the queue to unprep.
-                */
-               goto out;
-       }
-
-       BUG_ON(!p ||
-              bioset_initialized(&md->bs) ||
-              bioset_initialized(&md->io_bs));
-
-       ret = bioset_init_from_src(&md->bs, &p->bs);
-       if (ret)
-               goto out;
-       ret = bioset_init_from_src(&md->io_bs, &p->io_bs);
-       if (ret)
-               bioset_exit(&md->bs);
-out:
-       /* mempool bind completed, no longer need any mempools in the table */
-       dm_table_free_md_mempools(t);
-       return ret;
-}
-
 /*
  * Bind a table to the device.
  */
@@ -2144,12 +2100,28 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
                 * immutable singletons - used to optimize dm_mq_queue_rq.
                 */
                md->immutable_target = dm_table_get_immutable_target(t);
-       }
 
-       ret = __bind_mempools(md, t);
-       if (ret) {
-               old_map = ERR_PTR(ret);
-               goto out;
+               /*
+                * There is no need to reload with request-based dm because the
+                * size of front_pad doesn't change.
+                *
+                * Note for future: If you are to reload bioset, prep-ed
+                * requests in the queue may refer to bio from the old bioset,
+                * so you must walk through the queue to unprep.
+                */
+               if (!md->mempools) {
+                       md->mempools = t->mempools;
+                       t->mempools = NULL;
+               }
+       } else {
+               /*
+                * The md may already have mempools that need changing.
+                * If so, reload bioset because front_pad may have changed
+                * because a different table was loaded.
+                */
+               dm_free_md_mempools(md->mempools);
+               md->mempools = t->mempools;
+               t->mempools = NULL;
        }
 
        ret = dm_table_set_restrictions(t, md->queue, limits);
index 3f89664fea010121f793bc404c5d8870c68594b6..a8405ce305a968977d68d03e3820b5d3238ef5d5 100644 (file)
@@ -71,8 +71,6 @@ struct dm_target *dm_table_get_immutable_target(struct dm_table *t);
 struct dm_target *dm_table_get_wildcard_target(struct dm_table *t);
 bool dm_table_bio_based(struct dm_table *t);
 bool dm_table_request_based(struct dm_table *t);
-void dm_table_free_md_mempools(struct dm_table *t);
-struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t);
 
 void dm_lock_md_type(struct mapped_device *md);
 void dm_unlock_md_type(struct mapped_device *md);
index 8273ac5eef06a30fd9ccfcdc7b33a241a07f9f3d..c7ecb0bffda0d58678c57fa44be99aebf73f20d3 100644 (file)
@@ -4831,7 +4831,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                                flush_workqueue(md_misc_wq);
                        if (mddev->sync_thread) {
                                set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-                               md_reap_sync_thread(mddev, true);
+                               md_reap_sync_thread(mddev);
                        }
                        mddev_unlock(mddev);
                }
@@ -6197,7 +6197,7 @@ static void __md_stop_writes(struct mddev *mddev)
                flush_workqueue(md_misc_wq);
        if (mddev->sync_thread) {
                set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-               md_reap_sync_thread(mddev, true);
+               md_reap_sync_thread(mddev);
        }
 
        del_timer_sync(&mddev->safemode_timer);
@@ -9303,7 +9303,7 @@ void md_check_recovery(struct mddev *mddev)
                         * ->spare_active and clear saved_raid_disk
                         */
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-                       md_reap_sync_thread(mddev, true);
+                       md_reap_sync_thread(mddev);
                        clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
                        clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                        clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags);
@@ -9338,7 +9338,7 @@ void md_check_recovery(struct mddev *mddev)
                        goto unlock;
                }
                if (mddev->sync_thread) {
-                       md_reap_sync_thread(mddev, true);
+                       md_reap_sync_thread(mddev);
                        goto unlock;
                }
                /* Set RUNNING before clearing NEEDED to avoid
@@ -9411,18 +9411,14 @@ void md_check_recovery(struct mddev *mddev)
 }
 EXPORT_SYMBOL(md_check_recovery);
 
-void md_reap_sync_thread(struct mddev *mddev, bool reconfig_mutex_held)
+void md_reap_sync_thread(struct mddev *mddev)
 {
        struct md_rdev *rdev;
        sector_t old_dev_sectors = mddev->dev_sectors;
        bool is_reshaped = false;
 
-       if (reconfig_mutex_held)
-               mddev_unlock(mddev);
        /* resync has finished, collect result */
        md_unregister_thread(&mddev->sync_thread);
-       if (reconfig_mutex_held)
-               mddev_lock_nointr(mddev);
        if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
            !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
            mddev->degraded != mddev->raid_disks) {
index 5f62c46ac2d33e7fdf2228da72d946a8ba550e49..cf2cbb17acbd423ccebf7d1a008fc47ae07ed6a5 100644 (file)
@@ -719,7 +719,7 @@ extern struct md_thread *md_register_thread(
 extern void md_unregister_thread(struct md_thread **threadp);
 extern void md_wakeup_thread(struct md_thread *thread);
 extern void md_check_recovery(struct mddev *mddev);
-extern void md_reap_sync_thread(struct mddev *mddev, bool reconfig_mutex_held);
+extern void md_reap_sync_thread(struct mddev *mddev);
 extern int mddev_init_writes_pending(struct mddev *mddev);
 extern bool md_write_start(struct mddev *mddev, struct bio *bi);
 extern void md_write_inc(struct mddev *mddev, struct bio *bi);
index 973e2e06f19c220ae33f01aae8629e29d4e46cac..0a2e4806b1ece1e3330527ad694397d2204e05e6 100644 (file)
@@ -629,9 +629,9 @@ static void ppl_do_flush(struct ppl_io_unit *io)
                if (bdev) {
                        struct bio *bio;
 
-                       bio = bio_alloc_bioset(bdev, 0, GFP_NOIO,
+                       bio = bio_alloc_bioset(bdev, 0,
                                               REQ_OP_WRITE | REQ_PREFLUSH,
-                                              &ppl_conf->flush_bs);
+                                              GFP_NOIO, &ppl_conf->flush_bs);
                        bio->bi_private = io;
                        bio->bi_end_io = ppl_flush_endio;
 
index d6cd5537126c69bc76b5c019b17d0b01bb4a7eab..69f9b0336410d7e8da32ca0c7f0c2396eff942b2 100644 (file)
@@ -232,9 +232,9 @@ static int ssc_probe(struct platform_device *pdev)
        clk_disable_unprepare(ssc->clk);
 
        ssc->irq = platform_get_irq(pdev, 0);
-       if (!ssc->irq) {
+       if (ssc->irq < 0) {
                dev_dbg(&pdev->dev, "could not get irq\n");
-               return -ENXIO;
+               return ssc->irq;
        }
 
        mutex_lock(&user_lock);
index 8d169a35cf130c231255ee84a6de52aade3e2d84..c9c56fd194c1301f97fea1d48b94b2e2a156d6c6 100644 (file)
@@ -79,6 +79,11 @@ static int at25_ee_read(void *priv, unsigned int offset,
 {
        struct at25_data *at25 = priv;
        char *buf = val;
+       size_t max_chunk = spi_max_transfer_size(at25->spi);
+       size_t num_msgs = DIV_ROUND_UP(count, max_chunk);
+       size_t nr_bytes = 0;
+       unsigned int msg_offset;
+       size_t msg_count;
        u8                      *cp;
        ssize_t                 status;
        struct spi_transfer     t[2];
@@ -92,54 +97,59 @@ static int at25_ee_read(void *priv, unsigned int offset,
        if (unlikely(!count))
                return -EINVAL;
 
-       cp = at25->command;
+       msg_offset = (unsigned int)offset;
+       msg_count = min(count, max_chunk);
+       while (num_msgs) {
+               cp = at25->command;
 
-       instr = AT25_READ;
-       if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
-               if (offset >= BIT(at25->addrlen * 8))
-                       instr |= AT25_INSTR_BIT3;
+               instr = AT25_READ;
+               if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
+                       if (msg_offset >= BIT(at25->addrlen * 8))
+                               instr |= AT25_INSTR_BIT3;
 
-       mutex_lock(&at25->lock);
+               mutex_lock(&at25->lock);
 
-       *cp++ = instr;
-
-       /* 8/16/24-bit address is written MSB first */
-       switch (at25->addrlen) {
-       default:        /* case 3 */
-               *cp++ = offset >> 16;
-               fallthrough;
-       case 2:
-               *cp++ = offset >> 8;
-               fallthrough;
-       case 1:
-       case 0: /* can't happen: for better code generation */
-               *cp++ = offset >> 0;
-       }
+               *cp++ = instr;
 
-       spi_message_init(&m);
-       memset(t, 0, sizeof(t));
+               /* 8/16/24-bit address is written MSB first */
+               switch (at25->addrlen) {
+               default:        /* case 3 */
+                       *cp++ = msg_offset >> 16;
+                       fallthrough;
+               case 2:
+                       *cp++ = msg_offset >> 8;
+                       fallthrough;
+               case 1:
+               case 0: /* can't happen: for better code generation */
+                       *cp++ = msg_offset >> 0;
+               }
 
-       t[0].tx_buf = at25->command;
-       t[0].len = at25->addrlen + 1;
-       spi_message_add_tail(&t[0], &m);
+               spi_message_init(&m);
+               memset(t, 0, sizeof(t));
 
-       t[1].rx_buf = buf;
-       t[1].len = count;
-       spi_message_add_tail(&t[1], &m);
+               t[0].tx_buf = at25->command;
+               t[0].len = at25->addrlen + 1;
+               spi_message_add_tail(&t[0], &m);
 
-       /*
-        * Read it all at once.
-        *
-        * REVISIT that's potentially a problem with large chips, if
-        * other devices on the bus need to be accessed regularly or
-        * this chip is clocked very slowly.
-        */
-       status = spi_sync(at25->spi, &m);
-       dev_dbg(&at25->spi->dev, "read %zu bytes at %d --> %zd\n",
-               count, offset, status);
+               t[1].rx_buf = buf + nr_bytes;
+               t[1].len = msg_count;
+               spi_message_add_tail(&t[1], &m);
 
-       mutex_unlock(&at25->lock);
-       return status;
+               status = spi_sync(at25->spi, &m);
+
+               mutex_unlock(&at25->lock);
+
+               if (status)
+                       return status;
+
+               --num_msgs;
+               msg_offset += msg_count;
+               nr_bytes += msg_count;
+       }
+
+       dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n",
+               count, offset);
+       return 0;
 }
 
 /* Read extra registers as ID or serial number */
@@ -190,6 +200,7 @@ ATTRIBUTE_GROUPS(sernum);
 static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count)
 {
        struct at25_data *at25 = priv;
+       size_t maxsz = spi_max_transfer_size(at25->spi);
        const char *buf = val;
        int                     status = 0;
        unsigned                buf_size;
@@ -253,6 +264,8 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count)
                segment = buf_size - (offset % buf_size);
                if (segment > count)
                        segment = count;
+               if (segment > maxsz)
+                       segment = maxsz;
                memcpy(cp, buf, segment);
                status = spi_write(at25->spi, bounce,
                                segment + at25->addrlen + 1);
index 1259ca22d62500336e0833800d0bc34294ffa013..f4a1281658db07bd0152c2f509ee095d4c3470e7 100644 (file)
@@ -1499,8 +1499,7 @@ void mmc_blk_cqe_recovery(struct mmc_queue *mq)
        err = mmc_cqe_recovery(host);
        if (err)
                mmc_blk_reset(mq->blkdata, host, MMC_BLK_CQE_RECOVERY);
-       else
-               mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY);
+       mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY);
 
        pr_debug("%s: CQE recovery done\n", mmc_hostname(host));
 }
index 1499a64ec3aa1bafad4646bd20e161d5e227de82..f13c08db3da5fe61ac981afe4af51c88f94e6d27 100644 (file)
@@ -982,6 +982,9 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip)
        struct sdhci_host *host = slot->host;
        u16 clock;
 
+       if (host->mmc->ios.power_mode != MMC_POWER_ON)
+               return 0;
+
        clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
 
        clock |= SDHCI_CLOCK_PLL_EN;
index ebee5f07a208eb17e71352ff653d114119d4efb7..be2719a3ba702b634feb190cebeebe288b8adc56 100644 (file)
@@ -51,6 +51,7 @@ static char *status_str[] = {
 };
 
 static char *type_str[] = {
+       "", /* Type 0 is not defined */
        "AMT_MSG_DISCOVERY",
        "AMT_MSG_ADVERTISEMENT",
        "AMT_MSG_REQUEST",
@@ -2220,8 +2221,7 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
        struct amt_header_advertisement *amta;
        int hdr_size;
 
-       hdr_size = sizeof(*amta) - sizeof(struct amt_header);
-
+       hdr_size = sizeof(*amta) + sizeof(struct udphdr);
        if (!pskb_may_pull(skb, hdr_size))
                return true;
 
@@ -2251,19 +2251,27 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
        struct ethhdr *eth;
        struct iphdr *iph;
 
+       hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
+       if (!pskb_may_pull(skb, hdr_size))
+               return true;
+
        amtmd = (struct amt_header_mcast_data *)(udp_hdr(skb) + 1);
        if (amtmd->reserved || amtmd->version)
                return true;
 
-       hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
        if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_IP), false))
                return true;
+
        skb_reset_network_header(skb);
        skb_push(skb, sizeof(*eth));
        skb_reset_mac_header(skb);
        skb_pull(skb, sizeof(*eth));
        eth = eth_hdr(skb);
+
+       if (!pskb_may_pull(skb, sizeof(*iph)))
+               return true;
        iph = ip_hdr(skb);
+
        if (iph->version == 4) {
                if (!ipv4_is_multicast(iph->daddr))
                        return true;
@@ -2274,6 +2282,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
        } else if (iph->version == 6) {
                struct ipv6hdr *ip6h;
 
+               if (!pskb_may_pull(skb, sizeof(*ip6h)))
+                       return true;
+
                ip6h = ipv6_hdr(skb);
                if (!ipv6_addr_is_multicast(&ip6h->daddr))
                        return true;
@@ -2306,8 +2317,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
        struct iphdr *iph;
        int hdr_size, len;
 
-       hdr_size = sizeof(*amtmq) - sizeof(struct amt_header);
-
+       hdr_size = sizeof(*amtmq) + sizeof(struct udphdr);
        if (!pskb_may_pull(skb, hdr_size))
                return true;
 
@@ -2315,22 +2325,27 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
        if (amtmq->reserved || amtmq->version)
                return true;
 
-       hdr_size = sizeof(*amtmq) + sizeof(struct udphdr) - sizeof(*eth);
+       hdr_size -= sizeof(*eth);
        if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false))
                return true;
+
        oeth = eth_hdr(skb);
        skb_reset_mac_header(skb);
        skb_pull(skb, sizeof(*eth));
        skb_reset_network_header(skb);
        eth = eth_hdr(skb);
+       if (!pskb_may_pull(skb, sizeof(*iph)))
+               return true;
+
        iph = ip_hdr(skb);
        if (iph->version == 4) {
-               if (!ipv4_is_multicast(iph->daddr))
-                       return true;
                if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS +
                                   sizeof(*ihv3)))
                        return true;
 
+               if (!ipv4_is_multicast(iph->daddr))
+                       return true;
+
                ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
                skb_reset_transport_header(skb);
                skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
@@ -2345,15 +2360,17 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
                ip_eth_mc_map(iph->daddr, eth->h_dest);
 #if IS_ENABLED(CONFIG_IPV6)
        } else if (iph->version == 6) {
-               struct ipv6hdr *ip6h = ipv6_hdr(skb);
                struct mld2_query *mld2q;
+               struct ipv6hdr *ip6h;
 
-               if (!ipv6_addr_is_multicast(&ip6h->daddr))
-                       return true;
                if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS +
                                   sizeof(*mld2q)))
                        return true;
 
+               ip6h = ipv6_hdr(skb);
+               if (!ipv6_addr_is_multicast(&ip6h->daddr))
+                       return true;
+
                mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
                skb_reset_transport_header(skb);
                skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
@@ -2389,23 +2406,23 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
 {
        struct amt_header_membership_update *amtmu;
        struct amt_tunnel_list *tunnel;
-       struct udphdr *udph;
        struct ethhdr *eth;
        struct iphdr *iph;
-       int len;
+       int len, hdr_size;
 
        iph = ip_hdr(skb);
-       udph = udp_hdr(skb);
 
-       if (__iptunnel_pull_header(skb, sizeof(*udph), skb->protocol,
-                                  false, false))
+       hdr_size = sizeof(*amtmu) + sizeof(struct udphdr);
+       if (!pskb_may_pull(skb, hdr_size))
                return true;
 
-       amtmu = (struct amt_header_membership_update *)skb->data;
+       amtmu = (struct amt_header_membership_update *)(udp_hdr(skb) + 1);
        if (amtmu->reserved || amtmu->version)
                return true;
 
-       skb_pull(skb, sizeof(*amtmu));
+       if (iptunnel_pull_header(skb, hdr_size, skb->protocol, false))
+               return true;
+
        skb_reset_network_header(skb);
 
        list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
@@ -2426,6 +2443,9 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
        return true;
 
 report:
+       if (!pskb_may_pull(skb, sizeof(*iph)))
+               return true;
+
        iph = ip_hdr(skb);
        if (iph->version == 4) {
                if (ip_mc_check_igmp(skb)) {
@@ -2679,7 +2699,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
        amt = rcu_dereference_sk_user_data(sk);
        if (!amt) {
                err = true;
-               goto drop;
+               kfree_skb(skb);
+               goto out;
        }
 
        skb->dev = amt->dev;
index 8af4def38a988702a38f946334b48a6301ac7112..e531b93f3cb2715e84b5bcd76330e32d0747d4cc 100644 (file)
@@ -2070,8 +2070,10 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
        for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) {
                err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i],
                                          gphy_fw_np, i);
-               if (err)
+               if (err) {
+                       of_node_put(gphy_fw_np);
                        goto remove_gphy;
+               }
                i++;
        }
 
index 7b37d45bc9fb52c1f580b9efa7ce5b67fe149163..d94150d8f3f47c40269351d00540fca87a226385 100644 (file)
@@ -50,22 +50,25 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
 }
 
 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
-                                         u16 ctrl, u16 status, u16 lpa,
+                                         u16 bmsr, u16 lpa, u16 status,
                                          struct phylink_link_state *state)
 {
+       state->link = false;
+
+       /* If the BMSR reports that the link had failed, report this to
+        * phylink.
+        */
+       if (!(bmsr & BMSR_LSTATUS))
+               return 0;
+
        state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
+       state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
 
        if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
                /* The Spped and Duplex Resolved register is 1 if AN is enabled
                 * and complete, or if AN is disabled. So with disabled AN we
-                * still get here on link up. But we want to set an_complete
-                * only if AN was enabled, thus we look at BMCR_ANENABLE.
-                * (According to 802.3-2008 section 22.2.4.2.10, we should be
-                *  able to get this same value from BMSR_ANEGCAPABLE, but tests
-                *  show that these Marvell PHYs don't conform to this part of
-                *  the specificaion - BMSR_ANEGCAPABLE is simply always 1.)
+                * still get here on link up.
                 */
-               state->an_complete = !!(ctrl & BMCR_ANENABLE);
                state->duplex = status &
                                MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
                                                 DUPLEX_FULL : DUPLEX_HALF;
@@ -191,12 +194,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
                                   int lane, struct phylink_link_state *state)
 {
-       u16 lpa, status, ctrl;
+       u16 bmsr, lpa, status;
        int err;
 
-       err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl);
+       err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
        if (err) {
-               dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
+               dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
                return err;
        }
 
@@ -212,7 +215,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
                return err;
        }
 
-       return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
+       return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
 }
 
 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
@@ -918,13 +921,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
        int port, int lane, struct phylink_link_state *state)
 {
-       u16 lpa, status, ctrl;
+       u16 bmsr, lpa, status;
        int err;
 
        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
-                                   MV88E6390_SGMII_BMCR, &ctrl);
+                                   MV88E6390_SGMII_BMSR, &bmsr);
        if (err) {
-               dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
+               dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
                return err;
        }
 
@@ -942,7 +945,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
                return err;
        }
 
-       return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
+       return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
 }
 
 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
index 3bb42a9f236d2033cf10df9132e7d3b511c6f3fb..769f672e9128448741e60ed60eb722ecf2adb762 100644 (file)
@@ -955,35 +955,21 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port,
        return 0;
 }
 
-static bool rtl8365mb_phy_mode_supported(struct dsa_switch *ds, int port,
-                                        phy_interface_t interface)
-{
-       int ext_int;
-
-       ext_int = rtl8365mb_extint_port_map[port];
-
-       if (ext_int < 0 &&
-           (interface == PHY_INTERFACE_MODE_NA ||
-            interface == PHY_INTERFACE_MODE_INTERNAL ||
-            interface == PHY_INTERFACE_MODE_GMII))
-               /* Internal PHY */
-               return true;
-       else if ((ext_int >= 1) &&
-                phy_interface_mode_is_rgmii(interface))
-               /* Extension MAC */
-               return true;
-
-       return false;
-}
-
 static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port,
                                       struct phylink_config *config)
 {
-       if (dsa_is_user_port(ds, port))
+       if (dsa_is_user_port(ds, port)) {
                __set_bit(PHY_INTERFACE_MODE_INTERNAL,
                          config->supported_interfaces);
-       else if (dsa_is_cpu_port(ds, port))
+
+               /* GMII is the default interface mode for phylib, so
+                * we have to support it for ports with integrated PHY.
+                */
+               __set_bit(PHY_INTERFACE_MODE_GMII,
+                         config->supported_interfaces);
+       } else if (dsa_is_cpu_port(ds, port)) {
                phy_interface_set_rgmii(config->supported_interfaces);
+       }
 
        config->mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
                                   MAC_10 | MAC_100 | MAC_1000FD;
@@ -996,12 +982,6 @@ static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port,
        struct realtek_priv *priv = ds->priv;
        int ret;
 
-       if (!rtl8365mb_phy_mode_supported(ds, port, state->interface)) {
-               dev_err(priv->dev, "phy mode %s is unsupported on port %d\n",
-                       phy_modes(state->interface), port);
-               return;
-       }
-
        if (mode != MLO_AN_PHY && mode != MLO_AN_FIXED) {
                dev_err(priv->dev,
                        "port %d supports only conventional PHY or fixed-link\n",
index a3816264c35cbd927cab5ddd8164326e5d9324b3..8c5828582c21eac53d4fe927599395a319f384a7 100644 (file)
@@ -163,7 +163,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
        mdio = mdiobus_alloc();
        if (mdio == NULL) {
                netdev_err(dev, "Error allocating MDIO bus\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto put_node;
        }
 
        mdio->name = ALTERA_TSE_RESOURCE_NAME;
@@ -180,6 +181,7 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
                           mdio->id);
                goto out_free_mdio;
        }
+       of_node_put(mdio_node);
 
        if (netif_msg_drv(priv))
                netdev_info(dev, "MDIO bus %s: created\n", mdio->id);
@@ -189,6 +191,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
 out_free_mdio:
        mdiobus_free(mdio);
        mdio = NULL;
+put_node:
+       of_node_put(mdio_node);
        return ret;
 }
 
index c6f003975621b4ef2c20eb9d9db8dc3834ff728b..d5f2c698922102525a767cd44240baf4fd936998 100644 (file)
@@ -820,7 +820,7 @@ static int au1000_rx(struct net_device *dev)
                                pr_cont("\n");
                        }
                }
-               prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
+               prxd->buff_stat = lower_32_bits(pDB->dma_addr) | RX_DMA_ENABLE;
                aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
                wmb(); /* drain writebuffer */
 
@@ -996,7 +996,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
        ps->tx_packets++;
        ps->tx_bytes += ptxd->len;
 
-       ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
+       ptxd->buff_stat = lower_32_bits(pDB->dma_addr) | TX_DMA_ENABLE;
        wmb(); /* drain writebuffer */
        dev_kfree_skb(skb);
        aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
@@ -1131,9 +1131,9 @@ static int au1000_probe(struct platform_device *pdev)
        /* Allocate the data buffers
         * Snooping works fine with eth on all au1xxx
         */
-       aup->vaddr = (u32)dma_alloc_coherent(&pdev->dev, MAX_BUF_SIZE *
-                                         (NUM_TX_BUFFS + NUM_RX_BUFFS),
-                                         &aup->dma_addr, 0);
+       aup->vaddr = dma_alloc_coherent(&pdev->dev, MAX_BUF_SIZE *
+                                       (NUM_TX_BUFFS + NUM_RX_BUFFS),
+                                       &aup->dma_addr, 0);
        if (!aup->vaddr) {
                dev_err(&pdev->dev, "failed to allocate data buffers\n");
                err = -ENOMEM;
@@ -1234,8 +1234,8 @@ static int au1000_probe(struct platform_device *pdev)
        for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
                pDB->pnext = pDBfree;
                pDBfree = pDB;
-               pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
-               pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+               pDB->vaddr = aup->vaddr + MAX_BUF_SIZE * i;
+               pDB->dma_addr = aup->dma_addr + MAX_BUF_SIZE * i;
                pDB++;
        }
        aup->pDBfree = pDBfree;
@@ -1246,7 +1246,7 @@ static int au1000_probe(struct platform_device *pdev)
                if (!pDB)
                        goto err_out;
 
-               aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+               aup->rx_dma_ring[i]->buff_stat = lower_32_bits(pDB->dma_addr);
                aup->rx_db_inuse[i] = pDB;
        }
 
@@ -1255,7 +1255,7 @@ static int au1000_probe(struct platform_device *pdev)
                if (!pDB)
                        goto err_out;
 
-               aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+               aup->tx_dma_ring[i]->buff_stat = lower_32_bits(pDB->dma_addr);
                aup->tx_dma_ring[i]->len = 0;
                aup->tx_db_inuse[i] = pDB;
        }
@@ -1310,7 +1310,7 @@ err_remap2:
        iounmap(aup->mac);
 err_remap1:
        dma_free_coherent(&pdev->dev, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
-                       (void *)aup->vaddr, aup->dma_addr);
+                         aup->vaddr, aup->dma_addr);
 err_vaddr:
        free_netdev(dev);
 err_alloc:
@@ -1343,7 +1343,7 @@ static int au1000_remove(struct platform_device *pdev)
                        au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
 
        dma_free_coherent(&pdev->dev, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
-                       (void *)aup->vaddr, aup->dma_addr);
+                         aup->vaddr, aup->dma_addr);
 
        iounmap(aup->macdma);
        iounmap(aup->mac);
index e3a3ed29db61db80cafd9ace489e132c9d1eda14..2489c2f4fd8a6156adc48329b734ce8c4daff979 100644 (file)
@@ -106,8 +106,8 @@ struct au1000_private {
        struct mac_reg *mac;  /* mac registers                      */
        u32 *enable;     /* address of MAC Enable Register     */
        void __iomem *macdma;   /* base of MAC DMA port */
-       u32 vaddr;                /* virtual address of rx/tx buffers   */
-       dma_addr_t dma_addr;      /* dma address of rx/tx buffers       */
+       void *vaddr;            /* virtual address of rx/tx buffers   */
+       dma_addr_t dma_addr;    /* dma address of rx/tx buffers       */
 
        spinlock_t lock;       /* Serialise access to device */
 
index a3593290886f8cc61a0cc7c0f22da9be59402fe9..4d46780fad1316b70683be94e59c7419802fd074 100644 (file)
@@ -2784,7 +2784,7 @@ void xgbe_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx)
 
        netdev_dbg(netdev, "Dst MAC addr: %pM\n", eth->h_dest);
        netdev_dbg(netdev, "Src MAC addr: %pM\n", eth->h_source);
-       netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto));
+       netdev_dbg(netdev, "Protocol: %#06x\n", ntohs(eth->h_proto));
 
        for (i = 0; i < skb->len; i += 32) {
                unsigned int len = min(skb->len - i, 32U);
index 4ebd2410185a9544b515ce1192ca93836427f21f..4d790a89fe7717cffe7c502949dbc0e5ce4895b6 100644 (file)
@@ -338,7 +338,7 @@ static int xgbe_platform_probe(struct platform_device *pdev)
                 *   the PHY resources listed last
                 */
                phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3;
-               phy_irqnum = xgbe_resource_count(pdev, IORESOURCE_IRQ) - 1;
+               phy_irqnum = platform_irq_count(pdev) - 1;
                dma_irqnum = 1;
                dma_irqend = phy_irqnum;
        } else {
@@ -348,7 +348,7 @@ static int xgbe_platform_probe(struct platform_device *pdev)
                phy_memnum = 0;
                phy_irqnum = 0;
                dma_irqnum = 1;
-               dma_irqend = xgbe_resource_count(pdev, IORESOURCE_IRQ);
+               dma_irqend = platform_irq_count(pdev);
        }
 
        /* Obtain the mmio areas for the device */
index 086739e4f40a9598d4b654c7b46208dfebfac8cc..9b83d536169940ea7f2b861c44fe256faed305aa 100644 (file)
@@ -234,6 +234,7 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac)
        np = of_get_child_by_name(core->dev.of_node, "mdio");
 
        err = of_mdiobus_register(mii_bus, np);
+       of_node_put(np);
        if (err) {
                dev_err(&core->dev, "Registration of mii bus failed\n");
                goto err_free_bus;
index e6f48786949c0fb5ed7db717df15db4fb622feb2..02bd3cf9a260e2342558dc7b559dd4df4db0afd4 100644 (file)
@@ -332,7 +332,6 @@ static void bgmac_remove(struct bcma_device *core)
        bcma_mdio_mii_unregister(bgmac->mii_bus);
        bgmac_enet_remove(bgmac);
        bcma_set_drvdata(core, NULL);
-       kfree(bgmac);
 }
 
 static struct bcma_driver bgmac_bcma_driver = {
index 8a3a446219f7471c3d547574b4777879e75bc7e5..94f80e1c4020cd855823c4701535d37eed13e4c9 100644 (file)
@@ -769,6 +769,7 @@ struct hnae3_tc_info {
        u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */
        u16 tqp_count[HNAE3_MAX_TC];
        u16 tqp_offset[HNAE3_MAX_TC];
+       u8 max_tc; /* Total number of TCs */
        u8 num_tc; /* Total number of enabled TCs */
        bool mqprio_active;
 };
index 6d20974519fef04f5cc3074ce482e55268f46b3e..4c7988e308a2ff0f0465ce9cb1c578ef0859e502 100644 (file)
@@ -1129,7 +1129,7 @@ hns3_is_ringparam_changed(struct net_device *ndev,
        if (old_ringparam->tx_desc_num == new_ringparam->tx_desc_num &&
            old_ringparam->rx_desc_num == new_ringparam->rx_desc_num &&
            old_ringparam->rx_buf_len == new_ringparam->rx_buf_len) {
-               netdev_info(ndev, "ringparam not changed\n");
+               netdev_info(ndev, "descriptor number and rx buffer length not changed\n");
                return false;
        }
 
index 1ebad0e50e6a2a30aa7d6d6e20389318e1e4cb42..fae79764dc4427647189962ea003775ece4f0e78 100644 (file)
@@ -3268,7 +3268,7 @@ static int hclge_tp_port_init(struct hclge_dev *hdev)
 static int hclge_update_port_info(struct hclge_dev *hdev)
 {
        struct hclge_mac *mac = &hdev->hw.mac;
-       int speed = HCLGE_MAC_SPEED_UNKNOWN;
+       int speed;
        int ret;
 
        /* get the port info from SFP cmd if not copper port */
@@ -3279,10 +3279,13 @@ static int hclge_update_port_info(struct hclge_dev *hdev)
        if (!hdev->support_sfp_query)
                return 0;
 
-       if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2)
+       if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
+               speed = mac->speed;
                ret = hclge_get_sfp_info(hdev, mac);
-       else
+       } else {
+               speed = HCLGE_MAC_SPEED_UNKNOWN;
                ret = hclge_get_sfp_speed(hdev, &speed);
+       }
 
        if (ret == -EOPNOTSUPP) {
                hdev->support_sfp_query = false;
@@ -3294,6 +3297,8 @@ static int hclge_update_port_info(struct hclge_dev *hdev)
        if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
                if (mac->speed_type == QUERY_ACTIVE_SPEED) {
                        hclge_update_port_capability(hdev, mac);
+                       if (mac->speed != speed)
+                               (void)hclge_tm_port_shaper_cfg(hdev);
                        return 0;
                }
                return hclge_cfg_mac_speed_dup(hdev, mac->speed,
@@ -3376,6 +3381,12 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
        link_state_old = vport->vf_info.link_state;
        vport->vf_info.link_state = link_state;
 
+       /* return success directly if the VF is unalive, VF will
+        * query link state itself when it starts work.
+        */
+       if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+               return 0;
+
        ret = hclge_push_vf_link_status(vport);
        if (ret) {
                vport->vf_info.link_state = link_state_old;
@@ -10117,6 +10128,7 @@ static int hclge_modify_port_base_vlan_tag(struct hclge_vport *vport,
        if (ret)
                return ret;
 
+       vport->port_base_vlan_cfg.tbl_sta = false;
        /* remove old VLAN tag */
        if (old_info->vlan_tag == 0)
                ret = hclge_set_vf_vlan_common(hdev, vport->vport_id,
index 1f87a8a3fe321e4b649b14e8c5c1f01e3db29992..2f33b036a47a7ece9a99a86a988d50129f7ab2b4 100644 (file)
@@ -282,8 +282,8 @@ static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev,
        return hclge_cmd_send(&hdev->hw, &desc, 1);
 }
 
-static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev,
-                                     u16 qs_id, u8 pri)
+static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, u16 qs_id, u8 pri,
+                                     bool link_vld)
 {
        struct hclge_qs_to_pri_link_cmd *map;
        struct hclge_desc desc;
@@ -294,7 +294,7 @@ static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev,
 
        map->qs_id = cpu_to_le16(qs_id);
        map->priority = pri;
-       map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK;
+       map->link_vld = link_vld ? HCLGE_TM_QS_PRI_LINK_VLD_MSK : 0;
 
        return hclge_cmd_send(&hdev->hw, &desc, 1);
 }
@@ -420,7 +420,7 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
        return hclge_cmd_send(&hdev->hw, &desc, 1);
 }
 
-static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
+int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
 {
        struct hclge_port_shapping_cmd *shap_cfg_cmd;
        struct hclge_shaper_ir_para ir_para;
@@ -642,11 +642,13 @@ static void hclge_tm_update_kinfo_rss_size(struct hclge_vport *vport)
         * one tc for VF for simplicity. VF's vport_id is non zero.
         */
        if (vport->vport_id) {
+               kinfo->tc_info.max_tc = 1;
                kinfo->tc_info.num_tc = 1;
                vport->qs_offset = HNAE3_MAX_TC +
                                   vport->vport_id - HCLGE_VF_VPORT_START_NUM;
                vport_max_rss_size = hdev->vf_rss_size_max;
        } else {
+               kinfo->tc_info.max_tc = hdev->tc_max;
                kinfo->tc_info.num_tc =
                        min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc);
                vport->qs_offset = 0;
@@ -679,7 +681,9 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
        kinfo->num_tqps = hclge_vport_get_tqp_num(vport);
        vport->dwrr = 100;  /* 100 percent as init */
        vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit;
-       hdev->rss_cfg.rss_size = kinfo->rss_size;
+
+       if (vport->vport_id == PF_VPORT_ID)
+               hdev->rss_cfg.rss_size = kinfo->rss_size;
 
        /* when enable mqprio, the tc_info has been updated. */
        if (kinfo->tc_info.mqprio_active)
@@ -714,14 +718,22 @@ static void hclge_tm_vport_info_update(struct hclge_dev *hdev)
 
 static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
 {
-       u8 i;
+       u8 i, tc_sch_mode;
+       u32 bw_limit;
+
+       for (i = 0; i < hdev->tc_max; i++) {
+               if (i < hdev->tm_info.num_tc) {
+                       tc_sch_mode = HCLGE_SCH_MODE_DWRR;
+                       bw_limit = hdev->tm_info.pg_info[0].bw_limit;
+               } else {
+                       tc_sch_mode = HCLGE_SCH_MODE_SP;
+                       bw_limit = 0;
+               }
 
-       for (i = 0; i < hdev->tm_info.num_tc; i++) {
                hdev->tm_info.tc_info[i].tc_id = i;
-               hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR;
+               hdev->tm_info.tc_info[i].tc_sch_mode = tc_sch_mode;
                hdev->tm_info.tc_info[i].pgid = 0;
-               hdev->tm_info.tc_info[i].bw_limit =
-                       hdev->tm_info.pg_info[0].bw_limit;
+               hdev->tm_info.tc_info[i].bw_limit = bw_limit;
        }
 
        for (i = 0; i < HNAE3_MAX_USER_PRIO; i++)
@@ -926,10 +938,13 @@ static int hclge_tm_pri_q_qs_cfg_tc_base(struct hclge_dev *hdev)
        for (k = 0; k < hdev->num_alloc_vport; k++) {
                struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo;
 
-               for (i = 0; i < kinfo->tc_info.num_tc; i++) {
+               for (i = 0; i < kinfo->tc_info.max_tc; i++) {
+                       u8 pri = i < kinfo->tc_info.num_tc ? i : 0;
+                       bool link_vld = i < kinfo->tc_info.num_tc;
+
                        ret = hclge_tm_qs_to_pri_map_cfg(hdev,
                                                         vport[k].qs_offset + i,
-                                                        i);
+                                                        pri, link_vld);
                        if (ret)
                                return ret;
                }
@@ -949,7 +964,7 @@ static int hclge_tm_pri_q_qs_cfg_vnet_base(struct hclge_dev *hdev)
                for (i = 0; i < HNAE3_MAX_TC; i++) {
                        ret = hclge_tm_qs_to_pri_map_cfg(hdev,
                                                         vport[k].qs_offset + i,
-                                                        k);
+                                                        k, true);
                        if (ret)
                                return ret;
                }
@@ -989,33 +1004,39 @@ static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev)
 {
        u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
        struct hclge_shaper_ir_para ir_para;
-       u32 shaper_para;
+       u32 shaper_para_c, shaper_para_p;
        int ret;
        u32 i;
 
-       for (i = 0; i < hdev->tm_info.num_tc; i++) {
+       for (i = 0; i < hdev->tc_max; i++) {
                u32 rate = hdev->tm_info.tc_info[i].bw_limit;
 
-               ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI,
-                                            &ir_para, max_tm_rate);
-               if (ret)
-                       return ret;
+               if (rate) {
+                       ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI,
+                                                    &ir_para, max_tm_rate);
+                       if (ret)
+                               return ret;
+
+                       shaper_para_c = hclge_tm_get_shapping_para(0, 0, 0,
+                                                                  HCLGE_SHAPER_BS_U_DEF,
+                                                                  HCLGE_SHAPER_BS_S_DEF);
+                       shaper_para_p = hclge_tm_get_shapping_para(ir_para.ir_b,
+                                                                  ir_para.ir_u,
+                                                                  ir_para.ir_s,
+                                                                  HCLGE_SHAPER_BS_U_DEF,
+                                                                  HCLGE_SHAPER_BS_S_DEF);
+               } else {
+                       shaper_para_c = 0;
+                       shaper_para_p = 0;
+               }
 
-               shaper_para = hclge_tm_get_shapping_para(0, 0, 0,
-                                                        HCLGE_SHAPER_BS_U_DEF,
-                                                        HCLGE_SHAPER_BS_S_DEF);
                ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i,
-                                               shaper_para, rate);
+                                               shaper_para_c, rate);
                if (ret)
                        return ret;
 
-               shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b,
-                                                        ir_para.ir_u,
-                                                        ir_para.ir_s,
-                                                        HCLGE_SHAPER_BS_U_DEF,
-                                                        HCLGE_SHAPER_BS_S_DEF);
                ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i,
-                                               shaper_para, rate);
+                                               shaper_para_p, rate);
                if (ret)
                        return ret;
        }
@@ -1125,7 +1146,7 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
        int ret;
        u32 i, k;
 
-       for (i = 0; i < hdev->tm_info.num_tc; i++) {
+       for (i = 0; i < hdev->tc_max; i++) {
                pg_info =
                        &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
                dwrr = pg_info->tc_dwrr[i];
@@ -1135,9 +1156,15 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
                        return ret;
 
                for (k = 0; k < hdev->num_alloc_vport; k++) {
+                       struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo;
+
+                       if (i >= kinfo->tc_info.max_tc)
+                               continue;
+
+                       dwrr = i < kinfo->tc_info.num_tc ? vport[k].dwrr : 0;
                        ret = hclge_tm_qs_weight_cfg(
                                hdev, vport[k].qs_offset + i,
-                               vport[k].dwrr);
+                               dwrr);
                        if (ret)
                                return ret;
                }
@@ -1303,6 +1330,7 @@ static int hclge_tm_schd_mode_tc_base_cfg(struct hclge_dev *hdev, u8 pri_id)
 {
        struct hclge_vport *vport = hdev->vport;
        int ret;
+       u8 mode;
        u16 i;
 
        ret = hclge_tm_pri_schd_mode_cfg(hdev, pri_id);
@@ -1310,9 +1338,16 @@ static int hclge_tm_schd_mode_tc_base_cfg(struct hclge_dev *hdev, u8 pri_id)
                return ret;
 
        for (i = 0; i < hdev->num_alloc_vport; i++) {
+               struct hnae3_knic_private_info *kinfo = &vport[i].nic.kinfo;
+
+               if (pri_id >= kinfo->tc_info.max_tc)
+                       continue;
+
+               mode = pri_id < kinfo->tc_info.num_tc ? HCLGE_SCH_MODE_DWRR :
+                      HCLGE_SCH_MODE_SP;
                ret = hclge_tm_qs_schd_mode_cfg(hdev,
                                                vport[i].qs_offset + pri_id,
-                                               HCLGE_SCH_MODE_DWRR);
+                                               mode);
                if (ret)
                        return ret;
        }
@@ -1353,7 +1388,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev)
        u8 i;
 
        if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
-               for (i = 0; i < hdev->tm_info.num_tc; i++) {
+               for (i = 0; i < hdev->tc_max; i++) {
                        ret = hclge_tm_schd_mode_tc_base_cfg(hdev, i);
                        if (ret)
                                return ret;
index 619cc30a2dfcc2804312b6d110818c10599287bd..d943943912f76522ec340f99b32180a07a224c12 100644 (file)
@@ -237,6 +237,7 @@ int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
 void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
 void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
 int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate);
+int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev);
 int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num);
 int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num);
 int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority,
index 610f00cbaff9857cccb127741477293821270ee2..19704f5c8291c7ca1ec5f492d50542bdee8faa9b 100644 (file)
@@ -2586,15 +2586,16 @@ static void i40e_diag_test(struct net_device *netdev,
 
                set_bit(__I40E_TESTING, pf->state);
 
+               if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) ||
+                   test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) {
+                       dev_warn(&pf->pdev->dev,
+                                "Cannot start offline testing when PF is in reset state.\n");
+                       goto skip_ol_tests;
+               }
+
                if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) {
                        dev_warn(&pf->pdev->dev,
                                 "Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n");
-                       data[I40E_ETH_TEST_REG]         = 1;
-                       data[I40E_ETH_TEST_EEPROM]      = 1;
-                       data[I40E_ETH_TEST_INTR]        = 1;
-                       data[I40E_ETH_TEST_LINK]        = 1;
-                       eth_test->flags |= ETH_TEST_FL_FAILED;
-                       clear_bit(__I40E_TESTING, pf->state);
                        goto skip_ol_tests;
                }
 
@@ -2641,9 +2642,17 @@ static void i40e_diag_test(struct net_device *netdev,
                data[I40E_ETH_TEST_INTR] = 0;
        }
 
-skip_ol_tests:
-
        netif_info(pf, drv, netdev, "testing finished\n");
+       return;
+
+skip_ol_tests:
+       data[I40E_ETH_TEST_REG]         = 1;
+       data[I40E_ETH_TEST_EEPROM]      = 1;
+       data[I40E_ETH_TEST_INTR]        = 1;
+       data[I40E_ETH_TEST_LINK]        = 1;
+       eth_test->flags |= ETH_TEST_FL_FAILED;
+       clear_bit(__I40E_TESTING, pf->state);
+       netif_info(pf, drv, netdev, "testing failed\n");
 }
 
 static void i40e_get_wol(struct net_device *netdev,
index 332a608dbaa68c48a9c5a6dd5ceaa734bf30d411..72576bb3e94d45e93158415d8840654e3e86f45d 100644 (file)
@@ -8542,6 +8542,11 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi,
                return -EOPNOTSUPP;
        }
 
+       if (!tc) {
+               dev_err(&pf->pdev->dev, "Unable to add filter because of invalid destination");
+               return -EINVAL;
+       }
+
        if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) ||
            test_bit(__I40E_RESET_INTR_RECEIVED, pf->state))
                return -EBUSY;
index 2606e8f0f19be4764d48ec0cbe28850e3735d5d3..033ea71763e3de4437800fc83a5e9366107ef7da 100644 (file)
@@ -2282,7 +2282,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
        }
 
        if (vf->adq_enabled) {
-               for (i = 0; i < I40E_MAX_VF_VSI; i++)
+               for (i = 0; i < vf->num_tc; i++)
                        num_qps_all += vf->ch[i].num_qps;
                if (num_qps_all != qci->num_queue_pairs) {
                        aq_ret = I40E_ERR_PARAM;
index 7dfcf78b57fb54dbe67a69ecf1ac8be9acf8b339..f3ecb3bca33dde77895c7742861940c9675e9249 100644 (file)
@@ -984,7 +984,7 @@ struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
                list_add_tail(&f->list, &adapter->mac_filter_list);
                f->add = true;
                f->is_new_mac = true;
-               f->is_primary = false;
+               f->is_primary = ether_addr_equal(macaddr, adapter->hw.mac.addr);
                adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER;
        } else {
                f->remove = false;
index e1cae253412c781fb94a84304dd5f3f4b17434de..c1ac2f746714853b2f8dd64a4154206f3ab63e25 100644 (file)
@@ -5763,25 +5763,38 @@ static netdev_features_t
 ice_fix_features(struct net_device *netdev, netdev_features_t features)
 {
        struct ice_netdev_priv *np = netdev_priv(netdev);
-       netdev_features_t supported_vlan_filtering;
-       netdev_features_t requested_vlan_filtering;
-       struct ice_vsi *vsi = np->vsi;
-
-       requested_vlan_filtering = features & NETIF_VLAN_FILTERING_FEATURES;
-
-       /* make sure supported_vlan_filtering works for both SVM and DVM */
-       supported_vlan_filtering = NETIF_F_HW_VLAN_CTAG_FILTER;
-       if (ice_is_dvm_ena(&vsi->back->hw))
-               supported_vlan_filtering |= NETIF_F_HW_VLAN_STAG_FILTER;
-
-       if (requested_vlan_filtering &&
-           requested_vlan_filtering != supported_vlan_filtering) {
-               if (requested_vlan_filtering & NETIF_F_HW_VLAN_CTAG_FILTER) {
-                       netdev_warn(netdev, "cannot support requested VLAN filtering settings, enabling all supported VLAN filtering settings\n");
-                       features |= supported_vlan_filtering;
+       netdev_features_t req_vlan_fltr, cur_vlan_fltr;
+       bool cur_ctag, cur_stag, req_ctag, req_stag;
+
+       cur_vlan_fltr = netdev->features & NETIF_VLAN_FILTERING_FEATURES;
+       cur_ctag = cur_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER;
+       cur_stag = cur_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER;
+
+       req_vlan_fltr = features & NETIF_VLAN_FILTERING_FEATURES;
+       req_ctag = req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER;
+       req_stag = req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER;
+
+       if (req_vlan_fltr != cur_vlan_fltr) {
+               if (ice_is_dvm_ena(&np->vsi->back->hw)) {
+                       if (req_ctag && req_stag) {
+                               features |= NETIF_VLAN_FILTERING_FEATURES;
+                       } else if (!req_ctag && !req_stag) {
+                               features &= ~NETIF_VLAN_FILTERING_FEATURES;
+                       } else if ((!cur_ctag && req_ctag && !cur_stag) ||
+                                  (!cur_stag && req_stag && !cur_ctag)) {
+                               features |= NETIF_VLAN_FILTERING_FEATURES;
+                               netdev_warn(netdev,  "802.1Q and 802.1ad VLAN filtering must be either both on or both off. VLAN filtering has been enabled for both types.\n");
+                       } else if ((cur_ctag && !req_ctag && cur_stag) ||
+                                  (cur_stag && !req_stag && cur_ctag)) {
+                               features &= ~NETIF_VLAN_FILTERING_FEATURES;
+                               netdev_warn(netdev,  "802.1Q and 802.1ad VLAN filtering must be either both on or both off. VLAN filtering has been disabled for both types.\n");
+                       }
                } else {
-                       netdev_warn(netdev, "cannot support requested VLAN filtering settings, clearing all supported VLAN filtering settings\n");
-                       features &= ~supported_vlan_filtering;
+                       if (req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER)
+                               netdev_warn(netdev, "cannot support requested 802.1ad filtering setting in SVM mode\n");
+
+                       if (req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER)
+                               features |= NETIF_F_HW_VLAN_CTAG_FILTER;
                }
        }
 
index 662947c882e8b1c84439eec7310a55c4893395ea..ef9344ef0d8e46654aae8b46b3e1cf6fb58a9222 100644 (file)
@@ -2271,7 +2271,7 @@ static int
 ice_ptp_init_tx_e822(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
 {
        tx->quad = port / ICE_PORTS_PER_QUAD;
-       tx->quad_offset = tx->quad * INDEX_PER_PORT;
+       tx->quad_offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT;
        tx->len = INDEX_PER_PORT;
 
        return ice_ptp_alloc_tx_tracker(tx);
index afd048d699598170cc5850e21cb80e5206710ae5..10e396abf13094cc633b5baf8a05124b94a18534 100644 (file)
@@ -49,6 +49,37 @@ struct ice_perout_channel {
  * To allow multiple ports to access the shared register block independently,
  * the blocks are split up so that indexes are assigned to each port based on
  * hardware logical port number.
+ *
+ * The timestamp blocks are handled differently for E810- and E822-based
+ * devices. In E810 devices, each port has its own block of timestamps, while in
+ * E822 there is a need to logically break the block of registers into smaller
+ * chunks based on the port number to avoid collisions.
+ *
+ * Example for port 5 in E810:
+ *  +--------+--------+--------+--------+--------+--------+--------+--------+
+ *  |register|register|register|register|register|register|register|register|
+ *  | block  | block  | block  | block  | block  | block  | block  | block  |
+ *  |  for   |  for   |  for   |  for   |  for   |  for   |  for   |  for   |
+ *  | port 0 | port 1 | port 2 | port 3 | port 4 | port 5 | port 6 | port 7 |
+ *  +--------+--------+--------+--------+--------+--------+--------+--------+
+ *                                               ^^
+ *                                               ||
+ *                                               |---  quad offset is always 0
+ *                                               ---- quad number
+ *
+ * Example for port 5 in E822:
+ * +-----------------------------+-----------------------------+
+ * |  register block for quad 0  |  register block for quad 1  |
+ * |+------+------+------+------+|+------+------+------+------+|
+ * ||port 0|port 1|port 2|port 3|||port 0|port 1|port 2|port 3||
+ * |+------+------+------+------+|+------+------+------+------+|
+ * +-----------------------------+-------^---------------------+
+ *                                ^      |
+ *                                |      --- quad offset*
+ *                                ---- quad number
+ *
+ *   * PHY port 5 is port 1 in quad 1
+ *
  */
 
 /**
index cd8e6b50968c18d5308d405c88e81b12107c28b8..7adf9ddf129eb0ea1d48d3f6ac44091ba3117a0b 100644 (file)
@@ -504,6 +504,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
        }
 
        if (ice_is_vf_disabled(vf)) {
+               vsi = ice_get_vf_vsi(vf);
+               if (WARN_ON(!vsi))
+                       return -EINVAL;
+               ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
+               ice_vsi_stop_all_rx_rings(vsi);
                dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",
                        vf->vf_id);
                return 0;
index 1d9b84c3937aab3e69e3012eaf3fd7878d887d36..4547bc1f7cee7e8d70dac936e1296f0a5e603c89 100644 (file)
@@ -1569,35 +1569,27 @@ error_param:
  */
 static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
 {
-       enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
        struct virtchnl_vsi_queue_config_info *qci =
            (struct virtchnl_vsi_queue_config_info *)msg;
        struct virtchnl_queue_pair_info *qpi;
        struct ice_pf *pf = vf->pf;
        struct ice_vsi *vsi;
-       int i, q_idx;
+       int i = -1, q_idx;
 
-       if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
-               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+       if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
                goto error_param;
-       }
 
-       if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) {
-               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+       if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id))
                goto error_param;
-       }
 
        vsi = ice_get_vf_vsi(vf);
-       if (!vsi) {
-               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+       if (!vsi)
                goto error_param;
-       }
 
        if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF ||
            qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {
                dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n",
                        vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq));
-               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                goto error_param;
        }
 
@@ -1610,7 +1602,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
                    !ice_vc_isvalid_ring_len(qpi->txq.ring_len) ||
                    !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) ||
                    !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) {
-                       v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                        goto error_param;
                }
 
@@ -1620,7 +1611,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
                 * for selected "vsi"
                 */
                if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) {
-                       v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                        goto error_param;
                }
 
@@ -1630,14 +1620,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
                        vsi->tx_rings[i]->count = qpi->txq.ring_len;
 
                        /* Disable any existing queue first */
-                       if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) {
-                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                       if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx))
                                goto error_param;
-                       }
 
                        /* Configure a queue with the requested settings */
                        if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) {
-                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                               dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n",
+                                        vf->vf_id, i);
                                goto error_param;
                        }
                }
@@ -1651,17 +1640,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
 
                        if (qpi->rxq.databuffer_size != 0 &&
                            (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
-                            qpi->rxq.databuffer_size < 1024)) {
-                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                            qpi->rxq.databuffer_size < 1024))
                                goto error_param;
-                       }
                        vsi->rx_buf_len = qpi->rxq.databuffer_size;
                        vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len;
                        if (qpi->rxq.max_pkt_size > max_frame_size ||
-                           qpi->rxq.max_pkt_size < 64) {
-                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                           qpi->rxq.max_pkt_size < 64)
                                goto error_param;
-                       }
 
                        vsi->max_frame = qpi->rxq.max_pkt_size;
                        /* add space for the port VLAN since the VF driver is
@@ -1672,16 +1657,30 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
                                vsi->max_frame += VLAN_HLEN;
 
                        if (ice_vsi_cfg_single_rxq(vsi, q_idx)) {
-                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                               dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n",
+                                        vf->vf_id, i);
                                goto error_param;
                        }
                }
        }
 
+       /* send the response to the VF */
+       return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
+                                    VIRTCHNL_STATUS_SUCCESS, NULL, 0);
 error_param:
+       /* disable whatever we can */
+       for (; i >= 0; i--) {
+               if (ice_vsi_ctrl_one_rx_ring(vsi, false, i, true))
+                       dev_err(ice_pf_to_dev(pf), "VF-%d could not disable RX queue %d\n",
+                               vf->vf_id, i);
+               if (ice_vf_vsi_dis_single_txq(vf, vsi, i))
+                       dev_err(ice_pf_to_dev(pf), "VF-%d could not disable TX queue %d\n",
+                               vf->vf_id, i);
+       }
+
        /* send the response to the VF */
-       return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, v_ret,
-                                    NULL, 0);
+       return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
+                                    VIRTCHNL_STATUS_ERR_PARAM, NULL, 0);
 }
 
 /**
index 7f11c0a8e7a91de4d1893bdbc15c027f80d70c44..d4e63f0644c366598eb435872b1c3aed5ab1866d 100644 (file)
@@ -1184,9 +1184,9 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
 
        switch (xcast_mode) {
        case IXGBEVF_XCAST_MODE_NONE:
-               disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE |
+               disable = IXGBE_VMOLR_ROMPE |
                          IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
-               enable = 0;
+               enable = IXGBE_VMOLR_BAM;
                break;
        case IXGBEVF_XCAST_MODE_MULTI:
                disable = IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
@@ -1208,9 +1208,9 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
                        return -EPERM;
                }
 
-               disable = 0;
+               disable = IXGBE_VMOLR_VPE;
                enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE |
-                        IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
+                        IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE;
                break;
        default:
                return -EOPNOTSUPP;
index bc614a4def9ef6a2b334107f52762f08ac0e3793..3f60a80e34c822433beb4386cca26f2064bf0405 100644 (file)
@@ -1390,7 +1390,8 @@ static int otx2vf_get_link_ksettings(struct net_device *netdev,
 
 static const struct ethtool_ops otx2vf_ethtool_ops = {
        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
-                                    ETHTOOL_COALESCE_MAX_FRAMES,
+                                    ETHTOOL_COALESCE_MAX_FRAMES |
+                                    ETHTOOL_COALESCE_USE_ADAPTIVE,
        .supported_ring_params  = ETHTOOL_RING_USE_RX_BUF_LEN |
                                  ETHTOOL_RING_USE_CQE_SIZE,
        .get_link               = otx2_get_link,
index b3b3c079a0fafcffd4a3555daf9b1835069a7ea4..59c9a10f83ba5c758c41d1ec007091ca987dad45 100644 (file)
@@ -899,6 +899,17 @@ static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd,
        return true;
 }
 
+static void *mtk_max_lro_buf_alloc(gfp_t gfp_mask)
+{
+       unsigned int size = mtk_max_frag_size(MTK_MAX_LRO_RX_LENGTH);
+       unsigned long data;
+
+       data = __get_free_pages(gfp_mask | __GFP_COMP | __GFP_NOWARN,
+                               get_order(size));
+
+       return (void *)data;
+}
+
 /* the qdma core needs scratch memory to be setup */
 static int mtk_init_fq_dma(struct mtk_eth *eth)
 {
@@ -1467,7 +1478,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
                        goto release_desc;
 
                /* alloc new buffer */
-               new_data = napi_alloc_frag(ring->frag_size);
+               if (ring->frag_size <= PAGE_SIZE)
+                       new_data = napi_alloc_frag(ring->frag_size);
+               else
+                       new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC);
                if (unlikely(!new_data)) {
                        netdev->stats.rx_dropped++;
                        goto release_desc;
@@ -1914,7 +1928,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
                return -ENOMEM;
 
        for (i = 0; i < rx_dma_size; i++) {
-               ring->data[i] = netdev_alloc_frag(ring->frag_size);
+               if (ring->frag_size <= PAGE_SIZE)
+                       ring->data[i] = netdev_alloc_frag(ring->frag_size);
+               else
+                       ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL);
                if (!ring->data[i])
                        return -ENOMEM;
        }
index ed5038d98ef6e226d4c5fcc7f4c7958d8160c854..6400a827173cfa898173c9f258859c05de238e42 100644 (file)
@@ -2110,7 +2110,7 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
                        en_err(priv,
                               "mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n",
                               i, offset, ee->len - i, ret);
-                       return 0;
+                       return ret;
                }
 
                i += ret;
index 0eb9d74547f85f5a4256c54a4f985def6f2efc8d..50422b56a64de792e5d0504dfae54ad4ea67dc2f 100644 (file)
@@ -579,17 +579,6 @@ static void *pci_get_other_drvdata(struct device *this, struct device *other)
        return pci_get_drvdata(to_pci_dev(other));
 }
 
-static int next_phys_dev(struct device *dev, const void *data)
-{
-       struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data;
-
-       mdev = pci_get_other_drvdata(this->device, dev);
-       if (!mdev)
-               return 0;
-
-       return _next_phys_dev(mdev, data);
-}
-
 static int next_phys_dev_lag(struct device *dev, const void *data)
 {
        struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data;
@@ -623,13 +612,6 @@ static struct mlx5_core_dev *mlx5_get_next_dev(struct mlx5_core_dev *dev,
        return pci_get_drvdata(to_pci_dev(next));
 }
 
-/* Must be called with intf_mutex held */
-struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev)
-{
-       lockdep_assert_held(&mlx5_intf_mutex);
-       return mlx5_get_next_dev(dev, &next_phys_dev);
-}
-
 /* Must be called with intf_mutex held */
 struct mlx5_core_dev *mlx5_get_next_phys_dev_lag(struct mlx5_core_dev *dev)
 {
index eae9aa9c081185f0ddda36707ffa9bfa0c77b6fb..978a2bb8e12205f9f5e5db0593953b1cf422ae5d 100644 (file)
@@ -675,6 +675,9 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
        if (!tracer->owner)
                return;
 
+       if (unlikely(!tracer->str_db.loaded))
+               goto arm;
+
        block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE;
        start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE;
 
@@ -732,6 +735,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
                                                      &tmp_trace_block[TRACES_PER_BLOCK - 1]);
        }
 
+arm:
        mlx5_fw_tracer_arm(dev);
 }
 
@@ -1136,8 +1140,7 @@ static int fw_tracer_event(struct notifier_block *nb, unsigned long action, void
                queue_work(tracer->work_queue, &tracer->ownership_change_work);
                break;
        case MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE:
-               if (likely(tracer->str_db.loaded))
-                       queue_work(tracer->work_queue, &tracer->handle_traces_work);
+               queue_work(tracer->work_queue, &tracer->handle_traces_work);
                break;
        default:
                mlx5_core_dbg(dev, "FWTracer: Event with unrecognized subtype: sub_type %d\n",
index 68364484a435470f69338f551f5f144e3eb9d820..3c1edfa33aa79642e693c37b4eaeaa2ed4929210 100644 (file)
@@ -565,7 +565,8 @@ static void mlx5e_build_rx_cq_param(struct mlx5_core_dev *mdev,
 static u8 rq_end_pad_mode(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
 {
        bool lro_en = params->packet_merge.type == MLX5E_PACKET_MERGE_LRO;
-       bool ro = MLX5_CAP_GEN(mdev, relaxed_ordering_write);
+       bool ro = pcie_relaxed_ordering_enabled(mdev->pdev) &&
+               MLX5_CAP_GEN(mdev, relaxed_ordering_write);
 
        return ro && lro_en ?
                MLX5_WQ_END_PAD_MODE_NONE : MLX5_WQ_END_PAD_MODE_ALIGN;
index 43a536cb81db3e9539553870bb68316d154f7e6e..c0f409c195bf8dc20a9b7433469af8397f110b1a 100644 (file)
 
 void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc)
 {
+       bool ro_pci_enable = pcie_relaxed_ordering_enabled(mdev->pdev);
        bool ro_write = MLX5_CAP_GEN(mdev, relaxed_ordering_write);
        bool ro_read = MLX5_CAP_GEN(mdev, relaxed_ordering_read);
 
-       MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_read);
-       MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_write);
+       MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_pci_enable && ro_read);
+       MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_pci_enable && ro_write);
 }
 
 static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
index eb90e79388f19c6e324edd3373e9183df65ce7f4..f797fd97d305bc4d1269645232411a8cf371daa5 100644 (file)
@@ -950,6 +950,13 @@ err_event_reg:
        return err;
 }
 
+static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
+{
+       mlx5e_rep_tc_netdevice_event_unregister(rpriv);
+       mlx5e_rep_bond_cleanup(rpriv);
+       mlx5e_rep_tc_cleanup(rpriv);
+}
+
 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
 {
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
@@ -961,42 +968,36 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
                return err;
        }
 
-       err = mlx5e_tc_ht_init(&rpriv->tc_ht);
-       if (err)
-               goto err_ht_init;
-
        if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
                err = mlx5e_init_uplink_rep_tx(rpriv);
                if (err)
                        goto err_init_tx;
        }
 
+       err = mlx5e_tc_ht_init(&rpriv->tc_ht);
+       if (err)
+               goto err_ht_init;
+
        return 0;
 
-err_init_tx:
-       mlx5e_tc_ht_cleanup(&rpriv->tc_ht);
 err_ht_init:
+       if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
+               mlx5e_cleanup_uplink_rep_tx(rpriv);
+err_init_tx:
        mlx5e_destroy_tises(priv);
        return err;
 }
 
-static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
-{
-       mlx5e_rep_tc_netdevice_event_unregister(rpriv);
-       mlx5e_rep_bond_cleanup(rpriv);
-       mlx5e_rep_tc_cleanup(rpriv);
-}
-
 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
 {
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
 
-       mlx5e_destroy_tises(priv);
+       mlx5e_tc_ht_cleanup(&rpriv->tc_ht);
 
        if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
                mlx5e_cleanup_uplink_rep_tx(rpriv);
 
-       mlx5e_tc_ht_cleanup(&rpriv->tc_ht);
+       mlx5e_destroy_tises(priv);
 }
 
 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
index 217cac29057fcdb40b74d9a21c1357b3579d1052..2ce3728576d1a29aaf562f6456cb5d1890e0db34 100644 (file)
@@ -2690,9 +2690,6 @@ static int mlx5_esw_offloads_devcom_event(int event,
 
        switch (event) {
        case ESW_OFFLOADS_DEVCOM_PAIR:
-               if (mlx5_get_next_phys_dev(esw->dev) != peer_esw->dev)
-                       break;
-
                if (mlx5_eswitch_vport_match_metadata_enabled(esw) !=
                    mlx5_eswitch_vport_match_metadata_enabled(peer_esw))
                        break;
@@ -2744,6 +2741,9 @@ static void esw_offloads_devcom_init(struct mlx5_eswitch *esw)
        if (!MLX5_CAP_ESW(esw->dev, merged_eswitch))
                return;
 
+       if (!mlx5_is_lag_supported(esw->dev))
+               return;
+
        mlx5_devcom_register_component(devcom,
                                       MLX5_DEVCOM_ESW_OFFLOADS,
                                       mlx5_esw_offloads_devcom_event,
@@ -2761,6 +2761,9 @@ static void esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw)
        if (!MLX5_CAP_ESW(esw->dev, merged_eswitch))
                return;
 
+       if (!mlx5_is_lag_supported(esw->dev))
+               return;
+
        mlx5_devcom_send_event(devcom, MLX5_DEVCOM_ESW_OFFLOADS,
                               ESW_OFFLOADS_DEVCOM_UNPAIR, esw);
 
index fdcf7f529330a901b887ba462c1198cb94c89128..21e5c709b2d3036bda3ead5409e3652b53186db5 100644 (file)
@@ -1574,9 +1574,22 @@ static struct mlx5_flow_rule *find_flow_rule(struct fs_fte *fte,
        return NULL;
 }
 
-static bool check_conflicting_actions(u32 action1, u32 action2)
+static bool check_conflicting_actions_vlan(const struct mlx5_fs_vlan *vlan0,
+                                          const struct mlx5_fs_vlan *vlan1)
 {
-       u32 xored_actions = action1 ^ action2;
+       return vlan0->ethtype != vlan1->ethtype ||
+              vlan0->vid != vlan1->vid ||
+              vlan0->prio != vlan1->prio;
+}
+
+static bool check_conflicting_actions(const struct mlx5_flow_act *act1,
+                                     const struct mlx5_flow_act *act2)
+{
+       u32 action1 = act1->action;
+       u32 action2 = act2->action;
+       u32 xored_actions;
+
+       xored_actions = action1 ^ action2;
 
        /* if one rule only wants to count, it's ok */
        if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT ||
@@ -1593,6 +1606,22 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
                             MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2))
                return true;
 
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT &&
+           act1->pkt_reformat != act2->pkt_reformat)
+               return true;
+
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
+           act1->modify_hdr != act2->modify_hdr)
+               return true;
+
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
+           check_conflicting_actions_vlan(&act1->vlan[0], &act2->vlan[0]))
+               return true;
+
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2 &&
+           check_conflicting_actions_vlan(&act1->vlan[1], &act2->vlan[1]))
+               return true;
+
        return false;
 }
 
@@ -1600,7 +1629,7 @@ static int check_conflicting_ftes(struct fs_fte *fte,
                                  const struct mlx5_flow_context *flow_context,
                                  const struct mlx5_flow_act *flow_act)
 {
-       if (check_conflicting_actions(flow_act->action, fte->action.action)) {
+       if (check_conflicting_actions(flow_act, &fte->action)) {
                mlx5_core_warn(get_dev(&fte->node),
                               "Found two FTEs with conflicting actions\n");
                return -EEXIST;
index 552b6e26e701940fdd4e7f4edbfbce51260fa99a..2a8fc547eb37cb73f5a4e0bc6f78804f7bc6c9b3 100644 (file)
@@ -783,7 +783,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
 {
        struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
        struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev;
-       struct lag_tracker tracker;
+       struct lag_tracker tracker = { };
        bool do_bond, roce_lag;
        int err;
        int i;
index 72f70fad464157066708969297045a2e52638d2d..c81b173156d283b6a47b4d4587a9c4b46efe4f04 100644 (file)
@@ -74,6 +74,16 @@ struct mlx5_lag {
        struct lag_mpesw          lag_mpesw;
 };
 
+static inline bool mlx5_is_lag_supported(struct mlx5_core_dev *dev)
+{
+       if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
+           !MLX5_CAP_GEN(dev, lag_master) ||
+           MLX5_CAP_GEN(dev, num_lag_ports) < 2 ||
+           MLX5_CAP_GEN(dev, num_lag_ports) > MLX5_MAX_PORTS)
+               return false;
+       return true;
+}
+
 static inline struct mlx5_lag *
 mlx5_lag_dev(struct mlx5_core_dev *dev)
 {
index 484cb1e4fc7f649467f3bf83a04c8f7aa2b2648a..9cc7afea2758f62b4db512704c50b2188953d0b8 100644 (file)
@@ -209,7 +209,6 @@ int mlx5_attach_device(struct mlx5_core_dev *dev);
 void mlx5_detach_device(struct mlx5_core_dev *dev);
 int mlx5_register_device(struct mlx5_core_dev *dev);
 void mlx5_unregister_device(struct mlx5_core_dev *dev);
-struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev);
 struct mlx5_core_dev *mlx5_get_next_phys_dev_lag(struct mlx5_core_dev *dev);
 void mlx5_dev_list_lock(void);
 void mlx5_dev_list_unlock(void);
index a68d931090dd5824f3a865c24d6bf6748c0c0b95..15c8d4de83508a591ae6108a93758a648442c6fc 100644 (file)
@@ -8,8 +8,8 @@
 #include "spectrum.h"
 
 enum mlxsw_sp_counter_sub_pool_id {
-       MLXSW_SP_COUNTER_SUB_POOL_FLOW,
        MLXSW_SP_COUNTER_SUB_POOL_RIF,
+       MLXSW_SP_COUNTER_SUB_POOL_FLOW,
 };
 
 int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp,
index 443a5d6eb57be6be7a99c7730654df35e47f9d69..7c31a46195b26337aa34dd42fdda57770397037b 100644 (file)
@@ -507,6 +507,11 @@ nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map)
                key_size += sizeof(struct nfp_flower_ipv6);
        }
 
+       if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_QINQ) {
+               map[FLOW_PAY_QINQ] = key_size;
+               key_size += sizeof(struct nfp_flower_vlan);
+       }
+
        if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GRE) {
                map[FLOW_PAY_GRE] = key_size;
                if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6)
@@ -515,11 +520,6 @@ nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map)
                        key_size += sizeof(struct nfp_flower_ipv4_gre_tun);
        }
 
-       if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_QINQ) {
-               map[FLOW_PAY_QINQ] = key_size;
-               key_size += sizeof(struct nfp_flower_vlan);
-       }
-
        if ((in_key_ls.key_layer & NFP_FLOWER_LAYER_VXLAN) ||
            (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GENEVE)) {
                map[FLOW_PAY_UDP_TUN] = key_size;
@@ -758,6 +758,17 @@ static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry)
                }
        }
 
+       if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) {
+               offset = key_map[FLOW_PAY_QINQ];
+               key = kdata + offset;
+               msk = mdata + offset;
+               for (i = 0; i < _CT_TYPE_MAX; i++) {
+                       nfp_flower_compile_vlan((struct nfp_flower_vlan *)key,
+                                               (struct nfp_flower_vlan *)msk,
+                                               rules[i]);
+               }
+       }
+
        if (key_layer.key_layer_two & NFP_FLOWER_LAYER2_GRE) {
                offset = key_map[FLOW_PAY_GRE];
                key = kdata + offset;
@@ -798,17 +809,6 @@ static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry)
                }
        }
 
-       if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) {
-               offset = key_map[FLOW_PAY_QINQ];
-               key = kdata + offset;
-               msk = mdata + offset;
-               for (i = 0; i < _CT_TYPE_MAX; i++) {
-                       nfp_flower_compile_vlan((struct nfp_flower_vlan *)key,
-                                               (struct nfp_flower_vlan *)msk,
-                                               rules[i]);
-               }
-       }
-
        if (key_layer.key_layer & NFP_FLOWER_LAYER_VXLAN ||
            key_layer.key_layer_two & NFP_FLOWER_LAYER2_GENEVE) {
                offset = key_map[FLOW_PAY_UDP_TUN];
index 193a167a6762e81f42878f6858ca3769f2e120c8..e01430139b6d87298f7e5f784444794896ef529c 100644 (file)
@@ -625,6 +625,14 @@ int nfp_flower_compile_flow_match(struct nfp_app *app,
                msk += sizeof(struct nfp_flower_ipv6);
        }
 
+       if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) {
+               nfp_flower_compile_vlan((struct nfp_flower_vlan *)ext,
+                                       (struct nfp_flower_vlan *)msk,
+                                       rule);
+               ext += sizeof(struct nfp_flower_vlan);
+               msk += sizeof(struct nfp_flower_vlan);
+       }
+
        if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GRE) {
                if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) {
                        struct nfp_flower_ipv6_gre_tun *gre_match;
@@ -660,14 +668,6 @@ int nfp_flower_compile_flow_match(struct nfp_app *app,
                }
        }
 
-       if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) {
-               nfp_flower_compile_vlan((struct nfp_flower_vlan *)ext,
-                                       (struct nfp_flower_vlan *)msk,
-                                       rule);
-               ext += sizeof(struct nfp_flower_vlan);
-               msk += sizeof(struct nfp_flower_vlan);
-       }
-
        if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN ||
            key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE) {
                if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) {
index 54af309613510aa8a59696d8ff1b69bfcc322d2e..6eeeb0fda91fac4d494f1b60794f1591360f41bd 100644 (file)
@@ -15,7 +15,7 @@
 #include "nfp_net_sriov.h"
 
 static int
-nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg)
+nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg, bool warn)
 {
        u16 cap_vf;
 
@@ -24,12 +24,14 @@ nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg)
 
        cap_vf = readw(app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_CAP);
        if ((cap_vf & cap) != cap) {
-               nfp_warn(app->pf->cpp, "ndo_set_vf_%s not supported\n", msg);
+               if (warn)
+                       nfp_warn(app->pf->cpp, "ndo_set_vf_%s not supported\n", msg);
                return -EOPNOTSUPP;
        }
 
        if (vf < 0 || vf >= app->pf->num_vfs) {
-               nfp_warn(app->pf->cpp, "invalid VF id %d\n", vf);
+               if (warn)
+                       nfp_warn(app->pf->cpp, "invalid VF id %d\n", vf);
                return -EINVAL;
        }
 
@@ -65,7 +67,7 @@ int nfp_app_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
        unsigned int vf_offset;
        int err;
 
-       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_MAC, "mac");
+       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_MAC, "mac", true);
        if (err)
                return err;
 
@@ -101,7 +103,7 @@ int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
        u32 vlan_tag;
        int err;
 
-       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan");
+       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan", true);
        if (err)
                return err;
 
@@ -115,7 +117,7 @@ int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
        }
 
        /* Check if fw supports or not */
-       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto");
+       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto", true);
        if (err)
                is_proto_sup = false;
 
@@ -149,7 +151,7 @@ int nfp_app_set_vf_rate(struct net_device *netdev, int vf,
        u32 vf_offset, ratevalue;
        int err;
 
-       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate");
+       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate", true);
        if (err)
                return err;
 
@@ -181,7 +183,7 @@ int nfp_app_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable)
        int err;
 
        err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_SPOOF,
-                                 "spoofchk");
+                                 "spoofchk", true);
        if (err)
                return err;
 
@@ -205,7 +207,7 @@ int nfp_app_set_vf_trust(struct net_device *netdev, int vf, bool enable)
        int err;
 
        err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_TRUST,
-                                 "trust");
+                                 "trust", true);
        if (err)
                return err;
 
@@ -230,7 +232,7 @@ int nfp_app_set_vf_link_state(struct net_device *netdev, int vf,
        int err;
 
        err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_LINK_STATE,
-                                 "link_state");
+                                 "link_state", true);
        if (err)
                return err;
 
@@ -265,7 +267,7 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf,
        u8 flags;
        int err;
 
-       err = nfp_net_sriov_check(app, vf, 0, "");
+       err = nfp_net_sriov_check(app, vf, 0, "", true);
        if (err)
                return err;
 
@@ -285,13 +287,13 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf,
 
        ivi->vlan = FIELD_GET(NFP_NET_VF_CFG_VLAN_VID, vlan_tag);
        ivi->qos = FIELD_GET(NFP_NET_VF_CFG_VLAN_QOS, vlan_tag);
-       if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto"))
+       if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto", false))
                ivi->vlan_proto = htons(FIELD_GET(NFP_NET_VF_CFG_VLAN_PROT, vlan_tag));
        ivi->spoofchk = FIELD_GET(NFP_NET_VF_CFG_CTRL_SPOOF, flags);
        ivi->trusted = FIELD_GET(NFP_NET_VF_CFG_CTRL_TRUST, flags);
        ivi->linkstate = FIELD_GET(NFP_NET_VF_CFG_CTRL_LINK_STATE, flags);
 
-       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate");
+       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate", false);
        if (!err) {
                rate = readl(app->pf->vfcfg_tbl2 + vf_offset +
                             NFP_NET_VF_CFG_RATE);
index f9f80933e0c9c2531e6c79ccc16dce72be14a9c4..38fe77d1035e306c6d3fd13c3fb547d8bfd2cbec 100644 (file)
@@ -1072,13 +1072,11 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
 
        ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
        if (ret) {
-               goto err_dvr_probe;
+               goto err_alloc_irq;
        }
 
        return 0;
 
-err_dvr_probe:
-       pci_free_irq_vectors(pdev);
 err_alloc_irq:
        clk_disable_unprepare(plat->stmmac_clk);
        clk_unregister_fixed_rate(plat->stmmac_clk);
index 4225efbeda3dac9d44a436cbfcaebfedd6c4be88..f2e2261b4b7d90078a1a4b3707971c2000aff72e 100644 (file)
@@ -547,6 +547,57 @@ static inline void axienet_iow(struct axienet_local *lp, off_t offset,
        iowrite32(value, lp->regs + offset);
 }
 
+/**
+ * axienet_dma_out32 - Memory mapped Axi DMA register write.
+ * @lp:                Pointer to axienet local structure
+ * @reg:       Address offset from the base address of the Axi DMA core
+ * @value:     Value to be written into the Axi DMA register
+ *
+ * This function writes the desired value into the corresponding Axi DMA
+ * register.
+ */
+
+static inline void axienet_dma_out32(struct axienet_local *lp,
+                                    off_t reg, u32 value)
+{
+       iowrite32(value, lp->dma_regs + reg);
+}
+
+#if defined(CONFIG_64BIT) && defined(iowrite64)
+/**
+ * axienet_dma_out64 - Memory mapped Axi DMA register write.
+ * @lp:                Pointer to axienet local structure
+ * @reg:       Address offset from the base address of the Axi DMA core
+ * @value:     Value to be written into the Axi DMA register
+ *
+ * This function writes the desired value into the corresponding Axi DMA
+ * register.
+ */
+static inline void axienet_dma_out64(struct axienet_local *lp,
+                                    off_t reg, u64 value)
+{
+       iowrite64(value, lp->dma_regs + reg);
+}
+
+static inline void axienet_dma_out_addr(struct axienet_local *lp, off_t reg,
+                                       dma_addr_t addr)
+{
+       if (lp->features & XAE_FEATURE_DMA_64BIT)
+               axienet_dma_out64(lp, reg, addr);
+       else
+               axienet_dma_out32(lp, reg, lower_32_bits(addr));
+}
+
+#else /* CONFIG_64BIT */
+
+static inline void axienet_dma_out_addr(struct axienet_local *lp, off_t reg,
+                                dma_addr_t addr)
+{
+       axienet_dma_out32(lp, reg, lower_32_bits(addr));
+}
+
+#endif /* CONFIG_64BIT */
+
 /* Function prototypes visible in xilinx_axienet_mdio.c for other files */
 int axienet_mdio_enable(struct axienet_local *lp);
 void axienet_mdio_disable(struct axienet_local *lp);
index 93c9f305bba42fcc7cab953c1068f11a920c13dd..1760930ec0c49ddaf95bcb72fbc0046ba46badcf 100644 (file)
@@ -133,30 +133,6 @@ static inline u32 axienet_dma_in32(struct axienet_local *lp, off_t reg)
        return ioread32(lp->dma_regs + reg);
 }
 
-/**
- * axienet_dma_out32 - Memory mapped Axi DMA register write.
- * @lp:                Pointer to axienet local structure
- * @reg:       Address offset from the base address of the Axi DMA core
- * @value:     Value to be written into the Axi DMA register
- *
- * This function writes the desired value into the corresponding Axi DMA
- * register.
- */
-static inline void axienet_dma_out32(struct axienet_local *lp,
-                                    off_t reg, u32 value)
-{
-       iowrite32(value, lp->dma_regs + reg);
-}
-
-static void axienet_dma_out_addr(struct axienet_local *lp, off_t reg,
-                                dma_addr_t addr)
-{
-       axienet_dma_out32(lp, reg, lower_32_bits(addr));
-
-       if (lp->features & XAE_FEATURE_DMA_64BIT)
-               axienet_dma_out32(lp, reg + 4, upper_32_bits(addr));
-}
-
 static void desc_set_phys_addr(struct axienet_local *lp, dma_addr_t addr,
                               struct axidma_bd *desc)
 {
@@ -2061,6 +2037,11 @@ static int axienet_probe(struct platform_device *pdev)
                        iowrite32(0x0, desc);
                }
        }
+       if (!IS_ENABLED(CONFIG_64BIT) && lp->features & XAE_FEATURE_DMA_64BIT) {
+               dev_err(&pdev->dev, "64-bit addressable DMA is not compatible with 32-bit archecture\n");
+               ret = -EINVAL;
+               goto cleanup_clk;
+       }
 
        ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width));
        if (ret) {
index 8561f2d4443bfc00670630e74e8c28f44442843a..13dafe7a29bde5871218e6f85a6c9b9d56681e7a 100644 (file)
 #define DP83867_DOWNSHIFT_2_COUNT      2
 #define DP83867_DOWNSHIFT_4_COUNT      4
 #define DP83867_DOWNSHIFT_8_COUNT      8
+#define DP83867_SGMII_AUTONEG_EN       BIT(7)
 
 /* CFG3 bits */
 #define DP83867_CFG3_INT_OE                    BIT(7)
@@ -855,6 +856,32 @@ static int dp83867_phy_reset(struct phy_device *phydev)
                         DP83867_PHYCR_FORCE_LINK_GOOD, 0);
 }
 
+static void dp83867_link_change_notify(struct phy_device *phydev)
+{
+       /* There is a limitation in DP83867 PHY device where SGMII AN is
+        * only triggered once after the device is booted up. Even after the
+        * PHY TPI is down and up again, SGMII AN is not triggered and
+        * hence no new in-band message from PHY to MAC side SGMII.
+        * This could cause an issue during power up, when PHY is up prior
+        * to MAC. At this condition, once MAC side SGMII is up, MAC side
+        * SGMII wouldn`t receive new in-band message from TI PHY with
+        * correct link status, speed and duplex info.
+        * Thus, implemented a SW solution here to retrigger SGMII Auto-Neg
+        * whenever there is a link change.
+        */
+       if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+               int val = 0;
+
+               val = phy_clear_bits(phydev, DP83867_CFG2,
+                                    DP83867_SGMII_AUTONEG_EN);
+               if (val < 0)
+                       return;
+
+               phy_set_bits(phydev, DP83867_CFG2,
+                            DP83867_SGMII_AUTONEG_EN);
+       }
+}
+
 static struct phy_driver dp83867_driver[] = {
        {
                .phy_id         = DP83867_PHY_ID,
@@ -879,6 +906,8 @@ static struct phy_driver dp83867_driver[] = {
 
                .suspend        = genphy_suspend,
                .resume         = genphy_resume,
+
+               .link_change_notify = dp83867_link_change_notify,
        },
 };
 module_phy_driver(dp83867_driver);
index 58d602985877bd9637f99bee8d422db569ee533a..8a2dbe849866d1eb643719e04350745aea358837 100644 (file)
@@ -1046,7 +1046,6 @@ int __init mdio_bus_init(void)
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(mdio_bus_init);
 
 #if IS_ENABLED(CONFIG_PHYLIB)
 void mdio_bus_exit(void)
index 7a8c11a26eb5f5481db06c990f7268a69ac62b8f..4704ed6f00efe98307c9f51f064cb024c42795ca 100644 (file)
@@ -1750,7 +1750,7 @@ static const struct driver_info ax88179_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1763,7 +1763,7 @@ static const struct driver_info ax88178a_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1776,7 +1776,7 @@ static const struct driver_info cypress_GX3_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1789,7 +1789,7 @@ static const struct driver_info dlink_dub1312_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1802,7 +1802,7 @@ static const struct driver_info sitecom_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1815,7 +1815,7 @@ static const struct driver_info samsung_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1828,7 +1828,7 @@ static const struct driver_info lenovo_info = {
        .link_reset = ax88179_link_reset,
        .reset = ax88179_reset,
        .stop = ax88179_stop,
-       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1841,7 +1841,7 @@ static const struct driver_info belkin_info = {
        .link_reset = ax88179_link_reset,
        .reset  = ax88179_reset,
        .stop   = ax88179_stop,
-       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1854,7 +1854,7 @@ static const struct driver_info toshiba_info = {
        .link_reset = ax88179_link_reset,
        .reset  = ax88179_reset,
        .stop = ax88179_stop,
-       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1867,7 +1867,7 @@ static const struct driver_info mct_info = {
        .link_reset = ax88179_link_reset,
        .reset  = ax88179_reset,
        .stop   = ax88179_stop,
-       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1880,7 +1880,7 @@ static const struct driver_info at_umc2000_info = {
        .link_reset = ax88179_link_reset,
        .reset  = ax88179_reset,
        .stop   = ax88179_stop,
-       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1893,7 +1893,7 @@ static const struct driver_info at_umc200_info = {
        .link_reset = ax88179_link_reset,
        .reset  = ax88179_reset,
        .stop   = ax88179_stop,
-       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
@@ -1906,7 +1906,7 @@ static const struct driver_info at_umc2000sp_info = {
        .link_reset = ax88179_link_reset,
        .reset  = ax88179_reset,
        .stop   = ax88179_stop,
-       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
        .rx_fixup = ax88179_rx_fixup,
        .tx_fixup = ax88179_tx_fixup,
 };
index a99aedff795dc6745a5a4692a9a69715133d52d0..ea7309453096890304c2d5aba42c9a590a9c88f0 100644 (file)
@@ -388,13 +388,25 @@ static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)
        int err;
 
        while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
+               usb_anchor_urb(urb, &drv_data->tx_anchor);
+
                err = usb_submit_urb(urb, GFP_ATOMIC);
-               if (err)
+               if (err) {
+                       kfree(urb->setup_packet);
+                       usb_unanchor_urb(urb);
+                       usb_free_urb(urb);
                        break;
+               }
 
                drv_data->tx_in_flight++;
+               usb_free_urb(urb);
+       }
+
+       /* Cleanup the rest deferred urbs. */
+       while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
+               kfree(urb->setup_packet);
+               usb_free_urb(urb);
        }
-       usb_scuttle_anchored_urbs(&drv_data->deferred);
 }
 
 static int nfcmrvl_resume(struct usb_interface *intf)
index 7e213f8ddc98b11ebc98b87c85fd7a7ceed89f64..df8d27cf2956bcb7a55bb4adcea516cf86d1a87b 100644 (file)
@@ -300,6 +300,8 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
        int r = 0;
        struct device *dev = &hdev->ndev->dev;
        struct nfc_evt_transaction *transaction;
+       u32 aid_len;
+       u8 params_len;
 
        pr_debug("connectivity gate event: %x\n", event);
 
@@ -308,43 +310,48 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
                r = nfc_se_connectivity(hdev->ndev, host);
        break;
        case ST21NFCA_EVT_TRANSACTION:
-               /*
-                * According to specification etsi 102 622
+               /* According to specification etsi 102 622
                 * 11.2.2.4 EVT_TRANSACTION Table 52
                 * Description  Tag     Length
                 * AID          81      5 to 16
                 * PARAMETERS   82      0 to 255
+                *
+                * The key differences are aid storage length is variably sized
+                * in the packet, but fixed in nfc_evt_transaction, and that the aid_len
+                * is u8 in the packet, but u32 in the structure, and the tags in
+                * the packet are not included in nfc_evt_transaction.
+                *
+                * size in bytes: 1          1       5-16 1             1           0-255
+                * offset:        0          1       2    aid_len + 2   aid_len + 3 aid_len + 4
+                * member name:   aid_tag(M) aid_len aid  params_tag(M) params_len  params
+                * example:       0x81       5-16    X    0x82 0-255    X
                 */
-               if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
-                   skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+               if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
                        return -EPROTO;
 
-               transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
-               if (!transaction)
-                       return -ENOMEM;
-
-               transaction->aid_len = skb->data[1];
+               aid_len = skb->data[1];
 
-               /* Checking if the length of the AID is valid */
-               if (transaction->aid_len > sizeof(transaction->aid))
-                       return -EINVAL;
+               if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid))
+                       return -EPROTO;
 
-               memcpy(transaction->aid, &skb->data[2],
-                      transaction->aid_len);
+               params_len = skb->data[aid_len + 3];
 
-               /* Check next byte is PARAMETERS tag (82) */
-               if (skb->data[transaction->aid_len + 2] !=
-                   NFC_EVT_TRANSACTION_PARAMS_TAG)
+               /* Verify PARAMETERS tag is (82), and final check that there is enough
+                * space in the packet to read everything.
+                */
+               if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) ||
+                   (skb->len < aid_len + 4 + params_len))
                        return -EPROTO;
 
-               transaction->params_len = skb->data[transaction->aid_len + 3];
+               transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL);
+               if (!transaction)
+                       return -ENOMEM;
 
-               /* Total size is allocated (skb->len - 2) minus fixed array members */
-               if (transaction->params_len > ((skb->len - 2) - sizeof(struct nfc_evt_transaction)))
-                       return -EINVAL;
+               transaction->aid_len = aid_len;
+               transaction->params_len = params_len;
 
-               memcpy(transaction->params, skb->data +
-                      transaction->aid_len + 4, transaction->params_len);
+               memcpy(transaction->aid, &skb->data[2], aid_len);
+               memcpy(transaction->params, &skb->data[aid_len + 4], params_len);
 
                r = nfc_se_transaction(hdev->ndev, host, transaction);
        break;
index 24165daee3c8f0819b83d90f6c4293560c04a2c6..3ab2cfd254a448d729498d303787136ded54c56e 100644 (file)
@@ -3285,8 +3285,8 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
         * we have no UUID set
         */
        if (uuid_is_null(&ids->uuid)) {
-               printk_ratelimited(KERN_WARNING
-                                  "No UUID available providing old NGUID\n");
+               dev_warn_ratelimited(dev,
+                       "No UUID available providing old NGUID\n");
                return sysfs_emit(buf, "%pU\n", ids->nguid);
        }
        return sysfs_emit(buf, "%pU\n", &ids->uuid);
@@ -3863,6 +3863,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
        if (ret) {
                dev_err(ctrl->device,
                        "globally duplicate IDs for nsid %d\n", nsid);
+               nvme_print_device_info(ctrl);
                return ret;
        }
 
index 9b72b6ecf33c9cfc66a5d45c36225b15781773b7..0da94b233feda837070277ee5a46318328cad1df 100644 (file)
@@ -503,6 +503,7 @@ struct nvme_ctrl_ops {
        void (*submit_async_event)(struct nvme_ctrl *ctrl);
        void (*delete_ctrl)(struct nvme_ctrl *ctrl);
        int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
+       void (*print_device_info)(struct nvme_ctrl *ctrl);
 };
 
 /*
@@ -548,6 +549,33 @@ static inline struct request *nvme_cid_to_rq(struct blk_mq_tags *tags,
        return blk_mq_tag_to_rq(tags, nvme_tag_from_cid(command_id));
 }
 
+/*
+ * Return the length of the string without the space padding
+ */
+static inline int nvme_strlen(char *s, int len)
+{
+       while (s[len - 1] == ' ')
+               len--;
+       return len;
+}
+
+static inline void nvme_print_device_info(struct nvme_ctrl *ctrl)
+{
+       struct nvme_subsystem *subsys = ctrl->subsys;
+
+       if (ctrl->ops->print_device_info) {
+               ctrl->ops->print_device_info(ctrl);
+               return;
+       }
+
+       dev_err(ctrl->device,
+               "VID:%04x model:%.*s firmware:%.*s\n", subsys->vendor_id,
+               nvme_strlen(subsys->model, sizeof(subsys->model)),
+               subsys->model, nvme_strlen(subsys->firmware_rev,
+                                          sizeof(subsys->firmware_rev)),
+               subsys->firmware_rev);
+}
+
 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
 void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj,
                            const char *dev_name);
index 48f4f6eb877bcca6f678cbe634e3fd9cd7881003..c7012e85d035d6114792e0066c2a449de3ae42d6 100644 (file)
@@ -1334,6 +1334,14 @@ static void nvme_warn_reset(struct nvme_dev *dev, u32 csts)
                dev_warn(dev->ctrl.device,
                         "controller is down; will reset: CSTS=0x%x, PCI_STATUS read failed (%d)\n",
                         csts, result);
+
+       if (csts != ~0)
+               return;
+
+       dev_warn(dev->ctrl.device,
+                "Does your device have a faulty power saving mode enabled?\n");
+       dev_warn(dev->ctrl.device,
+                "Try \"nvme_core.default_ps_max_latency_us=0 pcie_aspm=off\" and report a bug\n");
 }
 
 static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
@@ -2976,6 +2984,21 @@ static int nvme_pci_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
        return snprintf(buf, size, "%s\n", dev_name(&pdev->dev));
 }
 
+
+static void nvme_pci_print_device_info(struct nvme_ctrl *ctrl)
+{
+       struct pci_dev *pdev = to_pci_dev(to_nvme_dev(ctrl)->dev);
+       struct nvme_subsystem *subsys = ctrl->subsys;
+
+       dev_err(ctrl->device,
+               "VID:DID %04x:%04x model:%.*s firmware:%.*s\n",
+               pdev->vendor, pdev->device,
+               nvme_strlen(subsys->model, sizeof(subsys->model)),
+               subsys->model, nvme_strlen(subsys->firmware_rev,
+                                          sizeof(subsys->firmware_rev)),
+               subsys->firmware_rev);
+}
+
 static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
        .name                   = "pcie",
        .module                 = THIS_MODULE,
@@ -2987,6 +3010,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
        .free_ctrl              = nvme_pci_free_ctrl,
        .submit_async_event     = nvme_pci_submit_async_event,
        .get_address            = nvme_pci_get_address,
+       .print_device_info      = nvme_pci_print_device_info,
 };
 
 static int nvme_dev_map(struct nvme_dev *dev)
@@ -3421,7 +3445,8 @@ static const struct pci_device_id nvme_id_table[] = {
        { PCI_VDEVICE(REDHAT, 0x0010),  /* Qemu emulated controller */
                .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x126f, 0x2263),   /* Silicon Motion unidentified */
-               .driver_data = NVME_QUIRK_NO_NS_DESC_LIST, },
+               .driver_data = NVME_QUIRK_NO_NS_DESC_LIST |
+                               NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1bb1, 0x0100),   /* Seagate Nytro Flash Storage */
                .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY |
                                NVME_QUIRK_NO_NS_DESC_LIST, },
@@ -3437,6 +3462,8 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY |
                                NVME_QUIRK_DISABLE_WRITE_ZEROES|
                                NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+       { PCI_DEVICE(0x1987, 0x5012),   /* Phison E12 */
+               .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1987, 0x5016),   /* Phison E16 */
                .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, },
        { PCI_DEVICE(0x1b4b, 0x1092),   /* Lexar 256 GB SSD */
@@ -3449,10 +3476,20 @@ static const struct pci_device_id nvme_id_table[] = {
                                NVME_QUIRK_IGNORE_DEV_SUBNQN, },
        { PCI_DEVICE(0x1c5c, 0x1504),   /* SK Hynix PC400 */
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x1c5c, 0x174a),   /* SK Hynix P31 SSD */
+               .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x15b7, 0x2001),   /*  Sandisk Skyhawk */
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
        { PCI_DEVICE(0x1d97, 0x2263),   /* SPCC */
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x144d, 0xa80b),   /* Samsung PM9B1 256G and 512G */
+               .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x144d, 0xa809),   /* Samsung MZALQ256HBJD 256G */
+               .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x1cc4, 0x6303),   /* UMIS RPJTJ512MGE1QDY 512G */
+               .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x1cc4, 0x6302),   /* UMIS RPJTJ256MGE1QDY 256G */
+               .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
        { PCI_DEVICE(0x2646, 0x2262),   /* KINGSTON SKC2000 NVMe SSD */
                .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
        { PCI_DEVICE(0x2646, 0x2263),   /* KINGSTON A2000 NVMe SSD  */
@@ -3463,6 +3500,10 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1e4B, 0x1202),   /* MAXIO MAP1202 */
                .driver_data = NVME_QUIRK_BOGUS_NID, },
+       { PCI_DEVICE(0x1cc1, 0x5350),   /* ADATA XPG GAMMIX S50 */
+               .driver_data = NVME_QUIRK_BOGUS_NID, },
+       { PCI_DEVICE(0x1e49, 0x0041),   /* ZHITAI TiPro7000 NVMe SSD */
+               .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
        { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0061),
                .driver_data = NVME_QUIRK_DMA_ADDRESS_BITS_48, },
        { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0065),
index 72df4b8f4dd8b5a09e4943e49d7c4167a104b36c..09c7829e95c4b037947f573ff2045cf6cebbdd81 100644 (file)
@@ -85,7 +85,7 @@ config NVSW_SN2201
        depends on I2C
        depends on REGMAP_I2C
        help
-         This driver provides support for the Nvidia SN2201 platfom.
+         This driver provides support for the Nvidia SN2201 platform.
          The SN2201 is a highly integrated for one rack unit system with
          L3 management switches. It has 48 x 1Gbps RJ45 + 4 x 100G QSFP28
          ports in a compact 1RU form factor. The system also including a
index 0bcdc7c75007d046c5a8cb2676fdd3466d3f7e11..2923daf63b75d663ebaad745309c555ad824d8cb 100644 (file)
@@ -326,7 +326,7 @@ static struct resource nvsw_sn2201_lpc_res[] = {
 };
 
 /* SN2201 I2C platform data. */
-struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = {
+static struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = {
        .irq = NVSW_SN2201_CPLD_SYSIRQ,
 };
 
index d421e148239579182230c03ac1447588e47b8fd9..6b51ad01f79151dc2b15e8f287283e93b361f9da 100644 (file)
@@ -17,7 +17,7 @@ menuconfig MIPS_PLATFORM_DEVICES
 if MIPS_PLATFORM_DEVICES
 
 config CPU_HWMON
-       tristate "Loongson-3 CPU HWMon Driver"
+       bool "Loongson-3 CPU HWMon Driver"
        depends on MACH_LOONGSON64
        select HWMON
        default y
index 05534287bc26b65db179ab0e29f83508ae5e4b87..8dd67233948584f02bc0c62610179fd710d4c89d 100644 (file)
@@ -405,11 +405,14 @@ MODULE_DEVICE_TABLE(dmi, dmi_ids);
 static int __init p50_module_init(void)
 {
        struct resource res = DEFINE_RES_IO(P50_GPIO_IO_PORT_BASE, P50_PORT_CMD + 1);
+       int ret;
 
        if (!dmi_first_match(dmi_ids))
                return -ENODEV;
 
-       platform_driver_register(&p50_gpio_driver);
+       ret = platform_driver_register(&p50_gpio_driver);
+       if (ret)
+               return ret;
 
        gpio_pdev = platform_device_register_simple(DRIVER_NAME, PLATFORM_DEVID_NONE, &res, 1);
        if (IS_ERR(gpio_pdev)) {
index 1ef606e3ef80d2ab9b31a7086f4459f3d1f7c6c1..497ad2f64a51c0400e9062c0acf1f08464b546a4 100644 (file)
@@ -140,6 +140,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
        }}
 
 static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H-CF"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE AX V2"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"),
@@ -156,6 +157,7 @@ static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 I AORUS PRO WIFI"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 UD"),
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z690M AORUS ELITE AX DDR4"),
        { }
 };
 
index 667f94bba905b26a337b9b857fdb1f3e265fd069..0d8cb22e30df9081797d1d84d5e25243a3d7ac38 100644 (file)
@@ -38,6 +38,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
 #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
+#define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required
 
 /* DMI board names of devices that should use the omen specific path for
  * thermal profiles.
@@ -220,6 +221,7 @@ static struct input_dev *hp_wmi_input_dev;
 static struct platform_device *hp_wmi_platform_dev;
 static struct platform_profile_handler platform_profile_handler;
 static bool platform_profile_support;
+static bool zero_insize_support;
 
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
@@ -290,14 +292,16 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
        struct bios_return *bios_return;
        union acpi_object *obj = NULL;
        struct bios_args *args = NULL;
-       int mid, actual_outsize, ret;
+       int mid, actual_insize, actual_outsize;
        size_t bios_args_size;
+       int ret;
 
        mid = encode_outsize_for_pvsz(outsize);
        if (WARN_ON(mid < 0))
                return mid;
 
-       bios_args_size = struct_size(args, data, insize);
+       actual_insize = max(insize, 128);
+       bios_args_size = struct_size(args, data, actual_insize);
        args = kmalloc(bios_args_size, GFP_KERNEL);
        if (!args)
                return -ENOMEM;
@@ -374,7 +378,7 @@ static int hp_wmi_read_int(int query)
        int val = 0, ret;
 
        ret = hp_wmi_perform_query(query, HPWMI_READ, &val,
-                                  0, sizeof(val));
+                                  zero_if_sup(val), sizeof(val));
 
        if (ret)
                return ret < 0 ? ret : -EINVAL;
@@ -410,7 +414,8 @@ static int hp_wmi_get_tablet_mode(void)
                return -ENODEV;
 
        ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ,
-                                  system_device_mode, 0, sizeof(system_device_mode));
+                                  system_device_mode, zero_if_sup(system_device_mode),
+                                  sizeof(system_device_mode));
        if (ret < 0)
                return ret;
 
@@ -497,7 +502,7 @@ static int hp_wmi_fan_speed_max_get(void)
        int val = 0, ret;
 
        ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM,
-                                  &val, 0, sizeof(val));
+                                  &val, zero_if_sup(val), sizeof(val));
 
        if (ret)
                return ret < 0 ? ret : -EINVAL;
@@ -509,7 +514,7 @@ static int __init hp_wmi_bios_2008_later(void)
 {
        int state = 0;
        int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
-                                      0, sizeof(state));
+                                      zero_if_sup(state), sizeof(state));
        if (!ret)
                return 1;
 
@@ -520,7 +525,7 @@ static int __init hp_wmi_bios_2009_later(void)
 {
        u8 state[128];
        int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
-                                      0, sizeof(state));
+                                      zero_if_sup(state), sizeof(state));
        if (!ret)
                return 1;
 
@@ -598,7 +603,7 @@ static int hp_wmi_rfkill2_refresh(void)
        int err, i;
 
        err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
-                                  0, sizeof(state));
+                                  zero_if_sup(state), sizeof(state));
        if (err)
                return err;
 
@@ -1007,7 +1012,7 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
        int err, i;
 
        err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
-                                  0, sizeof(state));
+                                  zero_if_sup(state), sizeof(state));
        if (err)
                return err < 0 ? err : -EINVAL;
 
@@ -1483,11 +1488,15 @@ static int __init hp_wmi_init(void)
 {
        int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
        int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
-       int err;
+       int err, tmp = 0;
 
        if (!bios_capable && !event_capable)
                return -ENODEV;
 
+       if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp,
+                                sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS)
+               zero_insize_support = true;
+
        if (event_capable) {
                err = hp_wmi_input_setup();
                if (err)
index 216d31e3403dde4fb8ed842e4be09df6c1a8c8cc..79cff1fc675c2006ffedd35dfcf08b5cac5d1cdc 100644 (file)
@@ -122,6 +122,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible 15-df0xxx"),
                },
        },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"),
+               },
+       },
        { }
 };
 
index edaf22e5ae98cf80d64cef1f33858f824fbde7c3..40183bda7894ae7890e5042aaa97ae0c2aa8e0d4 100644 (file)
@@ -1912,6 +1912,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
        X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE,          &tgl_reg_map),
        X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,         &tgl_reg_map),
        X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,           &adl_reg_map),
+       X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P,        &tgl_reg_map),
        {}
 };
 
index 34daf9df168b11c3b0aeee100ba5a749cbd56a35..ace1239bc0a0bfd5e091d91f500c4f46c82503ce 100644 (file)
@@ -282,7 +282,7 @@ static int pmt_crashlog_probe(struct auxiliary_device *auxdev,
        auxiliary_set_drvdata(auxdev, priv);
 
        for (i = 0; i < intel_vsec_dev->num_resources; i++) {
-               struct intel_pmt_entry *entry = &priv->entry[i].entry;
+               struct intel_pmt_entry *entry = &priv->entry[priv->num_entries].entry;
 
                ret = intel_pmt_dev_create(entry, &pmt_crashlog_ns, intel_vsec_dev, i);
                if (ret < 0)
index 256ec6d08c168d8916e54bc28f9c7eb2d8ab6fad..9d01a3e3c26aa6cc149414e0536f0f1ce2e7676b 100644 (file)
@@ -9795,7 +9795,7 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
                                        GFP_KERNEL);
 
                if (!ioa_cfg->hrrq[i].host_rrq)  {
-                       while (--i > 0)
+                       while (--i >= 0)
                                dma_free_coherent(&pdev->dev,
                                        sizeof(u32) * ioa_cfg->hrrq[i].size,
                                        ioa_cfg->hrrq[i].host_rrq,
@@ -10068,7 +10068,7 @@ static int ipr_request_other_msi_irqs(struct ipr_ioa_cfg *ioa_cfg,
                        ioa_cfg->vectors_info[i].desc,
                        &ioa_cfg->hrrq[i]);
                if (rc) {
-                       while (--i >= 0)
+                       while (--i > 0)
                                free_irq(pci_irq_vector(pdev, i),
                                        &ioa_cfg->hrrq[i]);
                        return rc;
index b1be0dd0337a52bf5e4517ca76812743a10705fa..f5d74958b6643f08cdaa7f3998852bf9b50c6fcd 100644 (file)
@@ -420,8 +420,6 @@ int lpfc_sli_issue_iocb_wait(struct lpfc_hba *, uint32_t,
                             uint32_t);
 void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *, struct lpfc_iocbq *,
                             struct lpfc_iocbq *);
-void lpfc_sli4_abort_fcp_cmpl(struct lpfc_hba *h, struct lpfc_iocbq *i,
-                             struct lpfc_wcqe_complete *w);
 
 void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
 
@@ -630,7 +628,7 @@ void lpfc_nvmet_invalidate_host(struct lpfc_hba *phba,
                        struct lpfc_nodelist *ndlp);
 void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
                                struct lpfc_iocbq *cmdiocb,
-                               struct lpfc_wcqe_complete *abts_cmpl);
+                               struct lpfc_iocbq *rspiocb);
 void lpfc_create_multixri_pools(struct lpfc_hba *phba);
 void lpfc_create_destroy_pools(struct lpfc_hba *phba);
 void lpfc_move_xri_pvt_to_pbl(struct lpfc_hba *phba, u32 hwqid);
index 9d36b20fb8787f3d06779332f0a813b1a176aab5..13dfe285493d18153ee0cece721cc51fcc6656fb 100644 (file)
@@ -197,7 +197,7 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
        memset(bpl, 0, sizeof(struct ulp_bde64));
        bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys));
        bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys));
-       bpl->tus.f.bdeFlags = BUFF_TYPE_BLP_64;
+       bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
        bpl->tus.f.bdeSize = (LPFC_CT_PREAMBLE - 4);
        bpl->tus.w = le32_to_cpu(bpl->tus.w);
 
index 07f9a6e61e10b90f7b5ed08ee4f034be59ced1f2..3fababb7c18184a4761d40eff1923a38acad80d3 100644 (file)
@@ -2998,10 +2998,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                 ndlp->nlp_DID, ulp_status,
                                 ulp_word4);
 
-               /* Call NLP_EVT_DEVICE_RM if link is down or LOGO is aborted */
                if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
-                       lpfc_disc_state_machine(vport, ndlp, cmdiocb,
-                                               NLP_EVT_DEVICE_RM);
                        skip_recovery = 1;
                        goto out;
                }
@@ -3021,18 +3018,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                spin_unlock_irq(&ndlp->lock);
                lpfc_disc_state_machine(vport, ndlp, cmdiocb,
                                        NLP_EVT_DEVICE_RM);
-               lpfc_els_free_iocb(phba, cmdiocb);
-               lpfc_nlp_put(ndlp);
-
-               /* Presume the node was released. */
-               return;
+               goto out_rsrc_free;
        }
 
 out:
-       /* Driver is done with the IO.  */
-       lpfc_els_free_iocb(phba, cmdiocb);
-       lpfc_nlp_put(ndlp);
-
        /* At this point, the LOGO processing is complete. NOTE: For a
         * pt2pt topology, we are assuming the NPortID will only change
         * on link up processing. For a LOGO / PLOGI initiated by the
@@ -3059,6 +3048,10 @@ out:
                                 ndlp->nlp_DID, ulp_status,
                                 ulp_word4, tmo,
                                 vport->num_disc_nodes);
+
+               lpfc_els_free_iocb(phba, cmdiocb);
+               lpfc_nlp_put(ndlp);
+
                lpfc_disc_start(vport);
                return;
        }
@@ -3075,6 +3068,10 @@ out:
                lpfc_disc_state_machine(vport, ndlp, cmdiocb,
                                        NLP_EVT_DEVICE_RM);
        }
+out_rsrc_free:
+       /* Driver is done with the I/O. */
+       lpfc_els_free_iocb(phba, cmdiocb);
+       lpfc_nlp_put(ndlp);
 }
 
 /**
index 8511369d2cf8ef083b8791b164780769c4e4abd0..f024415731ac71187e3ba101398c643508facfd7 100644 (file)
@@ -4487,6 +4487,9 @@ struct wqe_common {
 #define wqe_sup_SHIFT         6
 #define wqe_sup_MASK          0x00000001
 #define wqe_sup_WORD          word11
+#define wqe_ffrq_SHIFT         6
+#define wqe_ffrq_MASK          0x00000001
+#define wqe_ffrq_WORD          word11
 #define wqe_wqec_SHIFT        7
 #define wqe_wqec_MASK         0x00000001
 #define wqe_wqec_WORD         word11
index 93b94c64518dffd79caac777b14d0b66f46d2e74..750dd1e9f2cc76681cd62e2dcdaaeddca74467fb 100644 (file)
@@ -12188,7 +12188,7 @@ lpfc_sli_enable_msi(struct lpfc_hba *phba)
        rc = pci_enable_msi(phba->pcidev);
        if (!rc)
                lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "0462 PCI enable MSI mode success.\n");
+                               "0012 PCI enable MSI mode success.\n");
        else {
                lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
                                "0471 PCI enable MSI mode failed (%d)\n", rc);
index 639f866351271e690735c715497ea706a26687c8..b86ff9fcdf0c6a909197cf1e2d6824ccdb28007b 100644 (file)
@@ -834,7 +834,8 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                lpfc_nvmet_invalidate_host(phba, ndlp);
 
        if (ndlp->nlp_DID == Fabric_DID) {
-               if (vport->port_state <= LPFC_FDISC)
+               if (vport->port_state <= LPFC_FDISC ||
+                   vport->fc_flag & FC_PT2PT)
                        goto out;
                lpfc_linkdown_port(vport);
                spin_lock_irq(shost->host_lock);
index 335e906339331580042c787f12786903d83be344..cd10ee6482fc0b8d188174738b9512629c8f7583 100644 (file)
@@ -1065,25 +1065,37 @@ lpfc_nvme_io_cmd_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
                        nCmd->rcv_rsplen = wcqe->parameter;
                        nCmd->status = 0;
 
+                       /* Get the NVME cmd details for this unique error. */
+                       cp = (struct nvme_fc_cmd_iu *)nCmd->cmdaddr;
+                       ep = (struct nvme_fc_ersp_iu *)nCmd->rspaddr;
+
                        /* Check if this is really an ERSP */
                        if (nCmd->rcv_rsplen == LPFC_NVME_ERSP_LEN) {
                                lpfc_ncmd->status = IOSTAT_SUCCESS;
                                lpfc_ncmd->result = 0;
 
                                lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME,
-                                        "6084 NVME Completion ERSP: "
-                                        "xri %x placed x%x\n",
-                                        lpfc_ncmd->cur_iocbq.sli4_xritag,
-                                        wcqe->total_data_placed);
+                                       "6084 NVME FCP_ERR ERSP: "
+                                       "xri %x placed x%x opcode x%x cmd_id "
+                                       "x%x cqe_status x%x\n",
+                                       lpfc_ncmd->cur_iocbq.sli4_xritag,
+                                       wcqe->total_data_placed,
+                                       cp->sqe.common.opcode,
+                                       cp->sqe.common.command_id,
+                                       ep->cqe.status);
                                break;
                        }
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
                                         "6081 NVME Completion Protocol Error: "
                                         "xri %x status x%x result x%x "
-                                        "placed x%x\n",
+                                        "placed x%x opcode x%x cmd_id x%x, "
+                                        "cqe_status x%x\n",
                                         lpfc_ncmd->cur_iocbq.sli4_xritag,
                                         lpfc_ncmd->status, lpfc_ncmd->result,
-                                        wcqe->total_data_placed);
+                                        wcqe->total_data_placed,
+                                        cp->sqe.common.opcode,
+                                        cp->sqe.common.command_id,
+                                        ep->cqe.status);
                        break;
                case IOSTAT_LOCAL_REJECT:
                        /* Let fall through to set command final state. */
@@ -1195,7 +1207,8 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
 {
        struct lpfc_hba *phba = vport->phba;
        struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd;
-       struct lpfc_iocbq *pwqeq = &(lpfc_ncmd->cur_iocbq);
+       struct nvme_common_command *sqe;
+       struct lpfc_iocbq *pwqeq = &lpfc_ncmd->cur_iocbq;
        union lpfc_wqe128 *wqe = &pwqeq->wqe;
        uint32_t req_len;
 
@@ -1252,8 +1265,14 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
                cstat->control_requests++;
        }
 
-       if (pnode->nlp_nvme_info & NLP_NVME_NSLER)
+       if (pnode->nlp_nvme_info & NLP_NVME_NSLER) {
                bf_set(wqe_erp, &wqe->generic.wqe_com, 1);
+               sqe = &((struct nvme_fc_cmd_iu *)
+                       nCmd->cmdaddr)->sqe.common;
+               if (sqe->opcode == nvme_admin_async_event)
+                       bf_set(wqe_ffrq, &wqe->generic.wqe_com, 1);
+       }
+
        /*
         * Finish initializing those WQE fields that are independent
         * of the nvme_cmnd request_buffer
@@ -1787,7 +1806,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
  * lpfc_nvme_abort_fcreq_cmpl - Complete an NVME FCP abort request.
  * @phba: Pointer to HBA context object
  * @cmdiocb: Pointer to command iocb object.
- * @abts_cmpl: Pointer to wcqe complete object.
+ * @rspiocb: Pointer to response iocb object.
  *
  * This is the callback function for any NVME FCP IO that was aborted.
  *
@@ -1796,8 +1815,10 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
  **/
 void
 lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-                          struct lpfc_wcqe_complete *abts_cmpl)
+                          struct lpfc_iocbq *rspiocb)
 {
+       struct lpfc_wcqe_complete *abts_cmpl = &rspiocb->wcqe_cmpl;
+
        lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
                        "6145 ABORT_XRI_CN completing on rpi x%x "
                        "original iotag x%x, abort cmd iotag x%x "
@@ -1840,6 +1861,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
        struct lpfc_nvme_fcpreq_priv *freqpriv;
        unsigned long flags;
        int ret_val;
+       struct nvme_fc_cmd_iu *cp;
 
        /* Validate pointers. LLDD fault handling with transport does
         * have timing races.
@@ -1963,10 +1985,16 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
                return;
        }
 
+       /*
+        * Get Command Id from cmd to plug into response. This
+        * code is not needed in the next NVME Transport drop.
+        */
+       cp = (struct nvme_fc_cmd_iu *)lpfc_nbuf->nvmeCmd->cmdaddr;
        lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS,
                         "6138 Transport Abort NVME Request Issued for "
-                        "ox_id x%x\n",
-                        nvmereq_wqe->sli4_xritag);
+                        "ox_id x%x nvme opcode x%x nvme cmd_id x%x\n",
+                        nvmereq_wqe->sli4_xritag, cp->sqe.common.opcode,
+                        cp->sqe.common.command_id);
        return;
 
 out_unlock:
index d439682032489f630675390674bb1224dc7ede28..ba5e4016262e2f1c99a3d80df04064e1a068c97b 100644 (file)
@@ -6062,6 +6062,9 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
        int status;
        u32 logit = LOG_FCP;
 
+       if (!rport)
+               return FAILED;
+
        rdata = rport->dd_data;
        if (!rdata || !rdata->pnode) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
@@ -6140,6 +6143,9 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
        unsigned long flags;
        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
 
+       if (!rport)
+               return FAILED;
+
        rdata = rport->dd_data;
        if (!rdata || !rdata->pnode) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
index 6ed696c4602aa9c883ca64198e1389f54fafef3c..80ac3a051c19234ce88369b057724b159e97afe5 100644 (file)
@@ -1930,7 +1930,7 @@ lpfc_issue_cmf_sync_wqe(struct lpfc_hba *phba, u32 ms, u64 total)
        sync_buf = __lpfc_sli_get_iocbq(phba);
        if (!sync_buf) {
                lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT,
-                               "6213 No available WQEs for CMF_SYNC_WQE\n");
+                               "6244 No available WQEs for CMF_SYNC_WQE\n");
                ret_val = ENOMEM;
                goto out_unlock;
        }
@@ -3805,7 +3805,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                                set_job_ulpword4(cmdiocbp,
                                                                 IOERR_ABORT_REQUESTED);
                                                /*
-                                                * For SLI4, irsiocb contains
+                                                * For SLI4, irspiocb contains
                                                 * NO_XRI in sli_xritag, it
                                                 * shall not affect releasing
                                                 * sgl (xri) process.
@@ -3823,7 +3823,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                        }
                                }
                        }
-                       (cmdiocbp->cmd_cmpl) (phba, cmdiocbp, saveq);
+                       cmdiocbp->cmd_cmpl(phba, cmdiocbp, saveq);
                } else
                        lpfc_sli_release_iocbq(phba, cmdiocbp);
        } else {
@@ -4063,8 +4063,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
                                cmdiocbq->cmd_flag &= ~LPFC_DRIVER_ABORTED;
                        if (cmdiocbq->cmd_cmpl) {
                                spin_unlock_irqrestore(&phba->hbalock, iflag);
-                               (cmdiocbq->cmd_cmpl)(phba, cmdiocbq,
-                                                     &rspiocbq);
+                               cmdiocbq->cmd_cmpl(phba, cmdiocbq, &rspiocbq);
                                spin_lock_irqsave(&phba->hbalock, iflag);
                        }
                        break;
@@ -10288,7 +10287,7 @@ __lpfc_sli_issue_iocb_s3(struct lpfc_hba *phba, uint32_t ring_number,
  * @flag: Flag indicating if this command can be put into txq.
  *
  * __lpfc_sli_issue_fcp_io_s3 is wrapper function to invoke lockless func to
- * send  an iocb command to an HBA with SLI-4 interface spec.
+ * send  an iocb command to an HBA with SLI-3 interface spec.
  *
  * This function takes the hbalock before invoking the lockless version.
  * The function will return success after it successfully submit the wqe to
@@ -12740,7 +12739,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
                cmdiocbq->cmd_cmpl = cmdiocbq->wait_cmd_cmpl;
                cmdiocbq->wait_cmd_cmpl = NULL;
                if (cmdiocbq->cmd_cmpl)
-                       (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, NULL);
+                       cmdiocbq->cmd_cmpl(phba, cmdiocbq, NULL);
                else
                        lpfc_sli_release_iocbq(phba, cmdiocbq);
                return;
@@ -12754,9 +12753,9 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
 
        /* Set the exchange busy flag for task management commands */
        if ((cmdiocbq->cmd_flag & LPFC_IO_FCP) &&
-               !(cmdiocbq->cmd_flag & LPFC_IO_LIBDFC)) {
+           !(cmdiocbq->cmd_flag & LPFC_IO_LIBDFC)) {
                lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf,
-                       cur_iocbq);
+                                       cur_iocbq);
                if (rspiocbq && (rspiocbq->cmd_flag & LPFC_EXCHANGE_BUSY))
                        lpfc_cmd->flags |= LPFC_SBUF_XBUSY;
                else
@@ -13896,7 +13895,7 @@ void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba)
  * @irspiocbq: Pointer to work-queue completion queue entry.
  *
  * This routine handles an ELS work-queue completion event and construct
- * a pseudo response ELS IODBQ from the SLI4 ELS WCQE for the common
+ * a pseudo response ELS IOCBQ from the SLI4 ELS WCQE for the common
  * discovery engine to handle.
  *
  * Return: Pointer to the receive IOCBQ, NULL otherwise.
@@ -13940,7 +13939,7 @@ lpfc_sli4_els_preprocess_rspiocbq(struct lpfc_hba *phba,
 
        if (bf_get(lpfc_wcqe_c_xb, wcqe)) {
                spin_lock_irqsave(&phba->hbalock, iflags);
-               cmdiocbq->cmd_flag |= LPFC_EXCHANGE_BUSY;
+               irspiocbq->cmd_flag |= LPFC_EXCHANGE_BUSY;
                spin_unlock_irqrestore(&phba->hbalock, iflags);
        }
 
@@ -14799,7 +14798,7 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
                /* Pass the cmd_iocb and the wcqe to the upper layer */
                memcpy(&cmdiocbq->wcqe_cmpl, wcqe,
                       sizeof(struct lpfc_wcqe_complete));
-               (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, cmdiocbq);
+               cmdiocbq->cmd_cmpl(phba, cmdiocbq, cmdiocbq);
        } else {
                lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
                                "0375 FCP cmdiocb not callback function "
@@ -18956,7 +18955,7 @@ lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport,
 
        /* Free iocb created in lpfc_prep_seq */
        list_for_each_entry_safe(curr_iocb, next_iocb,
-               &iocbq->list, list) {
+                                &iocbq->list, list) {
                list_del_init(&curr_iocb->list);
                lpfc_sli_release_iocbq(phba, curr_iocb);
        }
index 4fab79ed58ed041ca0843a69ca30b9fd1a473b24..2ab6f7db64d8604c2e960e6009ad614aa55a289d 100644 (file)
@@ -20,7 +20,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "14.2.0.3"
+#define LPFC_DRIVER_VERSION "14.2.0.4"
 #define LPFC_DRIVER_NAME               "lpfc"
 
 /* Used for SLI 2/3 */
index 37d46ae5c61d36a65c209508f29c28f29e492627..9a1ae52bb621db87842b156a2a7449decabf6e1b 100644 (file)
@@ -5369,6 +5369,7 @@ static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc)
        Mpi2ConfigReply_t mpi_reply;
        Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
        Mpi26PCIeIOUnitPage1_t pcie_iounit_pg1;
+       u16 depth;
        int sz;
        int rc = 0;
 
@@ -5380,7 +5381,7 @@ static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc)
                goto out;
        /* sas iounit page 1 */
        sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData);
-       sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
+       sas_iounit_pg1 = kzalloc(sizeof(Mpi2SasIOUnitPage1_t), GFP_KERNEL);
        if (!sas_iounit_pg1) {
                pr_err("%s: failure at %s:%d/%s()!\n",
                    ioc->name, __FILE__, __LINE__, __func__);
@@ -5393,16 +5394,16 @@ static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc)
                    ioc->name, __FILE__, __LINE__, __func__);
                goto out;
        }
-       ioc->max_wideport_qd =
-           (le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth)) ?
-           le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth) :
-           MPT3SAS_SAS_QUEUE_DEPTH;
-       ioc->max_narrowport_qd =
-           (le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth)) ?
-           le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth) :
-           MPT3SAS_SAS_QUEUE_DEPTH;
-       ioc->max_sata_qd = (sas_iounit_pg1->SATAMaxQDepth) ?
-           sas_iounit_pg1->SATAMaxQDepth : MPT3SAS_SATA_QUEUE_DEPTH;
+
+       depth = le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth);
+       ioc->max_wideport_qd = (depth ? depth : MPT3SAS_SAS_QUEUE_DEPTH);
+
+       depth = le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth);
+       ioc->max_narrowport_qd = (depth ? depth : MPT3SAS_SAS_QUEUE_DEPTH);
+
+       depth = sas_iounit_pg1->SATAMaxQDepth;
+       ioc->max_sata_qd = (depth ? depth : MPT3SAS_SATA_QUEUE_DEPTH);
+
        /* pcie iounit page 1 */
        rc = mpt3sas_config_get_pcie_iounit_pg1(ioc, &mpi_reply,
            &pcie_iounit_pg1, sizeof(Mpi26PCIeIOUnitPage1_t));
index bfce60183a6e5173ac556334e3befbf6721892b3..836ddc476764ee155d0396f9c3a474f5d07e5368 100644 (file)
@@ -4031,7 +4031,7 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
        return 0;
 
 out_unwind:
-       while (--i > 0)
+       while (--i >= 0)
                free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]);
        pci_free_irq_vectors(pdev);
        return rc;
index 895b56c8f25e3c137afffc41b8a3eb60fe58ac5c..a1a2ac09066fdb8a57114c61d1207090de9754fd 100644 (file)
@@ -3072,7 +3072,7 @@ static void sd_read_cpr(struct scsi_disk *sdkp)
                goto out;
 
        /* We must have at least a 64B header and one 32B range descriptor */
-       vpd_len = get_unaligned_be16(&buffer[2]) + 3;
+       vpd_len = get_unaligned_be16(&buffer[2]) + 4;
        if (vpd_len > buf_len || vpd_len < 64 + 32 || (vpd_len & 31)) {
                sd_printk(KERN_ERR, sdkp,
                          "Invalid Concurrent Positioning Ranges VPD page\n");
index 51a82f7803d3c7ede3643dc2ea04fee0cc387989..9d16cf925483744813ab5804f573a1d464673f4a 100644 (file)
@@ -331,8 +331,8 @@ struct PVSCSIRingReqDesc {
        u8      tag;
        u8      bus;
        u8      target;
-       u     vcpuHint;
-       u8      unused[59];
+       u16     vcpuHint;
+       u8      unused[58];
 } __packed;
 
 /*
index d1a0dea09ef013aaa973121694b3fe92e8c9aaaa..d0ba34cc32f7a8f9861cd97e2dbc27358a9767ec 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 config FB_OLPC_DCON
        tristate "One Laptop Per Child Display CONtroller support"
-       depends on OLPC && FB
+       depends on OLPC && FB && BROKEN
        depends on I2C
        depends on GPIO_CS5535 && ACPI
        select BACKLIGHT_CLASS_DEVICE
index 3d8e9dea76514fd9f7e77176a341ce1ab6e3ee57..7135d89caac11649e882c0e20da8893bae1beb54 100644 (file)
@@ -178,8 +178,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
 
        pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
 
-       res = rtw_alloc_hwxmits(padapter);
-       if (res) {
+       if (rtw_alloc_hwxmits(padapter)) {
                res = _FAIL;
                goto exit;
        }
@@ -1483,19 +1482,10 @@ int rtw_alloc_hwxmits(struct adapter *padapter)
 
        hwxmits = pxmitpriv->hwxmits;
 
-       if (pxmitpriv->hwxmit_entry == 5) {
-               hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
-               hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
-               hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
-               hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
-               hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
-       } else if (pxmitpriv->hwxmit_entry == 4) {
-               hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
-               hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
-               hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
-               hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
-       } else {
-       }
+       hwxmits[0].sta_queue = &pxmitpriv->vo_pending;
+       hwxmits[1].sta_queue = &pxmitpriv->vi_pending;
+       hwxmits[2].sta_queue = &pxmitpriv->be_pending;
+       hwxmits[3].sta_queue = &pxmitpriv->bk_pending;
 
        return 0;
 }
index 1b09462ca908d88089c0a2abd81e16c3b77c941c..8dd280e2739a240a0f23ac01c4bac367b59874e8 100644 (file)
@@ -403,7 +403,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
 
                if (wep_key_len > 0) {
                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
-                       wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
+                       wep_total_len = wep_key_len + sizeof(*pwep);
                        pwep = kzalloc(wep_total_len, GFP_KERNEL);
                        if (!pwep)
                                goto exit;
index ece97e37ac91d0ea522e56c8100438c1eab041b3..30374a820496e6a137f934f5d53d5e9ad8b41988 100644 (file)
@@ -90,7 +90,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
                if (wep_key_len > 0) {
                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
                        wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
-                       pwep = kzalloc(wep_total_len, GFP_KERNEL);
+                       /* Allocate a full structure to avoid potentially running off the end. */
+                       pwep = kzalloc(sizeof(*pwep), GFP_KERNEL);
                        if (!pwep) {
                                ret = -ENOMEM;
                                goto exit;
@@ -582,7 +583,8 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
                if (wep_key_len > 0) {
                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
                        wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
-                       pwep = kzalloc(wep_total_len, GFP_KERNEL);
+                       /* Allocate a full structure to avoid potentially running off the end. */
+                       pwep = kzalloc(sizeof(*pwep), GFP_KERNEL);
                        if (!pwep)
                                goto exit;
 
index c7968aecd8702ef34c208d8bdbe528fd039a6d03..d02de3f0326fbbc2fa588cdc890e3f5a2b4cf4e6 100644 (file)
@@ -426,7 +426,7 @@ static int goldfish_tty_remove(struct platform_device *pdev)
        tty_unregister_device(goldfish_tty_driver, qtty->console.index);
        iounmap(qtty->base);
        qtty->base = NULL;
-       free_irq(qtty->irq, pdev);
+       free_irq(qtty->irq, qtty);
        tty_port_destroy(&qtty->port);
        goldfish_tty_current_line_count--;
        if (goldfish_tty_current_line_count == 0)
index 137eebdcfda91dc6bf10822f4074478d8aae222f..fd4d24f61c46bae1ed3eff6b7d82c1deb2e7764b 100644 (file)
@@ -455,7 +455,7 @@ static void gsm_hex_dump_bytes(const char *fname, const u8 *data,
                return;
        }
 
-       prefix = kasprintf(GFP_KERNEL, "%s: ", fname);
+       prefix = kasprintf(GFP_ATOMIC, "%s: ", fname);
        if (!prefix)
                return;
        print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, data, len,
index 78b6dedc43e6b89ce71c0b79a320ce8f8efd5840..8f32fe9e149e913081d49758f168feb79c87323f 100644 (file)
@@ -1517,6 +1517,8 @@ static inline void __stop_tx(struct uart_8250_port *p)
                unsigned char lsr = serial_in(p, UART_LSR);
                u64 stop_delay = 0;
 
+               p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+
                if (!(lsr & UART_LSR_THRE))
                        return;
                /*
index 4733a233bd0c50ab02b6815574583efd92989e1c..f8f950641ad9f049462fcae1f474b3814323e353 100644 (file)
@@ -1306,6 +1306,7 @@ static const struct uart_ops qcom_geni_console_pops = {
        .stop_tx = qcom_geni_serial_stop_tx,
        .start_tx = qcom_geni_serial_start_tx,
        .stop_rx = qcom_geni_serial_stop_rx,
+       .start_rx = qcom_geni_serial_start_rx,
        .set_termios = qcom_geni_serial_set_termios,
        .startup = qcom_geni_serial_startup,
        .request_port = qcom_geni_serial_request_port,
index 9a85b41caa0a4da69442dbda30969edb34b2a137..338ebadfd44b8cff7fc00ef7bef0a73fbfef188c 100644 (file)
@@ -2214,11 +2214,12 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
        /*
         * Nothing to do if the console is not suspending
         * except stop_rx to prevent any asynchronous data
-        * over RX line. Re-start_rx, when required, is
-        * done by set_termios in resume sequence
+        * over RX line. However ensure that we will be
+        * able to Re-start_rx later.
         */
        if (!console_suspend_enabled && uart_console(uport)) {
-               uport->ops->stop_rx(uport);
+               if (uport->ops->start_rx)
+                       uport->ops->stop_rx(uport);
                goto unlock;
        }
 
@@ -2310,6 +2311,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
                if (console_suspend_enabled)
                        uart_change_pm(state, UART_PM_STATE_ON);
                uport->ops->set_termios(uport, &termios, NULL);
+               if (!console_suspend_enabled && uport->ops->start_rx)
+                       uport->ops->start_rx(uport);
                if (console_suspend_enabled)
                        console_start(uport->cons);
        }
index e45c3d6e1536cf6dba325fef8ce925c35f0eb9e8..794e413800ae8239ac8ce2d92de8ddb8c6620345 100644 (file)
@@ -1941,13 +1941,16 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
                }
 
                if (enqd_len + trb_buff_len >= full_len) {
-                       if (need_zero_pkt)
-                               zero_len_trb = !zero_len_trb;
-
-                       field &= ~TRB_CHAIN;
-                       field |= TRB_IOC;
-                       more_trbs_coming = false;
-                       preq->td.last_trb = ring->enqueue;
+                       if (need_zero_pkt && !zero_len_trb) {
+                               zero_len_trb = true;
+                       } else {
+                               zero_len_trb = false;
+                               field &= ~TRB_CHAIN;
+                               field |= TRB_IOC;
+                               more_trbs_coming = false;
+                               need_zero_pkt = false;
+                               preq->td.last_trb = ring->enqueue;
+                       }
                }
 
                /* Only set interrupt on short packet for OUT endpoints. */
@@ -1962,7 +1965,7 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
                length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
                        TRB_INTR_TARGET(0);
 
-               cdnsp_queue_trb(pdev, ring, more_trbs_coming | zero_len_trb,
+               cdnsp_queue_trb(pdev, ring, more_trbs_coming,
                                lower_32_bits(send_addr),
                                upper_32_bits(send_addr),
                                length_field,
index f63a27d11fac8d91fd456074d7a181cdddb882ee..3f107a06817d86e088bd30a87dfc8597d7e15b97 100644 (file)
@@ -5190,7 +5190,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                retval = -EINVAL;
-               goto error1;
+               goto error2;
        }
        hcd->rsrc_start = res->start;
        hcd->rsrc_len = resource_size(res);
index e027c0420dc301922d7c2b47bd7df02eb953639b..573421984948af4eb7cc39bcdadc7cfa61690954 100644 (file)
@@ -1644,13 +1644,8 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
         * This device property is for kernel internal use only and
         * is expected to be set by the glue code.
         */
-       if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
-               edev = extcon_get_extcon_dev(name);
-               if (!edev)
-                       return ERR_PTR(-EPROBE_DEFER);
-
-               return edev;
-       }
+       if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
+               return extcon_get_extcon_dev(name);
 
        /*
         * Try to get an extcon device from the USB PHY controller's "port"
index ba51de7dd7605cf725119ec0ff6abfa434510cc3..6b018048fe2e15b9a11aa907db76773771c32b28 100644 (file)
@@ -127,6 +127,7 @@ static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[
        PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
        PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
        PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"),
+       PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
        {}
 };
 
index 00427d108ab9c0bef19e2cce77dc537a90dcd393..8716bece107208289dc479bf4ee0da226688c115 100644 (file)
@@ -2976,6 +2976,7 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
        struct dwc3 *dwc = dep->dwc;
        u32 mdwidth;
        int size;
+       int maxpacket;
 
        mdwidth = dwc3_mdwidth(dwc);
 
@@ -2988,21 +2989,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
        else
                size = DWC31_GTXFIFOSIZ_TXFDEP(size);
 
-       /* FIFO Depth is in MDWDITH bytes. Multiply */
-       size *= mdwidth;
-
        /*
-        * To meet performance requirement, a minimum TxFIFO size of 3x
-        * MaxPacketSize is recommended for endpoints that support burst and a
-        * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't
-        * support burst. Use those numbers and we can calculate the max packet
-        * limit as below.
+        * maxpacket size is determined as part of the following, after assuming
+        * a mult value of one maxpacket:
+        * DWC3 revision 280A and prior:
+        * fifo_size = mult * (max_packet / mdwidth) + 1;
+        * maxpacket = mdwidth * (fifo_size - 1);
+        *
+        * DWC3 revision 290A and onwards:
+        * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1
+        * maxpacket = mdwidth * ((fifo_size - 1) - 1) - mdwidth;
         */
-       if (dwc->maximum_speed >= USB_SPEED_SUPER)
-               size /= 3;
+       if (DWC3_VER_IS_PRIOR(DWC3, 290A))
+               maxpacket = mdwidth * (size - 1);
        else
-               size /= 2;
+               maxpacket = mdwidth * ((size - 1) - 1) - mdwidth;
 
+       /* Functionally, space for one max packet is sufficient */
+       size = min_t(int, maxpacket, 1024);
        usb_ep_set_maxpacket_limit(&dep->endpoint, size);
 
        dep->endpoint.max_streams = 16;
index 4585ee3a444a8322880c180235a6ce173e60a9f3..e0fa4b186ec6d21e037eeb76737b49c09c3ee88a 100644 (file)
@@ -122,8 +122,6 @@ struct ffs_ep {
        struct usb_endpoint_descriptor  *descs[3];
 
        u8                              num;
-
-       int                             status; /* P: epfile->mutex */
 };
 
 struct ffs_epfile {
@@ -227,6 +225,9 @@ struct ffs_io_data {
        bool use_sg;
 
        struct ffs_data *ffs;
+
+       int status;
+       struct completion done;
 };
 
 struct ffs_desc_helper {
@@ -707,12 +708,15 @@ static const struct file_operations ffs_ep0_operations = {
 
 static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)
 {
+       struct ffs_io_data *io_data = req->context;
+
        ENTER();
-       if (req->context) {
-               struct ffs_ep *ep = _ep->driver_data;
-               ep->status = req->status ? req->status : req->actual;
-               complete(req->context);
-       }
+       if (req->status)
+               io_data->status = req->status;
+       else
+               io_data->status = req->actual;
+
+       complete(&io_data->done);
 }
 
 static ssize_t ffs_copy_to_iter(void *data, int data_len, struct iov_iter *iter)
@@ -1050,7 +1054,6 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
                WARN(1, "%s: data_len == -EINVAL\n", __func__);
                ret = -EINVAL;
        } else if (!io_data->aio) {
-               DECLARE_COMPLETION_ONSTACK(done);
                bool interrupted = false;
 
                req = ep->req;
@@ -1066,7 +1069,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
 
                io_data->buf = data;
 
-               req->context  = &done;
+               init_completion(&io_data->done);
+               req->context  = io_data;
                req->complete = ffs_epfile_io_complete;
 
                ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);
@@ -1075,7 +1079,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
 
                spin_unlock_irq(&epfile->ffs->eps_lock);
 
-               if (wait_for_completion_interruptible(&done)) {
+               if (wait_for_completion_interruptible(&io_data->done)) {
+                       spin_lock_irq(&epfile->ffs->eps_lock);
+                       if (epfile->ep != ep) {
+                               ret = -ESHUTDOWN;
+                               goto error_lock;
+                       }
                        /*
                         * To avoid race condition with ffs_epfile_io_complete,
                         * dequeue the request first then check
@@ -1083,17 +1092,18 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
                         * condition with req->complete callback.
                         */
                        usb_ep_dequeue(ep->ep, req);
-                       wait_for_completion(&done);
-                       interrupted = ep->status < 0;
+                       spin_unlock_irq(&epfile->ffs->eps_lock);
+                       wait_for_completion(&io_data->done);
+                       interrupted = io_data->status < 0;
                }
 
                if (interrupted)
                        ret = -EINTR;
-               else if (io_data->read && ep->status > 0)
-                       ret = __ffs_epfile_read_data(epfile, data, ep->status,
+               else if (io_data->read && io_data->status > 0)
+                       ret = __ffs_epfile_read_data(epfile, data, io_data->status,
                                                     &io_data->data);
                else
-                       ret = ep->status;
+                       ret = io_data->status;
                goto error_mutex;
        } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) {
                ret = -ENOMEM;
index 6f5d45ef2e39a8caeab230cd42111477e387195a..f51694f29de92bb3d882d75d8c845ea42117aa3f 100644 (file)
@@ -775,9 +775,13 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
        dev->qmult = qmult;
        snprintf(net->name, sizeof(net->name), "%s%%d", netname);
 
-       if (get_ether_addr(dev_addr, addr))
+       if (get_ether_addr(dev_addr, addr)) {
+               net->addr_assign_type = NET_ADDR_RANDOM;
                dev_warn(&g->dev,
                        "using random %s ethernet address\n", "self");
+       } else {
+               net->addr_assign_type = NET_ADDR_SET;
+       }
        eth_hw_addr_set(net, addr);
        if (get_ether_addr(host_addr, dev->host_mac))
                dev_warn(&g->dev,
@@ -844,6 +848,10 @@ struct net_device *gether_setup_name_default(const char *netname)
 
        eth_random_addr(dev->dev_mac);
        pr_warn("using random %s ethernet address\n", "self");
+
+       /* by default we always have a random MAC address */
+       net->addr_assign_type = NET_ADDR_RANDOM;
+
        eth_random_addr(dev->host_mac);
        pr_warn("using random %s ethernet address\n", "host");
 
@@ -871,7 +879,6 @@ int gether_register_netdev(struct net_device *net)
        dev = netdev_priv(net);
        g = dev->gadget;
 
-       net->addr_assign_type = NET_ADDR_RANDOM;
        eth_hw_addr_set(net, dev->dev_mac);
 
        status = register_netdev(net);
@@ -912,6 +919,7 @@ int gether_set_dev_addr(struct net_device *net, const char *dev_addr)
        if (get_ether_addr(dev_addr, new_addr))
                return -EINVAL;
        memcpy(dev->dev_mac, new_addr, ETH_ALEN);
+       net->addr_assign_type = NET_ADDR_SET;
        return 0;
 }
 EXPORT_SYMBOL_GPL(gether_set_dev_addr);
index 6117ae8e7242beac495279574a05716e3fdee294..cea10cdb83ae502ccc15ed5eabf74577e9120eee 100644 (file)
@@ -3016,6 +3016,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
        }
 
        udc->isp1301_i2c_client = isp1301_get_client(isp1301_node);
+       of_node_put(isp1301_node);
        if (!udc->isp1301_i2c_client) {
                return -EPROBE_DEFER;
        }
index f0ab63138016508a4065b8c057e78ba206753b8f..9ac56e9ffc645f68d8c7e328371f83be50915501 100644 (file)
@@ -1107,7 +1107,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
 {
        u32                     command, temp = 0;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
-       struct usb_hcd          *secondary_hcd;
        int                     retval = 0;
        bool                    comp_timer_running = false;
        bool                    pending_portevent = false;
@@ -1214,23 +1213,19 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                 * first with the primary HCD, and then with the secondary HCD.
                 * If we don't do the same, the host will never be started.
                 */
-               if (!usb_hcd_is_primary_hcd(hcd))
-                       secondary_hcd = hcd;
-               else
-                       secondary_hcd = xhci->shared_hcd;
-
                xhci_dbg(xhci, "Initialize the xhci_hcd\n");
-               retval = xhci_init(hcd->primary_hcd);
+               retval = xhci_init(hcd);
                if (retval)
                        return retval;
                comp_timer_running = true;
 
                xhci_dbg(xhci, "Start the primary HCD\n");
-               retval = xhci_run(hcd->primary_hcd);
-               if (!retval && secondary_hcd) {
+               retval = xhci_run(hcd);
+               if (!retval && xhci->shared_hcd) {
                        xhci_dbg(xhci, "Start the secondary HCD\n");
-                       retval = xhci_run(secondary_hcd);
+                       retval = xhci_run(xhci->shared_hcd);
                }
+
                hcd->state = HC_STATE_SUSPENDED;
                if (xhci->shared_hcd)
                        xhci->shared_hcd->state = HC_STATE_SUSPENDED;
index a7b3c15957ba937f39767b94ed694b69ef21fc85..feba2a8d1233a902f20886f1d7050f5ede11fa2f 100644 (file)
@@ -166,6 +166,7 @@ static const struct usb_device_id edgeport_2port_id_table[] = {
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) },
        { }
 };
 
@@ -204,6 +205,7 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) },
        { }
 };
 
index 52cbc353051feddb45b7b546aefbfe8dac25c1a4..9a6f742ad3abd032b8c481c216049dcf32f2ebf0 100644 (file)
 //
 // Definitions for other product IDs
 #define ION_DEVICE_ID_MT4X56USB                        0x1403  // OEM device
+#define ION_DEVICE_ID_E5805A                   0x1A01  // OEM device (rebranded Edgeport/4)
 
 
 #define        GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId)                            \
index e60425bbf5376481bc5f9063a36223f3b1b2e43b..ed1e50d83ccab1cf460ff538489f2463861fc0a6 100644 (file)
@@ -432,6 +432,8 @@ static void option_instat_callback(struct urb *urb);
 #define CINTERION_PRODUCT_CLS8                 0x00b0
 #define CINTERION_PRODUCT_MV31_MBIM            0x00b3
 #define CINTERION_PRODUCT_MV31_RMNET           0x00b7
+#define CINTERION_PRODUCT_MV31_2_MBIM          0x00b8
+#define CINTERION_PRODUCT_MV31_2_RMNET         0x00b9
 #define CINTERION_PRODUCT_MV32_WA              0x00f1
 #define CINTERION_PRODUCT_MV32_WB              0x00f2
 
@@ -1979,6 +1981,10 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = RSVD(3)},
        { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),
          .driver_info = RSVD(0)},
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_MBIM, 0xff),
+         .driver_info = RSVD(3)},
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_RMNET, 0xff),
+         .driver_info = RSVD(0)},
        { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff),
          .driver_info = RSVD(3)},
        { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff),
index b7a95547915606ff8b7f954229059ebb8a3f64b2..1b6d46b86f810b822cee4dceb966f7871641861f 100644 (file)
@@ -107,7 +107,7 @@ struct mlx5_vdpa_virtqueue {
 
        /* Resources for implementing the notification channel from the device
         * to the driver. fwqp is the firmware end of an RC connection; the
-        * other end is vqqp used by the driver. cq is is where completions are
+        * other end is vqqp used by the driver. cq is where completions are
         * reported.
         */
        struct mlx5_vdpa_cq cq;
@@ -1814,12 +1814,13 @@ static virtio_net_ctrl_ack handle_ctrl_vlan(struct mlx5_vdpa_dev *mvdev, u8 cmd)
 
                id = mlx5vdpa16_to_cpu(mvdev, vlan);
                mac_vlan_del(ndev, ndev->config.mac, id, true);
+               status = VIRTIO_NET_OK;
                break;
        default:
-       break;
-}
+               break;
+       }
 
-return status;
+       return status;
 }
 
 static void mlx5_cvq_kick_handler(struct work_struct *work)
index d503848b3b6ed6dc20c59d819e2887d26726887e..776ad7496f534ab1cf534c1a2224edf954f7c75d 100644 (file)
@@ -1345,9 +1345,9 @@ static int vduse_create_dev(struct vduse_dev_config *config,
 
        dev->minor = ret;
        dev->msg_timeout = VDUSE_MSG_DEFAULT_TIMEOUT;
-       dev->dev = device_create(vduse_class, NULL,
-                                MKDEV(MAJOR(vduse_major), dev->minor),
-                                dev, "%s", config->name);
+       dev->dev = device_create_with_groups(vduse_class, NULL,
+                               MKDEV(MAJOR(vduse_major), dev->minor),
+                               dev, vduse_dev_groups, "%s", config->name);
        if (IS_ERR(dev->dev)) {
                ret = PTR_ERR(dev->dev);
                goto err_dev;
@@ -1596,7 +1596,6 @@ static int vduse_init(void)
                return PTR_ERR(vduse_class);
 
        vduse_class->devnode = vduse_devnode;
-       vduse_class->dev_groups = vduse_dev_groups;
 
        ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse");
        if (ret)
index 935a1d0ddb97e035ecc7329bd78649a558860a8b..5ad2596c6e8a1631a249f7d61df4e8a53f401c64 100644 (file)
@@ -499,6 +499,8 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
                ops->set_vq_ready(vdpa, idx, s.num);
                return 0;
        case VHOST_VDPA_GET_VRING_GROUP:
+               if (!ops->get_vq_group)
+                       return -EOPNOTSUPP;
                s.index = idx;
                s.num = ops->get_vq_group(vdpa, idx);
                if (s.num >= vdpa->ngroups)
index 14e2043d7685216c9a26adaf007228e2c47f276e..eab55accf381f83ad96ffaaa0998f276dca8551a 100644 (file)
@@ -292,7 +292,7 @@ __vringh_iov(struct vringh *vrh, u16 i,
             int (*copy)(const struct vringh *vrh,
                         void *dst, const void *src, size_t len))
 {
-       int err, count = 0, up_next, desc_max;
+       int err, count = 0, indirect_count = 0, up_next, desc_max;
        struct vring_desc desc, *descs;
        struct vringh_range range = { -1ULL, 0 }, slowrange;
        bool slow = false;
@@ -349,7 +349,12 @@ __vringh_iov(struct vringh *vrh, u16 i,
                        continue;
                }
 
-               if (count++ == vrh->vring.num) {
+               if (up_next == -1)
+                       count++;
+               else
+                       indirect_count++;
+
+               if (count > vrh->vring.num || indirect_count > desc_max) {
                        vringh_bad("Descriptor loop in %p", descs);
                        err = -ELOOP;
                        goto fail;
@@ -411,6 +416,7 @@ __vringh_iov(struct vringh *vrh, u16 i,
                                i = return_from_indirect(vrh, &up_next,
                                                         &descs, &desc_max);
                                slow = false;
+                               indirect_count = 0;
                        } else
                                break;
                }
index b5adf6abd241e8c254215449052cb73c18dd07a6..a6dc8b5846fe71758be036c44d184ebca72643c3 100644 (file)
@@ -6,12 +6,6 @@ config VIRTIO
          bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG
          or CONFIG_S390_GUEST.
 
-config ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
-       bool
-       help
-         This option is selected if the architecture may need to enforce
-         VIRTIO_F_ACCESS_PLATFORM
-
 config VIRTIO_PCI_LIB
        tristate
        help
index ef04a96942bfbda3afee2a0c0d65562abdb22de9..6bace84ae37ec5674934dca5dc58bf8044738547 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/idr.h>
 #include <linux/of.h>
+#include <linux/platform-feature.h>
 #include <uapi/linux/virtio_ids.h>
 
 /* Unique numbering for virtio devices. */
@@ -170,12 +171,10 @@ EXPORT_SYMBOL_GPL(virtio_add_status);
 static int virtio_features_ok(struct virtio_device *dev)
 {
        unsigned int status;
-       int ret;
 
        might_sleep();
 
-       ret = arch_has_restricted_virtio_memory_access();
-       if (ret) {
+       if (platform_has(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS)) {
                if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
                        dev_warn(&dev->dev,
                                 "device must provide VIRTIO_F_VERSION_1\n");
index f9a36bc7ac27e1f32d6192b3cb68da31c36c315b..c9bec3813e94949928f24b22322f1b92ba036044 100644 (file)
@@ -255,7 +255,7 @@ static void vm_set_status(struct virtio_device *vdev, u8 status)
 
        /*
         * Per memory-barriers.txt, wmb() is not needed to guarantee
-        * that the the cache coherent memory writes have completed
+        * that the cache coherent memory writes have completed
         * before writing to the MMIO region.
         */
        writel(status, vm_dev->base + VIRTIO_MMIO_STATUS);
@@ -701,6 +701,7 @@ static int vm_cmdline_set(const char *device,
        if (!vm_cmdline_parent_registered) {
                err = device_register(&vm_cmdline_parent);
                if (err) {
+                       put_device(&vm_cmdline_parent);
                        pr_err("Failed to register parent device!\n");
                        return err;
                }
index a0fa14f28a7fc0b490910b75ad834c247a59ad59..b790f30b2b56620e1def1effc366abee5dad4bf9 100644 (file)
@@ -469,7 +469,7 @@ void vp_modern_set_status(struct virtio_pci_modern_device *mdev,
 
        /*
         * Per memory-barriers.txt, wmb() is not needed to guarantee
-        * that the the cache coherent memory writes have completed
+        * that the cache coherent memory writes have completed
         * before writing to the MMIO region.
         */
        vp_iowrite8(status, &cfg->device_status);
index b0b2d7a6fdde7fde073bda3b7d3b854f6b30f8da..2fd85be882786418125172732a2bf0507f67ff2e 100644 (file)
@@ -172,3 +172,4 @@ module_platform_driver(gxp_wdt_driver);
 MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>");
 MODULE_AUTHOR("Jean-Marie Verdun <verdun@hpe.com>");
 MODULE_DESCRIPTION("Driver for GXP watchdog timer");
+MODULE_LICENSE("GPL");
index 120d32f164ace79b9dada0f778357e6d761fef19..bfd5f4f706bcc02e925d8fd0d19d12c9185b0a0a 100644 (file)
@@ -335,4 +335,24 @@ config XEN_UNPOPULATED_ALLOC
          having to balloon out RAM regions in order to obtain physical memory
          space to create such mappings.
 
+config XEN_GRANT_DMA_IOMMU
+       bool
+       select IOMMU_API
+
+config XEN_GRANT_DMA_OPS
+       bool
+       select DMA_OPS
+
+config XEN_VIRTIO
+       bool "Xen virtio support"
+       depends on VIRTIO
+       select XEN_GRANT_DMA_OPS
+       select XEN_GRANT_DMA_IOMMU if OF
+       help
+         Enable virtio support for running as Xen guest. Depending on the
+         guest type this will require special support on the backend side
+         (qemu or kernel, depending on the virtio device types used).
+
+         If in doubt, say n.
+
 endmenu
index 5aae66e638a7c5e28acc6be8081846317dc01382..c0503f1c7d5b2a04a0a6f664424927bcdd065dc4 100644 (file)
@@ -39,3 +39,5 @@ xen-gntalloc-y                                := gntalloc.o
 xen-privcmd-y                          := privcmd.o privcmd-buf.o
 obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF)    += xen-front-pgdir-shbuf.o
 obj-$(CONFIG_XEN_UNPOPULATED_ALLOC)    += unpopulated-alloc.o
+obj-$(CONFIG_XEN_GRANT_DMA_OPS)                += grant-dma-ops.o
+obj-$(CONFIG_XEN_GRANT_DMA_IOMMU)      += grant-dma-iommu.o
diff --git a/drivers/xen/grant-dma-iommu.c b/drivers/xen/grant-dma-iommu.c
new file mode 100644 (file)
index 0000000..16b8bc0
--- /dev/null
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Stub IOMMU driver which does nothing.
+ * The main purpose of it being present is to reuse generic IOMMU device tree
+ * bindings by Xen grant DMA-mapping layer.
+ *
+ * Copyright (C) 2022 EPAM Systems Inc.
+ */
+
+#include <linux/iommu.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct grant_dma_iommu_device {
+       struct device *dev;
+       struct iommu_device iommu;
+};
+
+/* Nothing is really needed here */
+static const struct iommu_ops grant_dma_iommu_ops;
+
+static const struct of_device_id grant_dma_iommu_of_match[] = {
+       { .compatible = "xen,grant-dma" },
+       { },
+};
+
+static int grant_dma_iommu_probe(struct platform_device *pdev)
+{
+       struct grant_dma_iommu_device *mmu;
+       int ret;
+
+       mmu = devm_kzalloc(&pdev->dev, sizeof(*mmu), GFP_KERNEL);
+       if (!mmu)
+               return -ENOMEM;
+
+       mmu->dev = &pdev->dev;
+
+       ret = iommu_device_register(&mmu->iommu, &grant_dma_iommu_ops, &pdev->dev);
+       if (ret)
+               return ret;
+
+       platform_set_drvdata(pdev, mmu);
+
+       return 0;
+}
+
+static int grant_dma_iommu_remove(struct platform_device *pdev)
+{
+       struct grant_dma_iommu_device *mmu = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+       iommu_device_unregister(&mmu->iommu);
+
+       return 0;
+}
+
+static struct platform_driver grant_dma_iommu_driver = {
+       .driver = {
+               .name = "grant-dma-iommu",
+               .of_match_table = grant_dma_iommu_of_match,
+       },
+       .probe = grant_dma_iommu_probe,
+       .remove = grant_dma_iommu_remove,
+};
+
+static int __init grant_dma_iommu_init(void)
+{
+       struct device_node *iommu_np;
+
+       iommu_np = of_find_matching_node(NULL, grant_dma_iommu_of_match);
+       if (!iommu_np)
+               return 0;
+
+       of_node_put(iommu_np);
+
+       return platform_driver_register(&grant_dma_iommu_driver);
+}
+subsys_initcall(grant_dma_iommu_init);
diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c
new file mode 100644 (file)
index 0000000..fc01424
--- /dev/null
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Xen grant DMA-mapping layer - contains special DMA-mapping routines
+ * for providing grant references as DMA addresses to be used by frontends
+ * (e.g. virtio) in Xen guests
+ *
+ * Copyright (c) 2021, Juergen Gross <jgross@suse.com>
+ */
+
+#include <linux/module.h>
+#include <linux/dma-map-ops.h>
+#include <linux/of.h>
+#include <linux/pfn.h>
+#include <linux/xarray.h>
+#include <xen/xen.h>
+#include <xen/xen-ops.h>
+#include <xen/grant_table.h>
+
+struct xen_grant_dma_data {
+       /* The ID of backend domain */
+       domid_t backend_domid;
+       /* Is device behaving sane? */
+       bool broken;
+};
+
+static DEFINE_XARRAY(xen_grant_dma_devices);
+
+#define XEN_GRANT_DMA_ADDR_OFF (1ULL << 63)
+
+static inline dma_addr_t grant_to_dma(grant_ref_t grant)
+{
+       return XEN_GRANT_DMA_ADDR_OFF | ((dma_addr_t)grant << PAGE_SHIFT);
+}
+
+static inline grant_ref_t dma_to_grant(dma_addr_t dma)
+{
+       return (grant_ref_t)((dma & ~XEN_GRANT_DMA_ADDR_OFF) >> PAGE_SHIFT);
+}
+
+static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev)
+{
+       struct xen_grant_dma_data *data;
+
+       xa_lock(&xen_grant_dma_devices);
+       data = xa_load(&xen_grant_dma_devices, (unsigned long)dev);
+       xa_unlock(&xen_grant_dma_devices);
+
+       return data;
+}
+
+/*
+ * DMA ops for Xen frontends (e.g. virtio).
+ *
+ * Used to act as a kind of software IOMMU for Xen guests by using grants as
+ * DMA addresses.
+ * Such a DMA address is formed by using the grant reference as a frame
+ * number and setting the highest address bit (this bit is for the backend
+ * to be able to distinguish it from e.g. a mmio address).
+ */
+static void *xen_grant_dma_alloc(struct device *dev, size_t size,
+                                dma_addr_t *dma_handle, gfp_t gfp,
+                                unsigned long attrs)
+{
+       struct xen_grant_dma_data *data;
+       unsigned int i, n_pages = PFN_UP(size);
+       unsigned long pfn;
+       grant_ref_t grant;
+       void *ret;
+
+       data = find_xen_grant_dma_data(dev);
+       if (!data)
+               return NULL;
+
+       if (unlikely(data->broken))
+               return NULL;
+
+       ret = alloc_pages_exact(n_pages * PAGE_SIZE, gfp);
+       if (!ret)
+               return NULL;
+
+       pfn = virt_to_pfn(ret);
+
+       if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) {
+               free_pages_exact(ret, n_pages * PAGE_SIZE);
+               return NULL;
+       }
+
+       for (i = 0; i < n_pages; i++) {
+               gnttab_grant_foreign_access_ref(grant + i, data->backend_domid,
+                               pfn_to_gfn(pfn + i), 0);
+       }
+
+       *dma_handle = grant_to_dma(grant);
+
+       return ret;
+}
+
+static void xen_grant_dma_free(struct device *dev, size_t size, void *vaddr,
+                              dma_addr_t dma_handle, unsigned long attrs)
+{
+       struct xen_grant_dma_data *data;
+       unsigned int i, n_pages = PFN_UP(size);
+       grant_ref_t grant;
+
+       data = find_xen_grant_dma_data(dev);
+       if (!data)
+               return;
+
+       if (unlikely(data->broken))
+               return;
+
+       grant = dma_to_grant(dma_handle);
+
+       for (i = 0; i < n_pages; i++) {
+               if (unlikely(!gnttab_end_foreign_access_ref(grant + i))) {
+                       dev_alert(dev, "Grant still in use by backend domain, disabled for further use\n");
+                       data->broken = true;
+                       return;
+               }
+       }
+
+       gnttab_free_grant_reference_seq(grant, n_pages);
+
+       free_pages_exact(vaddr, n_pages * PAGE_SIZE);
+}
+
+static struct page *xen_grant_dma_alloc_pages(struct device *dev, size_t size,
+                                             dma_addr_t *dma_handle,
+                                             enum dma_data_direction dir,
+                                             gfp_t gfp)
+{
+       void *vaddr;
+
+       vaddr = xen_grant_dma_alloc(dev, size, dma_handle, gfp, 0);
+       if (!vaddr)
+               return NULL;
+
+       return virt_to_page(vaddr);
+}
+
+static void xen_grant_dma_free_pages(struct device *dev, size_t size,
+                                    struct page *vaddr, dma_addr_t dma_handle,
+                                    enum dma_data_direction dir)
+{
+       xen_grant_dma_free(dev, size, page_to_virt(vaddr), dma_handle, 0);
+}
+
+static dma_addr_t xen_grant_dma_map_page(struct device *dev, struct page *page,
+                                        unsigned long offset, size_t size,
+                                        enum dma_data_direction dir,
+                                        unsigned long attrs)
+{
+       struct xen_grant_dma_data *data;
+       unsigned int i, n_pages = PFN_UP(size);
+       grant_ref_t grant;
+       dma_addr_t dma_handle;
+
+       if (WARN_ON(dir == DMA_NONE))
+               return DMA_MAPPING_ERROR;
+
+       data = find_xen_grant_dma_data(dev);
+       if (!data)
+               return DMA_MAPPING_ERROR;
+
+       if (unlikely(data->broken))
+               return DMA_MAPPING_ERROR;
+
+       if (gnttab_alloc_grant_reference_seq(n_pages, &grant))
+               return DMA_MAPPING_ERROR;
+
+       for (i = 0; i < n_pages; i++) {
+               gnttab_grant_foreign_access_ref(grant + i, data->backend_domid,
+                               xen_page_to_gfn(page) + i, dir == DMA_TO_DEVICE);
+       }
+
+       dma_handle = grant_to_dma(grant) + offset;
+
+       return dma_handle;
+}
+
+static void xen_grant_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
+                                    size_t size, enum dma_data_direction dir,
+                                    unsigned long attrs)
+{
+       struct xen_grant_dma_data *data;
+       unsigned int i, n_pages = PFN_UP(size);
+       grant_ref_t grant;
+
+       if (WARN_ON(dir == DMA_NONE))
+               return;
+
+       data = find_xen_grant_dma_data(dev);
+       if (!data)
+               return;
+
+       if (unlikely(data->broken))
+               return;
+
+       grant = dma_to_grant(dma_handle);
+
+       for (i = 0; i < n_pages; i++) {
+               if (unlikely(!gnttab_end_foreign_access_ref(grant + i))) {
+                       dev_alert(dev, "Grant still in use by backend domain, disabled for further use\n");
+                       data->broken = true;
+                       return;
+               }
+       }
+
+       gnttab_free_grant_reference_seq(grant, n_pages);
+}
+
+static void xen_grant_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+                                  int nents, enum dma_data_direction dir,
+                                  unsigned long attrs)
+{
+       struct scatterlist *s;
+       unsigned int i;
+
+       if (WARN_ON(dir == DMA_NONE))
+               return;
+
+       for_each_sg(sg, s, nents, i)
+               xen_grant_dma_unmap_page(dev, s->dma_address, sg_dma_len(s), dir,
+                               attrs);
+}
+
+static int xen_grant_dma_map_sg(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction dir,
+                               unsigned long attrs)
+{
+       struct scatterlist *s;
+       unsigned int i;
+
+       if (WARN_ON(dir == DMA_NONE))
+               return -EINVAL;
+
+       for_each_sg(sg, s, nents, i) {
+               s->dma_address = xen_grant_dma_map_page(dev, sg_page(s), s->offset,
+                               s->length, dir, attrs);
+               if (s->dma_address == DMA_MAPPING_ERROR)
+                       goto out;
+
+               sg_dma_len(s) = s->length;
+       }
+
+       return nents;
+
+out:
+       xen_grant_dma_unmap_sg(dev, sg, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
+       sg_dma_len(sg) = 0;
+
+       return -EIO;
+}
+
+static int xen_grant_dma_supported(struct device *dev, u64 mask)
+{
+       return mask == DMA_BIT_MASK(64);
+}
+
+static const struct dma_map_ops xen_grant_dma_ops = {
+       .alloc = xen_grant_dma_alloc,
+       .free = xen_grant_dma_free,
+       .alloc_pages = xen_grant_dma_alloc_pages,
+       .free_pages = xen_grant_dma_free_pages,
+       .mmap = dma_common_mmap,
+       .get_sgtable = dma_common_get_sgtable,
+       .map_page = xen_grant_dma_map_page,
+       .unmap_page = xen_grant_dma_unmap_page,
+       .map_sg = xen_grant_dma_map_sg,
+       .unmap_sg = xen_grant_dma_unmap_sg,
+       .dma_supported = xen_grant_dma_supported,
+};
+
+bool xen_is_grant_dma_device(struct device *dev)
+{
+       struct device_node *iommu_np;
+       bool has_iommu;
+
+       /* XXX Handle only DT devices for now */
+       if (!dev->of_node)
+               return false;
+
+       iommu_np = of_parse_phandle(dev->of_node, "iommus", 0);
+       has_iommu = iommu_np && of_device_is_compatible(iommu_np, "xen,grant-dma");
+       of_node_put(iommu_np);
+
+       return has_iommu;
+}
+
+void xen_grant_setup_dma_ops(struct device *dev)
+{
+       struct xen_grant_dma_data *data;
+       struct of_phandle_args iommu_spec;
+
+       data = find_xen_grant_dma_data(dev);
+       if (data) {
+               dev_err(dev, "Xen grant DMA data is already created\n");
+               return;
+       }
+
+       /* XXX ACPI device unsupported for now */
+       if (!dev->of_node)
+               goto err;
+
+       if (of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells",
+                       0, &iommu_spec)) {
+               dev_err(dev, "Cannot parse iommus property\n");
+               goto err;
+       }
+
+       if (!of_device_is_compatible(iommu_spec.np, "xen,grant-dma") ||
+                       iommu_spec.args_count != 1) {
+               dev_err(dev, "Incompatible IOMMU node\n");
+               of_node_put(iommu_spec.np);
+               goto err;
+       }
+
+       of_node_put(iommu_spec.np);
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               goto err;
+
+       /*
+        * The endpoint ID here means the ID of the domain where the corresponding
+        * backend is running
+        */
+       data->backend_domid = iommu_spec.args[0];
+
+       if (xa_err(xa_store(&xen_grant_dma_devices, (unsigned long)dev, data,
+                       GFP_KERNEL))) {
+               dev_err(dev, "Cannot store Xen grant DMA data\n");
+               goto err;
+       }
+
+       dev->dma_ops = &xen_grant_dma_ops;
+
+       return;
+
+err:
+       dev_err(dev, "Cannot set up Xen grant DMA ops, retain platform DMA ops\n");
+}
+
+MODULE_DESCRIPTION("Xen grant DMA-mapping layer");
+MODULE_AUTHOR("Juergen Gross <jgross@suse.com>");
+MODULE_LICENSE("GPL");
index 7a18292540bc3f3b9e815e0649d52e0dfc445634..738029de3c6722598ba3c96441f0109159b6fed3 100644 (file)
@@ -33,6 +33,7 @@
 
 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
 
+#include <linux/bitmap.h>
 #include <linux/memblock.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 
 static grant_ref_t **gnttab_list;
 static unsigned int nr_grant_frames;
+
+/*
+ * Handling of free grants:
+ *
+ * Free grants are in a simple list anchored in gnttab_free_head. They are
+ * linked by grant ref, the last element contains GNTTAB_LIST_END. The number
+ * of free entries is stored in gnttab_free_count.
+ * Additionally there is a bitmap of free entries anchored in
+ * gnttab_free_bitmap. This is being used for simplifying allocation of
+ * multiple consecutive grants, which is needed e.g. for support of virtio.
+ * gnttab_last_free is used to add free entries of new frames at the end of
+ * the free list.
+ * gnttab_free_tail_ptr specifies the variable which references the start
+ * of consecutive free grants ending with gnttab_last_free. This pointer is
+ * updated in a rather defensive way, in order to avoid performance hits in
+ * hot paths.
+ * All those variables are protected by gnttab_list_lock.
+ */
 static int gnttab_free_count;
-static grant_ref_t gnttab_free_head;
+static unsigned int gnttab_size;
+static grant_ref_t gnttab_free_head = GNTTAB_LIST_END;
+static grant_ref_t gnttab_last_free = GNTTAB_LIST_END;
+static grant_ref_t *gnttab_free_tail_ptr;
+static unsigned long *gnttab_free_bitmap;
 static DEFINE_SPINLOCK(gnttab_list_lock);
+
 struct grant_frames xen_auto_xlat_grant_frames;
 static unsigned int xen_gnttab_version;
 module_param_named(version, xen_gnttab_version, uint, 0);
@@ -168,16 +192,116 @@ static int get_free_entries(unsigned count)
 
        ref = head = gnttab_free_head;
        gnttab_free_count -= count;
-       while (count-- > 1)
-               head = gnttab_entry(head);
+       while (count--) {
+               bitmap_clear(gnttab_free_bitmap, head, 1);
+               if (gnttab_free_tail_ptr == __gnttab_entry(head))
+                       gnttab_free_tail_ptr = &gnttab_free_head;
+               if (count)
+                       head = gnttab_entry(head);
+       }
        gnttab_free_head = gnttab_entry(head);
        gnttab_entry(head) = GNTTAB_LIST_END;
 
+       if (!gnttab_free_count) {
+               gnttab_last_free = GNTTAB_LIST_END;
+               gnttab_free_tail_ptr = NULL;
+       }
+
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
 
        return ref;
 }
 
+static int get_seq_entry_count(void)
+{
+       if (gnttab_last_free == GNTTAB_LIST_END || !gnttab_free_tail_ptr ||
+           *gnttab_free_tail_ptr == GNTTAB_LIST_END)
+               return 0;
+
+       return gnttab_last_free - *gnttab_free_tail_ptr + 1;
+}
+
+/* Rebuilds the free grant list and tries to find count consecutive entries. */
+static int get_free_seq(unsigned int count)
+{
+       int ret = -ENOSPC;
+       unsigned int from, to;
+       grant_ref_t *last;
+
+       gnttab_free_tail_ptr = &gnttab_free_head;
+       last = &gnttab_free_head;
+
+       for (from = find_first_bit(gnttab_free_bitmap, gnttab_size);
+            from < gnttab_size;
+            from = find_next_bit(gnttab_free_bitmap, gnttab_size, to + 1)) {
+               to = find_next_zero_bit(gnttab_free_bitmap, gnttab_size,
+                                       from + 1);
+               if (ret < 0 && to - from >= count) {
+                       ret = from;
+                       bitmap_clear(gnttab_free_bitmap, ret, count);
+                       from += count;
+                       gnttab_free_count -= count;
+                       if (from == to)
+                               continue;
+               }
+
+               /*
+                * Recreate the free list in order to have it properly sorted.
+                * This is needed to make sure that the free tail has the maximum
+                * possible size.
+                */
+               while (from < to) {
+                       *last = from;
+                       last = __gnttab_entry(from);
+                       gnttab_last_free = from;
+                       from++;
+               }
+               if (to < gnttab_size)
+                       gnttab_free_tail_ptr = __gnttab_entry(to - 1);
+       }
+
+       *last = GNTTAB_LIST_END;
+       if (gnttab_last_free != gnttab_size - 1)
+               gnttab_free_tail_ptr = NULL;
+
+       return ret;
+}
+
+static int get_free_entries_seq(unsigned int count)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+
+       if (gnttab_free_count < count) {
+               ret = gnttab_expand(count - gnttab_free_count);
+               if (ret < 0)
+                       goto out;
+       }
+
+       if (get_seq_entry_count() < count) {
+               ret = get_free_seq(count);
+               if (ret >= 0)
+                       goto out;
+               ret = gnttab_expand(count - get_seq_entry_count());
+               if (ret < 0)
+                       goto out;
+       }
+
+       ret = *gnttab_free_tail_ptr;
+       *gnttab_free_tail_ptr = gnttab_entry(ret + count - 1);
+       gnttab_free_count -= count;
+       if (!gnttab_free_count)
+               gnttab_free_tail_ptr = NULL;
+       bitmap_clear(gnttab_free_bitmap, ret, count);
+
+ out:
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
+
+       return ret;
+}
+
 static void do_free_callbacks(void)
 {
        struct gnttab_free_callback *callback, *next;
@@ -204,21 +328,51 @@ static inline void check_free_callbacks(void)
                do_free_callbacks();
 }
 
-static void put_free_entry(grant_ref_t ref)
+static void put_free_entry_locked(grant_ref_t ref)
 {
-       unsigned long flags;
-
        if (unlikely(ref < GNTTAB_NR_RESERVED_ENTRIES))
                return;
 
-       spin_lock_irqsave(&gnttab_list_lock, flags);
        gnttab_entry(ref) = gnttab_free_head;
        gnttab_free_head = ref;
+       if (!gnttab_free_count)
+               gnttab_last_free = ref;
+       if (gnttab_free_tail_ptr == &gnttab_free_head)
+               gnttab_free_tail_ptr = __gnttab_entry(ref);
        gnttab_free_count++;
+       bitmap_set(gnttab_free_bitmap, ref, 1);
+}
+
+static void put_free_entry(grant_ref_t ref)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       put_free_entry_locked(ref);
        check_free_callbacks();
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
 
+static void gnttab_set_free(unsigned int start, unsigned int n)
+{
+       unsigned int i;
+
+       for (i = start; i < start + n - 1; i++)
+               gnttab_entry(i) = i + 1;
+
+       gnttab_entry(i) = GNTTAB_LIST_END;
+       if (!gnttab_free_count) {
+               gnttab_free_head = start;
+               gnttab_free_tail_ptr = &gnttab_free_head;
+       } else {
+               gnttab_entry(gnttab_last_free) = start;
+       }
+       gnttab_free_count += n;
+       gnttab_last_free = i;
+
+       bitmap_set(gnttab_free_bitmap, start, n);
+}
+
 /*
  * Following applies to gnttab_update_entry_v1 and gnttab_update_entry_v2.
  * Introducing a valid entry into the grant table:
@@ -450,23 +604,31 @@ void gnttab_free_grant_references(grant_ref_t head)
 {
        grant_ref_t ref;
        unsigned long flags;
-       int count = 1;
-       if (head == GNTTAB_LIST_END)
-               return;
+
        spin_lock_irqsave(&gnttab_list_lock, flags);
-       ref = head;
-       while (gnttab_entry(ref) != GNTTAB_LIST_END) {
-               ref = gnttab_entry(ref);
-               count++;
+       while (head != GNTTAB_LIST_END) {
+               ref = gnttab_entry(head);
+               put_free_entry_locked(head);
+               head = ref;
        }
-       gnttab_entry(ref) = gnttab_free_head;
-       gnttab_free_head = head;
-       gnttab_free_count += count;
        check_free_callbacks();
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
 EXPORT_SYMBOL_GPL(gnttab_free_grant_references);
 
+void gnttab_free_grant_reference_seq(grant_ref_t head, unsigned int count)
+{
+       unsigned long flags;
+       unsigned int i;
+
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       for (i = count; i > 0; i--)
+               put_free_entry_locked(head + i - 1);
+       check_free_callbacks();
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
+}
+EXPORT_SYMBOL_GPL(gnttab_free_grant_reference_seq);
+
 int gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
 {
        int h = get_free_entries(count);
@@ -480,6 +642,24 @@ int gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
 }
 EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references);
 
+int gnttab_alloc_grant_reference_seq(unsigned int count, grant_ref_t *first)
+{
+       int h;
+
+       if (count == 1)
+               h = get_free_entries(1);
+       else
+               h = get_free_entries_seq(count);
+
+       if (h < 0)
+               return -ENOSPC;
+
+       *first = h;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gnttab_alloc_grant_reference_seq);
+
 int gnttab_empty_grant_references(const grant_ref_t *private_head)
 {
        return (*private_head == GNTTAB_LIST_END);
@@ -572,16 +752,13 @@ static int grow_gnttab_list(unsigned int more_frames)
                        goto grow_nomem;
        }
 
+       gnttab_set_free(gnttab_size, extra_entries);
 
-       for (i = grefs_per_frame * nr_grant_frames;
-            i < grefs_per_frame * new_nr_grant_frames - 1; i++)
-               gnttab_entry(i) = i + 1;
-
-       gnttab_entry(i) = gnttab_free_head;
-       gnttab_free_head = grefs_per_frame * nr_grant_frames;
-       gnttab_free_count += extra_entries;
+       if (!gnttab_free_tail_ptr)
+               gnttab_free_tail_ptr = __gnttab_entry(gnttab_size);
 
        nr_grant_frames = new_nr_grant_frames;
+       gnttab_size += extra_entries;
 
        check_free_callbacks();
 
@@ -1424,20 +1601,20 @@ static int gnttab_expand(unsigned int req_entries)
 int gnttab_init(void)
 {
        int i;
-       unsigned long max_nr_grant_frames;
+       unsigned long max_nr_grant_frames, max_nr_grefs;
        unsigned int max_nr_glist_frames, nr_glist_frames;
-       unsigned int nr_init_grefs;
        int ret;
 
        gnttab_request_version();
        max_nr_grant_frames = gnttab_max_grant_frames();
+       max_nr_grefs = max_nr_grant_frames *
+                       gnttab_interface->grefs_per_grant_frame;
        nr_grant_frames = 1;
 
        /* Determine the maximum number of frames required for the
         * grant reference free list on the current hypervisor.
         */
-       max_nr_glist_frames = (max_nr_grant_frames *
-                              gnttab_interface->grefs_per_grant_frame / RPP);
+       max_nr_glist_frames = max_nr_grefs / RPP;
 
        gnttab_list = kmalloc_array(max_nr_glist_frames,
                                    sizeof(grant_ref_t *),
@@ -1454,6 +1631,12 @@ int gnttab_init(void)
                }
        }
 
+       gnttab_free_bitmap = bitmap_zalloc(max_nr_grefs, GFP_KERNEL);
+       if (!gnttab_free_bitmap) {
+               ret = -ENOMEM;
+               goto ini_nomem;
+       }
+
        ret = arch_gnttab_init(max_nr_grant_frames,
                               nr_status_frames(max_nr_grant_frames));
        if (ret < 0)
@@ -1464,15 +1647,10 @@ int gnttab_init(void)
                goto ini_nomem;
        }
 
-       nr_init_grefs = nr_grant_frames *
-                       gnttab_interface->grefs_per_grant_frame;
-
-       for (i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++)
-               gnttab_entry(i) = i + 1;
+       gnttab_size = nr_grant_frames * gnttab_interface->grefs_per_grant_frame;
 
-       gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END;
-       gnttab_free_count = nr_init_grefs - GNTTAB_NR_RESERVED_ENTRIES;
-       gnttab_free_head  = GNTTAB_NR_RESERVED_ENTRIES;
+       gnttab_set_free(GNTTAB_NR_RESERVED_ENTRIES,
+                       gnttab_size - GNTTAB_NR_RESERVED_ENTRIES);
 
        printk("Grant table initialized\n");
        return 0;
@@ -1481,6 +1659,7 @@ int gnttab_init(void)
        for (i--; i >= 0; i--)
                free_page((unsigned long)gnttab_list[i]);
        kfree(gnttab_list);
+       bitmap_free(gnttab_free_bitmap);
        return ret;
 }
 EXPORT_SYMBOL_GPL(gnttab_init);
index 34742c6e189e386a5120ad67667faae3031ab25c..f17c4c03db30c85e72f8c56d48ffb62f61c2a338 100644 (file)
@@ -261,7 +261,6 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(xen_xlate_map_ballooned_pages);
 
 struct remap_pfn {
        struct mm_struct *mm;
index 1c8dc696d516fc925fa93f1f0d33095bd9316eec..cebba4eaa0b575af6305faa19363d18593133ea4 100644 (file)
@@ -62,12 +62,12 @@ void v9fs_cache_inode_get_cookie(struct inode *inode)
        version = cpu_to_le32(v9inode->qid.version);
        path = cpu_to_le64(v9inode->qid.path);
        v9ses = v9fs_inode2v9ses(inode);
-       v9inode->netfs_ctx.cache =
+       v9inode->netfs.cache =
                fscache_acquire_cookie(v9fs_session_cache(v9ses),
                                       0,
                                       &path, sizeof(path),
                                       &version, sizeof(version),
-                                      i_size_read(&v9inode->vfs_inode));
+                                      i_size_read(&v9inode->netfs.inode));
 
        p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
                 inode, v9fs_inode_cookie(v9inode));
index e28ddf763b3b92e3cfecabffa424a97a0731f3cd..0129de2ea31ae514007428c2c9e71188ee405dbf 100644 (file)
@@ -625,7 +625,7 @@ static void v9fs_inode_init_once(void *foo)
        struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
 
        memset(&v9inode->qid, 0, sizeof(v9inode->qid));
-       inode_init_once(&v9inode->vfs_inode);
+       inode_init_once(&v9inode->netfs.inode);
 }
 
 /**
index ec0e8df3b2eb27b1337c5259c635bdf3598205d2..6acabc2e7dc9dd513696dc3948a2fd90d058fd3d 100644 (file)
@@ -109,11 +109,7 @@ struct v9fs_session_info {
 #define V9FS_INO_INVALID_ATTR 0x01
 
 struct v9fs_inode {
-       struct {
-               /* These must be contiguous */
-               struct inode    vfs_inode;      /* the VFS's inode record */
-               struct netfs_i_context netfs_ctx; /* Netfslib context */
-       };
+       struct netfs_inode netfs; /* Netfslib context and vfs inode */
        struct p9_qid qid;
        unsigned int cache_validity;
        struct p9_fid *writeback_fid;
@@ -122,13 +118,13 @@ struct v9fs_inode {
 
 static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
 {
-       return container_of(inode, struct v9fs_inode, vfs_inode);
+       return container_of(inode, struct v9fs_inode, netfs.inode);
 }
 
 static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inode)
 {
 #ifdef CONFIG_9P_FSCACHE
-       return netfs_i_cookie(&v9inode->vfs_inode);
+       return netfs_i_cookie(&v9inode->netfs);
 #else
        return NULL;
 #endif
index 8ce82ff1e40afdabf152b968b3a245f7ef158636..a8f512b44a851d6f9a71d031138a139a6b61dc6e 100644 (file)
@@ -66,13 +66,12 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
 }
 
 /**
- * v9fs_req_cleanup - Cleanup request initialized by v9fs_init_request
- * @mapping: unused mapping of request to cleanup
- * @priv: private data to cleanup, a fid, guaranted non-null.
+ * v9fs_free_request - Cleanup request initialized by v9fs_init_rreq
+ * @rreq: The I/O request to clean up
  */
-static void v9fs_req_cleanup(struct address_space *mapping, void *priv)
+static void v9fs_free_request(struct netfs_io_request *rreq)
 {
-       struct p9_fid *fid = priv;
+       struct p9_fid *fid = rreq->netfs_priv;
 
        p9_client_clunk(fid);
 }
@@ -94,9 +93,9 @@ static int v9fs_begin_cache_operation(struct netfs_io_request *rreq)
 
 const struct netfs_request_ops v9fs_req_ops = {
        .init_request           = v9fs_init_request,
+       .free_request           = v9fs_free_request,
        .begin_cache_operation  = v9fs_begin_cache_operation,
        .issue_read             = v9fs_issue_read,
-       .cleanup                = v9fs_req_cleanup,
 };
 
 /**
@@ -140,7 +139,7 @@ static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error,
            transferred_or_error != -ENOBUFS) {
                version = cpu_to_le32(v9inode->qid.version);
                fscache_invalidate(v9fs_inode_cookie(v9inode), &version,
-                                  i_size_read(&v9inode->vfs_inode), 0);
+                                  i_size_read(&v9inode->netfs.inode), 0);
        }
 }
 
@@ -274,7 +273,7 @@ static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
         * file.  We need to do this before we get a lock on the page in case
         * there's more than one writer competing for the same cache block.
         */
-       retval = netfs_write_begin(filp, mapping, pos, len, &folio, fsdata);
+       retval = netfs_write_begin(&v9inode->netfs, filp, mapping, pos, len, &folio, fsdata);
        if (retval < 0)
                return retval;
 
index 55367ecb9442e0129fe2e9b89778b063d48fc9fa..419d2f3cf2c2633fa7caa46070a30a97078ca2f7 100644 (file)
@@ -234,7 +234,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
        v9inode->writeback_fid = NULL;
        v9inode->cache_validity = 0;
        mutex_init(&v9inode->v_mutex);
-       return &v9inode->vfs_inode;
+       return &v9inode->netfs.inode;
 }
 
 /**
@@ -252,7 +252,8 @@ void v9fs_free_inode(struct inode *inode)
  */
 static void v9fs_set_netfs_context(struct inode *inode)
 {
-       netfs_i_context_init(inode, &v9fs_req_ops);
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       netfs_inode_init(&v9inode->netfs, &v9fs_req_ops);
 }
 
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
index 1b4d5809808d0d232d6a66d1c4a2b74d8bd980f7..a484fa6428081ab6d34bad627bb5d468793a0708 100644 (file)
@@ -30,7 +30,7 @@ void afs_invalidate_mmap_work(struct work_struct *work)
 {
        struct afs_vnode *vnode = container_of(work, struct afs_vnode, cb_work);
 
-       unmap_mapping_pages(vnode->vfs_inode.i_mapping, 0, 0, false);
+       unmap_mapping_pages(vnode->netfs.inode.i_mapping, 0, 0, false);
 }
 
 void afs_server_init_callback_work(struct work_struct *work)
index 79f6b74336d28bb4b4d14189455f8989b2477552..56ae5cd5184f08c4f5757face83a8cb870d7cd7d 100644 (file)
@@ -109,7 +109,7 @@ struct afs_lookup_cookie {
  */
 static void afs_dir_read_cleanup(struct afs_read *req)
 {
-       struct address_space *mapping = req->vnode->vfs_inode.i_mapping;
+       struct address_space *mapping = req->vnode->netfs.inode.i_mapping;
        struct folio *folio;
        pgoff_t last = req->nr_pages - 1;
 
@@ -153,7 +153,7 @@ static bool afs_dir_check_folio(struct afs_vnode *dvnode, struct folio *folio,
                block = kmap_local_folio(folio, offset);
                if (block->hdr.magic != AFS_DIR_MAGIC) {
                        printk("kAFS: %s(%lx): [%llx] bad magic %zx/%zx is %04hx\n",
-                              __func__, dvnode->vfs_inode.i_ino,
+                              __func__, dvnode->netfs.inode.i_ino,
                               pos, offset, size, ntohs(block->hdr.magic));
                        trace_afs_dir_check_failed(dvnode, pos + offset, i_size);
                        kunmap_local(block);
@@ -183,7 +183,7 @@ error:
 static void afs_dir_dump(struct afs_vnode *dvnode, struct afs_read *req)
 {
        union afs_xdr_dir_block *block;
-       struct address_space *mapping = dvnode->vfs_inode.i_mapping;
+       struct address_space *mapping = dvnode->netfs.inode.i_mapping;
        struct folio *folio;
        pgoff_t last = req->nr_pages - 1;
        size_t offset, size;
@@ -217,7 +217,7 @@ static void afs_dir_dump(struct afs_vnode *dvnode, struct afs_read *req)
  */
 static int afs_dir_check(struct afs_vnode *dvnode, struct afs_read *req)
 {
-       struct address_space *mapping = dvnode->vfs_inode.i_mapping;
+       struct address_space *mapping = dvnode->netfs.inode.i_mapping;
        struct folio *folio;
        pgoff_t last = req->nr_pages - 1;
        int ret = 0;
@@ -269,7 +269,7 @@ static int afs_dir_open(struct inode *inode, struct file *file)
 static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
        __acquires(&dvnode->validate_lock)
 {
-       struct address_space *mapping = dvnode->vfs_inode.i_mapping;
+       struct address_space *mapping = dvnode->netfs.inode.i_mapping;
        struct afs_read *req;
        loff_t i_size;
        int nr_pages, i;
@@ -287,7 +287,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
        req->cleanup = afs_dir_read_cleanup;
 
 expand:
-       i_size = i_size_read(&dvnode->vfs_inode);
+       i_size = i_size_read(&dvnode->netfs.inode);
        if (i_size < 2048) {
                ret = afs_bad(dvnode, afs_file_error_dir_small);
                goto error;
@@ -305,7 +305,7 @@ expand:
        req->actual_len = i_size; /* May change */
        req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */
        req->data_version = dvnode->status.data_version; /* May change */
-       iov_iter_xarray(&req->def_iter, READ, &dvnode->vfs_inode.i_mapping->i_pages,
+       iov_iter_xarray(&req->def_iter, READ, &dvnode->netfs.inode.i_mapping->i_pages,
                        0, i_size);
        req->iter = &req->def_iter;
 
@@ -897,7 +897,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
 
 out_op:
        if (op->error == 0) {
-               inode = &op->file[1].vnode->vfs_inode;
+               inode = &op->file[1].vnode->netfs.inode;
                op->file[1].vnode = NULL;
        }
 
@@ -1139,7 +1139,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
        afs_stat_v(dir, n_reval);
 
        /* search the directory for this vnode */
-       ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key, &dir_version);
+       ret = afs_do_lookup_one(&dir->netfs.inode, dentry, &fid, key, &dir_version);
        switch (ret) {
        case 0:
                /* the filename maps to something */
@@ -1170,7 +1170,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
                        _debug("%pd: file deleted (uq %u -> %u I:%u)",
                               dentry, fid.unique,
                               vnode->fid.unique,
-                              vnode->vfs_inode.i_generation);
+                              vnode->netfs.inode.i_generation);
                        goto not_found;
                }
                goto out_valid;
@@ -1368,7 +1368,7 @@ static void afs_dir_remove_subdir(struct dentry *dentry)
        if (d_really_is_positive(dentry)) {
                struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
 
-               clear_nlink(&vnode->vfs_inode);
+               clear_nlink(&vnode->netfs.inode);
                set_bit(AFS_VNODE_DELETED, &vnode->flags);
                clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
                clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
@@ -1487,8 +1487,8 @@ static void afs_dir_remove_link(struct afs_operation *op)
                /* Already done */
        } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {
                write_seqlock(&vnode->cb_lock);
-               drop_nlink(&vnode->vfs_inode);
-               if (vnode->vfs_inode.i_nlink == 0) {
+               drop_nlink(&vnode->netfs.inode);
+               if (vnode->netfs.inode.i_nlink == 0) {
                        set_bit(AFS_VNODE_DELETED, &vnode->flags);
                        __afs_break_callback(vnode, afs_cb_break_for_unlink);
                }
@@ -1504,7 +1504,7 @@ static void afs_dir_remove_link(struct afs_operation *op)
                        op->error = ret;
        }
 
-       _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, op->error);
+       _debug("nlink %d [val %d]", vnode->netfs.inode.i_nlink, op->error);
 }
 
 static void afs_unlink_success(struct afs_operation *op)
@@ -1680,8 +1680,8 @@ static void afs_link_success(struct afs_operation *op)
        afs_update_dentry_version(op, dvp, op->dentry);
        if (op->dentry_2->d_parent == op->dentry->d_parent)
                afs_update_dentry_version(op, dvp, op->dentry_2);
-       ihold(&vp->vnode->vfs_inode);
-       d_instantiate(op->dentry, &vp->vnode->vfs_inode);
+       ihold(&vp->vnode->netfs.inode);
+       d_instantiate(op->dentry, &vp->vnode->netfs.inode);
 }
 
 static void afs_link_put(struct afs_operation *op)
index d98e109ecee9a3ef6d9c7a04e801f8f39b791078..0ab7752d1b758e7bd593bfe44faf04bf43951f0b 100644 (file)
@@ -109,7 +109,7 @@ static void afs_clear_contig_bits(union afs_xdr_dir_block *block,
  */
 static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index)
 {
-       struct address_space *mapping = vnode->vfs_inode.i_mapping;
+       struct address_space *mapping = vnode->netfs.inode.i_mapping;
        struct folio *folio;
 
        folio = __filemap_get_folio(mapping, index,
@@ -216,7 +216,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode,
 
        _enter(",,{%d,%s},", name->len, name->name);
 
-       i_size = i_size_read(&vnode->vfs_inode);
+       i_size = i_size_read(&vnode->netfs.inode);
        if (i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
            (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
                clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
@@ -336,7 +336,7 @@ found_space:
        if (b < AFS_DIR_BLOCKS_WITH_CTR)
                meta->meta.alloc_ctrs[b] -= need_slots;
 
-       inode_inc_iversion_raw(&vnode->vfs_inode);
+       inode_inc_iversion_raw(&vnode->netfs.inode);
        afs_stat_v(vnode, n_dir_cr);
        _debug("Insert %s in %u[%u]", name->name, b, slot);
 
@@ -383,7 +383,7 @@ void afs_edit_dir_remove(struct afs_vnode *vnode,
 
        _enter(",,{%d,%s},", name->len, name->name);
 
-       i_size = i_size_read(&vnode->vfs_inode);
+       i_size = i_size_read(&vnode->netfs.inode);
        if (i_size < AFS_DIR_BLOCK_SIZE ||
            i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
            (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
@@ -463,7 +463,7 @@ found_dirent:
        if (b < AFS_DIR_BLOCKS_WITH_CTR)
                meta->meta.alloc_ctrs[b] += need_slots;
 
-       inode_set_iversion_raw(&vnode->vfs_inode, vnode->status.data_version);
+       inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version);
        afs_stat_v(vnode, n_dir_rm);
        _debug("Remove %s from %u[%u]", name->name, b, slot);
 
index 45cfd50a95210b95375f1df9a44db34aabc3bb0c..bb5807e87fa4c430d6be36f6e1754aa62f5c11b9 100644 (file)
@@ -131,7 +131,7 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode,
                        goto out;
        } while (!d_is_negative(sdentry));
 
-       ihold(&vnode->vfs_inode);
+       ihold(&vnode->netfs.inode);
 
        ret = afs_do_silly_rename(dvnode, vnode, dentry, sdentry, key);
        switch (ret) {
@@ -148,7 +148,7 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode,
                d_drop(sdentry);
        }
 
-       iput(&vnode->vfs_inode);
+       iput(&vnode->netfs.inode);
        dput(sdentry);
 out:
        _leave(" = %d", ret);
index f120bcb8bf738d6434179bd0dfa7da1fd4fef243..d7d9402ff7182adfb702a4bc473ce0db3d3aa2ac 100644 (file)
@@ -76,7 +76,7 @@ struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
        /* there shouldn't be an existing inode */
        BUG_ON(!(inode->i_state & I_NEW));
 
-       netfs_i_context_init(inode, NULL);
+       netfs_inode_init(&vnode->netfs, NULL);
        inode->i_size           = 0;
        inode->i_mode           = S_IFDIR | S_IRUGO | S_IXUGO;
        if (root) {
index a8e8832179e4e5438b82220d4773c04a6efff887..42118a4f338331433af660cd9464c43e1cc8b03b 100644 (file)
@@ -194,7 +194,7 @@ int afs_release(struct inode *inode, struct file *file)
                afs_put_wb_key(af->wb);
 
        if ((file->f_mode & FMODE_WRITE)) {
-               i_size = i_size_read(&vnode->vfs_inode);
+               i_size = i_size_read(&vnode->netfs.inode);
                afs_set_cache_aux(vnode, &aux);
                fscache_unuse_cookie(afs_vnode_cache(vnode), &aux, &i_size);
        } else {
@@ -325,7 +325,7 @@ static void afs_issue_read(struct netfs_io_subrequest *subreq)
        fsreq->iter     = &fsreq->def_iter;
 
        iov_iter_xarray(&fsreq->def_iter, READ,
-                       &fsreq->vnode->vfs_inode.i_mapping->i_pages,
+                       &fsreq->vnode->netfs.inode.i_mapping->i_pages,
                        fsreq->pos, fsreq->len);
 
        afs_fetch_data(fsreq->vnode, fsreq);
@@ -382,17 +382,17 @@ static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
        return test_bit(AFS_VNODE_DELETED, &vnode->flags) ? -ESTALE : 0;
 }
 
-static void afs_priv_cleanup(struct address_space *mapping, void *netfs_priv)
+static void afs_free_request(struct netfs_io_request *rreq)
 {
-       key_put(netfs_priv);
+       key_put(rreq->netfs_priv);
 }
 
 const struct netfs_request_ops afs_req_ops = {
        .init_request           = afs_init_request,
+       .free_request           = afs_free_request,
        .begin_cache_operation  = afs_begin_cache_operation,
        .check_write_begin      = afs_check_write_begin,
        .issue_read             = afs_issue_read,
-       .cleanup                = afs_priv_cleanup,
 };
 
 int afs_write_inode(struct inode *inode, struct writeback_control *wbc)
index d222dfbe976be58af90743bf8367db8c3ee63608..7a3803ce3a22970786699436763bc0925144cfb9 100644 (file)
@@ -232,14 +232,14 @@ int afs_put_operation(struct afs_operation *op)
        if (op->file[1].modification && op->file[1].vnode != op->file[0].vnode)
                clear_bit(AFS_VNODE_MODIFYING, &op->file[1].vnode->flags);
        if (op->file[0].put_vnode)
-               iput(&op->file[0].vnode->vfs_inode);
+               iput(&op->file[0].vnode->netfs.inode);
        if (op->file[1].put_vnode)
-               iput(&op->file[1].vnode->vfs_inode);
+               iput(&op->file[1].vnode->netfs.inode);
 
        if (op->more_files) {
                for (i = 0; i < op->nr_files - 2; i++)
                        if (op->more_files[i].put_vnode)
-                               iput(&op->more_files[i].vnode->vfs_inode);
+                               iput(&op->more_files[i].vnode->netfs.inode);
                kfree(op->more_files);
        }
 
index 30b066299d39f70a450539823dbe75602427e81a..89630acbc2cc5410ae0d326c29e45b49f5041a98 100644 (file)
@@ -58,7 +58,7 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren
  */
 static void afs_set_netfs_context(struct afs_vnode *vnode)
 {
-       netfs_i_context_init(&vnode->vfs_inode, &afs_req_ops);
+       netfs_inode_init(&vnode->netfs, &afs_req_ops);
 }
 
 /*
@@ -96,7 +96,7 @@ static int afs_inode_init_from_status(struct afs_operation *op,
        inode->i_flags |= S_NOATIME;
        inode->i_uid = make_kuid(&init_user_ns, status->owner);
        inode->i_gid = make_kgid(&init_user_ns, status->group);
-       set_nlink(&vnode->vfs_inode, status->nlink);
+       set_nlink(&vnode->netfs.inode, status->nlink);
 
        switch (status->type) {
        case AFS_FTYPE_FILE:
@@ -139,7 +139,7 @@ static int afs_inode_init_from_status(struct afs_operation *op,
        afs_set_netfs_context(vnode);
 
        vnode->invalid_before   = status->data_version;
-       inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
+       inode_set_iversion_raw(&vnode->netfs.inode, status->data_version);
 
        if (!vp->scb.have_cb) {
                /* it's a symlink we just created (the fileserver
@@ -163,7 +163,7 @@ static void afs_apply_status(struct afs_operation *op,
 {
        struct afs_file_status *status = &vp->scb.status;
        struct afs_vnode *vnode = vp->vnode;
-       struct inode *inode = &vnode->vfs_inode;
+       struct inode *inode = &vnode->netfs.inode;
        struct timespec64 t;
        umode_t mode;
        bool data_changed = false;
@@ -246,7 +246,7 @@ static void afs_apply_status(struct afs_operation *op,
                 * idea of what the size should be that's not the same as
                 * what's on the server.
                 */
-               vnode->netfs_ctx.remote_i_size = status->size;
+               vnode->netfs.remote_i_size = status->size;
                if (change_size) {
                        afs_set_i_size(vnode, status->size);
                        inode->i_ctime = t;
@@ -289,7 +289,7 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v
                 */
                if (vp->scb.status.abort_code == VNOVNODE) {
                        set_bit(AFS_VNODE_DELETED, &vnode->flags);
-                       clear_nlink(&vnode->vfs_inode);
+                       clear_nlink(&vnode->netfs.inode);
                        __afs_break_callback(vnode, afs_cb_break_for_deleted);
                        op->flags &= ~AFS_OPERATION_DIR_CONFLICT;
                }
@@ -306,8 +306,8 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v
                if (vp->scb.have_cb)
                        afs_apply_callback(op, vp);
        } else if (vp->op_unlinked && !(op->flags & AFS_OPERATION_DIR_CONFLICT)) {
-               drop_nlink(&vnode->vfs_inode);
-               if (vnode->vfs_inode.i_nlink == 0) {
+               drop_nlink(&vnode->netfs.inode);
+               if (vnode->netfs.inode.i_nlink == 0) {
                        set_bit(AFS_VNODE_DELETED, &vnode->flags);
                        __afs_break_callback(vnode, afs_cb_break_for_deleted);
                }
@@ -326,7 +326,7 @@ static void afs_fetch_status_success(struct afs_operation *op)
        struct afs_vnode *vnode = vp->vnode;
        int ret;
 
-       if (vnode->vfs_inode.i_state & I_NEW) {
+       if (vnode->netfs.inode.i_state & I_NEW) {
                ret = afs_inode_init_from_status(op, vp, vnode);
                op->error = ret;
                if (ret == 0)
@@ -430,7 +430,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
        struct afs_vnode_cache_aux aux;
 
        if (vnode->status.type != AFS_FTYPE_FILE) {
-               vnode->netfs_ctx.cache = NULL;
+               vnode->netfs.cache = NULL;
                return;
        }
 
@@ -457,7 +457,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
 struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp)
 {
        struct afs_vnode_param *dvp = &op->file[0];
-       struct super_block *sb = dvp->vnode->vfs_inode.i_sb;
+       struct super_block *sb = dvp->vnode->netfs.inode.i_sb;
        struct afs_vnode *vnode;
        struct inode *inode;
        int ret;
@@ -582,10 +582,10 @@ static void afs_zap_data(struct afs_vnode *vnode)
        /* nuke all the non-dirty pages that aren't locked, mapped or being
         * written back in a regular file and completely discard the pages in a
         * directory or symlink */
-       if (S_ISREG(vnode->vfs_inode.i_mode))
-               invalidate_remote_inode(&vnode->vfs_inode);
+       if (S_ISREG(vnode->netfs.inode.i_mode))
+               invalidate_remote_inode(&vnode->netfs.inode);
        else
-               invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
+               invalidate_inode_pages2(vnode->netfs.inode.i_mapping);
 }
 
 /*
@@ -683,8 +683,8 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
               key_serial(key));
 
        if (unlikely(test_bit(AFS_VNODE_DELETED, &vnode->flags))) {
-               if (vnode->vfs_inode.i_nlink)
-                       clear_nlink(&vnode->vfs_inode);
+               if (vnode->netfs.inode.i_nlink)
+                       clear_nlink(&vnode->netfs.inode);
                goto valid;
        }
 
@@ -826,7 +826,7 @@ void afs_evict_inode(struct inode *inode)
 static void afs_setattr_success(struct afs_operation *op)
 {
        struct afs_vnode_param *vp = &op->file[0];
-       struct inode *inode = &vp->vnode->vfs_inode;
+       struct inode *inode = &vp->vnode->netfs.inode;
        loff_t old_i_size = i_size_read(inode);
 
        op->setattr.old_i_size = old_i_size;
@@ -843,7 +843,7 @@ static void afs_setattr_success(struct afs_operation *op)
 static void afs_setattr_edit_file(struct afs_operation *op)
 {
        struct afs_vnode_param *vp = &op->file[0];
-       struct inode *inode = &vp->vnode->vfs_inode;
+       struct inode *inode = &vp->vnode->netfs.inode;
 
        if (op->setattr.attr->ia_valid & ATTR_SIZE) {
                loff_t size = op->setattr.attr->ia_size;
@@ -875,7 +875,7 @@ int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
                ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET | ATTR_TOUCH;
        struct afs_operation *op;
        struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
-       struct inode *inode = &vnode->vfs_inode;
+       struct inode *inode = &vnode->netfs.inode;
        loff_t i_size;
        int ret;
 
index a30995901266fd4379107a551847c0209d8a6cdf..a6f25d9e75b52a5ab0c5a59b363e3108875d8f3c 100644 (file)
@@ -619,12 +619,7 @@ enum afs_lock_state {
  * leak from one inode to another.
  */
 struct afs_vnode {
-       struct {
-               /* These must be contiguous */
-               struct inode    vfs_inode;      /* the VFS's inode record */
-               struct netfs_i_context netfs_ctx; /* Netfslib context */
-       };
-
+       struct netfs_inode      netfs;          /* Netfslib context and vfs inode */
        struct afs_volume       *volume;        /* volume on which vnode resides */
        struct afs_fid          fid;            /* the file identifier for this inode */
        struct afs_file_status  status;         /* AFS status info for this file */
@@ -675,7 +670,7 @@ struct afs_vnode {
 static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode)
 {
 #ifdef CONFIG_AFS_FSCACHE
-       return netfs_i_cookie(&vnode->vfs_inode);
+       return netfs_i_cookie(&vnode->netfs);
 #else
        return NULL;
 #endif
@@ -685,7 +680,7 @@ static inline void afs_vnode_set_cache(struct afs_vnode *vnode,
                                       struct fscache_cookie *cookie)
 {
 #ifdef CONFIG_AFS_FSCACHE
-       vnode->netfs_ctx.cache = cookie;
+       vnode->netfs.cache = cookie;
 #endif
 }
 
@@ -892,7 +887,7 @@ static inline void afs_invalidate_cache(struct afs_vnode *vnode, unsigned int fl
 
        afs_set_cache_aux(vnode, &aux);
        fscache_invalidate(afs_vnode_cache(vnode), &aux,
-                          i_size_read(&vnode->vfs_inode), flags);
+                          i_size_read(&vnode->netfs.inode), flags);
 }
 
 /*
@@ -1217,7 +1212,7 @@ static inline struct afs_net *afs_i2net(struct inode *inode)
 
 static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
 {
-       return afs_i2net(&vnode->vfs_inode);
+       return afs_i2net(&vnode->netfs.inode);
 }
 
 static inline struct afs_net *afs_sock2net(struct sock *sk)
@@ -1593,12 +1588,12 @@ extern void yfs_fs_store_opaque_acl2(struct afs_operation *);
  */
 static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
 {
-       return container_of(inode, struct afs_vnode, vfs_inode);
+       return container_of(inode, struct afs_vnode, netfs.inode);
 }
 
 static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode)
 {
-       return &vnode->vfs_inode;
+       return &vnode->netfs.inode;
 }
 
 /*
@@ -1621,8 +1616,8 @@ static inline void afs_update_dentry_version(struct afs_operation *op,
  */
 static inline void afs_set_i_size(struct afs_vnode *vnode, u64 size)
 {
-       i_size_write(&vnode->vfs_inode, size);
-       vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1;
+       i_size_write(&vnode->netfs.inode, size);
+       vnode->netfs.inode.i_blocks = ((size + 1023) >> 10) << 1;
 }
 
 /*
index 1fea195b0b2750d7d5282dddff4b80c7b96ef720..95d713074dc8130125e55da2cd4e19b693682f8f 100644 (file)
@@ -659,7 +659,7 @@ static void afs_i_init_once(void *_vnode)
        struct afs_vnode *vnode = _vnode;
 
        memset(vnode, 0, sizeof(*vnode));
-       inode_init_once(&vnode->vfs_inode);
+       inode_init_once(&vnode->netfs.inode);
        mutex_init(&vnode->io_lock);
        init_rwsem(&vnode->validate_lock);
        spin_lock_init(&vnode->wb_lock);
@@ -700,8 +700,8 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
        init_rwsem(&vnode->rmdir_lock);
        INIT_WORK(&vnode->cb_work, afs_invalidate_mmap_work);
 
-       _leave(" = %p", &vnode->vfs_inode);
-       return &vnode->vfs_inode;
+       _leave(" = %p", &vnode->netfs.inode);
+       return &vnode->netfs.inode;
 }
 
 static void afs_free_inode(struct inode *inode)
index 94a3d247924bce49a91851f25fae45c9f7c72b84..cc665cef0abe4cd9f8ac91315be1bda91f9b2282 100644 (file)
@@ -9,8 +9,7 @@
 #include <linux/slab.h>
 #include "internal.h"
 
-unsigned __read_mostly afs_volume_gc_delay = 10;
-unsigned __read_mostly afs_volume_record_life = 60 * 60;
+static unsigned __read_mostly afs_volume_record_life = 60 * 60;
 
 /*
  * Insert a volume into a cell.  If there's an existing volume record, that is
index 2236b2165e375dc20f195cc49d8e11572d47aa54..2c885b22de34feffc2d34a80151d58631b134a70 100644 (file)
@@ -60,7 +60,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
         * file.  We need to do this before we get a lock on the page in case
         * there's more than one writer competing for the same cache block.
         */
-       ret = netfs_write_begin(file, mapping, pos, len, &folio, fsdata);
+       ret = netfs_write_begin(&vnode->netfs, file, mapping, pos, len, &folio, fsdata);
        if (ret < 0)
                return ret;
 
@@ -146,10 +146,10 @@ int afs_write_end(struct file *file, struct address_space *mapping,
 
        write_end_pos = pos + copied;
 
-       i_size = i_size_read(&vnode->vfs_inode);
+       i_size = i_size_read(&vnode->netfs.inode);
        if (write_end_pos > i_size) {
                write_seqlock(&vnode->cb_lock);
-               i_size = i_size_read(&vnode->vfs_inode);
+               i_size = i_size_read(&vnode->netfs.inode);
                if (write_end_pos > i_size)
                        afs_set_i_size(vnode, write_end_pos);
                write_sequnlock(&vnode->cb_lock);
@@ -257,7 +257,7 @@ static void afs_redirty_pages(struct writeback_control *wbc,
  */
 static void afs_pages_written_back(struct afs_vnode *vnode, loff_t start, unsigned int len)
 {
-       struct address_space *mapping = vnode->vfs_inode.i_mapping;
+       struct address_space *mapping = vnode->netfs.inode.i_mapping;
        struct folio *folio;
        pgoff_t end;
 
@@ -354,7 +354,6 @@ static const struct afs_operation_ops afs_store_data_operation = {
 static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t pos,
                          bool laundering)
 {
-       struct netfs_i_context *ictx = &vnode->netfs_ctx;
        struct afs_operation *op;
        struct afs_wb_key *wbk = NULL;
        loff_t size = iov_iter_count(iter);
@@ -385,9 +384,9 @@ static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t
        op->store.write_iter = iter;
        op->store.pos = pos;
        op->store.size = size;
-       op->store.i_size = max(pos + size, ictx->remote_i_size);
+       op->store.i_size = max(pos + size, vnode->netfs.remote_i_size);
        op->store.laundering = laundering;
-       op->mtime = vnode->vfs_inode.i_mtime;
+       op->mtime = vnode->netfs.inode.i_mtime;
        op->flags |= AFS_OPERATION_UNINTR;
        op->ops = &afs_store_data_operation;
 
@@ -554,7 +553,7 @@ static ssize_t afs_write_back_from_locked_folio(struct address_space *mapping,
        struct iov_iter iter;
        unsigned long priv;
        unsigned int offset, to, len, max_len;
-       loff_t i_size = i_size_read(&vnode->vfs_inode);
+       loff_t i_size = i_size_read(&vnode->netfs.inode);
        bool new_content = test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
        bool caching = fscache_cookie_enabled(afs_vnode_cache(vnode));
        long count = wbc->nr_to_write;
@@ -845,7 +844,7 @@ ssize_t afs_file_write(struct kiocb *iocb, struct iov_iter *from)
        _enter("{%llx:%llu},{%zu},",
               vnode->fid.vid, vnode->fid.vnode, count);
 
-       if (IS_SWAPFILE(&vnode->vfs_inode)) {
+       if (IS_SWAPFILE(&vnode->netfs.inode)) {
                printk(KERN_INFO
                       "AFS: Attempt to write to active swap file!\n");
                return -EBUSY;
@@ -958,8 +957,8 @@ void afs_prune_wb_keys(struct afs_vnode *vnode)
        /* Discard unused keys */
        spin_lock(&vnode->wb_lock);
 
-       if (!mapping_tagged(&vnode->vfs_inode.i_data, PAGECACHE_TAG_WRITEBACK) &&
-           !mapping_tagged(&vnode->vfs_inode.i_data, PAGECACHE_TAG_DIRTY)) {
+       if (!mapping_tagged(&vnode->netfs.inode.i_data, PAGECACHE_TAG_WRITEBACK) &&
+           !mapping_tagged(&vnode->netfs.inode.i_data, PAGECACHE_TAG_DIRTY)) {
                list_for_each_entry_safe(wbk, tmp, &vnode->wb_keys, vnode_link) {
                        if (refcount_read(&wbk->usage) == 1)
                                list_move(&wbk->vnode_link, &graveyard);
@@ -1034,6 +1033,6 @@ static void afs_write_to_cache(struct afs_vnode *vnode,
                               bool caching)
 {
        fscache_write_to_cache(afs_vnode_cache(vnode),
-                              vnode->vfs_inode.i_mapping, start, len, i_size,
+                              vnode->netfs.inode.i_mapping, start, len, i_size,
                               afs_write_to_cache_done, vnode, caching);
 }
index 66899b6e9bd86117f4330a3add56399d888dfa05..dbe996b0dedfcf78a91c077b9ee51d132a73d8d1 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -61,9 +61,15 @@ static bool chgrp_ok(struct user_namespace *mnt_userns,
                     const struct inode *inode, kgid_t gid)
 {
        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, inode->i_gid)))
-               return true;
+       if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode))) {
+               kgid_t mapped_gid;
+
+               if (gid_eq(gid, inode->i_gid))
+                       return true;
+               mapped_gid = mapped_kgid_fs(mnt_userns, i_user_ns(inode), gid);
+               if (in_group_p(mapped_gid))
+                       return true;
+       }
        if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
                return true;
        if (gid_eq(kgid, INVALID_GID) &&
@@ -123,12 +129,20 @@ int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry,
 
        /* Make sure a caller can chmod. */
        if (ia_valid & ATTR_MODE) {
+               kgid_t mapped_gid;
+
                if (!inode_owner_or_capable(mnt_userns, inode))
                        return -EPERM;
+
+               if (ia_valid & ATTR_GID)
+                       mapped_gid = mapped_kgid_fs(mnt_userns,
+                                               i_user_ns(inode), attr->ia_gid);
+               else
+                       mapped_gid = i_gid_into_mnt(mnt_userns, inode);
+
                /* Also check the setgid bit! */
-               if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
-                                i_gid_into_mnt(mnt_userns, inode)) &&
-                    !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
+               if (!in_group_p(mapped_gid) &&
+                   !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
                        attr->ia_mode &= ~S_ISGID;
        }
 
index e5221be6eb555bb317a2fef2692853aefc05644d..6dee88815491c869364ee223dcaed0a0f1ff7492 100644 (file)
@@ -394,11 +394,10 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file)
        return 0;
 }
 
-static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
+static void ceph_netfs_free_request(struct netfs_io_request *rreq)
 {
-       struct inode *inode = mapping->host;
-       struct ceph_inode_info *ci = ceph_inode(inode);
-       int got = (uintptr_t)priv;
+       struct ceph_inode_info *ci = ceph_inode(rreq->inode);
+       int got = (uintptr_t)rreq->netfs_priv;
 
        if (got)
                ceph_put_cap_refs(ci, got);
@@ -406,12 +405,12 @@ static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
 
 const struct netfs_request_ops ceph_netfs_ops = {
        .init_request           = ceph_init_request,
+       .free_request           = ceph_netfs_free_request,
        .begin_cache_operation  = ceph_begin_cache_operation,
        .issue_read             = ceph_netfs_issue_read,
        .expand_readahead       = ceph_netfs_expand_readahead,
        .clamp_length           = ceph_netfs_clamp_length,
        .check_write_begin      = ceph_netfs_check_write_begin,
-       .cleanup                = ceph_readahead_cleanup,
 };
 
 #ifdef CONFIG_CEPH_FSCACHE
@@ -1322,10 +1321,11 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
                            struct page **pagep, void **fsdata)
 {
        struct inode *inode = file_inode(file);
+       struct ceph_inode_info *ci = ceph_inode(inode);
        struct folio *folio = NULL;
        int r;
 
-       r = netfs_write_begin(file, inode->i_mapping, pos, len, &folio, NULL);
+       r = netfs_write_begin(&ci->netfs, file, inode->i_mapping, pos, len, &folio, NULL);
        if (r == 0)
                folio_wait_fscache(folio);
        if (r < 0) {
@@ -1798,7 +1798,7 @@ enum {
 static int __ceph_pool_perm_get(struct ceph_inode_info *ci,
                                s64 pool, struct ceph_string *pool_ns)
 {
-       struct ceph_fs_client *fsc = ceph_inode_to_client(&ci->vfs_inode);
+       struct ceph_fs_client *fsc = ceph_inode_to_client(&ci->netfs.inode);
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct ceph_osd_request *rd_req = NULL, *wr_req = NULL;
        struct rb_node **p, *parent;
@@ -1913,7 +1913,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci,
                                     0, false, true);
        err = ceph_osdc_start_request(&fsc->client->osdc, rd_req, false);
 
-       wr_req->r_mtime = ci->vfs_inode.i_mtime;
+       wr_req->r_mtime = ci->netfs.inode.i_mtime;
        err2 = ceph_osdc_start_request(&fsc->client->osdc, wr_req, false);
 
        if (!err)
index ddea999220739aaf49770c1cb1e7bc77ee2358fa..177d8e8d73fe424a412be19635e1f99b37b2e1b3 100644 (file)
@@ -29,9 +29,9 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
        if (!(inode->i_state & I_NEW))
                return;
 
-       WARN_ON_ONCE(ci->netfs_ctx.cache);
+       WARN_ON_ONCE(ci->netfs.cache);
 
-       ci->netfs_ctx.cache =
+       ci->netfs.cache =
                fscache_acquire_cookie(fsc->fscache, 0,
                                       &ci->i_vino, sizeof(ci->i_vino),
                                       &ci->i_version, sizeof(ci->i_version),
index 7255b790a4c1c579827223d4b5493f204a24e053..dc502daac49ab580380deca8f969b3f648a4c299 100644 (file)
@@ -28,7 +28,7 @@ void ceph_fscache_invalidate(struct inode *inode, bool dio_write);
 
 static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci)
 {
-       return netfs_i_cookie(&ci->vfs_inode);
+       return netfs_i_cookie(&ci->netfs);
 }
 
 static inline void ceph_fscache_resize(struct inode *inode, loff_t to)
index bf2e9400559842610304e8ad05af28c2e203d12d..38c930384d417dc33ab527546b46fef858d9268d 100644 (file)
@@ -492,7 +492,7 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
        struct ceph_mount_options *opt = mdsc->fsc->mount_options;
        ci->i_hold_caps_max = round_jiffies(jiffies +
                                            opt->caps_wanted_delay_max * HZ);
-       dout("__cap_set_timeouts %p %lu\n", &ci->vfs_inode,
+       dout("__cap_set_timeouts %p %lu\n", &ci->netfs.inode,
             ci->i_hold_caps_max - jiffies);
 }
 
@@ -507,7 +507,7 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
 static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
                                struct ceph_inode_info *ci)
 {
-       dout("__cap_delay_requeue %p flags 0x%lx at %lu\n", &ci->vfs_inode,
+       dout("__cap_delay_requeue %p flags 0x%lx at %lu\n", &ci->netfs.inode,
             ci->i_ceph_flags, ci->i_hold_caps_max);
        if (!mdsc->stopping) {
                spin_lock(&mdsc->cap_delay_lock);
@@ -531,7 +531,7 @@ no_change:
 static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc,
                                      struct ceph_inode_info *ci)
 {
-       dout("__cap_delay_requeue_front %p\n", &ci->vfs_inode);
+       dout("__cap_delay_requeue_front %p\n", &ci->netfs.inode);
        spin_lock(&mdsc->cap_delay_lock);
        ci->i_ceph_flags |= CEPH_I_FLUSH;
        if (!list_empty(&ci->i_cap_delay_list))
@@ -548,7 +548,7 @@ static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc,
 static void __cap_delay_cancel(struct ceph_mds_client *mdsc,
                               struct ceph_inode_info *ci)
 {
-       dout("__cap_delay_cancel %p\n", &ci->vfs_inode);
+       dout("__cap_delay_cancel %p\n", &ci->netfs.inode);
        if (list_empty(&ci->i_cap_delay_list))
                return;
        spin_lock(&mdsc->cap_delay_lock);
@@ -568,7 +568,7 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
         * Each time we receive FILE_CACHE anew, we increment
         * i_rdcache_gen.
         */
-       if (S_ISREG(ci->vfs_inode.i_mode) &&
+       if (S_ISREG(ci->netfs.inode.i_mode) &&
            (issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
            (had & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0) {
                ci->i_rdcache_gen++;
@@ -583,14 +583,14 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
        if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) {
                if (issued & CEPH_CAP_FILE_SHARED)
                        atomic_inc(&ci->i_shared_gen);
-               if (S_ISDIR(ci->vfs_inode.i_mode)) {
-                       dout(" marking %p NOT complete\n", &ci->vfs_inode);
+               if (S_ISDIR(ci->netfs.inode.i_mode)) {
+                       dout(" marking %p NOT complete\n", &ci->netfs.inode);
                        __ceph_dir_clear_complete(ci);
                }
        }
 
        /* Wipe saved layout if we're losing DIR_CREATE caps */
-       if (S_ISDIR(ci->vfs_inode.i_mode) && (had & CEPH_CAP_DIR_CREATE) &&
+       if (S_ISDIR(ci->netfs.inode.i_mode) && (had & CEPH_CAP_DIR_CREATE) &&
                !(issued & CEPH_CAP_DIR_CREATE)) {
             ceph_put_string(rcu_dereference_raw(ci->i_cached_layout.pool_ns));
             memset(&ci->i_cached_layout, 0, sizeof(ci->i_cached_layout));
@@ -771,7 +771,7 @@ static int __cap_is_valid(struct ceph_cap *cap)
 
        if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) {
                dout("__cap_is_valid %p cap %p issued %s "
-                    "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode,
+                    "but STALE (gen %u vs %u)\n", &cap->ci->netfs.inode,
                     cap, ceph_cap_string(cap->issued), cap->cap_gen, gen);
                return 0;
        }
@@ -797,7 +797,7 @@ int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented)
                if (!__cap_is_valid(cap))
                        continue;
                dout("__ceph_caps_issued %p cap %p issued %s\n",
-                    &ci->vfs_inode, cap, ceph_cap_string(cap->issued));
+                    &ci->netfs.inode, cap, ceph_cap_string(cap->issued));
                have |= cap->issued;
                if (implemented)
                        *implemented |= cap->implemented;
@@ -844,12 +844,12 @@ static void __touch_cap(struct ceph_cap *cap)
 
        spin_lock(&s->s_cap_lock);
        if (!s->s_cap_iterator) {
-               dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
+               dout("__touch_cap %p cap %p mds%d\n", &cap->ci->netfs.inode, cap,
                     s->s_mds);
                list_move_tail(&cap->session_caps, &s->s_caps);
        } else {
                dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n",
-                    &cap->ci->vfs_inode, cap, s->s_mds);
+                    &cap->ci->netfs.inode, cap, s->s_mds);
        }
        spin_unlock(&s->s_cap_lock);
 }
@@ -867,7 +867,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
 
        if ((have & mask) == mask) {
                dout("__ceph_caps_issued_mask ino 0x%llx snap issued %s"
-                    " (mask %s)\n", ceph_ino(&ci->vfs_inode),
+                    " (mask %s)\n", ceph_ino(&ci->netfs.inode),
                     ceph_cap_string(have),
                     ceph_cap_string(mask));
                return 1;
@@ -879,7 +879,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
                        continue;
                if ((cap->issued & mask) == mask) {
                        dout("__ceph_caps_issued_mask ino 0x%llx cap %p issued %s"
-                            " (mask %s)\n", ceph_ino(&ci->vfs_inode), cap,
+                            " (mask %s)\n", ceph_ino(&ci->netfs.inode), cap,
                             ceph_cap_string(cap->issued),
                             ceph_cap_string(mask));
                        if (touch)
@@ -891,7 +891,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
                have |= cap->issued;
                if ((have & mask) == mask) {
                        dout("__ceph_caps_issued_mask ino 0x%llx combo issued %s"
-                            " (mask %s)\n", ceph_ino(&ci->vfs_inode),
+                            " (mask %s)\n", ceph_ino(&ci->netfs.inode),
                             ceph_cap_string(cap->issued),
                             ceph_cap_string(mask));
                        if (touch) {
@@ -919,7 +919,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
 int __ceph_caps_issued_mask_metric(struct ceph_inode_info *ci, int mask,
                                   int touch)
 {
-       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
+       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb);
        int r;
 
        r = __ceph_caps_issued_mask(ci, mask, touch);
@@ -950,7 +950,7 @@ int __ceph_caps_revoking_other(struct ceph_inode_info *ci,
 
 int ceph_caps_revoking(struct ceph_inode_info *ci, int mask)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        int ret;
 
        spin_lock(&ci->i_ceph_lock);
@@ -969,8 +969,8 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
        if (ci->i_rd_ref)
                used |= CEPH_CAP_FILE_RD;
        if (ci->i_rdcache_ref ||
-           (S_ISREG(ci->vfs_inode.i_mode) &&
-            ci->vfs_inode.i_data.nrpages))
+           (S_ISREG(ci->netfs.inode.i_mode) &&
+            ci->netfs.inode.i_data.nrpages))
                used |= CEPH_CAP_FILE_CACHE;
        if (ci->i_wr_ref)
                used |= CEPH_CAP_FILE_WR;
@@ -993,11 +993,11 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
        const int WR_SHIFT = ffs(CEPH_FILE_MODE_WR);
        const int LAZY_SHIFT = ffs(CEPH_FILE_MODE_LAZY);
        struct ceph_mount_options *opt =
-               ceph_inode_to_client(&ci->vfs_inode)->mount_options;
+               ceph_inode_to_client(&ci->netfs.inode)->mount_options;
        unsigned long used_cutoff = jiffies - opt->caps_wanted_delay_max * HZ;
        unsigned long idle_cutoff = jiffies - opt->caps_wanted_delay_min * HZ;
 
-       if (S_ISDIR(ci->vfs_inode.i_mode)) {
+       if (S_ISDIR(ci->netfs.inode.i_mode)) {
                int want = 0;
 
                /* use used_cutoff here, to keep dir's wanted caps longer */
@@ -1050,7 +1050,7 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
 int __ceph_caps_wanted(struct ceph_inode_info *ci)
 {
        int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
-       if (S_ISDIR(ci->vfs_inode.i_mode)) {
+       if (S_ISDIR(ci->netfs.inode.i_mode)) {
                /* we want EXCL if holding caps of dir ops */
                if (w & CEPH_CAP_ANY_DIR_OPS)
                        w |= CEPH_CAP_FILE_EXCL;
@@ -1116,9 +1116,9 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
 
        lockdep_assert_held(&ci->i_ceph_lock);
 
-       dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
+       dout("__ceph_remove_cap %p from %p\n", cap, &ci->netfs.inode);
 
-       mdsc = ceph_inode_to_client(&ci->vfs_inode)->mdsc;
+       mdsc = ceph_inode_to_client(&ci->netfs.inode)->mdsc;
 
        /* remove from inode's cap rbtree, and clear auth cap */
        rb_erase(&cap->ci_node, &ci->i_caps);
@@ -1169,7 +1169,7 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
                 * keep i_snap_realm.
                 */
                if (ci->i_wr_ref == 0 && ci->i_snap_realm)
-                       ceph_change_snap_realm(&ci->vfs_inode, NULL);
+                       ceph_change_snap_realm(&ci->netfs.inode, NULL);
 
                __cap_delay_cancel(mdsc, ci);
        }
@@ -1188,11 +1188,11 @@ void ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
 
        lockdep_assert_held(&ci->i_ceph_lock);
 
-       fsc = ceph_inode_to_client(&ci->vfs_inode);
+       fsc = ceph_inode_to_client(&ci->netfs.inode);
        WARN_ON_ONCE(ci->i_auth_cap == cap &&
                     !list_empty(&ci->i_dirty_item) &&
                     !fsc->blocklisted &&
-                    !ceph_inode_is_shutdown(&ci->vfs_inode));
+                    !ceph_inode_is_shutdown(&ci->netfs.inode));
 
        __ceph_remove_cap(cap, queue_release);
 }
@@ -1343,7 +1343,7 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap,
                       int flushing, u64 flush_tid, u64 oldest_flush_tid)
 {
        struct ceph_inode_info *ci = cap->ci;
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        int held, revoking;
 
        lockdep_assert_held(&ci->i_ceph_lock);
@@ -1440,7 +1440,7 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap,
 static void __send_cap(struct cap_msg_args *arg, struct ceph_inode_info *ci)
 {
        struct ceph_msg *msg;
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
 
        msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, CAP_MSG_SIZE, GFP_NOFS, false);
        if (!msg) {
@@ -1528,7 +1528,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci,
                __releases(ci->i_ceph_lock)
                __acquires(ci->i_ceph_lock)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_mds_client *mdsc = session->s_mdsc;
        struct ceph_cap_snap *capsnap;
        u64 oldest_flush_tid = 0;
@@ -1622,7 +1622,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci,
 void ceph_flush_snaps(struct ceph_inode_info *ci,
                      struct ceph_mds_session **psession)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
        struct ceph_mds_session *session = NULL;
        int mds;
@@ -1682,8 +1682,8 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
                           struct ceph_cap_flush **pcf)
 {
        struct ceph_mds_client *mdsc =
-               ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
-       struct inode *inode = &ci->vfs_inode;
+               ceph_sb_to_client(ci->netfs.inode.i_sb)->mdsc;
+       struct inode *inode = &ci->netfs.inode;
        int was = ci->i_dirty_caps;
        int dirty = 0;
 
@@ -1696,7 +1696,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
                return 0;
        }
 
-       dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode,
+       dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->netfs.inode,
             ceph_cap_string(mask), ceph_cap_string(was),
             ceph_cap_string(was | mask));
        ci->i_dirty_caps |= mask;
@@ -1712,7 +1712,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
                                ci->i_snap_realm->cached_context);
                }
                dout(" inode %p now dirty snapc %p auth cap %p\n",
-                    &ci->vfs_inode, ci->i_head_snapc, ci->i_auth_cap);
+                    &ci->netfs.inode, ci->i_head_snapc, ci->i_auth_cap);
                BUG_ON(!list_empty(&ci->i_dirty_item));
                spin_lock(&mdsc->cap_dirty_lock);
                list_add(&ci->i_dirty_item, &session->s_cap_dirty);
@@ -1875,7 +1875,7 @@ static int try_nonblocking_invalidate(struct inode *inode)
 
 bool __ceph_should_report_size(struct ceph_inode_info *ci)
 {
-       loff_t size = i_size_read(&ci->vfs_inode);
+       loff_t size = i_size_read(&ci->netfs.inode);
        /* mds will adjust max size according to the reported size */
        if (ci->i_flushing_caps & CEPH_CAP_FILE_WR)
                return false;
@@ -1900,7 +1900,7 @@ bool __ceph_should_report_size(struct ceph_inode_info *ci)
 void ceph_check_caps(struct ceph_inode_info *ci, int flags,
                     struct ceph_mds_session *session)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
        struct ceph_cap *cap;
        u64 flush_tid, oldest_flush_tid;
@@ -2467,7 +2467,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
        __releases(ci->i_ceph_lock)
        __acquires(ci->i_ceph_lock)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_cap *cap;
        struct ceph_cap_flush *cf;
        int ret;
@@ -2560,7 +2560,7 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc,
                cap = ci->i_auth_cap;
                if (!(cap && cap->session == session)) {
                        pr_err("%p auth cap %p not mds%d ???\n",
-                               &ci->vfs_inode, cap, session->s_mds);
+                               &ci->netfs.inode, cap, session->s_mds);
                        spin_unlock(&ci->i_ceph_lock);
                        continue;
                }
@@ -2610,7 +2610,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
                cap = ci->i_auth_cap;
                if (!(cap && cap->session == session)) {
                        pr_err("%p auth cap %p not mds%d ???\n",
-                               &ci->vfs_inode, cap, session->s_mds);
+                               &ci->netfs.inode, cap, session->s_mds);
                        spin_unlock(&ci->i_ceph_lock);
                        continue;
                }
@@ -2630,7 +2630,7 @@ void ceph_kick_flushing_inode_caps(struct ceph_mds_session *session,
 
        lockdep_assert_held(&ci->i_ceph_lock);
 
-       dout("%s %p flushing %s\n", __func__, &ci->vfs_inode,
+       dout("%s %p flushing %s\n", __func__, &ci->netfs.inode,
             ceph_cap_string(ci->i_flushing_caps));
 
        if (!list_empty(&ci->i_cap_flush_list)) {
@@ -2673,10 +2673,10 @@ void ceph_take_cap_refs(struct ceph_inode_info *ci, int got,
        }
        if (got & CEPH_CAP_FILE_BUFFER) {
                if (ci->i_wb_ref == 0)
-                       ihold(&ci->vfs_inode);
+                       ihold(&ci->netfs.inode);
                ci->i_wb_ref++;
                dout("%s %p wb %d -> %d (?)\n", __func__,
-                    &ci->vfs_inode, ci->i_wb_ref-1, ci->i_wb_ref);
+                    &ci->netfs.inode, ci->i_wb_ref-1, ci->i_wb_ref);
        }
 }
 
@@ -3004,7 +3004,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
                        return ret;
                }
 
-               if (S_ISREG(ci->vfs_inode.i_mode) &&
+               if (S_ISREG(ci->netfs.inode.i_mode) &&
                    ci->i_inline_version != CEPH_INLINE_NONE &&
                    (_got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
                    i_size_read(inode) > 0) {
@@ -3094,7 +3094,7 @@ enum put_cap_refs_mode {
 static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had,
                                enum put_cap_refs_mode mode)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        int last = 0, put = 0, flushsnaps = 0, wake = 0;
        bool check_flushsnaps = false;
 
@@ -3202,7 +3202,7 @@ void ceph_put_cap_refs_no_check_caps(struct ceph_inode_info *ci, int had)
 void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
                                struct ceph_snap_context *snapc)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_cap_snap *capsnap = NULL, *iter;
        int put = 0;
        bool last = false;
@@ -3698,7 +3698,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
                                     session->s_mds,
                                     &list_first_entry(&session->s_cap_flushing,
                                                struct ceph_inode_info,
-                                               i_flushing_item)->vfs_inode);
+                                               i_flushing_item)->netfs.inode);
                        }
                }
                mdsc->num_cap_flushing--;
@@ -4345,7 +4345,7 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
                        break;
                list_del_init(&ci->i_cap_delay_list);
 
-               inode = igrab(&ci->vfs_inode);
+               inode = igrab(&ci->netfs.inode);
                if (inode) {
                        spin_unlock(&mdsc->cap_delay_lock);
                        dout("check_delayed_caps on %p\n", inode);
@@ -4373,7 +4373,7 @@ static void flush_dirty_session_caps(struct ceph_mds_session *s)
        while (!list_empty(&s->s_cap_dirty)) {
                ci = list_first_entry(&s->s_cap_dirty, struct ceph_inode_info,
                                      i_dirty_item);
-               inode = &ci->vfs_inode;
+               inode = &ci->netfs.inode;
                ihold(inode);
                dout("flush_dirty_caps %llx.%llx\n", ceph_vinop(inode));
                spin_unlock(&mdsc->cap_dirty_lock);
@@ -4407,7 +4407,7 @@ void __ceph_touch_fmode(struct ceph_inode_info *ci,
 
 void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count)
 {
-       struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb);
+       struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->netfs.inode.i_sb);
        int bits = (fmode << 1) | 1;
        bool already_opened = false;
        int i;
@@ -4441,7 +4441,7 @@ void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count)
  */
 void ceph_put_fmode(struct ceph_inode_info *ci, int fmode, int count)
 {
-       struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb);
+       struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->netfs.inode.i_sb);
        int bits = (fmode << 1) | 1;
        bool is_closed = true;
        int i;
@@ -4656,7 +4656,7 @@ int ceph_purge_inode_cap(struct inode *inode, struct ceph_cap *cap, bool *invali
        lockdep_assert_held(&ci->i_ceph_lock);
 
        dout("removing cap %p, ci is %p, inode is %p\n",
-            cap, ci, &ci->vfs_inode);
+            cap, ci, &ci->netfs.inode);
 
        is_auth = (cap == ci->i_auth_cap);
        __ceph_remove_cap(cap, false);
index 8c8226c0feaccce31395d349d2bc266b6497b033..da59e836a06eb7502c84ff0bb9d7a0f9e49a7b31 100644 (file)
@@ -205,7 +205,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_mount_options *opt =
-               ceph_inode_to_client(&ci->vfs_inode)->mount_options;
+               ceph_inode_to_client(&ci->netfs.inode)->mount_options;
        struct ceph_file_info *fi;
        int ret;
 
index b7e9cac3aeef06f50d05d42f2b1e983481ad0d70..56c53ab3618e8eb1b4aae7cf17027f9908de50d3 100644 (file)
@@ -176,7 +176,7 @@ static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci,
        rb_insert_color(&frag->node, &ci->i_fragtree);
 
        dout("get_or_create_frag added %llx.%llx frag %x\n",
-            ceph_vinop(&ci->vfs_inode), f);
+            ceph_vinop(&ci->netfs.inode), f);
        return frag;
 }
 
@@ -457,10 +457,10 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
        if (!ci)
                return NULL;
 
-       dout("alloc_inode %p\n", &ci->vfs_inode);
+       dout("alloc_inode %p\n", &ci->netfs.inode);
 
        /* Set parameters for the netfs library */
-       netfs_i_context_init(&ci->vfs_inode, &ceph_netfs_ops);
+       netfs_inode_init(&ci->netfs, &ceph_netfs_ops);
 
        spin_lock_init(&ci->i_ceph_lock);
 
@@ -547,7 +547,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
        INIT_WORK(&ci->i_work, ceph_inode_work);
        ci->i_work_mask = 0;
        memset(&ci->i_btime, '\0', sizeof(ci->i_btime));
-       return &ci->vfs_inode;
+       return &ci->netfs.inode;
 }
 
 void ceph_free_inode(struct inode *inode)
@@ -1978,7 +1978,7 @@ static void ceph_inode_work(struct work_struct *work)
 {
        struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
                                                 i_work);
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
 
        if (test_and_clear_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask)) {
                dout("writeback %p\n", inode);
index f5d110d90b77044bdb43a9265fe39620c69f5069..33f517d549ce521e8725a436ffde55be2e2e4788 100644 (file)
@@ -1564,7 +1564,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
        p = session->s_caps.next;
        while (p != &session->s_caps) {
                cap = list_entry(p, struct ceph_cap, session_caps);
-               inode = igrab(&cap->ci->vfs_inode);
+               inode = igrab(&cap->ci->netfs.inode);
                if (!inode) {
                        p = p->next;
                        continue;
@@ -1622,7 +1622,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
        int iputs;
 
        dout("removing cap %p, ci is %p, inode is %p\n",
-            cap, ci, &ci->vfs_inode);
+            cap, ci, &ci->netfs.inode);
        spin_lock(&ci->i_ceph_lock);
        iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
        spin_unlock(&ci->i_ceph_lock);
index 322ee5add94261838fd95e2c06caf7fb72ab23c4..864cdaa0d2bd659e43459ddfdecf6f5fd8bcc7b0 100644 (file)
@@ -521,7 +521,7 @@ static bool has_new_snaps(struct ceph_snap_context *o,
 static void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                                struct ceph_cap_snap **pcapsnap)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_snap_context *old_snapc, *new_snapc;
        struct ceph_cap_snap *capsnap = *pcapsnap;
        struct ceph_buffer *old_blob = NULL;
@@ -652,7 +652,7 @@ update_snapc:
 int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
                            struct ceph_cap_snap *capsnap)
 {
-       struct inode *inode = &ci->vfs_inode;
+       struct inode *inode = &ci->netfs.inode;
        struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
 
        BUG_ON(capsnap->writing);
@@ -712,7 +712,7 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
 
        spin_lock(&realm->inodes_with_caps_lock);
        list_for_each_entry(ci, &realm->inodes_with_caps, i_snap_realm_item) {
-               struct inode *inode = igrab(&ci->vfs_inode);
+               struct inode *inode = igrab(&ci->netfs.inode);
                if (!inode)
                        continue;
                spin_unlock(&realm->inodes_with_caps_lock);
@@ -904,7 +904,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
        while (!list_empty(&mdsc->snap_flush_list)) {
                ci = list_first_entry(&mdsc->snap_flush_list,
                                struct ceph_inode_info, i_snap_flush_item);
-               inode = &ci->vfs_inode;
+               inode = &ci->netfs.inode;
                ihold(inode);
                spin_unlock(&mdsc->snap_flush_lock);
                ceph_flush_snaps(ci, &session);
index b73b4f75462c3442d2d56a348d7ded4db26a11bb..40140805bdcfe924d2521c9eba068e7112a6c3ec 100644 (file)
@@ -876,7 +876,7 @@ mempool_t *ceph_wb_pagevec_pool;
 static void ceph_inode_init_once(void *foo)
 {
        struct ceph_inode_info *ci = foo;
-       inode_init_once(&ci->vfs_inode);
+       inode_init_once(&ci->netfs.inode);
 }
 
 static int __init init_caches(void)
index dd7dac0f984a89b6235e7a7e1d78f2ac1b525712..f59dac66955bbdaee08a00257ead922ea7b03061 100644 (file)
@@ -316,11 +316,7 @@ struct ceph_inode_xattrs_info {
  * Ceph inode.
  */
 struct ceph_inode_info {
-       struct {
-               /* These must be contiguous */
-               struct inode vfs_inode;
-               struct netfs_i_context netfs_ctx; /* Netfslib context */
-       };
+       struct netfs_inode netfs; /* Netfslib context and vfs inode */
        struct ceph_vino i_vino;   /* ceph ino + snap */
 
        spinlock_t i_ceph_lock;
@@ -436,7 +432,7 @@ struct ceph_inode_info {
 static inline struct ceph_inode_info *
 ceph_inode(const struct inode *inode)
 {
-       return container_of(inode, struct ceph_inode_info, vfs_inode);
+       return container_of(inode, struct ceph_inode_info, netfs.inode);
 }
 
 static inline struct ceph_fs_client *
@@ -1316,7 +1312,7 @@ static inline void __ceph_update_quota(struct ceph_inode_info *ci,
        has_quota = __ceph_has_quota(ci, QUOTA_GET_ANY);
 
        if (had_quota != has_quota)
-               ceph_adjust_quota_realms_count(&ci->vfs_inode, has_quota);
+               ceph_adjust_quota_realms_count(&ci->netfs.inode, has_quota);
 }
 
 extern void ceph_handle_quota(struct ceph_mds_client *mdsc,
index 8c2dc2c762a4ecc688abfe515d6c990dab297a15..f141f5246163db69c3039ac45e2f0b76469c2a78 100644 (file)
@@ -57,7 +57,7 @@ static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci)
 static ssize_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
                                    size_t size)
 {
-       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
+       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb);
        struct ceph_osd_client *osdc = &fsc->client->osdc;
        struct ceph_string *pool_ns;
        s64 pool = ci->i_layout.pool_id;
@@ -69,7 +69,7 @@ static ssize_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
 
        pool_ns = ceph_try_get_string(ci->i_layout.pool_ns);
 
-       dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode);
+       dout("ceph_vxattrcb_layout %p\n", &ci->netfs.inode);
        down_read(&osdc->lock);
        pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
        if (pool_name) {
@@ -161,7 +161,7 @@ static ssize_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci,
                                         char *val, size_t size)
 {
        ssize_t ret;
-       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
+       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb);
        struct ceph_osd_client *osdc = &fsc->client->osdc;
        s64 pool = ci->i_layout.pool_id;
        const char *pool_name;
@@ -313,7 +313,7 @@ static ssize_t ceph_vxattrcb_snap_btime(struct ceph_inode_info *ci, char *val,
 static ssize_t ceph_vxattrcb_cluster_fsid(struct ceph_inode_info *ci,
                                          char *val, size_t size)
 {
-       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
+       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb);
 
        return ceph_fmt_xattr(val, size, "%pU", &fsc->client->fsid);
 }
@@ -321,7 +321,7 @@ static ssize_t ceph_vxattrcb_cluster_fsid(struct ceph_inode_info *ci,
 static ssize_t ceph_vxattrcb_client_id(struct ceph_inode_info *ci,
                                       char *val, size_t size)
 {
-       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
+       struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb);
 
        return ceph_fmt_xattr(val, size, "client%lld",
                              ceph_client_gid(fsc->client));
@@ -629,7 +629,7 @@ static int __set_xattr(struct ceph_inode_info *ci,
        }
 
        dout("__set_xattr_val added %llx.%llx xattr %p %.*s=%.*s\n",
-            ceph_vinop(&ci->vfs_inode), xattr, name_len, name, val_len, val);
+            ceph_vinop(&ci->netfs.inode), xattr, name_len, name, val_len, val);
 
        return 0;
 }
@@ -871,7 +871,7 @@ struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci)
        struct ceph_buffer *old_blob = NULL;
        void *dest;
 
-       dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
+       dout("__build_xattrs_blob %p\n", &ci->netfs.inode);
        if (ci->i_xattrs.dirty) {
                int need = __get_required_blob_size(ci, 0, 0);
 
index 12c872800326f36655b3143f77b296ef23e15487..8f2e003e059075fe2c715728e5477d9d2d712028 100644 (file)
@@ -377,7 +377,7 @@ cifs_alloc_inode(struct super_block *sb)
        cifs_inode->flags = 0;
        spin_lock_init(&cifs_inode->writers_lock);
        cifs_inode->writers = 0;
-       cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
+       cifs_inode->netfs.inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
        cifs_inode->server_eof = 0;
        cifs_inode->uniqueid = 0;
        cifs_inode->createtime = 0;
@@ -389,12 +389,12 @@ cifs_alloc_inode(struct super_block *sb)
         * Can not set i_flags here - they get immediately overwritten to zero
         * by the VFS.
         */
-       /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */
+       /* cifs_inode->netfs.inode.i_flags = S_NOATIME | S_NOCMTIME; */
        INIT_LIST_HEAD(&cifs_inode->openFileList);
        INIT_LIST_HEAD(&cifs_inode->llist);
        INIT_LIST_HEAD(&cifs_inode->deferred_closes);
        spin_lock_init(&cifs_inode->deferred_lock);
-       return &cifs_inode->vfs_inode;
+       return &cifs_inode->netfs.inode;
 }
 
 static void
@@ -1086,7 +1086,7 @@ struct file_system_type cifs_fs_type = {
 };
 MODULE_ALIAS_FS("cifs");
 
-static struct file_system_type smb3_fs_type = {
+struct file_system_type smb3_fs_type = {
        .owner = THIS_MODULE,
        .name = "smb3",
        .init_fs_context = smb3_init_fs_context,
@@ -1418,7 +1418,7 @@ cifs_init_once(void *inode)
 {
        struct cifsInodeInfo *cifsi = inode;
 
-       inode_init_once(&cifsi->vfs_inode);
+       inode_init_once(&cifsi->netfs.inode);
        init_rwsem(&cifsi->lock_sem);
 }
 
index dd7e070ca243c0664bc874e307229c079920fd17..b17be47a8e595cf4a12a3278530b5f228f3ddca6 100644 (file)
@@ -38,7 +38,7 @@ static inline unsigned long cifs_get_time(struct dentry *dentry)
        return (unsigned long) dentry->d_fsdata;
 }
 
-extern struct file_system_type cifs_fs_type;
+extern struct file_system_type cifs_fs_type, smb3_fs_type;
 extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
 
index f873379066c7118e664cb80a1a40434f8c858e68..e7737166e5b860c5fc4db112ce286c8daf1691bb 100644 (file)
@@ -1479,20 +1479,16 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
 #define CIFS_CACHE_RW_FLG      (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG)
 #define CIFS_CACHE_RHW_FLG     (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG)
 
-#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE))
+#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE))
 #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG)
-#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE))
+#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE))
 
 /*
  * One of these for each file inode
  */
 
 struct cifsInodeInfo {
-       struct {
-               /* These must be contiguous */
-               struct inode    vfs_inode;      /* the VFS's inode record */
-               struct netfs_i_context netfs_ctx; /* Netfslib context */
-       };
+       struct netfs_inode netfs; /* Netfslib context and vfs inode */
        bool can_cache_brlcks;
        struct list_head llist; /* locks helb by this inode */
        /*
@@ -1531,7 +1527,7 @@ struct cifsInodeInfo {
 static inline struct cifsInodeInfo *
 CIFS_I(struct inode *inode)
 {
-       return container_of(inode, struct cifsInodeInfo, vfs_inode);
+       return container_of(inode, struct cifsInodeInfo, netfs.inode);
 }
 
 static inline struct cifs_sb_info *
index d46702f5a6630cd102f0850359f828227c1c5191..1849e34114878b5acfe5dfabedd26de1e346e67c 100644 (file)
@@ -97,6 +97,10 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
        if (!server->hostname)
                return -EINVAL;
 
+       /* if server hostname isn't populated, there's nothing to do here */
+       if (server->hostname[0] == '\0')
+               return 0;
+
        len = strlen(server->hostname) + 3;
 
        unc = kmalloc(len, GFP_KERNEL);
index 1618e0537d58c7d0438643dd309bd21f498a8b7d..e64cda7a761012563a82dc2afbd2582e01ea2607 100644 (file)
@@ -2004,7 +2004,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
 {
        struct cifsFileInfo *open_file = NULL;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb);
 
        /* only filter by fsuid on multiuser mounts */
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
@@ -2060,7 +2060,7 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
                return rc;
        }
 
-       cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
+       cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb);
 
        /* only filter by fsuid on multiuser mounts */
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
@@ -4669,14 +4669,14 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
                /* This inode is open for write at least once */
                struct cifs_sb_info *cifs_sb;
 
-               cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
+               cifs_sb = CIFS_SB(cifsInode->netfs.inode.i_sb);
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
                        /* since no page cache to corrupt on directio
                        we can change size safely */
                        return true;
                }
 
-               if (i_size_read(&cifsInode->vfs_inode) < end_of_file)
+               if (i_size_read(&cifsInode->netfs.inode) < end_of_file)
                        return true;
 
                return false;
index a638b29e906201a3128eb91e3170a673ca649df8..23ef56f55ce509d149923ae218d1f6dabd8f1da1 100644 (file)
@@ -101,13 +101,13 @@ void cifs_fscache_get_inode_cookie(struct inode *inode)
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 
-       cifs_fscache_fill_coherency(&cifsi->vfs_inode, &cd);
+       cifs_fscache_fill_coherency(&cifsi->netfs.inode, &cd);
 
-       cifsi->netfs_ctx.cache =
+       cifsi->netfs.cache =
                fscache_acquire_cookie(tcon->fscache, 0,
                                       &cifsi->uniqueid, sizeof(cifsi->uniqueid),
                                       &cd, sizeof(cd),
-                                      i_size_read(&cifsi->vfs_inode));
+                                      i_size_read(&cifsi->netfs.inode));
 }
 
 void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update)
@@ -131,7 +131,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
        if (cookie) {
                cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie);
                fscache_relinquish_cookie(cookie, false);
-               cifsi->netfs_ctx.cache = NULL;
+               cifsi->netfs.cache = NULL;
        }
 }
 
index 52355c0912aee44bb55d9a259ee3f233b07da8a8..aa3b941a55557f257dbbc106e198a6ffbeba9c67 100644 (file)
@@ -52,16 +52,16 @@ void cifs_fscache_fill_coherency(struct inode *inode,
        struct cifsInodeInfo *cifsi = CIFS_I(inode);
 
        memset(cd, 0, sizeof(*cd));
-       cd->last_write_time_sec   = cpu_to_le64(cifsi->vfs_inode.i_mtime.tv_sec);
-       cd->last_write_time_nsec  = cpu_to_le32(cifsi->vfs_inode.i_mtime.tv_nsec);
-       cd->last_change_time_sec  = cpu_to_le64(cifsi->vfs_inode.i_ctime.tv_sec);
-       cd->last_change_time_nsec = cpu_to_le32(cifsi->vfs_inode.i_ctime.tv_nsec);
+       cd->last_write_time_sec   = cpu_to_le64(cifsi->netfs.inode.i_mtime.tv_sec);
+       cd->last_write_time_nsec  = cpu_to_le32(cifsi->netfs.inode.i_mtime.tv_nsec);
+       cd->last_change_time_sec  = cpu_to_le64(cifsi->netfs.inode.i_ctime.tv_sec);
+       cd->last_change_time_nsec = cpu_to_le32(cifsi->netfs.inode.i_ctime.tv_nsec);
 }
 
 
 static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode)
 {
-       return netfs_i_cookie(inode);
+       return netfs_i_cookie(&CIFS_I(inode)->netfs);
 }
 
 static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags)
index 2f9e7d2f81b6f5bab7866b8ba0fb73d6f1ebfd51..81da81e185538a441be393734ffccbcdb1e1d333 100644 (file)
@@ -115,7 +115,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
                 __func__, cifs_i->uniqueid);
        set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags);
        /* Invalidate fscache cookie */
-       cifs_fscache_fill_coherency(&cifs_i->vfs_inode, &cd);
+       cifs_fscache_fill_coherency(&cifs_i->netfs.inode, &cd);
        fscache_invalidate(cifs_inode_cookie(inode), &cd, i_size_read(inode), 0);
 }
 
@@ -2499,7 +2499,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start,
                u64 len)
 {
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
-       struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->vfs_inode.i_sb);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->netfs.inode.i_sb);
        struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
        struct TCP_Server_Info *server = tcon->ses->server;
        struct cifsFileInfo *cfile;
index 35962a1a23b90f3775e58f3a642fe7a647253205..c69e1240d730b300044ff3213b99b18f7be276b7 100644 (file)
@@ -537,11 +537,11 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
        if (oplock == OPLOCK_EXCLUSIVE) {
                cinode->oplock = CIFS_CACHE_WRITE_FLG | CIFS_CACHE_READ_FLG;
                cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
-                        &cinode->vfs_inode);
+                        &cinode->netfs.inode);
        } else if (oplock == OPLOCK_READ) {
                cinode->oplock = CIFS_CACHE_READ_FLG;
                cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
-                        &cinode->vfs_inode);
+                        &cinode->netfs.inode);
        } else
                cinode->oplock = 0;
 }
@@ -1211,18 +1211,23 @@ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void
                .data = data,
                .sb = NULL,
        };
+       struct file_system_type **fs_type = (struct file_system_type *[]) {
+               &cifs_fs_type, &smb3_fs_type, NULL,
+       };
 
-       iterate_supers_type(&cifs_fs_type, f, &sd);
-
-       if (!sd.sb)
-               return ERR_PTR(-EINVAL);
-       /*
-        * Grab an active reference in order to prevent automounts (DFS links)
-        * of expiring and then freeing up our cifs superblock pointer while
-        * we're doing failover.
-        */
-       cifs_sb_active(sd.sb);
-       return sd.sb;
+       for (; *fs_type; fs_type++) {
+               iterate_supers_type(*fs_type, f, &sd);
+               if (sd.sb) {
+                       /*
+                        * Grab an active reference in order to prevent automounts (DFS links)
+                        * of expiring and then freeing up our cifs superblock pointer while
+                        * we're doing failover.
+                        */
+                       cifs_sb_active(sd.sb);
+                       return sd.sb;
+               }
+       }
+       return ERR_PTR(-EINVAL);
 }
 
 static void __cifs_put_super(struct super_block *sb)
index 3b7915af1f62e6150954d2ebba23c1033283e5b4..0bece97547d4b760138a22299feca6d8ebe6078c 100644 (file)
@@ -301,7 +301,10 @@ 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;
+
+       /* no hostname for extra channels */
+       ctx.server_hostname = "";
+
        ctx.username = ses->user_name;
        ctx.password = ses->password;
        ctx.sectype = ses->sectype;
index 98a76fa791c064c760bc0ec150e85e4f1a73de22..8543cafdfd341db3fb168e3b78d6747e08304dc3 100644 (file)
@@ -4260,15 +4260,15 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
        if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
                cinode->oplock = CIFS_CACHE_RHW_FLG;
                cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
-                        &cinode->vfs_inode);
+                        &cinode->netfs.inode);
        } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
                cinode->oplock = CIFS_CACHE_RW_FLG;
                cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
-                        &cinode->vfs_inode);
+                        &cinode->netfs.inode);
        } else if (oplock == SMB2_OPLOCK_LEVEL_II) {
                cinode->oplock = CIFS_CACHE_READ_FLG;
                cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
-                        &cinode->vfs_inode);
+                        &cinode->netfs.inode);
        } else
                cinode->oplock = 0;
 }
@@ -4307,7 +4307,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 
        cinode->oplock = new_oplock;
        cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
-                &cinode->vfs_inode);
+                &cinode->netfs.inode);
 }
 
 static void
index 0e8c8524957912bebf36faa3167c05c11068e228..eaf975f1ad8935673268dec17b3c8337cadb196b 100644 (file)
@@ -288,6 +288,9 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
                        mutex_unlock(&ses->session_mutex);
                        rc = -EHOSTDOWN;
                        goto failed;
+               } else if (rc) {
+                       mutex_unlock(&ses->session_mutex);
+                       goto out;
                }
        } else {
                mutex_unlock(&ses->session_mutex);
index 2c2f179b69779b7b5887b9c12f8ff7b2c73c7b60..43de293cef56be78f40a6cf12830b82a9b10697c 100644 (file)
@@ -672,17 +672,14 @@ int ext2_empty_dir (struct inode * inode)
        void *page_addr = NULL;
        struct page *page = NULL;
        unsigned long i, npages = dir_pages(inode);
-       int dir_has_error = 0;
 
        for (i = 0; i < npages; i++) {
                char *kaddr;
                ext2_dirent * de;
-               page = ext2_get_page(inode, i, dir_has_error, &page_addr);
+               page = ext2_get_page(inode, i, 0, &page_addr);
 
-               if (IS_ERR(page)) {
-                       dir_has_error = 1;
-                       continue;
-               }
+               if (IS_ERR(page))
+                       goto not_empty;
 
                kaddr = page_addr;
                de = (ext2_dirent *)kaddr;
index 360ce3604a2d293c38c6002ccb2de63d9af665d6..e6b932219803ed9984c08d656806c6242bb430f0 100644 (file)
@@ -1549,7 +1549,7 @@ static int __ext2_write_inode(struct inode *inode, int do_sync)
        if (IS_ERR(raw_inode))
                return -EIO;
 
-       /* For fields not not tracking in the in-memory inode,
+       /* For fields not tracking in the in-memory inode,
         * initialise them to zero for new inodes. */
        if (ei->i_state & EXT2_STATE_NEW)
                memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size);
index a21d8f1a56d19d3cb1e40bd9e21213aafa715a00..05221366a16dc913961f3e3f7b4a703477bc7bb9 100644 (file)
@@ -120,6 +120,7 @@ static bool inode_io_list_move_locked(struct inode *inode,
                                      struct list_head *head)
 {
        assert_spin_locked(&wb->list_lock);
+       assert_spin_locked(&inode->i_lock);
 
        list_move(&inode->i_io_list, head);
 
@@ -1365,9 +1366,9 @@ static int move_expired_inodes(struct list_head *delaying_queue,
                inode = wb_inode(delaying_queue->prev);
                if (inode_dirtied_after(inode, dirtied_before))
                        break;
+               spin_lock(&inode->i_lock);
                list_move(&inode->i_io_list, &tmp);
                moved++;
-               spin_lock(&inode->i_lock);
                inode->i_state |= I_SYNC_QUEUED;
                spin_unlock(&inode->i_lock);
                if (sb_is_blkdev_sb(inode->i_sb))
@@ -1383,7 +1384,12 @@ static int move_expired_inodes(struct list_head *delaying_queue,
                goto out;
        }
 
-       /* Move inodes from one superblock together */
+       /*
+        * Although inode's i_io_list is moved from 'tmp' to 'dispatch_queue',
+        * we don't take inode->i_lock here because it is just a pointless overhead.
+        * Inode is already marked as I_SYNC_QUEUED so writeback list handling is
+        * fully under our control.
+        */
        while (!list_empty(&tmp)) {
                sb = wb_inode(tmp.prev)->i_sb;
                list_for_each_prev_safe(pos, node, &tmp) {
@@ -1826,8 +1832,8 @@ static long writeback_sb_inodes(struct super_block *sb,
                         * We'll have another go at writing back this inode
                         * when we completed a full scan of b_io.
                         */
-                       spin_unlock(&inode->i_lock);
                        requeue_io(inode, wb);
+                       spin_unlock(&inode->i_lock);
                        trace_writeback_sb_inodes_requeue(inode);
                        continue;
                }
@@ -2358,6 +2364,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 {
        struct super_block *sb = inode->i_sb;
        int dirtytime = 0;
+       struct bdi_writeback *wb = NULL;
 
        trace_writeback_mark_inode_dirty(inode, flags);
 
@@ -2409,6 +2416,17 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                        inode->i_state &= ~I_DIRTY_TIME;
                inode->i_state |= flags;
 
+               /*
+                * Grab inode's wb early because it requires dropping i_lock and we
+                * need to make sure following checks happen atomically with dirty
+                * list handling so that we don't move inodes under flush worker's
+                * hands.
+                */
+               if (!was_dirty) {
+                       wb = locked_inode_to_wb_and_lock_list(inode);
+                       spin_lock(&inode->i_lock);
+               }
+
                /*
                 * If the inode is queued for writeback by flush worker, just
                 * update its dirty state. Once the flush worker is done with
@@ -2416,7 +2434,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                 * list, based upon its state.
                 */
                if (inode->i_state & I_SYNC_QUEUED)
-                       goto out_unlock_inode;
+                       goto out_unlock;
 
                /*
                 * Only add valid (hashed) inodes to the superblock's
@@ -2424,22 +2442,19 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                 */
                if (!S_ISBLK(inode->i_mode)) {
                        if (inode_unhashed(inode))
-                               goto out_unlock_inode;
+                               goto out_unlock;
                }
                if (inode->i_state & I_FREEING)
-                       goto out_unlock_inode;
+                       goto out_unlock;
 
                /*
                 * If the inode was already on b_dirty/b_io/b_more_io, don't
                 * reposition it (that would break b_dirty time-ordering).
                 */
                if (!was_dirty) {
-                       struct bdi_writeback *wb;
                        struct list_head *dirty_list;
                        bool wakeup_bdi = false;
 
-                       wb = locked_inode_to_wb_and_lock_list(inode);
-
                        inode->dirtied_when = jiffies;
                        if (dirtytime)
                                inode->dirtied_time_when = jiffies;
@@ -2453,6 +2468,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                                                               dirty_list);
 
                        spin_unlock(&wb->list_lock);
+                       spin_unlock(&inode->i_lock);
                        trace_writeback_dirty_inode_enqueue(inode);
 
                        /*
@@ -2467,6 +2483,9 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                        return;
                }
        }
+out_unlock:
+       if (wb)
+               spin_unlock(&wb->list_lock);
 out_unlock_inode:
        spin_unlock(&inode->i_lock);
 }
index 9d9b422504d1a883236f030befd73953d29dc774..bd4da9c5207eabb0cec8722ee3d30acd963169bf 100644 (file)
@@ -27,7 +27,7 @@
  * Inode locking rules:
  *
  * inode->i_lock protects:
- *   inode->i_state, inode->i_hash, __iget()
+ *   inode->i_state, inode->i_hash, __iget(), inode->i_io_list
  * Inode LRU list locks protect:
  *   inode->i_sb->s_inode_lru, inode->i_lru
  * inode->i_sb->s_inode_list_lock protects:
index 3aab4182fd892173e16b900fa437d47094195db0..d3ee4fc532fafc8601e20b53f059c6f8bf620ede 100644 (file)
@@ -298,8 +298,8 @@ struct io_buffer_list {
        /* below is for ring provided buffers */
        __u16 buf_nr_pages;
        __u16 nr_entries;
-       __u32 head;
-       __u32 mask;
+       __u16 head;
+       __u16 mask;
 };
 
 struct io_buffer {
@@ -576,7 +576,6 @@ struct io_close {
        struct file                     *file;
        int                             fd;
        u32                             file_slot;
-       u32                             flags;
 };
 
 struct io_timeout_data {
@@ -784,12 +783,6 @@ struct io_msg {
        u32 len;
 };
 
-struct io_nop {
-       struct file                     *file;
-       u64                             extra1;
-       u64                             extra2;
-};
-
 struct io_async_connect {
        struct sockaddr_storage         address;
 };
@@ -851,6 +844,7 @@ enum {
        REQ_F_SINGLE_POLL_BIT,
        REQ_F_DOUBLE_POLL_BIT,
        REQ_F_PARTIAL_IO_BIT,
+       REQ_F_CQE32_INIT_BIT,
        REQ_F_APOLL_MULTISHOT_BIT,
        /* keep async read/write and isreg together and in order */
        REQ_F_SUPPORT_NOWAIT_BIT,
@@ -920,6 +914,8 @@ enum {
        REQ_F_PARTIAL_IO        = BIT(REQ_F_PARTIAL_IO_BIT),
        /* fast poll multishot mode */
        REQ_F_APOLL_MULTISHOT   = BIT(REQ_F_APOLL_MULTISHOT_BIT),
+       /* ->extra1 and ->extra2 are initialised */
+       REQ_F_CQE32_INIT        = BIT(REQ_F_CQE32_INIT_BIT),
 };
 
 struct async_poll {
@@ -994,7 +990,6 @@ struct io_kiocb {
                struct io_msg           msg;
                struct io_xattr         xattr;
                struct io_socket        sock;
-               struct io_nop           nop;
                struct io_uring_cmd     uring_cmd;
        };
 
@@ -1121,7 +1116,6 @@ static const struct io_op_def io_op_defs[] = {
        [IORING_OP_NOP] = {
                .audit_skip             = 1,
                .iopoll                 = 1,
-               .buffer_select          = 1,
        },
        [IORING_OP_READV] = {
                .needs_file             = 1,
@@ -1729,9 +1723,16 @@ static void io_kbuf_recycle(struct io_kiocb *req, unsigned issue_flags)
 
        if (!(req->flags & (REQ_F_BUFFER_SELECTED|REQ_F_BUFFER_RING)))
                return;
-       /* don't recycle if we already did IO to this buffer */
-       if (req->flags & REQ_F_PARTIAL_IO)
+       /*
+        * For legacy provided buffer mode, don't recycle if we already did
+        * IO to this buffer. For ring-mapped provided buffer mode, we should
+        * increment ring->head to explicitly monopolize the buffer to avoid
+        * multiple use.
+        */
+       if ((req->flags & REQ_F_BUFFER_SELECTED) &&
+           (req->flags & REQ_F_PARTIAL_IO))
                return;
+
        /*
         * We don't need to recycle for REQ_F_BUFFER_RING, we can just clear
         * the flag and hence ensure that bl->head doesn't get incremented.
@@ -1739,8 +1740,13 @@ static void io_kbuf_recycle(struct io_kiocb *req, unsigned issue_flags)
         */
        if (req->flags & REQ_F_BUFFER_RING) {
                if (req->buf_list) {
-                       req->buf_index = req->buf_list->bgid;
-                       req->flags &= ~REQ_F_BUFFER_RING;
+                       if (req->flags & REQ_F_PARTIAL_IO) {
+                               req->buf_list->head++;
+                               req->buf_list = NULL;
+                       } else {
+                               req->buf_index = req->buf_list->bgid;
+                               req->flags &= ~REQ_F_BUFFER_RING;
+                       }
                }
                return;
        }
@@ -2441,94 +2447,66 @@ static bool io_cqring_event_overflow(struct io_ring_ctx *ctx, u64 user_data,
        return true;
 }
 
-static inline bool __io_fill_cqe(struct io_ring_ctx *ctx, u64 user_data,
-                                s32 res, u32 cflags)
+static inline bool __io_fill_cqe_req(struct io_ring_ctx *ctx,
+                                    struct io_kiocb *req)
 {
        struct io_uring_cqe *cqe;
 
-       /*
-        * If we can't get a cq entry, userspace overflowed the
-        * submission (by quite a lot). Increment the overflow count in
-        * the ring.
-        */
-       cqe = io_get_cqe(ctx);
-       if (likely(cqe)) {
-               WRITE_ONCE(cqe->user_data, user_data);
-               WRITE_ONCE(cqe->res, res);
-               WRITE_ONCE(cqe->flags, cflags);
-               return true;
-       }
-       return io_cqring_event_overflow(ctx, user_data, res, cflags, 0, 0);
-}
+       if (!(ctx->flags & IORING_SETUP_CQE32)) {
+               trace_io_uring_complete(req->ctx, req, req->cqe.user_data,
+                                       req->cqe.res, req->cqe.flags, 0, 0);
 
-static inline bool __io_fill_cqe_req_filled(struct io_ring_ctx *ctx,
-                                           struct io_kiocb *req)
-{
-       struct io_uring_cqe *cqe;
+               /*
+                * If we can't get a cq entry, userspace overflowed the
+                * submission (by quite a lot). Increment the overflow count in
+                * the ring.
+                */
+               cqe = io_get_cqe(ctx);
+               if (likely(cqe)) {
+                       memcpy(cqe, &req->cqe, sizeof(*cqe));
+                       return true;
+               }
 
-       trace_io_uring_complete(req->ctx, req, req->cqe.user_data,
-                               req->cqe.res, req->cqe.flags, 0, 0);
+               return io_cqring_event_overflow(ctx, req->cqe.user_data,
+                                               req->cqe.res, req->cqe.flags,
+                                               0, 0);
+       } else {
+               u64 extra1 = 0, extra2 = 0;
 
-       /*
-        * If we can't get a cq entry, userspace overflowed the
-        * submission (by quite a lot). Increment the overflow count in
-        * the ring.
-        */
-       cqe = io_get_cqe(ctx);
-       if (likely(cqe)) {
-               memcpy(cqe, &req->cqe, sizeof(*cqe));
-               return true;
-       }
-       return io_cqring_event_overflow(ctx, req->cqe.user_data,
-                                       req->cqe.res, req->cqe.flags, 0, 0);
-}
+               if (req->flags & REQ_F_CQE32_INIT) {
+                       extra1 = req->extra1;
+                       extra2 = req->extra2;
+               }
 
-static inline bool __io_fill_cqe32_req_filled(struct io_ring_ctx *ctx,
-                                             struct io_kiocb *req)
-{
-       struct io_uring_cqe *cqe;
-       u64 extra1 = req->extra1;
-       u64 extra2 = req->extra2;
+               trace_io_uring_complete(req->ctx, req, req->cqe.user_data,
+                                       req->cqe.res, req->cqe.flags, extra1, extra2);
 
-       trace_io_uring_complete(req->ctx, req, req->cqe.user_data,
-                               req->cqe.res, req->cqe.flags, extra1, extra2);
+               /*
+                * If we can't get a cq entry, userspace overflowed the
+                * submission (by quite a lot). Increment the overflow count in
+                * the ring.
+                */
+               cqe = io_get_cqe(ctx);
+               if (likely(cqe)) {
+                       memcpy(cqe, &req->cqe, sizeof(struct io_uring_cqe));
+                       WRITE_ONCE(cqe->big_cqe[0], extra1);
+                       WRITE_ONCE(cqe->big_cqe[1], extra2);
+                       return true;
+               }
 
-       /*
-        * If we can't get a cq entry, userspace overflowed the
-        * submission (by quite a lot). Increment the overflow count in
-        * the ring.
-        */
-       cqe = io_get_cqe(ctx);
-       if (likely(cqe)) {
-               memcpy(cqe, &req->cqe, sizeof(struct io_uring_cqe));
-               cqe->big_cqe[0] = extra1;
-               cqe->big_cqe[1] = extra2;
-               return true;
+               return io_cqring_event_overflow(ctx, req->cqe.user_data,
+                               req->cqe.res, req->cqe.flags,
+                               extra1, extra2);
        }
-
-       return io_cqring_event_overflow(ctx, req->cqe.user_data, req->cqe.res,
-                                       req->cqe.flags, extra1, extra2);
-}
-
-static inline bool __io_fill_cqe_req(struct io_kiocb *req, s32 res, u32 cflags)
-{
-       trace_io_uring_complete(req->ctx, req, req->cqe.user_data, res, cflags, 0, 0);
-       return __io_fill_cqe(req->ctx, req->cqe.user_data, res, cflags);
 }
 
-static inline void __io_fill_cqe32_req(struct io_kiocb *req, s32 res, u32 cflags,
-                               u64 extra1, u64 extra2)
+static noinline bool io_fill_cqe_aux(struct io_ring_ctx *ctx, u64 user_data,
+                                    s32 res, u32 cflags)
 {
-       struct io_ring_ctx *ctx = req->ctx;
        struct io_uring_cqe *cqe;
 
-       if (WARN_ON_ONCE(!(ctx->flags & IORING_SETUP_CQE32)))
-               return;
-       if (req->flags & REQ_F_CQE_SKIP)
-               return;
-
-       trace_io_uring_complete(ctx, req, req->cqe.user_data, res, cflags,
-                               extra1, extra2);
+       ctx->cq_extra++;
+       trace_io_uring_complete(ctx, NULL, user_data, res, cflags, 0, 0);
 
        /*
         * If we can't get a cq entry, userspace overflowed the
@@ -2537,23 +2515,17 @@ static inline void __io_fill_cqe32_req(struct io_kiocb *req, s32 res, u32 cflags
         */
        cqe = io_get_cqe(ctx);
        if (likely(cqe)) {
-               WRITE_ONCE(cqe->user_data, req->cqe.user_data);
+               WRITE_ONCE(cqe->user_data, user_data);
                WRITE_ONCE(cqe->res, res);
                WRITE_ONCE(cqe->flags, cflags);
-               WRITE_ONCE(cqe->big_cqe[0], extra1);
-               WRITE_ONCE(cqe->big_cqe[1], extra2);
-               return;
-       }
 
-       io_cqring_event_overflow(ctx, req->cqe.user_data, res, cflags, extra1, extra2);
-}
-
-static noinline bool io_fill_cqe_aux(struct io_ring_ctx *ctx, u64 user_data,
-                                    s32 res, u32 cflags)
-{
-       ctx->cq_extra++;
-       trace_io_uring_complete(ctx, NULL, user_data, res, cflags, 0, 0);
-       return __io_fill_cqe(ctx, user_data, res, cflags);
+               if (ctx->flags & IORING_SETUP_CQE32) {
+                       WRITE_ONCE(cqe->big_cqe[0], 0);
+                       WRITE_ONCE(cqe->big_cqe[1], 0);
+               }
+               return true;
+       }
+       return io_cqring_event_overflow(ctx, user_data, res, cflags, 0, 0);
 }
 
 static void __io_req_complete_put(struct io_kiocb *req)
@@ -2590,16 +2562,11 @@ static void __io_req_complete_put(struct io_kiocb *req)
 static void __io_req_complete_post(struct io_kiocb *req, s32 res,
                                   u32 cflags)
 {
-       if (!(req->flags & REQ_F_CQE_SKIP))
-               __io_fill_cqe_req(req, res, cflags);
-       __io_req_complete_put(req);
-}
-
-static void __io_req_complete_post32(struct io_kiocb *req, s32 res,
-                                  u32 cflags, u64 extra1, u64 extra2)
-{
-       if (!(req->flags & REQ_F_CQE_SKIP))
-               __io_fill_cqe32_req(req, res, cflags, extra1, extra2);
+       if (!(req->flags & REQ_F_CQE_SKIP)) {
+               req->cqe.res = res;
+               req->cqe.flags = cflags;
+               __io_fill_cqe_req(req->ctx, req);
+       }
        __io_req_complete_put(req);
 }
 
@@ -2614,18 +2581,6 @@ static void io_req_complete_post(struct io_kiocb *req, s32 res, u32 cflags)
        io_cqring_ev_posted(ctx);
 }
 
-static void io_req_complete_post32(struct io_kiocb *req, s32 res,
-                                  u32 cflags, u64 extra1, u64 extra2)
-{
-       struct io_ring_ctx *ctx = req->ctx;
-
-       spin_lock(&ctx->completion_lock);
-       __io_req_complete_post32(req, res, cflags, extra1, extra2);
-       io_commit_cqring(ctx);
-       spin_unlock(&ctx->completion_lock);
-       io_cqring_ev_posted(ctx);
-}
-
 static inline void io_req_complete_state(struct io_kiocb *req, s32 res,
                                         u32 cflags)
 {
@@ -2643,19 +2598,6 @@ static inline void __io_req_complete(struct io_kiocb *req, unsigned issue_flags,
                io_req_complete_post(req, res, cflags);
 }
 
-static inline void __io_req_complete32(struct io_kiocb *req,
-                                      unsigned int issue_flags, s32 res,
-                                      u32 cflags, u64 extra1, u64 extra2)
-{
-       if (issue_flags & IO_URING_F_COMPLETE_DEFER) {
-               io_req_complete_state(req, res, cflags);
-               req->extra1 = extra1;
-               req->extra2 = extra2;
-       } else {
-               io_req_complete_post32(req, res, cflags, extra1, extra2);
-       }
-}
-
 static inline void io_req_complete(struct io_kiocb *req, s32 res)
 {
        if (res < 0)
@@ -3202,12 +3144,8 @@ static void __io_submit_flush_completions(struct io_ring_ctx *ctx)
                        struct io_kiocb *req = container_of(node, struct io_kiocb,
                                                    comp_list);
 
-                       if (!(req->flags & REQ_F_CQE_SKIP)) {
-                               if (!(ctx->flags & IORING_SETUP_CQE32))
-                                       __io_fill_cqe_req_filled(ctx, req);
-                               else
-                                       __io_fill_cqe32_req_filled(ctx, req);
-                       }
+                       if (!(req->flags & REQ_F_CQE_SKIP))
+                               __io_fill_cqe_req(ctx, req);
                }
 
                io_commit_cqring(ctx);
@@ -3326,7 +3264,9 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin)
                nr_events++;
                if (unlikely(req->flags & REQ_F_CQE_SKIP))
                        continue;
-               __io_fill_cqe_req(req, req->cqe.res, io_put_kbuf(req, 0));
+
+               req->cqe.flags = io_put_kbuf(req, 0);
+               __io_fill_cqe_req(req->ctx, req);
        }
 
        if (unlikely(!nr_events))
@@ -3677,6 +3617,20 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        int ret;
 
        kiocb->ki_pos = READ_ONCE(sqe->off);
+       /* used for fixed read/write too - just read unconditionally */
+       req->buf_index = READ_ONCE(sqe->buf_index);
+
+       if (req->opcode == IORING_OP_READ_FIXED ||
+           req->opcode == IORING_OP_WRITE_FIXED) {
+               struct io_ring_ctx *ctx = req->ctx;
+               u16 index;
+
+               if (unlikely(req->buf_index >= ctx->nr_user_bufs))
+                       return -EFAULT;
+               index = array_index_nospec(req->buf_index, ctx->nr_user_bufs);
+               req->imu = ctx->user_bufs[index];
+               io_req_set_rsrc_node(req, ctx, 0);
+       }
 
        ioprio = READ_ONCE(sqe->ioprio);
        if (ioprio) {
@@ -3689,12 +3643,9 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                kiocb->ki_ioprio = get_current_ioprio();
        }
 
-       req->imu = NULL;
        req->rw.addr = READ_ONCE(sqe->addr);
        req->rw.len = READ_ONCE(sqe->len);
        req->rw.flags = READ_ONCE(sqe->rw_flags);
-       /* used for fixed read/write too - just read unconditionally */
-       req->buf_index = READ_ONCE(sqe->buf_index);
        return 0;
 }
 
@@ -3826,20 +3777,9 @@ static int __io_import_fixed(struct io_kiocb *req, int rw, struct iov_iter *iter
 static int io_import_fixed(struct io_kiocb *req, int rw, struct iov_iter *iter,
                           unsigned int issue_flags)
 {
-       struct io_mapped_ubuf *imu = req->imu;
-       u16 index, buf_index = req->buf_index;
-
-       if (likely(!imu)) {
-               struct io_ring_ctx *ctx = req->ctx;
-
-               if (unlikely(buf_index >= ctx->nr_user_bufs))
-                       return -EFAULT;
-               io_req_set_rsrc_node(req, ctx, issue_flags);
-               index = array_index_nospec(buf_index, ctx->nr_user_bufs);
-               imu = READ_ONCE(ctx->user_bufs[index]);
-               req->imu = imu;
-       }
-       return __io_import_fixed(req, rw, iter, imu);
+       if (WARN_ON_ONCE(!req->imu))
+               return -EFAULT;
+       return __io_import_fixed(req, rw, iter, req->imu);
 }
 
 static int io_buffer_add_list(struct io_ring_ctx *ctx,
@@ -3876,19 +3816,17 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
 {
        struct io_uring_buf_ring *br = bl->buf_ring;
        struct io_uring_buf *buf;
-       __u32 head = bl->head;
+       __u16 head = bl->head;
 
-       if (unlikely(smp_load_acquire(&br->tail) == head)) {
-               io_ring_submit_unlock(req->ctx, issue_flags);
+       if (unlikely(smp_load_acquire(&br->tail) == head))
                return NULL;
-       }
 
        head &= bl->mask;
        if (head < IO_BUFFER_LIST_BUF_PER_PAGE) {
                buf = &br->bufs[head];
        } else {
                int off = head & (IO_BUFFER_LIST_BUF_PER_PAGE - 1);
-               int index = head / IO_BUFFER_LIST_BUF_PER_PAGE - 1;
+               int index = head / IO_BUFFER_LIST_BUF_PER_PAGE;
                buf = page_address(bl->buf_pages[index]);
                buf += off;
        }
@@ -3898,7 +3836,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
        req->buf_list = bl;
        req->buf_index = buf->bid;
 
-       if (issue_flags & IO_URING_F_UNLOCKED) {
+       if (issue_flags & IO_URING_F_UNLOCKED || !file_can_poll(req->file)) {
                /*
                 * If we came in unlocked, we have no choice but to consume the
                 * buffer here. This does mean it'll be pinned until the IO
@@ -5079,10 +5017,18 @@ void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
 
        req->uring_cmd.task_work_cb = task_work_cb;
        req->io_task_work.func = io_uring_cmd_work;
-       io_req_task_prio_work_add(req);
+       io_req_task_work_add(req);
 }
 EXPORT_SYMBOL_GPL(io_uring_cmd_complete_in_task);
 
+static inline void io_req_set_cqe32_extra(struct io_kiocb *req,
+                                         u64 extra1, u64 extra2)
+{
+       req->extra1 = extra1;
+       req->extra2 = extra2;
+       req->flags |= REQ_F_CQE32_INIT;
+}
+
 /*
  * Called by consumers of io_uring_cmd, if they originally returned
  * -EIOCBQUEUED upon receiving the command.
@@ -5093,10 +5039,10 @@ void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2)
 
        if (ret < 0)
                req_set_fail(req);
+
        if (req->ctx->flags & IORING_SETUP_CQE32)
-               __io_req_complete32(req, 0, ret, 0, res2, 0);
-       else
-               io_req_complete(req, ret);
+               io_req_set_cqe32_extra(req, res2, 0);
+       io_req_complete(req, ret);
 }
 EXPORT_SYMBOL_GPL(io_uring_cmd_done);
 
@@ -5258,14 +5204,6 @@ done:
 
 static int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
-       /*
-        * If the ring is setup with CQE32, relay back addr/addr
-        */
-       if (req->ctx->flags & IORING_SETUP_CQE32) {
-               req->nop.extra1 = READ_ONCE(sqe->addr);
-               req->nop.extra2 = READ_ONCE(sqe->addr2);
-       }
-
        return 0;
 }
 
@@ -5274,23 +5212,7 @@ static int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  */
 static int io_nop(struct io_kiocb *req, unsigned int issue_flags)
 {
-       unsigned int cflags;
-       void __user *buf;
-
-       if (req->flags & REQ_F_BUFFER_SELECT) {
-               size_t len = 1;
-
-               buf = io_buffer_select(req, &len, issue_flags);
-               if (!buf)
-                       return -ENOBUFS;
-       }
-
-       cflags = io_put_kbuf(req, issue_flags);
-       if (!(req->ctx->flags & IORING_SETUP_CQE32))
-               __io_req_complete(req, issue_flags, 0, cflags);
-       else
-               __io_req_complete32(req, issue_flags, 0, cflags,
-                                   req->nop.extra1, req->nop.extra2);
+       __io_req_complete(req, issue_flags, 0, 0);
        return 0;
 }
 
@@ -5988,18 +5910,14 @@ static int io_statx(struct io_kiocb *req, unsigned int issue_flags)
 
 static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
-       if (sqe->off || sqe->addr || sqe->len || sqe->buf_index)
+       if (sqe->off || sqe->addr || sqe->len || sqe->rw_flags || sqe->buf_index)
                return -EINVAL;
        if (req->flags & REQ_F_FIXED_FILE)
                return -EBADF;
 
        req->close.fd = READ_ONCE(sqe->fd);
        req->close.file_slot = READ_ONCE(sqe->file_index);
-       req->close.flags = READ_ONCE(sqe->close_flags);
-       if (req->close.flags & ~IORING_CLOSE_FD_AND_FILE_SLOT)
-               return -EINVAL;
-       if (!(req->close.flags & IORING_CLOSE_FD_AND_FILE_SLOT) &&
-           req->close.file_slot && req->close.fd)
+       if (req->close.file_slot && req->close.fd)
                return -EINVAL;
 
        return 0;
@@ -6015,8 +5933,7 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
 
        if (req->close.file_slot) {
                ret = io_close_fixed(req, issue_flags);
-               if (ret || !(req->close.flags & IORING_CLOSE_FD_AND_FILE_SLOT))
-                       goto err;
+               goto err;
        }
 
        spin_lock(&files->file_lock);
@@ -8063,8 +7980,8 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req,
                if (ret < 0)
                        break;
                if (copy_to_user(&fds[done], &ret, sizeof(ret))) {
-                       ret = -EFAULT;
                        __io_close_fixed(req, issue_flags, ret);
+                       ret = -EFAULT;
                        break;
                }
        }
@@ -8773,6 +8690,7 @@ static void io_queue_async(struct io_kiocb *req, int ret)
                 * Queued up for async execution, worker will release
                 * submit reference when the iocb is actually submitted.
                 */
+               io_kbuf_recycle(req, 0);
                io_queue_iowq(req, NULL);
                break;
        case IO_APOLL_OK:
@@ -9788,11 +9706,19 @@ static void __io_sqe_files_unregister(struct io_ring_ctx *ctx)
 
 static int io_sqe_files_unregister(struct io_ring_ctx *ctx)
 {
+       unsigned nr = ctx->nr_user_files;
        int ret;
 
        if (!ctx->file_data)
                return -ENXIO;
+
+       /*
+        * Quiesce may unlock ->uring_lock, and while it's not held
+        * prevent new requests using the table.
+        */
+       ctx->nr_user_files = 0;
        ret = io_rsrc_ref_quiesce(ctx->file_data, ctx);
+       ctx->nr_user_files = nr;
        if (!ret)
                __io_sqe_files_unregister(ctx);
        return ret;
@@ -10690,12 +10616,19 @@ static void __io_sqe_buffers_unregister(struct io_ring_ctx *ctx)
 
 static int io_sqe_buffers_unregister(struct io_ring_ctx *ctx)
 {
+       unsigned nr = ctx->nr_user_bufs;
        int ret;
 
        if (!ctx->buf_data)
                return -ENXIO;
 
+       /*
+        * Quiesce may unlock ->uring_lock, and while it's not held
+        * prevent new requests using the table.
+        */
+       ctx->nr_user_bufs = 0;
        ret = io_rsrc_ref_quiesce(ctx->buf_data, ctx);
+       ctx->nr_user_bufs = nr;
        if (!ret)
                __io_sqe_buffers_unregister(ctx);
        return ret;
@@ -13002,6 +12935,10 @@ static int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
        if (!is_power_of_2(reg.ring_entries))
                return -EINVAL;
 
+       /* cannot disambiguate full vs empty due to head/tail size */
+       if (reg.ring_entries >= 65536)
+               return -EINVAL;
+
        if (unlikely(reg.bgid < BGID_ARRAY && !ctx->io_bl)) {
                int ret = io_init_bl_list(ctx);
                if (ret)
index 8742d22dfd2b240ee9695af5c284b5b4b44cbb3c..42f892c5712eae9daead74227a202ab8e5b4aa0e 100644 (file)
@@ -155,7 +155,7 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq,
 void netfs_readahead(struct readahead_control *ractl)
 {
        struct netfs_io_request *rreq;
-       struct netfs_i_context *ctx = netfs_i_context(ractl->mapping->host);
+       struct netfs_inode *ctx = netfs_inode(ractl->mapping->host);
        int ret;
 
        _enter("%lx,%x", readahead_index(ractl), readahead_count(ractl));
@@ -215,7 +215,7 @@ int netfs_read_folio(struct file *file, struct folio *folio)
 {
        struct address_space *mapping = folio_file_mapping(folio);
        struct netfs_io_request *rreq;
-       struct netfs_i_context *ctx = netfs_i_context(mapping->host);
+       struct netfs_inode *ctx = netfs_inode(mapping->host);
        int ret;
 
        _enter("%lx", folio_index(folio));
@@ -297,6 +297,7 @@ zero_out:
 
 /**
  * netfs_write_begin - Helper to prepare for writing
+ * @ctx: The netfs context
  * @file: The file to read from
  * @mapping: The mapping to read from
  * @pos: File position at which the write will begin
@@ -326,12 +327,12 @@ zero_out:
  *
  * This is usable whether or not caching is enabled.
  */
-int netfs_write_begin(struct file *file, struct address_space *mapping,
+int netfs_write_begin(struct netfs_inode *ctx,
+                     struct file *file, struct address_space *mapping,
                      loff_t pos, unsigned int len, struct folio **_folio,
                      void **_fsdata)
 {
        struct netfs_io_request *rreq;
-       struct netfs_i_context *ctx = netfs_i_context(file_inode(file ));
        struct folio *folio;
        unsigned int fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE;
        pgoff_t index = pos >> PAGE_SHIFT;
index b7b0e3d18d9e8583d9b2bceb6e9661e8768f3ac6..43fac1b14e40cd1351cbac875d1886b0a9256835 100644 (file)
@@ -91,7 +91,7 @@ static inline void netfs_stat_d(atomic_t *stat)
 /*
  * Miscellaneous functions.
  */
-static inline bool netfs_is_cache_enabled(struct netfs_i_context *ctx)
+static inline bool netfs_is_cache_enabled(struct netfs_inode *ctx)
 {
 #if IS_ENABLED(CONFIG_FSCACHE)
        struct fscache_cookie *cookie = ctx->cache;
index e86107b30ba443ba783ac28eb66126ce61488e93..e17cdf53f6a7883a3459c47d5695554e516f4c51 100644 (file)
@@ -18,7 +18,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
 {
        static atomic_t debug_ids;
        struct inode *inode = file ? file_inode(file) : mapping->host;
-       struct netfs_i_context *ctx = netfs_i_context(inode);
+       struct netfs_inode *ctx = netfs_inode(inode);
        struct netfs_io_request *rreq;
        int ret;
 
@@ -75,10 +75,10 @@ static void netfs_free_request(struct work_struct *work)
        struct netfs_io_request *rreq =
                container_of(work, struct netfs_io_request, work);
 
-       netfs_clear_subrequests(rreq, false);
-       if (rreq->netfs_priv)
-               rreq->netfs_ops->cleanup(rreq->mapping, rreq->netfs_priv);
        trace_netfs_rreq(rreq, netfs_rreq_trace_free);
+       netfs_clear_subrequests(rreq, false);
+       if (rreq->netfs_ops->free_request)
+               rreq->netfs_ops->free_request(rreq);
        if (rreq->cache_resources.ops)
                rreq->cache_resources.ops->end_operation(&rreq->cache_resources);
        kfree(rreq);
index f172412447f5db2d2b123f6efdf94ac5aa60bc3a..9cb2d590c0361b80fb4531e0b634d78ac6fd7600 100644 (file)
@@ -309,11 +309,12 @@ nfsd_file_put(struct nfsd_file *nf)
        if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) {
                nfsd_file_flush(nf);
                nfsd_file_put_noref(nf);
-       } else {
+       } else if (nf->nf_file) {
                nfsd_file_put_noref(nf);
-               if (nf->nf_file)
-                       nfsd_file_schedule_laundrette();
-       }
+               nfsd_file_schedule_laundrette();
+       } else
+               nfsd_file_put_noref(nf);
+
        if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
                nfsd_file_gc();
 }
index a74aef99bd3d6105b07da8ee90f07f1ff15d0c69..09d1307959d085720769839b95f5c99f0478de78 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/capability.h>
 #include <linux/quotaops.h>
 #include <linux/blkdev.h>
+#include <linux/sched/mm.h>
 #include "../internal.h" /* ugh */
 
 #include <linux/uaccess.h>
@@ -425,9 +426,11 @@ EXPORT_SYMBOL(mark_info_dirty);
 int dquot_acquire(struct dquot *dquot)
 {
        int ret = 0, ret2 = 0;
+       unsigned int memalloc;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        mutex_lock(&dquot->dq_lock);
+       memalloc = memalloc_nofs_save();
        if (!test_bit(DQ_READ_B, &dquot->dq_flags)) {
                ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot);
                if (ret < 0)
@@ -458,6 +461,7 @@ int dquot_acquire(struct dquot *dquot)
        smp_mb__before_atomic();
        set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
 out_iolock:
+       memalloc_nofs_restore(memalloc);
        mutex_unlock(&dquot->dq_lock);
        return ret;
 }
@@ -469,9 +473,11 @@ EXPORT_SYMBOL(dquot_acquire);
 int dquot_commit(struct dquot *dquot)
 {
        int ret = 0;
+       unsigned int memalloc;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        mutex_lock(&dquot->dq_lock);
+       memalloc = memalloc_nofs_save();
        if (!clear_dquot_dirty(dquot))
                goto out_lock;
        /* Inactive dquot can be only if there was error during read/init
@@ -481,6 +487,7 @@ int dquot_commit(struct dquot *dquot)
        else
                ret = -EIO;
 out_lock:
+       memalloc_nofs_restore(memalloc);
        mutex_unlock(&dquot->dq_lock);
        return ret;
 }
@@ -492,9 +499,11 @@ EXPORT_SYMBOL(dquot_commit);
 int dquot_release(struct dquot *dquot)
 {
        int ret = 0, ret2 = 0;
+       unsigned int memalloc;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        mutex_lock(&dquot->dq_lock);
+       memalloc = memalloc_nofs_save();
        /* Check whether we are not racing with some other dqget() */
        if (dquot_is_busy(dquot))
                goto out_dqlock;
@@ -510,6 +519,7 @@ int dquot_release(struct dquot *dquot)
        }
        clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
 out_dqlock:
+       memalloc_nofs_restore(memalloc);
        mutex_unlock(&dquot->dq_lock);
        return ret;
 }
index bcb21aea990aeb98ce3695139762110af5fe3a88..053299758deb98abfe8a2154dd14fb6e32646a07 100644 (file)
@@ -110,15 +110,51 @@ static inline void zonefs_i_size_write(struct inode *inode, loff_t isize)
        }
 }
 
-static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
-                             unsigned int flags, struct iomap *iomap,
-                             struct iomap *srcmap)
+static int zonefs_read_iomap_begin(struct inode *inode, loff_t offset,
+                                  loff_t length, unsigned int flags,
+                                  struct iomap *iomap, struct iomap *srcmap)
 {
        struct zonefs_inode_info *zi = ZONEFS_I(inode);
        struct super_block *sb = inode->i_sb;
        loff_t isize;
 
-       /* All I/Os should always be within the file maximum size */
+       /*
+        * All blocks are always mapped below EOF. If reading past EOF,
+        * act as if there is a hole up to the file maximum size.
+        */
+       mutex_lock(&zi->i_truncate_mutex);
+       iomap->bdev = inode->i_sb->s_bdev;
+       iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
+       isize = i_size_read(inode);
+       if (iomap->offset >= isize) {
+               iomap->type = IOMAP_HOLE;
+               iomap->addr = IOMAP_NULL_ADDR;
+               iomap->length = length;
+       } else {
+               iomap->type = IOMAP_MAPPED;
+               iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
+               iomap->length = isize - iomap->offset;
+       }
+       mutex_unlock(&zi->i_truncate_mutex);
+
+       trace_zonefs_iomap_begin(inode, iomap);
+
+       return 0;
+}
+
+static const struct iomap_ops zonefs_read_iomap_ops = {
+       .iomap_begin    = zonefs_read_iomap_begin,
+};
+
+static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset,
+                                   loff_t length, unsigned int flags,
+                                   struct iomap *iomap, struct iomap *srcmap)
+{
+       struct zonefs_inode_info *zi = ZONEFS_I(inode);
+       struct super_block *sb = inode->i_sb;
+       loff_t isize;
+
+       /* All write I/Os should always be within the file maximum size */
        if (WARN_ON_ONCE(offset + length > zi->i_max_size))
                return -EIO;
 
@@ -128,7 +164,7 @@ static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
         * operation.
         */
        if (WARN_ON_ONCE(zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
-                        (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT)))
+                        !(flags & IOMAP_DIRECT)))
                return -EIO;
 
        /*
@@ -137,47 +173,44 @@ static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
         * write pointer) and unwriten beyond.
         */
        mutex_lock(&zi->i_truncate_mutex);
+       iomap->bdev = inode->i_sb->s_bdev;
+       iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
+       iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
        isize = i_size_read(inode);
-       if (offset >= isize)
+       if (iomap->offset >= isize) {
                iomap->type = IOMAP_UNWRITTEN;
-       else
+               iomap->length = zi->i_max_size - iomap->offset;
+       } else {
                iomap->type = IOMAP_MAPPED;
-       if (flags & IOMAP_WRITE)
-               length = zi->i_max_size - offset;
-       else
-               length = min(length, isize - offset);
+               iomap->length = isize - iomap->offset;
+       }
        mutex_unlock(&zi->i_truncate_mutex);
 
-       iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
-       iomap->length = ALIGN(offset + length, sb->s_blocksize) - iomap->offset;
-       iomap->bdev = inode->i_sb->s_bdev;
-       iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
-
        trace_zonefs_iomap_begin(inode, iomap);
 
        return 0;
 }
 
-static const struct iomap_ops zonefs_iomap_ops = {
-       .iomap_begin    = zonefs_iomap_begin,
+static const struct iomap_ops zonefs_write_iomap_ops = {
+       .iomap_begin    = zonefs_write_iomap_begin,
 };
 
 static int zonefs_read_folio(struct file *unused, struct folio *folio)
 {
-       return iomap_read_folio(folio, &zonefs_iomap_ops);
+       return iomap_read_folio(folio, &zonefs_read_iomap_ops);
 }
 
 static void zonefs_readahead(struct readahead_control *rac)
 {
-       iomap_readahead(rac, &zonefs_iomap_ops);
+       iomap_readahead(rac, &zonefs_read_iomap_ops);
 }
 
 /*
  * Map blocks for page writeback. This is used only on conventional zone files,
  * which implies that the page range can only be within the fixed inode size.
  */
-static int zonefs_map_blocks(struct iomap_writepage_ctx *wpc,
-                            struct inode *inode, loff_t offset)
+static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc,
+                                  struct inode *inode, loff_t offset)
 {
        struct zonefs_inode_info *zi = ZONEFS_I(inode);
 
@@ -191,12 +224,12 @@ static int zonefs_map_blocks(struct iomap_writepage_ctx *wpc,
            offset < wpc->iomap.offset + wpc->iomap.length)
                return 0;
 
-       return zonefs_iomap_begin(inode, offset, zi->i_max_size - offset,
-                                 IOMAP_WRITE, &wpc->iomap, NULL);
+       return zonefs_write_iomap_begin(inode, offset, zi->i_max_size - offset,
+                                       IOMAP_WRITE, &wpc->iomap, NULL);
 }
 
 static const struct iomap_writeback_ops zonefs_writeback_ops = {
-       .map_blocks             = zonefs_map_blocks,
+       .map_blocks             = zonefs_write_map_blocks,
 };
 
 static int zonefs_writepage(struct page *page, struct writeback_control *wbc)
@@ -226,7 +259,8 @@ static int zonefs_swap_activate(struct swap_info_struct *sis,
                return -EINVAL;
        }
 
-       return iomap_swapfile_activate(sis, swap_file, span, &zonefs_iomap_ops);
+       return iomap_swapfile_activate(sis, swap_file, span,
+                                      &zonefs_read_iomap_ops);
 }
 
 static const struct address_space_operations zonefs_file_aops = {
@@ -647,7 +681,7 @@ static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf)
 
        /* Serialize against truncates */
        filemap_invalidate_lock_shared(inode->i_mapping);
-       ret = iomap_page_mkwrite(vmf, &zonefs_iomap_ops);
+       ret = iomap_page_mkwrite(vmf, &zonefs_write_iomap_ops);
        filemap_invalidate_unlock_shared(inode->i_mapping);
 
        sb_end_pagefault(inode->i_sb);
@@ -899,7 +933,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
        if (append)
                ret = zonefs_file_dio_append(iocb, from);
        else
-               ret = iomap_dio_rw(iocb, from, &zonefs_iomap_ops,
+               ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops,
                                   &zonefs_write_dio_ops, 0, NULL, 0);
        if (zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
            (ret > 0 || ret == -EIOCBQUEUED)) {
@@ -948,7 +982,7 @@ static ssize_t zonefs_file_buffered_write(struct kiocb *iocb,
        if (ret <= 0)
                goto inode_unlock;
 
-       ret = iomap_file_buffered_write(iocb, from, &zonefs_iomap_ops);
+       ret = iomap_file_buffered_write(iocb, from, &zonefs_write_iomap_ops);
        if (ret > 0)
                iocb->ki_pos += ret;
        else if (ret == -EIO)
@@ -1041,7 +1075,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
                        goto inode_unlock;
                }
                file_accessed(iocb->ki_filp);
-               ret = iomap_dio_rw(iocb, to, &zonefs_iomap_ops,
+               ret = iomap_dio_rw(iocb, to, &zonefs_read_iomap_ops,
                                   &zonefs_read_dio_ops, 0, NULL, 0);
        } else {
                ret = generic_file_read_iter(iocb, to);
@@ -1085,7 +1119,8 @@ static int zonefs_seq_file_write_open(struct inode *inode)
 
                if (sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) {
 
-                       if (wro > sbi->s_max_wro_seq_files) {
+                       if (sbi->s_max_wro_seq_files
+                           && wro > sbi->s_max_wro_seq_files) {
                                atomic_dec(&sbi->s_wro_seq_files);
                                ret = -EBUSY;
                                goto unlock;
@@ -1760,12 +1795,6 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
 
        atomic_set(&sbi->s_wro_seq_files, 0);
        sbi->s_max_wro_seq_files = bdev_max_open_zones(sb->s_bdev);
-       if (!sbi->s_max_wro_seq_files &&
-           sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) {
-               zonefs_info(sb, "No open zones limit. Ignoring explicit_open mount option\n");
-               sbi->s_mount_opts &= ~ZONEFS_MNTOPT_EXPLICIT_OPEN;
-       }
-
        atomic_set(&sbi->s_active_seq_files, 0);
        sbi->s_max_active_seq_files = bdev_max_active_zones(sb->s_bdev);
 
@@ -1790,6 +1819,14 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
        zonefs_info(sb, "Mounting %u zones",
                    blkdev_nr_zones(sb->s_bdev->bd_disk));
 
+       if (!sbi->s_max_wro_seq_files &&
+           !sbi->s_max_active_seq_files &&
+           sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) {
+               zonefs_info(sb,
+                       "No open and active zone limits. Ignoring explicit_open mount option\n");
+               sbi->s_mount_opts &= ~ZONEFS_MNTOPT_EXPLICIT_OPEN;
+       }
+
        /* Create root directory inode */
        ret = -ENOMEM;
        inode = new_inode(sb);
index 302506bbc2a4f73218fad6e4d2b2c7a685ec6959..8e47d483b524073aec44f94c6d6ab7ed9fea8b5d 100644 (file)
@@ -44,6 +44,7 @@ mandatory-y += msi.h
 mandatory-y += pci.h
 mandatory-y += percpu.h
 mandatory-y += pgalloc.h
+mandatory-y += platform-feature.h
 mandatory-y += preempt.h
 mandatory-y += rwonce.h
 mandatory-y += sections.h
diff --git a/include/asm-generic/platform-feature.h b/include/asm-generic/platform-feature.h
new file mode 100644 (file)
index 0000000..4b0af3d
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_PLATFORM_FEATURE_H
+#define _ASM_GENERIC_PLATFORM_FEATURE_H
+
+/* Number of arch specific feature flags. */
+#define PLATFORM_ARCH_FEAT_N   0
+
+#endif /* _ASM_GENERIC_PLATFORM_FEATURE_H */
index 0777725085df63199ca6005a04d5976b0ede71fb..10b1990bc1f68e5f2251c2deb8813de03e20ab25 100644 (file)
@@ -1022,6 +1022,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
        for ((__i) = 0; \
             (__i) < (__state)->num_private_objs && \
                     ((obj) = (__state)->private_objs[__i].ptr, \
+                     (void)(obj) /* Only to avoid unused-but-set-variable warning */, \
                      (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \
             (__i)++)
 
index 441653693970c6f4c1bab860d8411aed1d832d92..ca89a48c24609072ecbcf2e174e77f6e8ddf2151 100644 (file)
@@ -311,12 +311,12 @@ ttm_resource_manager_cleanup(struct ttm_resource_manager *man)
 }
 
 void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk);
-void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
-                          struct ttm_resource *res);
-void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
-                          struct ttm_resource *res);
 void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk);
 
+void ttm_resource_add_bulk_move(struct ttm_resource *res,
+                               struct ttm_buffer_object *bo);
+void ttm_resource_del_bulk_move(struct ttm_resource *res,
+                               struct ttm_buffer_object *bo);
 void ttm_resource_move_to_lru_tail(struct ttm_resource *res);
 
 void ttm_resource_init(struct ttm_buffer_object *bo,
index 2bd073fa6bb53ebd0efad023e3ba8c836c56b691..d452071db572e1f402f9d751458b2c7a21c84fdd 100644 (file)
@@ -119,6 +119,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
 
 extern struct backing_dev_info noop_backing_dev_info;
 
+int bdi_init(struct backing_dev_info *bdi);
+
 /**
  * writeback_in_progress - determine whether there is writeback in progress
  * @wb: bdi_writeback of interest
index 1cf3738ef1ea6d794271bc619a3072c1474ce46a..992ee987f2738568122d433bcc2e0b4b413a2ceb 100644 (file)
@@ -403,7 +403,6 @@ enum {
 extern int bioset_init(struct bio_set *, unsigned int, unsigned int, int flags);
 extern void bioset_exit(struct bio_set *);
 extern int biovec_init_pool(mempool_t *pool, int pool_entries);
-extern int bioset_init_from_src(struct bio_set *bs, struct bio_set *src);
 
 struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
                             unsigned int opf, gfp_t gfp_mask,
index 608d577734c299301e06445ee9005ce3621e4a61..bb6e3c31b3b7b31fadfeb3bdb22a3c23699614cf 100644 (file)
@@ -575,6 +575,7 @@ struct request_queue {
 #define QUEUE_FLAG_RQ_ALLOC_TIME 27    /* record rq->alloc_time_ns */
 #define QUEUE_FLAG_HCTX_ACTIVE 28      /* at least one blk-mq hctx is active */
 #define QUEUE_FLAG_NOWAIT       29     /* device supports NOWAIT */
+#define QUEUE_FLAG_SQ_SCHED     30     /* single queue style io dispatch */
 
 #define QUEUE_FLAG_MQ_DEFAULT  ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_SAME_COMP) |          \
@@ -616,6 +617,7 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
 #define blk_queue_pm_only(q)   atomic_read(&(q)->pm_only)
 #define blk_queue_registered(q)        test_bit(QUEUE_FLAG_REGISTERED, &(q)->queue_flags)
 #define blk_queue_nowait(q)    test_bit(QUEUE_FLAG_NOWAIT, &(q)->queue_flags)
+#define blk_queue_sq_sched(q)  test_bit(QUEUE_FLAG_SQ_SCHED, &(q)->queue_flags)
 
 extern void blk_set_pm_only(struct request_queue *q);
 extern void blk_clear_pm_only(struct request_queue *q);
@@ -1006,8 +1008,6 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
  */
 /* Supports zoned block devices sequential write constraint */
 #define ELEVATOR_F_ZBD_SEQ_WRITE       (1U << 0)
-/* Supports scheduling on multiple hardware queues */
-#define ELEVATOR_F_MQ_AWARE            (1U << 1)
 
 extern void blk_queue_required_elevator_features(struct request_queue *q,
                                                 unsigned int features);
index 54dc2f9a2d56e9f43cac9ef4e30600152c2230fd..2c74773547444e6ab4eb185d8eb62f5e06c6fe65 100644 (file)
@@ -65,6 +65,9 @@ extern ssize_t cpu_show_tsx_async_abort(struct device *dev,
 extern ssize_t cpu_show_itlb_multihit(struct device *dev,
                                      struct device_attribute *attr, char *buf);
 extern ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *buf);
+extern ssize_t cpu_show_mmio_stale_data(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf);
 
 extern __printf(4, 5)
 struct device *cpu_device_create(struct device *parent, void *drvdata,
index a4367051e192c1c9abefb79fd7a5bf5413dfaeeb..2f991a427aded803da2bf7365662e18eb76451a3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Implements the standard CRC ITU-T V.41:
  *   Width 16
- *   Poly  0x1021 (x^16 + x^12 + x^15 + 1)
+ *   Poly  0x1021 (x^16 + x^12 + x^5 + 1)
  *   Init  0
  */
 
index 732de90146261feadadb7a8eca01341fb9d66f33..0f2a59c9c735a92f54a6ee02a066d393f0e016c5 100644 (file)
@@ -822,7 +822,6 @@ struct ata_port {
        struct ata_queued_cmd   qcmd[ATA_MAX_QUEUE + 1];
        u64                     qc_active;
        int                     nr_active_links; /* #links with active qcs */
-       unsigned int            sas_last_tag;   /* track next tag hw expects */
 
        struct ata_link         link;           /* host default link */
        struct ata_link         *slave_link;    /* see ata_slave_link_init() */
index b34ff2cdbc4face79515b1881188c3e89f36034f..c29ab4c0cd5c661d3b7d13a377c1c36dd72c07ce 100644 (file)
@@ -227,6 +227,7 @@ struct page {
  * struct folio - Represents a contiguous set of bytes.
  * @flags: Identical to the page flags.
  * @lru: Least Recently Used list; tracks how recently this folio was used.
+ * @mlock_count: Number of times this folio has been pinned by mlock().
  * @mapping: The file this page belongs to, or refers to the anon_vma for
  *    anonymous memory.
  * @index: Offset within the file, in units of pages.  For anonymous memory,
@@ -255,10 +256,14 @@ struct folio {
                        unsigned long flags;
                        union {
                                struct list_head lru;
+       /* private: avoid cluttering the output */
                                struct {
                                        void *__filler;
+       /* public: */
                                        unsigned int mlock_count;
+       /* private: */
                                };
+       /* public: */
                        };
                        struct address_space *mapping;
                        pgoff_t index;
index 77fa6a61706a55493985869541ba2f270c8ed055..1773e5df8e65ba3c3e1cd563fc4f3e311ecacaf6 100644 (file)
@@ -119,9 +119,10 @@ typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
                                      bool was_async);
 
 /*
- * Per-inode description.  This must be directly after the inode struct.
+ * Per-inode context.  This wraps the VFS inode.
  */
-struct netfs_i_context {
+struct netfs_inode {
+       struct inode            inode;          /* The VFS inode */
        const struct netfs_request_ops *ops;
 #if IS_ENABLED(CONFIG_FSCACHE)
        struct fscache_cookie   *cache;
@@ -205,7 +206,9 @@ struct netfs_io_request {
  */
 struct netfs_request_ops {
        int (*init_request)(struct netfs_io_request *rreq, struct file *file);
+       void (*free_request)(struct netfs_io_request *rreq);
        int (*begin_cache_operation)(struct netfs_io_request *rreq);
+
        void (*expand_readahead)(struct netfs_io_request *rreq);
        bool (*clamp_length)(struct netfs_io_subrequest *subreq);
        void (*issue_read)(struct netfs_io_subrequest *subreq);
@@ -213,7 +216,6 @@ struct netfs_request_ops {
        int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
                                 struct folio *folio, void **_fsdata);
        void (*done)(struct netfs_io_request *rreq);
-       void (*cleanup)(struct address_space *mapping, void *netfs_priv);
 };
 
 /*
@@ -256,7 +258,7 @@ struct netfs_cache_ops {
         * boundary as appropriate.
         */
        enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq,
-                                              loff_t i_size);
+                                            loff_t i_size);
 
        /* Prepare a write operation, working out what part of the write we can
         * actually do.
@@ -276,7 +278,8 @@ struct netfs_cache_ops {
 struct readahead_control;
 extern void netfs_readahead(struct readahead_control *);
 int netfs_read_folio(struct file *, struct folio *);
-extern int netfs_write_begin(struct file *, struct address_space *,
+extern int netfs_write_begin(struct netfs_inode *,
+                            struct file *, struct address_space *,
                             loff_t, unsigned int, struct folio **,
                             void **);
 
@@ -288,71 +291,56 @@ extern void netfs_put_subrequest(struct netfs_io_subrequest *subreq,
 extern void netfs_stats_show(struct seq_file *);
 
 /**
- * netfs_i_context - Get the netfs inode context from the inode
+ * netfs_inode - Get the netfs inode context from the inode
  * @inode: The inode to query
  *
  * Get the netfs lib inode context from the network filesystem's inode.  The
  * context struct is expected to directly follow on from the VFS inode struct.
  */
-static inline struct netfs_i_context *netfs_i_context(struct inode *inode)
-{
-       return (void *)inode + sizeof(*inode);
-}
-
-/**
- * netfs_inode - Get the netfs inode from the inode context
- * @ctx: The context to query
- *
- * Get the netfs inode from the netfs library's inode context.  The VFS inode
- * is expected to directly precede the context struct.
- */
-static inline struct inode *netfs_inode(struct netfs_i_context *ctx)
+static inline struct netfs_inode *netfs_inode(struct inode *inode)
 {
-       return (void *)ctx - sizeof(struct inode);
+       return container_of(inode, struct netfs_inode, inode);
 }
 
 /**
- * netfs_i_context_init - Initialise a netfs lib context
- * @inode: The inode with which the context is associated
+ * netfs_inode_init - Initialise a netfslib inode context
+ * @ctx: The netfs inode to initialise
  * @ops: The netfs's operations list
  *
  * Initialise the netfs library context struct.  This is expected to follow on
  * directly from the VFS inode struct.
  */
-static inline void netfs_i_context_init(struct inode *inode,
-                                       const struct netfs_request_ops *ops)
+static inline void netfs_inode_init(struct netfs_inode *ctx,
+                                   const struct netfs_request_ops *ops)
 {
-       struct netfs_i_context *ctx = netfs_i_context(inode);
-
-       memset(ctx, 0, sizeof(*ctx));
        ctx->ops = ops;
-       ctx->remote_i_size = i_size_read(inode);
+       ctx->remote_i_size = i_size_read(&ctx->inode);
+#if IS_ENABLED(CONFIG_FSCACHE)
+       ctx->cache = NULL;
+#endif
 }
 
 /**
  * netfs_resize_file - Note that a file got resized
- * @inode: The inode being resized
+ * @ctx: The netfs inode being resized
  * @new_i_size: The new file size
  *
  * Inform the netfs lib that a file got resized so that it can adjust its state.
  */
-static inline void netfs_resize_file(struct inode *inode, loff_t new_i_size)
+static inline void netfs_resize_file(struct netfs_inode *ctx, loff_t new_i_size)
 {
-       struct netfs_i_context *ctx = netfs_i_context(inode);
-
        ctx->remote_i_size = new_i_size;
 }
 
 /**
  * netfs_i_cookie - Get the cache cookie from the inode
- * @inode: The inode to query
+ * @ctx: The netfs inode to query
  *
  * Get the caching cookie (if enabled) from the network filesystem's inode.
  */
-static inline struct fscache_cookie *netfs_i_cookie(struct inode *inode)
+static inline struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx)
 {
 #if IS_ENABLED(CONFIG_FSCACHE)
-       struct netfs_i_context *ctx = netfs_i_context(inode);
        return ctx->cache;
 #else
        return NULL;
diff --git a/include/linux/platform-feature.h b/include/linux/platform-feature.h
new file mode 100644 (file)
index 0000000..b2f48be
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _PLATFORM_FEATURE_H
+#define _PLATFORM_FEATURE_H
+
+#include <linux/bitops.h>
+#include <asm/platform-feature.h>
+
+/* The platform features are starting with the architecture specific ones. */
+
+/* Used to enable platform specific DMA handling for virtio devices. */
+#define PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS  (0 + PLATFORM_ARCH_FEAT_N)
+
+#define PLATFORM_FEAT_N                                (1 + PLATFORM_ARCH_FEAT_N)
+
+void platform_set(unsigned int feature);
+void platform_clear(unsigned int feature);
+bool platform_has(unsigned int feature);
+
+#endif /* _PLATFORM_FEATURE_H */
index fae0c84027fdcc4384f227aa75873d36608b36b5..20e389a14e5c71935a916e76e973626d45b6bbc7 100644 (file)
@@ -13,7 +13,7 @@
 struct notifier_block;
 
 void add_device_randomness(const void *buf, size_t len);
-void add_bootloader_randomness(const void *buf, size_t len);
+void __init add_bootloader_randomness(const void *buf, size_t len);
 void add_input_randomness(unsigned int type, unsigned int code,
                          unsigned int value) __latent_entropy;
 void add_interrupt_randomness(int irq) __latent_entropy;
@@ -74,7 +74,6 @@ static inline unsigned long get_random_canary(void)
 
 int __init random_init(const char *command_line);
 bool rng_is_initialized(void);
-bool rng_has_arch_random(void);
 int wait_for_random_bytes(void);
 
 /* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).
index cbd5070bc87f42aa450c4ca7af8a9b59fbe88574..657a0fc68a3fbdacf99e34f86b32e2f0a8d4794f 100644 (file)
@@ -45,6 +45,7 @@ struct uart_ops {
        void            (*unthrottle)(struct uart_port *);
        void            (*send_xchar)(struct uart_port *, char ch);
        void            (*stop_rx)(struct uart_port *);
+       void            (*start_rx)(struct uart_port *);
        void            (*enable_ms)(struct uart_port *);
        void            (*break_ctl)(struct uart_port *, int ctl);
        int             (*startup)(struct uart_port *);
index 4417f667c757e5e16be9d82b8696029687d30773..5860f32e3958037d5604a2feab8619bd159c7ca7 100644 (file)
@@ -243,7 +243,7 @@ extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf,
 extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
 extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
                size_t nbytes);
-extern void xdr_commit_encode(struct xdr_stream *xdr);
+extern void __xdr_commit_encode(struct xdr_stream *xdr);
 extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
 extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
 extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
@@ -306,6 +306,20 @@ xdr_reset_scratch_buffer(struct xdr_stream *xdr)
        xdr_set_scratch_buffer(xdr, NULL, 0);
 }
 
+/**
+ * xdr_commit_encode - Ensure all data is written to xdr->buf
+ * @xdr: pointer to xdr_stream
+ *
+ * Handle encoding across page boundaries by giving the caller a
+ * temporary location to write to, then later copying the data into
+ * place. __xdr_commit_encode() does that copying.
+ */
+static inline void xdr_commit_encode(struct xdr_stream *xdr)
+{
+       if (unlikely(xdr->scratch.iov_len))
+               __xdr_commit_encode(xdr);
+}
+
 /**
  * xdr_stream_remaining - Return the number of bytes remaining in the stream
  * @xdr: pointer to struct xdr_stream
index 4700a88a28f6c70a89f5d21ca7597936d4019f3e..7b4a13d3bd919009e4ebae7751f3685964f7e1a6 100644 (file)
@@ -178,7 +178,8 @@ struct vdpa_map_file {
  *                             for the device
  *                             @vdev: vdpa device
  *                             Returns virtqueue algin requirement
- * @get_vq_group:              Get the group id for a specific virtqueue
+ * @get_vq_group:              Get the group id for a specific
+ *                             virtqueue (optional)
  *                             @vdev: vdpa device
  *                             @idx: virtqueue index
  *                             Returns u32: group id for this virtqueue
@@ -243,7 +244,7 @@ struct vdpa_map_file {
  *                             Returns the iova range supported by
  *                             the device.
  * @set_group_asid:            Set address space identifier for a
- *                             virtqueue group
+ *                             virtqueue group (optional)
  *                             @vdev: vdpa device
  *                             @group: virtqueue group
  *                             @asid: address space id for this group
index 9a36051ceb76731b89f2ab7d5b0f61be795c731c..49c7c32815f1531e55ab1ec41a2afe69d771f982 100644 (file)
@@ -604,13 +604,4 @@ static inline void virtio_cwrite64(struct virtio_device *vdev,
                _r;                                                     \
        })
 
-#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
-int arch_has_restricted_virtio_memory_access(void);
-#else
-static inline int arch_has_restricted_virtio_memory_access(void)
-{
-       return 0;
-}
-#endif /* CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS */
-
 #endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/include/linux/visorbus.h b/include/linux/visorbus.h
deleted file mode 100644 (file)
index 0d8bd67..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- */
-
-/*
- *  This header file is to be included by other kernel mode components that
- *  implement a particular kind of visor_device.  Each of these other kernel
- *  mode components is called a visor device driver.  Refer to visortemplate
- *  for a minimal sample visor device driver.
- *
- *  There should be nothing in this file that is private to the visorbus
- *  bus implementation itself.
- */
-
-#ifndef __VISORBUS_H__
-#define __VISORBUS_H__
-
-#include <linux/device.h>
-
-#define VISOR_CHANNEL_SIGNATURE ('L' << 24 | 'N' << 16 | 'C' << 8 | 'E')
-
-/*
- * enum channel_serverstate
- * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state.
- * @CHANNELSRV_READY:        Channel has been initialized by server.
- */
-enum channel_serverstate {
-       CHANNELSRV_UNINITIALIZED = 0,
-       CHANNELSRV_READY = 1
-};
-
-/*
- * enum channel_clientstate
- * @CHANNELCLI_DETACHED:
- * @CHANNELCLI_DISABLED:  Client can see channel but is NOT allowed to use it
- *                       unless given TBD* explicit request
- *                       (should actually be < DETACHED).
- * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach.
- * @CHANNELCLI_ATTACHED:  Idle, but client may want to use channel any time.
- * @CHANNELCLI_BUSY:     Client either wants to use or is using channel.
- * @CHANNELCLI_OWNED:    "No worries" state - client can access channel
- *                       anytime.
- */
-enum channel_clientstate {
-       CHANNELCLI_DETACHED = 0,
-       CHANNELCLI_DISABLED = 1,
-       CHANNELCLI_ATTACHING = 2,
-       CHANNELCLI_ATTACHED = 3,
-       CHANNELCLI_BUSY = 4,
-       CHANNELCLI_OWNED = 5
-};
-
-/*
- * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that
- * a guest can look at the FeatureFlags in the io channel, and configure the
- * driver to use interrupts or not based on this setting. All feature bits for
- * all channels should be defined here. The io channel feature bits are defined
- * below.
- */
-#define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1)
-#define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3)
-#define VISOR_IOVM_OK_DRIVER_DISABLING_INTS (0x1ULL << 4)
-#define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5)
-#define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
-
-/*
- * struct channel_header - Common Channel Header
- * @signature:        Signature.
- * @legacy_state:      DEPRECATED - being replaced by.
- * @header_size:       sizeof(struct channel_header).
- * @size:             Total size of this channel in bytes.
- * @features:         Flags to modify behavior.
- * @chtype:           Channel type: data, bus, control, etc..
- * @partition_handle:  ID of guest partition.
- * @handle:           Device number of this channel in client.
- * @ch_space_offset:   Offset in bytes to channel specific area.
- * @version_id:               Struct channel_header Version ID.
- * @partition_index:   Index of guest partition.
- * @zone_uuid:        Guid of Channel's zone.
- * @cli_str_offset:    Offset from channel header to null-terminated
- *                    ClientString (0 if ClientString not present).
- * @cli_state_boot:    CHANNEL_CLIENTSTATE of pre-boot EFI client of this
- *                    channel.
- * @cmd_state_cli:     CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see
- *                    ServerStateUp, ServerStateDown, etc).
- * @cli_state_os:      CHANNEL_CLIENTSTATE of Guest OS client of this channel.
- * @ch_characteristic: CHANNEL_CHARACTERISTIC_<xxx>.
- * @cmd_state_srv:     CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see
- *                    ServerStateUp, ServerStateDown, etc).
- * @srv_state:        CHANNEL_SERVERSTATE.
- * @cli_error_boot:    Bits to indicate err states for boot clients, so err
- *                    messages can be throttled.
- * @cli_error_os:      Bits to indicate err states for OS clients, so err
- *                    messages can be throttled.
- * @filler:           Pad out to 128 byte cacheline.
- * @recover_channel:   Please add all new single-byte values below here.
- */
-struct channel_header {
-       u64 signature;
-       u32 legacy_state;
-       /* SrvState, CliStateBoot, and CliStateOS below */
-       u32 header_size;
-       u64 size;
-       u64 features;
-       guid_t chtype;
-       u64 partition_handle;
-       u64 handle;
-       u64 ch_space_offset;
-       u32 version_id;
-       u32 partition_index;
-       guid_t zone_guid;
-       u32 cli_str_offset;
-       u32 cli_state_boot;
-       u32 cmd_state_cli;
-       u32 cli_state_os;
-       u32 ch_characteristic;
-       u32 cmd_state_srv;
-       u32 srv_state;
-       u8 cli_error_boot;
-       u8 cli_error_os;
-       u8 filler[1];
-       u8 recover_channel;
-} __packed;
-
-#define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0)
-
-/*
- * struct signal_queue_header - Subheader for the Signal Type variation of the
- *                              Common Channel.
- * @version:         SIGNAL_QUEUE_HEADER Version ID.
- * @chtype:          Queue type: storage, network.
- * @size:            Total size of this queue in bytes.
- * @sig_base_offset:  Offset to signal queue area.
- * @features:        Flags to modify behavior.
- * @num_sent:        Total # of signals placed in this queue.
- * @num_overflows:    Total # of inserts failed due to full queue.
- * @signal_size:      Total size of a signal for this queue.
- * @max_slots:        Max # of slots in queue, 1 slot is always empty.
- * @max_signals:      Max # of signals in queue (MaxSignalSlots-1).
- * @head:            Queue head signal #.
- * @num_received:     Total # of signals removed from this queue.
- * @tail:            Queue tail signal.
- * @reserved1:       Reserved field.
- * @reserved2:       Reserved field.
- * @client_queue:
- * @num_irq_received: Total # of Interrupts received. This is incremented by the
- *                   ISR in the guest windows driver.
- * @num_empty:       Number of times that visor_signal_remove is called and
- *                   returned Empty Status.
- * @errorflags:              Error bits set during SignalReinit to denote trouble with
- *                   client's fields.
- * @filler:          Pad out to 64 byte cacheline.
- */
-struct signal_queue_header {
-       /* 1st cache line */
-       u32 version;
-       u32 chtype;
-       u64 size;
-       u64 sig_base_offset;
-       u64 features;
-       u64 num_sent;
-       u64 num_overflows;
-       u32 signal_size;
-       u32 max_slots;
-       u32 max_signals;
-       u32 head;
-       /* 2nd cache line */
-       u64 num_received;
-       u32 tail;
-       u32 reserved1;
-       u64 reserved2;
-       u64 client_queue;
-       u64 num_irq_received;
-       u64 num_empty;
-       u32 errorflags;
-       u8 filler[12];
-} __packed;
-
-/* VISORCHANNEL Guids */
-/* {414815ed-c58c-11da-95a9-00e08161165f} */
-#define VISOR_VHBA_CHANNEL_GUID \
-       GUID_INIT(0x414815ed, 0xc58c, 0x11da, \
-                 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-#define VISOR_VHBA_CHANNEL_GUID_STR \
-       "414815ed-c58c-11da-95a9-00e08161165f"
-struct visorchipset_state {
-       u32 created:1;
-       u32 attached:1;
-       u32 configured:1;
-       u32 running:1;
-       /* Remaining bits in this 32-bit word are reserved. */
-};
-
-/**
- * struct visor_device - A device type for things "plugged" into the visorbus
- *                       bus
- * @visorchannel:              Points to the channel that the device is
- *                             associated with.
- * @channel_type_guid:         Identifies the channel type to the bus driver.
- * @device:                    Device struct meant for use by the bus driver
- *                             only.
- * @list_all:                  Used by the bus driver to enumerate devices.
- * @timer:                     Timer fired periodically to do interrupt-type
- *                             activity.
- * @being_removed:             Indicates that the device is being removed from
- *                             the bus. Private bus driver use only.
- * @visordriver_callback_lock: Used by the bus driver to lock when adding and
- *                             removing devices.
- * @pausing:                   Indicates that a change towards a paused state.
- *                             is in progress. Only modified by the bus driver.
- * @resuming:                  Indicates that a change towards a running state
- *                             is in progress. Only modified by the bus driver.
- * @chipset_bus_no:            Private field used by the bus driver.
- * @chipset_dev_no:            Private field used the bus driver.
- * @state:                     Used to indicate the current state of the
- *                             device.
- * @inst:                      Unique GUID for this instance of the device.
- * @name:                      Name of the device.
- * @pending_msg_hdr:           For private use by bus driver to respond to
- *                             hypervisor requests.
- * @vbus_hdr_info:             A pointer to header info. Private use by bus
- *                             driver.
- * @partition_guid:            Indicates client partion id. This should be the
- *                             same across all visor_devices in the current
- *                             guest. Private use by bus driver only.
- */
-struct visor_device {
-       struct visorchannel *visorchannel;
-       guid_t channel_type_guid;
-       /* These fields are for private use by the bus driver only. */
-       struct device device;
-       struct list_head list_all;
-       struct timer_list timer;
-       bool timer_active;
-       bool being_removed;
-       struct mutex visordriver_callback_lock; /* synchronize probe/remove */
-       bool pausing;
-       bool resuming;
-       u32 chipset_bus_no;
-       u32 chipset_dev_no;
-       struct visorchipset_state state;
-       guid_t inst;
-       u8 *name;
-       struct controlvm_message_header *pending_msg_hdr;
-       void *vbus_hdr_info;
-       guid_t partition_guid;
-       struct dentry *debugfs_dir;
-       struct dentry *debugfs_bus_info;
-};
-
-#define to_visor_device(x) container_of(x, struct visor_device, device)
-
-typedef void (*visorbus_state_complete_func) (struct visor_device *dev,
-                                             int status);
-
-/*
- * This struct describes a specific visor channel, by providing its GUID, name,
- * and sizes.
- */
-struct visor_channeltype_descriptor {
-       const guid_t guid;
-       const char *name;
-       u64 min_bytes;
-       u32 version;
-};
-
-/**
- * struct visor_driver - Information provided by each visor driver when it
- *                       registers with the visorbus driver
- * @name:              Name of the visor driver.
- * @owner:             The module owner.
- * @channel_types:     Types of channels handled by this driver, ending with
- *                     a zero GUID. Our specialized BUS.match() method knows
- *                     about this list, and uses it to determine whether this
- *                     driver will in fact handle a new device that it has
- *                     detected.
- * @probe:             Called when a new device comes online, by our probe()
- *                     function specified by driver.probe() (triggered
- *                     ultimately by some call to driver_register(),
- *                     bus_add_driver(), or driver_attach()).
- * @remove:            Called when a new device is removed, by our remove()
- *                     function specified by driver.remove() (triggered
- *                     ultimately by some call to device_release_driver()).
- * @channel_interrupt: Called periodically, whenever there is a possiblity
- *                     that "something interesting" may have happened to the
- *                     channel.
- * @pause:             Called to initiate a change of the device's state.  If
- *                     the return valu`e is < 0, there was an error and the
- *                     state transition will NOT occur.  If the return value
- *                     is >= 0, then the state transition was INITIATED
- *                     successfully, and complete_func() will be called (or
- *                     was just called) with the final status when either the
- *                     state transition fails or completes successfully.
- * @resume:            Behaves similar to pause.
- * @driver:            Private reference to the device driver. For use by bus
- *                     driver only.
- */
-struct visor_driver {
-       const char *name;
-       struct module *owner;
-       struct visor_channeltype_descriptor *channel_types;
-       int (*probe)(struct visor_device *dev);
-       void (*remove)(struct visor_device *dev);
-       void (*channel_interrupt)(struct visor_device *dev);
-       int (*pause)(struct visor_device *dev,
-                    visorbus_state_complete_func complete_func);
-       int (*resume)(struct visor_device *dev,
-                     visorbus_state_complete_func complete_func);
-
-       /* These fields are for private use by the bus driver only. */
-       struct device_driver driver;
-};
-
-#define to_visor_driver(x) (container_of(x, struct visor_driver, driver))
-
-int visor_check_channel(struct channel_header *ch, struct device *dev,
-                       const guid_t *expected_uuid, char *chname,
-                       u64 expected_min_bytes, u32 expected_version,
-                       u64 expected_signature);
-
-int visorbus_register_visor_driver(struct visor_driver *drv);
-void visorbus_unregister_visor_driver(struct visor_driver *drv);
-int visorbus_read_channel(struct visor_device *dev,
-                         unsigned long offset, void *dest,
-                         unsigned long nbytes);
-int visorbus_write_channel(struct visor_device *dev,
-                          unsigned long offset, void *src,
-                          unsigned long nbytes);
-int visorbus_enable_channel_interrupts(struct visor_device *dev);
-void visorbus_disable_channel_interrupts(struct visor_device *dev);
-
-int visorchannel_signalremove(struct visorchannel *channel, u32 queue,
-                             void *msg);
-int visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
-                             void *msg);
-bool visorchannel_signalempty(struct visorchannel *channel, u32 queue);
-const guid_t *visorchannel_get_guid(struct visorchannel *channel);
-
-#define BUS_ROOT_DEVICE UINT_MAX
-struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
-                                              struct visor_device *from);
-#endif
index b159c278996128036f30b2bcbe8a51a3fa6aac3d..096d48aa3437330b7274d06fff48348195147da4 100644 (file)
@@ -215,6 +215,7 @@ extern struct vm_struct *__get_vm_area_caller(unsigned long size,
 void free_vm_area(struct vm_struct *area);
 extern struct vm_struct *remove_vm_area(const void *addr);
 extern struct vm_struct *find_vm_area(const void *addr);
+struct vmap_area *find_vmap_area(unsigned long addr);
 
 static inline bool is_vm_area_hugepages(const void *addr)
 {
index 7fee9b6cfedeffb8e425c9221a87e22d0d6da58c..62e75dd40d9a634648b6beab951de0cb624da161 100644 (file)
@@ -406,7 +406,7 @@ alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...);
  * alloc_ordered_workqueue - allocate an ordered workqueue
  * @fmt: printf format for the name of the workqueue
  * @flags: WQ_* flags (only WQ_FREEZABLE and WQ_MEM_RECLAIM are meaningful)
- * @args...: args for @fmt
+ * @args: args for @fmt
  *
  * Allocate an ordered workqueue.  An ordered workqueue executes at
  * most one work item at any given time in the queued order.  They are
@@ -445,7 +445,7 @@ extern bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq,
                        struct delayed_work *dwork, unsigned long delay);
 extern bool queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork);
 
-extern void flush_workqueue(struct workqueue_struct *wq);
+extern void __flush_workqueue(struct workqueue_struct *wq);
 extern void drain_workqueue(struct workqueue_struct *wq);
 
 extern int schedule_on_each_cpu(work_func_t func);
@@ -563,15 +563,23 @@ static inline bool schedule_work(struct work_struct *work)
        return queue_work(system_wq, work);
 }
 
+/*
+ * Detect attempt to flush system-wide workqueues at compile time when possible.
+ *
+ * See https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@I-love.SAKURA.ne.jp
+ * for reasons and steps for converting system-wide workqueues into local workqueues.
+ */
+extern void __warn_flushing_systemwide_wq(void)
+       __compiletime_warning("Please avoid flushing system-wide workqueues.");
+
 /**
  * flush_scheduled_work - ensure that any scheduled work has run to completion.
  *
  * Forces execution of the kernel-global workqueue and blocks until its
  * completion.
  *
- * Think twice before calling this function!  It's very easy to get into
- * trouble if you don't take great care.  Either of the following situations
- * will lead to deadlock:
+ * It's very easy to get into trouble if you don't take great care.
+ * Either of the following situations will lead to deadlock:
  *
  *     One of the work items currently on the workqueue needs to acquire
  *     a lock held by your code or its caller.
@@ -586,11 +594,51 @@ static inline bool schedule_work(struct work_struct *work)
  * need to know that a particular work item isn't queued and isn't running.
  * In such cases you should use cancel_delayed_work_sync() or
  * cancel_work_sync() instead.
+ *
+ * Please stop calling this function! A conversion to stop flushing system-wide
+ * workqueues is in progress. This function will be removed after all in-tree
+ * users stopped calling this function.
  */
-static inline void flush_scheduled_work(void)
-{
-       flush_workqueue(system_wq);
-}
+/*
+ * The background of commit 771c035372a036f8 ("deprecate the
+ * '__deprecated' attribute warnings entirely and for good") is that,
+ * since Linus builds all modules between every single pull he does,
+ * the standard kernel build needs to be _clean_ in order to be able to
+ * notice when new problems happen. Therefore, don't emit warning while
+ * there are in-tree users.
+ */
+#define flush_scheduled_work()                                         \
+({                                                                     \
+       if (0)                                                          \
+               __warn_flushing_systemwide_wq();                        \
+       __flush_workqueue(system_wq);                                   \
+})
+
+/*
+ * Although there is no longer in-tree caller, for now just emit warning
+ * in order to give out-of-tree callers time to update.
+ */
+#define flush_workqueue(wq)                                            \
+({                                                                     \
+       struct workqueue_struct *_wq = (wq);                            \
+                                                                       \
+       if ((__builtin_constant_p(_wq == system_wq) &&                  \
+            _wq == system_wq) ||                                       \
+           (__builtin_constant_p(_wq == system_highpri_wq) &&          \
+            _wq == system_highpri_wq) ||                               \
+           (__builtin_constant_p(_wq == system_long_wq) &&             \
+            _wq == system_long_wq) ||                                  \
+           (__builtin_constant_p(_wq == system_unbound_wq) &&          \
+            _wq == system_unbound_wq) ||                               \
+           (__builtin_constant_p(_wq == system_freezable_wq) &&        \
+            _wq == system_freezable_wq) ||                             \
+           (__builtin_constant_p(_wq == system_power_efficient_wq) &&  \
+            _wq == system_power_efficient_wq) ||                       \
+           (__builtin_constant_p(_wq == system_freezable_power_efficient_wq) && \
+            _wq == system_freezable_power_efficient_wq))               \
+               __warn_flushing_systemwide_wq();                        \
+       __flush_workqueue(_wq);                                         \
+})
 
 /**
  * schedule_delayed_work_on - queue work in global workqueue on CPU after delay
index 72feab5ea8d4a94d49ed48c531e2d74e9dbaac1d..c29e11b2c07395ee9ff1efdd03bcbfd9eaf3d1cc 100644 (file)
@@ -1508,6 +1508,7 @@ void *xas_find_marked(struct xa_state *, unsigned long max, xa_mark_t);
 void xas_init_marks(const struct xa_state *);
 
 bool xas_nomem(struct xa_state *, gfp_t);
+void xas_destroy(struct xa_state *);
 void xas_pause(struct xa_state *);
 
 void xas_create_range(struct xa_state *);
index 021778a7e1afa929400acca5e348b76716a737d8..6484095a8c011681ffbb5898adceecb4902c5255 100644 (file)
@@ -612,5 +612,6 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch,
                                enum tc_setup_type type, void *data,
                                struct flow_block_offload *bo,
                                void (*cleanup)(struct flow_block_cb *block_cb));
+bool flow_indr_dev_exists(void);
 
 #endif /* _NET_FLOW_OFFLOAD_H */
index 077cd730ce2fbfadad904b866f8f2137b240d14e..85cd695e7fd1d37cc59ac471c873d72517a40638 100644 (file)
@@ -25,7 +25,6 @@
 #undef INET_CSK_CLEAR_TIMERS
 
 struct inet_bind_bucket;
-struct inet_bind2_bucket;
 struct tcp_congestion_ops;
 
 /*
@@ -58,7 +57,6 @@ struct inet_connection_sock_af_ops {
  *
  * @icsk_accept_queue:    FIFO of established children
  * @icsk_bind_hash:       Bind node
- * @icsk_bind2_hash:      Bind node in the bhash2 table
  * @icsk_timeout:         Timeout
  * @icsk_retransmit_timer: Resend (no ack)
  * @icsk_rto:             Retransmit timeout
@@ -85,7 +83,6 @@ struct inet_connection_sock {
        struct inet_sock          icsk_inet;
        struct request_sock_queue icsk_accept_queue;
        struct inet_bind_bucket   *icsk_bind_hash;
-       struct inet_bind2_bucket  *icsk_bind2_hash;
        unsigned long             icsk_timeout;
        struct timer_list         icsk_retransmit_timer;
        struct timer_list         icsk_delack_timer;
index a0887b70967b6b2a1e7ed88243fc29047b50de2b..ebfa3df6f8dc365b4ce5f4c4fb573c37193492ab 100644 (file)
@@ -90,32 +90,11 @@ struct inet_bind_bucket {
        struct hlist_head       owners;
 };
 
-struct inet_bind2_bucket {
-       possible_net_t          ib_net;
-       int                     l3mdev;
-       unsigned short          port;
-       union {
-#if IS_ENABLED(CONFIG_IPV6)
-               struct in6_addr         v6_rcv_saddr;
-#endif
-               __be32                  rcv_saddr;
-       };
-       /* Node in the inet2_bind_hashbucket chain */
-       struct hlist_node       node;
-       /* List of sockets hashed to this bucket */
-       struct hlist_head       owners;
-};
-
 static inline struct net *ib_net(struct inet_bind_bucket *ib)
 {
        return read_pnet(&ib->ib_net);
 }
 
-static inline struct net *ib2_net(struct inet_bind2_bucket *ib)
-{
-       return read_pnet(&ib->ib_net);
-}
-
 #define inet_bind_bucket_for_each(tb, head) \
        hlist_for_each_entry(tb, head, node)
 
@@ -124,15 +103,6 @@ struct inet_bind_hashbucket {
        struct hlist_head       chain;
 };
 
-/* This is synchronized using the inet_bind_hashbucket's spinlock.
- * Instead of having separate spinlocks, the inet_bind2_hashbucket can share
- * the inet_bind_hashbucket's given that in every case where the bhash2 table
- * is useful, a lookup in the bhash table also occurs.
- */
-struct inet_bind2_hashbucket {
-       struct hlist_head       chain;
-};
-
 /* Sockets can be hashed in established or listening table.
  * We must use different 'nulls' end-of-chain value for all hash buckets :
  * A socket might transition from ESTABLISH to LISTEN state without
@@ -164,12 +134,6 @@ struct inet_hashinfo {
         */
        struct kmem_cache               *bind_bucket_cachep;
        struct inet_bind_hashbucket     *bhash;
-       /* The 2nd binding table hashed by port and address.
-        * This is used primarily for expediting the resolution of bind
-        * conflicts.
-        */
-       struct kmem_cache               *bind2_bucket_cachep;
-       struct inet_bind2_hashbucket    *bhash2;
        unsigned int                    bhash_size;
 
        /* The 2nd listener table hashed by local port and address */
@@ -229,36 +193,6 @@ inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
 void inet_bind_bucket_destroy(struct kmem_cache *cachep,
                              struct inet_bind_bucket *tb);
 
-static inline bool check_bind_bucket_match(struct inet_bind_bucket *tb,
-                                          struct net *net,
-                                          const unsigned short port,
-                                          int l3mdev)
-{
-       return net_eq(ib_net(tb), net) && tb->port == port &&
-               tb->l3mdev == l3mdev;
-}
-
-struct inet_bind2_bucket *
-inet_bind2_bucket_create(struct kmem_cache *cachep, struct net *net,
-                        struct inet_bind2_hashbucket *head,
-                        const unsigned short port, int l3mdev,
-                        const struct sock *sk);
-
-void inet_bind2_bucket_destroy(struct kmem_cache *cachep,
-                              struct inet_bind2_bucket *tb);
-
-struct inet_bind2_bucket *
-inet_bind2_bucket_find(struct inet_hashinfo *hinfo, struct net *net,
-                      const unsigned short port, int l3mdev,
-                      struct sock *sk,
-                      struct inet_bind2_hashbucket **head);
-
-bool check_bind2_bucket_match_nulladdr(struct inet_bind2_bucket *tb,
-                                      struct net *net,
-                                      const unsigned short port,
-                                      int l3mdev,
-                                      const struct sock *sk);
-
 static inline u32 inet_bhashfn(const struct net *net, const __u16 lport,
                               const u32 bhash_size)
 {
@@ -266,7 +200,7 @@ static inline u32 inet_bhashfn(const struct net *net, const __u16 lport,
 }
 
 void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
-                   struct inet_bind2_bucket *tb2, const unsigned short snum);
+                   const unsigned short snum);
 
 /* Caller must disable local BH processing. */
 int __inet_inherit_port(const struct sock *sk, struct sock *child);
index 5b38bf1a586b9da55f43db30d140d364a70f6c11..de9dcc5652c483c0a656b65504a356be9294f7fe 100644 (file)
@@ -1063,7 +1063,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
 int ip6_append_data(struct sock *sk,
                    int getfrag(void *from, char *to, int offset, int len,
                                int odd, struct sk_buff *skb),
-                   void *from, int length, int transhdrlen,
+                   void *from, size_t length, int transhdrlen,
                    struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
                    struct rt6_info *rt, unsigned int flags);
 
@@ -1079,7 +1079,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk, struct sk_buff_head *queue,
 struct sk_buff *ip6_make_skb(struct sock *sk,
                             int getfrag(void *from, char *to, int offset,
                                         int len, int odd, struct sk_buff *skb),
-                            void *from, int length, int transhdrlen,
+                            void *from, size_t length, int transhdrlen,
                             struct ipcm6_cookie *ipc6,
                             struct rt6_info *rt, unsigned int flags,
                             struct inet_cork_full *cork);
index 20af9d3557b9d4af410d89f7781e66743a5ce281..279ae0fff7adbbc37f124de87d789450fc4f3e9d 100644 (file)
@@ -1090,7 +1090,6 @@ struct nft_stats {
 
 struct nft_hook {
        struct list_head        list;
-       bool                    inactive;
        struct nf_hook_ops      ops;
        struct rcu_head         rcu;
 };
index 7971478439580c6a7db49892d021e1abfc9e9321..3568b6a2f5f0fcc918311a5b18daf0186b7b1016 100644 (file)
@@ -92,7 +92,7 @@ int nft_flow_rule_offload_commit(struct net *net);
        NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg)         \
        memset(&(__reg)->mask, 0xff, (__reg)->len);
 
-int nft_chain_offload_priority(struct nft_base_chain *basechain);
+bool nft_chain_offload_support(const struct nft_base_chain *basechain);
 
 int nft_offload_init(void);
 void nft_offload_exit(void);
index c585ef6565d935c434253cc3d7f7cb5e6bf106a6..72ca97ccb46072491179c1225f4e8bab85a7994f 100644 (file)
@@ -348,7 +348,6 @@ struct sk_filter;
   *    @sk_txtime_report_errors: set report errors mode for SO_TXTIME
   *    @sk_txtime_unused: unused txtime flags
   *    @ns_tracker: tracker for netns reference
-  *    @sk_bind2_node: bind node in the bhash2 table
   */
 struct sock {
        /*
@@ -538,7 +537,6 @@ struct sock {
 #endif
        struct rcu_head         sk_rcu;
        netns_tracker           ns_tracker;
-       struct hlist_node       sk_bind2_node;
 };
 
 enum sk_pacing {
@@ -819,16 +817,6 @@ static inline void sk_add_bind_node(struct sock *sk,
        hlist_add_head(&sk->sk_bind_node, list);
 }
 
-static inline void __sk_del_bind2_node(struct sock *sk)
-{
-       __hlist_del(&sk->sk_bind2_node);
-}
-
-static inline void sk_add_bind2_node(struct sock *sk, struct hlist_head *list)
-{
-       hlist_add_head(&sk->sk_bind2_node, list);
-}
-
 #define sk_for_each(__sk, list) \
        hlist_for_each_entry(__sk, list, sk_node)
 #define sk_for_each_rcu(__sk, list) \
@@ -846,8 +834,6 @@ static inline void sk_add_bind2_node(struct sock *sk, struct hlist_head *list)
        hlist_for_each_entry_safe(__sk, tmp, list, sk_node)
 #define sk_for_each_bound(__sk, list) \
        hlist_for_each_entry(__sk, list, sk_bind_node)
-#define sk_for_each_bound_bhash2(__sk, list) \
-       hlist_for_each_entry(__sk, list, sk_bind2_node)
 
 /**
  * sk_for_each_entry_offset_rcu - iterate over a list at a given struct offset
index 6154a2e72bce6dbf59962b669ac381c6a29c9324..262d52021c236c492d8fc92a70f54d3a351ca20d 100644 (file)
@@ -22,7 +22,7 @@ struct pool_workqueue;
  */
 TRACE_EVENT(workqueue_queue_work,
 
-       TP_PROTO(unsigned int req_cpu, struct pool_workqueue *pwq,
+       TP_PROTO(int req_cpu, struct pool_workqueue *pwq,
                 struct work_struct *work),
 
        TP_ARGS(req_cpu, pwq, work),
@@ -31,8 +31,8 @@ TRACE_EVENT(workqueue_queue_work,
                __field( void *,        work    )
                __field( void *,        function)
                __string( workqueue,    pwq->wq->name)
-               __field( unsigned int,  req_cpu )
-               __field( unsigned int,  cpu     )
+               __field( int,   req_cpu )
+               __field( int,   cpu     )
        ),
 
        TP_fast_assign(
@@ -43,7 +43,7 @@ TRACE_EVENT(workqueue_queue_work,
                __entry->cpu            = pwq->pool->cpu;
        ),
 
-       TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%u cpu=%u",
+       TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%d cpu=%d",
                  __entry->work, __entry->function, __get_str(workqueue),
                  __entry->req_cpu, __entry->cpu)
 );
index 776e0278f9dd4f005e4416b9f24b0b9ce26e6cc2..53e7dae92e42e4d9a373d2ef61ab925f0a8d64d8 100644 (file)
@@ -47,7 +47,6 @@ struct io_uring_sqe {
                __u32           unlink_flags;
                __u32           hardlink_flags;
                __u32           xattr_flags;
-               __u32           close_flags;
        };
        __u64   user_data;      /* data to be passed back at completion time */
        /* pack this to avoid bogus arm OABI complaints */
@@ -259,11 +258,6 @@ enum io_uring_op {
  */
 #define IORING_ACCEPT_MULTISHOT        (1U << 0)
 
-/*
- * close flags, store in sqe->close_flags
- */
-#define IORING_CLOSE_FD_AND_FILE_SLOT  (1U << 0)
-
 /*
  * IO completion data structure (Completion Queue Entry)
  */
index ac39328eabe734a3939a6d4da0a227a17026db81..bb8f80812b0bdddb82b7409d4770e9789e02f751 100644 (file)
@@ -39,7 +39,7 @@
 /* TLS socket options */
 #define TLS_TX                 1       /* Set transmit parameters */
 #define TLS_RX                 2       /* Set receive parameters */
-#define TLS_TX_ZEROCOPY_SENDFILE       3       /* transmit zerocopy sendfile */
+#define TLS_TX_ZEROCOPY_RO     3       /* TX zerocopy (only sendfile now) */
 
 /* Supported versions */
 #define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
@@ -161,7 +161,7 @@ enum {
        TLS_INFO_CIPHER,
        TLS_INFO_TXCONF,
        TLS_INFO_RXCONF,
-       TLS_INFO_ZC_SENDFILE,
+       TLS_INFO_ZC_RO_TX,
        __TLS_INFO_MAX,
 };
 #define TLS_INFO_MAX (__TLS_INFO_MAX - 1)
diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h
new file mode 100644 (file)
index 0000000..b0766a6
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM_XEN_OPS_H
+#define _ASM_ARM_XEN_OPS_H
+
+#include <xen/swiotlb-xen.h>
+#include <xen/xen-ops.h>
+
+static inline void xen_setup_dma_ops(struct device *dev)
+{
+#ifdef CONFIG_XEN
+       if (xen_is_grant_dma_device(dev))
+               xen_grant_setup_dma_ops(dev);
+       else if (xen_swiotlb_detect())
+               dev->dma_ops = &xen_swiotlb_dma_ops;
+#endif
+}
+
+#endif /* _ASM_ARM_XEN_OPS_H */
index 527c9907f99c621bbe1c530ea7e22a30b3cec259..e279be353e3f11f7d620cfddf22a78f4a6df1831 100644 (file)
@@ -127,10 +127,14 @@ int gnttab_try_end_foreign_access(grant_ref_t ref);
  */
 int gnttab_alloc_grant_references(u16 count, grant_ref_t *pprivate_head);
 
+int gnttab_alloc_grant_reference_seq(unsigned int count, grant_ref_t *first);
+
 void gnttab_free_grant_reference(grant_ref_t ref);
 
 void gnttab_free_grant_references(grant_ref_t head);
 
+void gnttab_free_grant_reference_seq(grant_ref_t head, unsigned int count);
+
 int gnttab_empty_grant_references(const grant_ref_t *pprivate_head);
 
 int gnttab_claim_grant_reference(grant_ref_t *pprivate_head);
index c7c1b46ff4cd47d2dd5862e407fec7d685e0b981..80546960f8b77f718b3c2120d44d8bb5bbb42fcd 100644 (file)
@@ -214,4 +214,17 @@ static inline void xen_preemptible_hcall_end(void) { }
 
 #endif /* CONFIG_XEN_PV && !CONFIG_PREEMPTION */
 
+#ifdef CONFIG_XEN_GRANT_DMA_OPS
+void xen_grant_setup_dma_ops(struct device *dev);
+bool xen_is_grant_dma_device(struct device *dev);
+#else
+static inline void xen_grant_setup_dma_ops(struct device *dev)
+{
+}
+static inline bool xen_is_grant_dma_device(struct device *dev)
+{
+       return false;
+}
+#endif /* CONFIG_XEN_GRANT_DMA_OPS */
+
 #endif /* INCLUDE_XEN_OPS_H */
index a99bab8175234eb9117dddcd36702083d0896c3c..0780a81e140de48670594e298aeefd55753bb49e 100644 (file)
@@ -52,6 +52,14 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
 extern u64 xen_saved_max_mem_size;
 #endif
 
+#include <linux/platform-feature.h>
+
+static inline void xen_set_restricted_virtio_memory_access(void)
+{
+       if (IS_ENABLED(CONFIG_XEN_VIRTIO) && xen_domain())
+               platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS);
+}
+
 #ifdef CONFIG_XEN_UNPOPULATED_ALLOC
 int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages);
 void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages);
index c984afc489dead0db3d4820b708d90f73b161553..c7900e8975f181857840d861e1cddd4e8201ecc4 100644 (file)
@@ -885,6 +885,15 @@ config CC_IMPLICIT_FALLTHROUGH
        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)
 
+# Currently, disable gcc-12 array-bounds globally.
+# We may want to target only particular configurations some day.
+config GCC12_NO_ARRAY_BOUNDS
+       def_bool y
+
+config CC_NO_ARRAY_BOUNDS
+       bool
+       default y if CC_IS_GCC && GCC_VERSION >= 120000 && GCC_VERSION < 130000 && GCC12_NO_ARRAY_BOUNDS
+
 #
 # For architectures that know their GCC __int128 support is sound
 #
index 318789c728d3290d0053f9f1a6bbe5235c969399..a7e1f49ab2b3bc49f632e4cc5f1aec43e0dfbd9d 100644 (file)
@@ -7,7 +7,7 @@ obj-y     = fork.o exec_domain.o panic.o \
            cpu.o exit.o softirq.o resource.o \
            sysctl.o capability.o ptrace.o user.o \
            signal.o sys.o umh.o workqueue.o pid.o task_work.o \
-           extable.o params.o \
+           extable.o params.o platform-feature.o \
            kthread.o sys_ni.o nsproxy.o \
            notifier.o ksysfs.o cred.o reboot.o \
            async.o range.o smpboot.o ucount.o regset.o
index f3a2abd6d1a1922c8e19e44e3b26a49064e0f521..3a8c9d744800a8d84cc88a52fc0bb6dd4e5e28cb 100644 (file)
@@ -1014,10 +1014,10 @@ static void audit_reset_context(struct audit_context *ctx)
        ctx->target_comm[0] = '\0';
        unroll_tree_refs(ctx, NULL, 0);
        WARN_ON(!list_empty(&ctx->killed_trees));
-       ctx->type = 0;
        audit_free_module(ctx);
        ctx->fds[0] = -1;
        audit_proctitle_free(ctx);
+       ctx->type = 0; /* reset last for audit_free_*() */
 }
 
 static inline struct audit_context *audit_alloc_context(enum audit_state state)
index 7bccaa4646e5197afe0a5d742e5bbf9e18594276..63d0ac7dfe2fbf991c4badafc2e4460a0ed04c8a 100644 (file)
@@ -6054,6 +6054,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
                                    struct bpf_reg_state *regs,
                                    bool ptr_to_mem_ok)
 {
+       enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
        struct bpf_verifier_log *log = &env->log;
        u32 i, nargs, ref_id, ref_obj_id = 0;
        bool is_kfunc = btf_is_kernel(btf);
@@ -6171,7 +6172,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
                                return -EINVAL;
                        }
                        /* rest of the arguments can be anything, like normal kfunc */
-               } else if (btf_get_prog_ctx_type(log, btf, t, env->prog->type, i)) {
+               } else if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
                        /* If function expects ctx type in BTF check that caller
                         * is passing PTR_TO_CTX.
                         */
index 9594cfd1cf2cf7ea7be1a44ad048d3b25b624acc..08102d19ec15a2e402c10ad8d22743caafe47d68 100644 (file)
@@ -281,6 +281,8 @@ static inline cfi_check_fn find_module_check_fn(unsigned long ptr)
 static inline cfi_check_fn find_check_fn(unsigned long ptr)
 {
        cfi_check_fn fn = NULL;
+       unsigned long flags;
+       bool rcu_idle;
 
        if (is_kernel_text(ptr))
                return __cfi_check;
@@ -290,13 +292,21 @@ static inline cfi_check_fn find_check_fn(unsigned long ptr)
         * the shadow and __module_address use RCU, so we need to wake it
         * up if necessary.
         */
-       RCU_NONIDLE({
-               if (IS_ENABLED(CONFIG_CFI_CLANG_SHADOW))
-                       fn = find_shadow_check_fn(ptr);
+       rcu_idle = !rcu_is_watching();
+       if (rcu_idle) {
+               local_irq_save(flags);
+               rcu_irq_enter();
+       }
+
+       if (IS_ENABLED(CONFIG_CFI_CLANG_SHADOW))
+               fn = find_shadow_check_fn(ptr);
+       if (!fn)
+               fn = find_module_check_fn(ptr);
 
-               if (!fn)
-                       fn = find_module_check_fn(ptr);
-       });
+       if (rcu_idle) {
+               rcu_irq_exit();
+               local_irq_restore(flags);
+       }
 
        return fn;
 }
index ac740630c79c2bdb4000115a6663186aca184eed..2caafd13f8aac27f92e0675d94050175c45d585d 100644 (file)
@@ -564,7 +564,7 @@ static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs)
 
        rc = active_cacheline_insert(entry);
        if (rc == -ENOMEM) {
-               pr_err("cacheline tracking ENOMEM, dma-debug disabled\n");
+               pr_err_once("cacheline tracking ENOMEM, dma-debug disabled\n");
                global_disable = true;
        } else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) {
                err_printk(entry->dev, entry,
index dfa1de89dc944f63bb355353162a658b911674e9..cb50f8d383606be7b12bf6b9f6c5c6799f3fb1a5 100644 (file)
@@ -192,7 +192,7 @@ void __init swiotlb_update_mem_attributes(void)
 }
 
 static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start,
-                                   unsigned long nslabs, bool late_alloc)
+               unsigned long nslabs, unsigned int flags, bool late_alloc)
 {
        void *vaddr = phys_to_virt(start);
        unsigned long bytes = nslabs << IO_TLB_SHIFT, i;
@@ -203,8 +203,7 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start,
        mem->index = 0;
        mem->late_alloc = late_alloc;
 
-       if (swiotlb_force_bounce)
-               mem->force_bounce = true;
+       mem->force_bounce = swiotlb_force_bounce || (flags & SWIOTLB_FORCE);
 
        spin_lock_init(&mem->lock);
        for (i = 0; i < mem->nslabs; i++) {
@@ -275,8 +274,7 @@ retry:
                panic("%s: Failed to allocate %zu bytes align=0x%lx\n",
                      __func__, alloc_size, PAGE_SIZE);
 
-       swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, false);
-       mem->force_bounce = flags & SWIOTLB_FORCE;
+       swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, flags, false);
 
        if (flags & SWIOTLB_VERBOSE)
                swiotlb_print_info();
@@ -348,7 +346,7 @@ retry:
 
        set_memory_decrypted((unsigned long)vstart,
                             (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
-       swiotlb_init_io_tlb_mem(mem, virt_to_phys(vstart), nslabs, true);
+       swiotlb_init_io_tlb_mem(mem, virt_to_phys(vstart), nslabs, 0, true);
 
        swiotlb_print_info();
        return 0;
@@ -835,8 +833,8 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
 
                set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
                                     rmem->size >> PAGE_SHIFT);
-               swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, false);
-               mem->force_bounce = true;
+               swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, SWIOTLB_FORCE,
+                               false);
                mem->for_alloc = true;
 
                rmem->priv = mem;
index 9d09f489b60e0c9872466a0ae6bf0a9fc3c7e23a..2e0f75bcb7fd1c21084df8ff885aeec001a359ea 100644 (file)
@@ -9,12 +9,6 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
                int ret;
 
                if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
-                       clear_notify_signal();
-                       if (task_work_pending(current))
-                               task_work_run();
-               }
-
-               if (ti_work & _TIF_SIGPENDING) {
                        kvm_handle_signal_exit(vcpu);
                        return -EINTR;
                }
diff --git a/kernel/platform-feature.c b/kernel/platform-feature.c
new file mode 100644 (file)
index 0000000..cb6a6c3
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bitops.h>
+#include <linux/cache.h>
+#include <linux/export.h>
+#include <linux/platform-feature.h>
+
+#define PLATFORM_FEAT_ARRAY_SZ  BITS_TO_LONGS(PLATFORM_FEAT_N)
+static unsigned long __read_mostly platform_features[PLATFORM_FEAT_ARRAY_SZ];
+
+void platform_set(unsigned int feature)
+{
+       set_bit(feature, platform_features);
+}
+EXPORT_SYMBOL_GPL(platform_set);
+
+void platform_clear(unsigned int feature)
+{
+       clear_bit(feature, platform_features);
+}
+EXPORT_SYMBOL_GPL(platform_clear);
+
+bool platform_has(unsigned int feature)
+{
+       return test_bit(feature, platform_features);
+}
+EXPORT_SYMBOL_GPL(platform_has);
index a091145ee7104bb2750f69f0885554c393c7bb62..b5a71d1ff603c36fd61138297fe2e83d1455099e 100644 (file)
@@ -315,6 +315,43 @@ static int sys_off_notify(struct notifier_block *nb,
        return handler->sys_off_cb(&data);
 }
 
+static struct sys_off_handler platform_sys_off_handler;
+
+static struct sys_off_handler *alloc_sys_off_handler(int priority)
+{
+       struct sys_off_handler *handler;
+       gfp_t flags;
+
+       /*
+        * Platforms like m68k can't allocate sys_off handler dynamically
+        * at the early boot time because memory allocator isn't available yet.
+        */
+       if (priority == SYS_OFF_PRIO_PLATFORM) {
+               handler = &platform_sys_off_handler;
+               if (handler->cb_data)
+                       return ERR_PTR(-EBUSY);
+       } else {
+               if (system_state > SYSTEM_RUNNING)
+                       flags = GFP_ATOMIC;
+               else
+                       flags = GFP_KERNEL;
+
+               handler = kzalloc(sizeof(*handler), flags);
+               if (!handler)
+                       return ERR_PTR(-ENOMEM);
+       }
+
+       return handler;
+}
+
+static void free_sys_off_handler(struct sys_off_handler *handler)
+{
+       if (handler == &platform_sys_off_handler)
+               memset(handler, 0, sizeof(*handler));
+       else
+               kfree(handler);
+}
+
 /**
  *     register_sys_off_handler - Register sys-off handler
  *     @mode: Sys-off mode
@@ -345,9 +382,9 @@ register_sys_off_handler(enum sys_off_mode mode,
        struct sys_off_handler *handler;
        int err;
 
-       handler = kzalloc(sizeof(*handler), GFP_KERNEL);
-       if (!handler)
-               return ERR_PTR(-ENOMEM);
+       handler = alloc_sys_off_handler(priority);
+       if (IS_ERR(handler))
+               return handler;
 
        switch (mode) {
        case SYS_OFF_MODE_POWER_OFF_PREPARE:
@@ -364,7 +401,7 @@ register_sys_off_handler(enum sys_off_mode mode,
                break;
 
        default:
-               kfree(handler);
+               free_sys_off_handler(handler);
                return ERR_PTR(-EINVAL);
        }
 
@@ -391,7 +428,7 @@ register_sys_off_handler(enum sys_off_mode mode,
        }
 
        if (err) {
-               kfree(handler);
+               free_sys_off_handler(handler);
                return ERR_PTR(err);
        }
 
@@ -409,7 +446,7 @@ void unregister_sys_off_handler(struct sys_off_handler *handler)
 {
        int err;
 
-       if (!handler)
+       if (IS_ERR_OR_NULL(handler))
                return;
 
        if (handler->blocking)
@@ -422,7 +459,7 @@ void unregister_sys_off_handler(struct sys_off_handler *handler)
        /* sanity check, shall never happen */
        WARN_ON(err);
 
-       kfree(handler);
+       free_sys_off_handler(handler);
 }
 EXPORT_SYMBOL_GPL(unregister_sys_off_handler);
 
@@ -584,7 +621,23 @@ static void do_kernel_power_off_prepare(void)
  */
 void do_kernel_power_off(void)
 {
+       struct sys_off_handler *sys_off = NULL;
+
+       /*
+        * Register sys-off handlers for legacy PM callback. This allows
+        * legacy PM callbacks temporary co-exist with the new sys-off API.
+        *
+        * TODO: Remove legacy handlers once all legacy PM users will be
+        *       switched to the sys-off based APIs.
+        */
+       if (pm_power_off)
+               sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+                                                  SYS_OFF_PRIO_DEFAULT,
+                                                  legacy_pm_power_off, NULL);
+
        atomic_notifier_call_chain(&power_off_handler_list, 0, NULL);
+
+       unregister_sys_off_handler(sys_off);
 }
 
 /**
@@ -595,7 +648,8 @@ void do_kernel_power_off(void)
  */
 bool kernel_can_power_off(void)
 {
-       return !atomic_notifier_call_chain_is_empty(&power_off_handler_list);
+       return !atomic_notifier_call_chain_is_empty(&power_off_handler_list) ||
+               pm_power_off;
 }
 EXPORT_SYMBOL_GPL(kernel_can_power_off);
 
@@ -630,7 +684,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
                void __user *, arg)
 {
        struct pid_namespace *pid_ns = task_active_pid_ns(current);
-       struct sys_off_handler *sys_off = NULL;
        char buffer[256];
        int ret = 0;
 
@@ -655,21 +708,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
        if (ret)
                return ret;
 
-       /*
-        * Register sys-off handlers for legacy PM callback. This allows
-        * legacy PM callbacks temporary co-exist with the new sys-off API.
-        *
-        * TODO: Remove legacy handlers once all legacy PM users will be
-        *       switched to the sys-off based APIs.
-        */
-       if (pm_power_off) {
-               sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
-                                                  SYS_OFF_PRIO_DEFAULT,
-                                                  legacy_pm_power_off, NULL);
-               if (IS_ERR(sys_off))
-                       return PTR_ERR(sys_off);
-       }
-
        /* Instead of trying to make the power_off code look like
         * halt when pm_power_off is not set do it the easy way.
         */
@@ -727,7 +765,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
                break;
        }
        mutex_unlock(&system_transition_mutex);
-       unregister_sys_off_handler(sys_off);
        return ret;
 }
 
index 10b157a6d73e0746d3ae2bf5ccfcd3423384085f..7a13e6ac6327ced0adedd309a1895a947572f1f7 100644 (file)
@@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32
        int err = -ENOMEM;
        unsigned int i;
 
-       syms = kvmalloc(cnt * sizeof(*syms), GFP_KERNEL);
+       syms = kvmalloc_array(cnt, sizeof(*syms), GFP_KERNEL);
        if (!syms)
                goto error;
 
-       buf = kvmalloc(cnt * KSYM_NAME_LEN, GFP_KERNEL);
+       buf = kvmalloc_array(cnt, KSYM_NAME_LEN, GFP_KERNEL);
        if (!buf)
                goto error;
 
@@ -2464,7 +2464,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
                return -EINVAL;
 
        size = cnt * sizeof(*addrs);
-       addrs = kvmalloc(size, GFP_KERNEL);
+       addrs = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL);
        if (!addrs)
                return -ENOMEM;
 
@@ -2489,7 +2489,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
 
        ucookies = u64_to_user_ptr(attr->link_create.kprobe_multi.cookies);
        if (ucookies) {
-               cookies = kvmalloc(size, GFP_KERNEL);
+               cookies = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL);
                if (!cookies) {
                        err = -ENOMEM;
                        goto error;
index 4056f2a3f9d59c0dbaa776e5bb8bce31390a1600..1ea50f6be843698965a14a13a7498834fc510e36 100644 (file)
@@ -2788,13 +2788,13 @@ static bool flush_workqueue_prep_pwqs(struct workqueue_struct *wq,
 }
 
 /**
- * flush_workqueue - ensure that any scheduled work has run to completion.
+ * __flush_workqueue - ensure that any scheduled work has run to completion.
  * @wq: workqueue to flush
  *
  * This function sleeps until all work items which were queued on entry
  * have finished execution, but it is not livelocked by new incoming ones.
  */
-void flush_workqueue(struct workqueue_struct *wq)
+void __flush_workqueue(struct workqueue_struct *wq)
 {
        struct wq_flusher this_flusher = {
                .list = LIST_HEAD_INIT(this_flusher.list),
@@ -2943,7 +2943,7 @@ void flush_workqueue(struct workqueue_struct *wq)
 out_unlock:
        mutex_unlock(&wq->mutex);
 }
-EXPORT_SYMBOL(flush_workqueue);
+EXPORT_SYMBOL(__flush_workqueue);
 
 /**
  * drain_workqueue - drain a workqueue
@@ -2971,7 +2971,7 @@ void drain_workqueue(struct workqueue_struct *wq)
                wq->flags |= __WQ_DRAINING;
        mutex_unlock(&wq->mutex);
 reflush:
-       flush_workqueue(wq);
+       __flush_workqueue(wq);
 
        mutex_lock(&wq->mutex);
 
@@ -6111,3 +6111,11 @@ void __init workqueue_init(void)
        wq_online = true;
        wq_watchdog_init();
 }
+
+/*
+ * Despite the naming, this is a no-op function which is here only for avoiding
+ * link error. Since compile-time warning may fail to catch, we will need to
+ * emit run-time warning from __flush_workqueue().
+ */
+void __warn_flushing_systemwide_wq(void) { }
+EXPORT_SYMBOL(__warn_flushing_systemwide_wq);
index 6a843639814fbfeb0e48fc99481411fea4a71b2d..eaaad4d85bf24b1a96389bf24f40181e19f5e8d1 100644 (file)
@@ -120,6 +120,9 @@ config INDIRECT_IOMEM_FALLBACK
 
 source "lib/crypto/Kconfig"
 
+config LIB_MEMNEQ
+       bool
+
 config CRC_CCITT
        tristate "CRC-CCITT functions"
        help
index ea54294d73bf4a4832d1862cc2121872c62ca4c4..f99bf61f8bbc67743d17b996ad3ebe341aa91ea4 100644 (file)
@@ -251,6 +251,7 @@ obj-$(CONFIG_DIMLIB) += dim/
 obj-$(CONFIG_SIGNATURE) += digsig.o
 
 lib-$(CONFIG_CLZ_TAB) += clz_tab.o
+lib-$(CONFIG_LIB_MEMNEQ) += memneq.o
 
 obj-$(CONFIG_GENERIC_STRNCPY_FROM_USER) += strncpy_from_user.o
 obj-$(CONFIG_GENERIC_STRNLEN_USER) += strnlen_user.o
index 1974b355c14862e810560b9565939caedff54c60..1d26a1647da537a2295bd3c036db430784f33a1c 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/module.h>
 #include <linux/crc-itu-t.h>
 
-/** CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^15 + 1) */
+/* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */
 const u16 crc_itu_t_table[256] = {
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
        0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
index 9856e291f41410b490ba411685924326f0a71c3e..2082af43d51fbe600c90f659e0e02f9746c0c82a 100644 (file)
@@ -71,6 +71,7 @@ config CRYPTO_LIB_CURVE25519
        tristate "Curve25519 scalar multiplication library"
        depends on CRYPTO_ARCH_HAVE_LIB_CURVE25519 || !CRYPTO_ARCH_HAVE_LIB_CURVE25519
        select CRYPTO_LIB_CURVE25519_GENERIC if CRYPTO_ARCH_HAVE_LIB_CURVE25519=n
+       select LIB_MEMNEQ
        help
          Enable the Curve25519 library interface. This interface may be
          fulfilled by either the generic implementation or an arch-specific
index 6dd5330f7a9957b6d67036390573e5d622df9f92..0b64695ab632f6f94d38627ce2bb4177107d8756 100644 (file)
@@ -1434,7 +1434,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i,
 {
        unsigned nr, offset;
        pgoff_t index, count;
-       size_t size = maxsize, actual;
+       size_t size = maxsize;
        loff_t pos;
 
        if (!size || !maxpages)
@@ -1461,13 +1461,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i,
        if (nr == 0)
                return 0;
 
-       actual = PAGE_SIZE * nr;
-       actual -= offset;
-       if (nr == count && size > 0) {
-               unsigned last_offset = (nr > 1) ? 0 : offset;
-               actual -= PAGE_SIZE - (last_offset + size);
-       }
-       return actual;
+       return min_t(size_t, nr * PAGE_SIZE - offset, maxsize);
 }
 
 /* must be done on non-empty ITER_IOVEC one */
@@ -1602,7 +1596,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i,
        struct page **p;
        unsigned nr, offset;
        pgoff_t index, count;
-       size_t size = maxsize, actual;
+       size_t size = maxsize;
        loff_t pos;
 
        if (!size)
@@ -1631,13 +1625,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i,
        if (nr == 0)
                return 0;
 
-       actual = PAGE_SIZE * nr;
-       actual -= offset;
-       if (nr == count && size > 0) {
-               unsigned last_offset = (nr > 1) ? 0 : offset;
-               actual -= PAGE_SIZE - (last_offset + size);
-       }
-       return actual;
+       return min_t(size_t, nr * PAGE_SIZE - offset, maxsize);
 }
 
 ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
similarity index 100%
rename from crypto/memneq.c
rename to lib/memneq.c
index fb77f7bfd126b5fd7498ec6e979d6eefd9f07b5a..3c1853a9d1c0908f51713773917b2baaf66a11e2 100644 (file)
@@ -769,8 +769,7 @@ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
                static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
                unsigned long flags;
 
-               if (!system_unbound_wq ||
-                   (!rng_is_initialized() && !rng_has_arch_random()) ||
+               if (!system_unbound_wq || !rng_is_initialized() ||
                    !spin_trylock_irqsave(&filling, flags))
                        return -EAGAIN;
 
index 54e646e8e6ee7ab9d46d7c6ed607ff0900eeb366..ea9ce1f0b3863c9486755d2e6f71503d022c033d 100644 (file)
@@ -264,9 +264,10 @@ static void xa_node_free(struct xa_node *node)
  * xas_destroy() - Free any resources allocated during the XArray operation.
  * @xas: XArray operation state.
  *
- * This function is now internal-only.
+ * Most users will not need to call this function; it is called for you
+ * by xas_nomem().
  */
-static void xas_destroy(struct xa_state *xas)
+void xas_destroy(struct xa_state *xas)
 {
        struct xa_node *next, *node = xas->xa_alloc;
 
index ff60bd7d74e0729b81f80ecfad4e9296e1e08079..95550b8fa7fe2e359b55eb3d4cb50001296e9f20 100644 (file)
@@ -231,20 +231,13 @@ static __init int bdi_class_init(void)
 }
 postcore_initcall(bdi_class_init);
 
-static int bdi_init(struct backing_dev_info *bdi);
-
 static int __init default_bdi_init(void)
 {
-       int err;
-
        bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_UNBOUND |
                                 WQ_SYSFS, 0);
        if (!bdi_wq)
                return -ENOMEM;
-
-       err = bdi_init(&noop_backing_dev_info);
-
-       return err;
+       return 0;
 }
 subsys_initcall(default_bdi_init);
 
@@ -781,7 +774,7 @@ static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb)
 
 #endif /* CONFIG_CGROUP_WRITEBACK */
 
-static int bdi_init(struct backing_dev_info *bdi)
+int bdi_init(struct backing_dev_info *bdi)
 {
        int ret;
 
index 9daeaab36081fd0ab86a9aaf4f8b7b62cfd45086..ac3775c1ce4cd853857d8838d3a86f087f3b9aa4 100644 (file)
@@ -2991,11 +2991,12 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
        struct address_space *mapping = file->f_mapping;
        DEFINE_READAHEAD(ractl, file, ra, mapping, vmf->pgoff);
        struct file *fpin = NULL;
+       unsigned long vm_flags = vmf->vma->vm_flags;
        unsigned int mmap_miss;
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
        /* Use the readahead code, even if readahead is disabled */
-       if (vmf->vma->vm_flags & VM_HUGEPAGE) {
+       if (vm_flags & VM_HUGEPAGE) {
                fpin = maybe_unlock_mmap_for_io(vmf, fpin);
                ractl._index &= ~((unsigned long)HPAGE_PMD_NR - 1);
                ra->size = HPAGE_PMD_NR;
@@ -3003,7 +3004,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
                 * Fetch two PMD folios, so we get the chance to actually
                 * readahead, unless we've been told not to.
                 */
-               if (!(vmf->vma->vm_flags & VM_RAND_READ))
+               if (!(vm_flags & VM_RAND_READ))
                        ra->size *= 2;
                ra->async_size = HPAGE_PMD_NR;
                page_cache_ra_order(&ractl, ra, HPAGE_PMD_ORDER);
@@ -3012,12 +3013,12 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 #endif
 
        /* If we don't want any read-ahead, don't bother */
-       if (vmf->vma->vm_flags & VM_RAND_READ)
+       if (vm_flags & VM_RAND_READ)
                return fpin;
        if (!ra->ra_pages)
                return fpin;
 
-       if (vmf->vma->vm_flags & VM_SEQ_READ) {
+       if (vm_flags & VM_SEQ_READ) {
                fpin = maybe_unlock_mmap_for_io(vmf, fpin);
                page_cache_sync_ra(&ractl, ra->ra_pages);
                return fpin;
index a77c78a2b6b5580a9f7400ad30e049a1fe476ee1..f7248002dad980bcf9f7e9573b491586b36dc7b3 100644 (file)
@@ -2672,8 +2672,7 @@ out_unlock:
        if (mapping)
                i_mmap_unlock_read(mapping);
 out:
-       /* Free any memory we didn't use */
-       xas_nomem(&xas, 0);
+       xas_destroy(&xas);
        count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED);
        return ret;
 }
index 415c39d764eaebc0696f270ef5a98117c8e51348..57a0151082543cb67b08d7c1721f62b1e10c6678 100644 (file)
@@ -164,12 +164,14 @@ static void read_pages(struct readahead_control *rac)
                while ((folio = readahead_folio(rac)) != NULL) {
                        unsigned long nr = folio_nr_pages(folio);
 
+                       folio_get(folio);
                        rac->ra->size -= nr;
                        if (rac->ra->async_size >= nr) {
                                rac->ra->async_size -= nr;
                                filemap_remove_folio(folio);
                        }
                        folio_unlock(folio);
+                       folio_put(folio);
                }
        } else {
                while ((folio = readahead_folio(rac)) != NULL)
index baeacc735b83f98cab991cbdc1fdecd9d213fcd9..4e1da708699bbb6b9fc69496b9c380cdc6607b38 100644 (file)
@@ -161,29 +161,27 @@ static inline void check_bogus_address(const unsigned long ptr, unsigned long n,
 static inline void check_heap_object(const void *ptr, unsigned long n,
                                     bool to_user)
 {
+       uintptr_t addr = (uintptr_t)ptr;
+       unsigned long offset;
        struct folio *folio;
 
        if (is_kmap_addr(ptr)) {
-               unsigned long page_end = (unsigned long)ptr | (PAGE_SIZE - 1);
-
-               if ((unsigned long)ptr + n - 1 > page_end)
-                       usercopy_abort("kmap", NULL, to_user,
-                                       offset_in_page(ptr), n);
+               offset = offset_in_page(ptr);
+               if (n > PAGE_SIZE - offset)
+                       usercopy_abort("kmap", NULL, to_user, offset, n);
                return;
        }
 
        if (is_vmalloc_addr(ptr)) {
-               struct vm_struct *area = find_vm_area(ptr);
-               unsigned long offset;
+               struct vmap_area *area = find_vmap_area(addr);
 
-               if (!area) {
+               if (!area)
                        usercopy_abort("vmalloc", "no area", to_user, 0, n);
-                       return;
-               }
 
-               offset = ptr - area->addr;
-               if (offset + n > get_vm_area_size(area))
+               if (n > area->va_end - addr) {
+                       offset = addr - area->va_start;
                        usercopy_abort("vmalloc", NULL, to_user, offset, n);
+               }
                return;
        }
 
@@ -196,8 +194,8 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
                /* Check slab allocator for flags and size. */
                __check_heap_object(ptr, n, folio_slab(folio), to_user);
        } else if (folio_test_large(folio)) {
-               unsigned long offset = ptr - folio_address(folio);
-               if (offset + n > folio_size(folio))
+               offset = ptr - folio_address(folio);
+               if (n > folio_size(folio) - offset)
                        usercopy_abort("page alloc", NULL, to_user, offset, n);
        }
 }
index 07db42455dd4d85b207ae3d7011dea39badf5a5b..effd1ff6a4b412995392de23a956a88f5a9a4074 100644 (file)
@@ -1798,7 +1798,7 @@ static void free_unmap_vmap_area(struct vmap_area *va)
        free_vmap_area_noflush(va);
 }
 
-static struct vmap_area *find_vmap_area(unsigned long addr)
+struct vmap_area *find_vmap_area(unsigned long addr)
 {
        struct vmap_area *va;
 
index 95393bb2760b3e322d531679451c81e2a3877b29..4c7030ed8d3319448f6cb158417c650308e341b8 100644 (file)
@@ -1661,9 +1661,12 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
                        int flags)
 {
        struct sock *sk = sock->sk;
-       struct sk_buff *skb;
+       struct sk_buff *skb, *last;
+       struct sk_buff_head *sk_queue;
        int copied;
        int err = 0;
+       int off = 0;
+       long timeo;
 
        lock_sock(sk);
        /*
@@ -1675,10 +1678,29 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
                goto out;
        }
 
-       /* Now we can treat all alike */
-       skb = skb_recv_datagram(sk, flags, &err);
-       if (skb == NULL)
-               goto out;
+       /*  We need support for non-blocking reads. */
+       sk_queue = &sk->sk_receive_queue;
+       skb = __skb_try_recv_datagram(sk, sk_queue, flags, &off, &err, &last);
+       /* If no packet is available, release_sock(sk) and try again. */
+       if (!skb) {
+               if (err != -EAGAIN)
+                       goto out;
+               release_sock(sk);
+               timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+               while (timeo && !__skb_wait_for_more_packets(sk, sk_queue, &err,
+                                                            &timeo, last)) {
+                       skb = __skb_try_recv_datagram(sk, sk_queue, flags, &off,
+                                                     &err, &last);
+                       if (skb)
+                               break;
+
+                       if (err != -EAGAIN)
+                               goto done;
+               }
+               if (!skb)
+                       goto done;
+               lock_sock(sk);
+       }
 
        if (!sk_to_ax25(sk)->pidincl)
                skb_pull(skb, 1);               /* Remove PID */
@@ -1725,6 +1747,7 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 out:
        release_sock(sk);
 
+done:
        return err;
 }
 
index 73f68d4625f32bb4c1b37740b1e21a73506b88e8..929f6379a279897b5b307134d39bc0c7c8fd62ae 100644 (file)
@@ -595,3 +595,9 @@ int flow_indr_dev_setup_offload(struct net_device *dev,     struct Qdisc *sch,
        return (bo && list_empty(&bo->cb_list)) ? -EOPNOTSUPP : count;
 }
 EXPORT_SYMBOL(flow_indr_dev_setup_offload);
+
+bool flow_indr_dev_exists(void)
+{
+       return !list_empty(&flow_block_indr_dev_list);
+}
+EXPORT_SYMBOL(flow_indr_dev_exists);
index 2e78458900f28d5356cf3e6ac6a3c8ba6e227df9..eb8e128e43e8be615bb173e43cac51987c3f7061 100644 (file)
@@ -1120,12 +1120,6 @@ static int __init dccp_init(void)
                                  SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT, NULL);
        if (!dccp_hashinfo.bind_bucket_cachep)
                goto out_free_hashinfo2;
-       dccp_hashinfo.bind2_bucket_cachep =
-               kmem_cache_create("dccp_bind2_bucket",
-                                 sizeof(struct inet_bind2_bucket), 0,
-                                 SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT, NULL);
-       if (!dccp_hashinfo.bind2_bucket_cachep)
-               goto out_free_bind_bucket_cachep;
 
        /*
         * Size and allocate the main established and bind bucket
@@ -1156,7 +1150,7 @@ static int __init dccp_init(void)
 
        if (!dccp_hashinfo.ehash) {
                DCCP_CRIT("Failed to allocate DCCP established hash table");
-               goto out_free_bind2_bucket_cachep;
+               goto out_free_bind_bucket_cachep;
        }
 
        for (i = 0; i <= dccp_hashinfo.ehash_mask; i++)
@@ -1182,23 +1176,14 @@ static int __init dccp_init(void)
                goto out_free_dccp_locks;
        }
 
-       dccp_hashinfo.bhash2 = (struct inet_bind2_hashbucket *)
-               __get_free_pages(GFP_ATOMIC | __GFP_NOWARN, bhash_order);
-
-       if (!dccp_hashinfo.bhash2) {
-               DCCP_CRIT("Failed to allocate DCCP bind2 hash table");
-               goto out_free_dccp_bhash;
-       }
-
        for (i = 0; i < dccp_hashinfo.bhash_size; i++) {
                spin_lock_init(&dccp_hashinfo.bhash[i].lock);
                INIT_HLIST_HEAD(&dccp_hashinfo.bhash[i].chain);
-               INIT_HLIST_HEAD(&dccp_hashinfo.bhash2[i].chain);
        }
 
        rc = dccp_mib_init();
        if (rc)
-               goto out_free_dccp_bhash2;
+               goto out_free_dccp_bhash;
 
        rc = dccp_ackvec_init();
        if (rc)
@@ -1222,38 +1207,30 @@ out_ackvec_exit:
        dccp_ackvec_exit();
 out_free_dccp_mib:
        dccp_mib_exit();
-out_free_dccp_bhash2:
-       free_pages((unsigned long)dccp_hashinfo.bhash2, bhash_order);
 out_free_dccp_bhash:
        free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
 out_free_dccp_locks:
        inet_ehash_locks_free(&dccp_hashinfo);
 out_free_dccp_ehash:
        free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
-out_free_bind2_bucket_cachep:
-       kmem_cache_destroy(dccp_hashinfo.bind2_bucket_cachep);
 out_free_bind_bucket_cachep:
        kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
 out_free_hashinfo2:
        inet_hashinfo2_free_mod(&dccp_hashinfo);
 out_fail:
        dccp_hashinfo.bhash = NULL;
-       dccp_hashinfo.bhash2 = NULL;
        dccp_hashinfo.ehash = NULL;
        dccp_hashinfo.bind_bucket_cachep = NULL;
-       dccp_hashinfo.bind2_bucket_cachep = NULL;
        return rc;
 }
 
 static void __exit dccp_fini(void)
 {
-       int bhash_order = get_order(dccp_hashinfo.bhash_size *
-                                   sizeof(struct inet_bind_hashbucket));
-
        ccid_cleanup_builtins();
        dccp_mib_exit();
-       free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
-       free_pages((unsigned long)dccp_hashinfo.bhash2, bhash_order);
+       free_pages((unsigned long)dccp_hashinfo.bhash,
+                  get_order(dccp_hashinfo.bhash_size *
+                            sizeof(struct inet_bind_hashbucket)));
        free_pages((unsigned long)dccp_hashinfo.ehash,
                   get_order((dccp_hashinfo.ehash_mask + 1) *
                             sizeof(struct inet_ehash_bucket)));
index c0b7e6c2136016d492efef6b4e4c76b3170f504b..53f5f956d9485df5cb863c8287c1fa9989bb29c9 100644 (file)
@@ -117,32 +117,6 @@ bool inet_rcv_saddr_any(const struct sock *sk)
        return !sk->sk_rcv_saddr;
 }
 
-static bool use_bhash2_on_bind(const struct sock *sk)
-{
-#if IS_ENABLED(CONFIG_IPV6)
-       int addr_type;
-
-       if (sk->sk_family == AF_INET6) {
-               addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
-               return addr_type != IPV6_ADDR_ANY &&
-                       addr_type != IPV6_ADDR_MAPPED;
-       }
-#endif
-       return sk->sk_rcv_saddr != htonl(INADDR_ANY);
-}
-
-static u32 get_bhash2_nulladdr_hash(const struct sock *sk, struct net *net,
-                                   int port)
-{
-#if IS_ENABLED(CONFIG_IPV6)
-       struct in6_addr nulladdr = {};
-
-       if (sk->sk_family == AF_INET6)
-               return ipv6_portaddr_hash(net, &nulladdr, port);
-#endif
-       return ipv4_portaddr_hash(net, 0, port);
-}
-
 void inet_get_local_port_range(struct net *net, int *low, int *high)
 {
        unsigned int seq;
@@ -156,71 +130,16 @@ void inet_get_local_port_range(struct net *net, int *low, int *high)
 }
 EXPORT_SYMBOL(inet_get_local_port_range);
 
-static bool bind_conflict_exist(const struct sock *sk, struct sock *sk2,
-                               kuid_t sk_uid, bool relax,
-                               bool reuseport_cb_ok, bool reuseport_ok)
-{
-       int bound_dev_if2;
-
-       if (sk == sk2)
-               return false;
-
-       bound_dev_if2 = READ_ONCE(sk2->sk_bound_dev_if);
-
-       if (!sk->sk_bound_dev_if || !bound_dev_if2 ||
-           sk->sk_bound_dev_if == bound_dev_if2) {
-               if (sk->sk_reuse && sk2->sk_reuse &&
-                   sk2->sk_state != TCP_LISTEN) {
-                       if (!relax || (!reuseport_ok && sk->sk_reuseport &&
-                                      sk2->sk_reuseport && reuseport_cb_ok &&
-                                      (sk2->sk_state == TCP_TIME_WAIT ||
-                                       uid_eq(sk_uid, sock_i_uid(sk2)))))
-                               return true;
-               } else if (!reuseport_ok || !sk->sk_reuseport ||
-                          !sk2->sk_reuseport || !reuseport_cb_ok ||
-                          (sk2->sk_state != TCP_TIME_WAIT &&
-                           !uid_eq(sk_uid, sock_i_uid(sk2)))) {
-                       return true;
-               }
-       }
-       return false;
-}
-
-static bool check_bhash2_conflict(const struct sock *sk,
-                                 struct inet_bind2_bucket *tb2, kuid_t sk_uid,
-                                 bool relax, bool reuseport_cb_ok,
-                                 bool reuseport_ok)
-{
-       struct sock *sk2;
-
-       sk_for_each_bound_bhash2(sk2, &tb2->owners) {
-               if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
-                       continue;
-
-               if (bind_conflict_exist(sk, sk2, sk_uid, relax,
-                                       reuseport_cb_ok, reuseport_ok))
-                       return true;
-       }
-       return false;
-}
-
-/* This should be called only when the corresponding inet_bind_bucket spinlock
- * is held
- */
-static int inet_csk_bind_conflict(const struct sock *sk, int port,
-                                 struct inet_bind_bucket *tb,
-                                 struct inet_bind2_bucket *tb2, /* may be null */
+static int inet_csk_bind_conflict(const struct sock *sk,
+                                 const struct inet_bind_bucket *tb,
                                  bool relax, bool reuseport_ok)
 {
-       struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;
-       kuid_t uid = sock_i_uid((struct sock *)sk);
-       struct sock_reuseport *reuseport_cb;
-       struct inet_bind2_hashbucket *head2;
-       bool reuseport_cb_ok;
        struct sock *sk2;
-       struct net *net;
-       int l3mdev;
-       u32 hash;
+       bool reuseport_cb_ok;
+       bool reuse = sk->sk_reuse;
+       bool reuseport = !!sk->sk_reuseport;
+       struct sock_reuseport *reuseport_cb;
+       kuid_t uid = sock_i_uid((struct sock *)sk);
 
        rcu_read_lock();
        reuseport_cb = rcu_dereference(sk->sk_reuseport_cb);
@@ -231,42 +150,40 @@ static int inet_csk_bind_conflict(const struct sock *sk, int port,
        /*
         * Unlike other sk lookup places we do not check
         * for sk_net here, since _all_ the socks listed
-        * in tb->owners and tb2->owners list belong
-        * to the same net
+        * in tb->owners list belong to the same net - the
+        * one this bucket belongs to.
         */
 
-       if (!use_bhash2_on_bind(sk)) {
-               sk_for_each_bound(sk2, &tb->owners)
-                       if (bind_conflict_exist(sk, sk2, uid, relax,
-                                               reuseport_cb_ok, reuseport_ok) &&
-                           inet_rcv_saddr_equal(sk, sk2, true))
-                               return true;
+       sk_for_each_bound(sk2, &tb->owners) {
+               int bound_dev_if2;
 
-               return false;
+               if (sk == sk2)
+                       continue;
+               bound_dev_if2 = READ_ONCE(sk2->sk_bound_dev_if);
+               if ((!sk->sk_bound_dev_if ||
+                    !bound_dev_if2 ||
+                    sk->sk_bound_dev_if == bound_dev_if2)) {
+                       if (reuse && sk2->sk_reuse &&
+                           sk2->sk_state != TCP_LISTEN) {
+                               if ((!relax ||
+                                    (!reuseport_ok &&
+                                     reuseport && sk2->sk_reuseport &&
+                                     reuseport_cb_ok &&
+                                     (sk2->sk_state == TCP_TIME_WAIT ||
+                                      uid_eq(uid, sock_i_uid(sk2))))) &&
+                                   inet_rcv_saddr_equal(sk, sk2, true))
+                                       break;
+                       } else if (!reuseport_ok ||
+                                  !reuseport || !sk2->sk_reuseport ||
+                                  !reuseport_cb_ok ||
+                                  (sk2->sk_state != TCP_TIME_WAIT &&
+                                   !uid_eq(uid, sock_i_uid(sk2)))) {
+                               if (inet_rcv_saddr_equal(sk, sk2, true))
+                                       break;
+                       }
+               }
        }
-
-       if (tb2 && check_bhash2_conflict(sk, tb2, uid, relax, reuseport_cb_ok,
-                                        reuseport_ok))
-               return true;
-
-       net = sock_net(sk);
-
-       /* check there's no conflict with an existing IPV6_ADDR_ANY (if ipv6) or
-        * INADDR_ANY (if ipv4) socket.
-        */
-       hash = get_bhash2_nulladdr_hash(sk, net, port);
-       head2 = &hinfo->bhash2[hash & (hinfo->bhash_size - 1)];
-
-       l3mdev = inet_sk_bound_l3mdev(sk);
-       inet_bind_bucket_for_each(tb2, &head2->chain)
-               if (check_bind2_bucket_match_nulladdr(tb2, net, port, l3mdev, sk))
-                       break;
-
-       if (tb2 && check_bhash2_conflict(sk, tb2, uid, relax, reuseport_cb_ok,
-                                        reuseport_ok))
-               return true;
-
-       return false;
+       return sk2 != NULL;
 }
 
 /*
@@ -274,20 +191,16 @@ static int inet_csk_bind_conflict(const struct sock *sk, int port,
  * inet_bind_hashbucket lock held.
  */
 static struct inet_bind_hashbucket *
-inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret,
-                       struct inet_bind2_bucket **tb2_ret,
-                       struct inet_bind2_hashbucket **head2_ret, int *port_ret)
+inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *port_ret)
 {
        struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;
-       struct inet_bind2_hashbucket *head2;
+       int port = 0;
        struct inet_bind_hashbucket *head;
        struct net *net = sock_net(sk);
+       bool relax = false;
        int i, low, high, attempt_half;
-       struct inet_bind2_bucket *tb2;
        struct inet_bind_bucket *tb;
        u32 remaining, offset;
-       bool relax = false;
-       int port = 0;
        int l3mdev;
 
        l3mdev = inet_sk_bound_l3mdev(sk);
@@ -326,12 +239,10 @@ other_parity_scan:
                head = &hinfo->bhash[inet_bhashfn(net, port,
                                                  hinfo->bhash_size)];
                spin_lock_bh(&head->lock);
-               tb2 = inet_bind2_bucket_find(hinfo, net, port, l3mdev, sk,
-                                            &head2);
                inet_bind_bucket_for_each(tb, &head->chain)
-                       if (check_bind_bucket_match(tb, net, port, l3mdev)) {
-                               if (!inet_csk_bind_conflict(sk, port, tb, tb2,
-                                                           relax, false))
+                       if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+                           tb->port == port) {
+                               if (!inet_csk_bind_conflict(sk, tb, relax, false))
                                        goto success;
                                goto next_port;
                        }
@@ -361,8 +272,6 @@ next_port:
 success:
        *port_ret = port;
        *tb_ret = tb;
-       *tb2_ret = tb2;
-       *head2_ret = head2;
        return head;
 }
 
@@ -458,81 +367,54 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
 {
        bool reuse = sk->sk_reuse && sk->sk_state != TCP_LISTEN;
        struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;
-       bool bhash_created = false, bhash2_created = false;
-       struct inet_bind2_bucket *tb2 = NULL;
-       struct inet_bind2_hashbucket *head2;
-       struct inet_bind_bucket *tb = NULL;
+       int ret = 1, port = snum;
        struct inet_bind_hashbucket *head;
        struct net *net = sock_net(sk);
-       int ret = 1, port = snum;
-       bool found_port = false;
+       struct inet_bind_bucket *tb = NULL;
        int l3mdev;
 
        l3mdev = inet_sk_bound_l3mdev(sk);
 
        if (!port) {
-               head = inet_csk_find_open_port(sk, &tb, &tb2, &head2, &port);
+               head = inet_csk_find_open_port(sk, &tb, &port);
                if (!head)
                        return ret;
-               if (tb && tb2)
-                       goto success;
-               found_port = true;
-       } else {
-               head = &hinfo->bhash[inet_bhashfn(net, port,
-                                                 hinfo->bhash_size)];
-               spin_lock_bh(&head->lock);
-               inet_bind_bucket_for_each(tb, &head->chain)
-                       if (check_bind_bucket_match(tb, net, port, l3mdev))
-                               break;
-
-               tb2 = inet_bind2_bucket_find(hinfo, net, port, l3mdev, sk,
-                                            &head2);
-       }
-
-       if (!tb) {
-               tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, net,
-                                            head, port, l3mdev);
                if (!tb)
-                       goto fail_unlock;
-               bhash_created = true;
-       }
-
-       if (!tb2) {
-               tb2 = inet_bind2_bucket_create(hinfo->bind2_bucket_cachep,
-                                              net, head2, port, l3mdev, sk);
-               if (!tb2)
-                       goto fail_unlock;
-               bhash2_created = true;
+                       goto tb_not_found;
+               goto success;
        }
-
-       /* If we had to find an open port, we already checked for conflicts */
-       if (!found_port && !hlist_empty(&tb->owners)) {
+       head = &hinfo->bhash[inet_bhashfn(net, port,
+                                         hinfo->bhash_size)];
+       spin_lock_bh(&head->lock);
+       inet_bind_bucket_for_each(tb, &head->chain)
+               if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+                   tb->port == port)
+                       goto tb_found;
+tb_not_found:
+       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+                                    net, head, port, l3mdev);
+       if (!tb)
+               goto fail_unlock;
+tb_found:
+       if (!hlist_empty(&tb->owners)) {
                if (sk->sk_reuse == SK_FORCE_REUSE)
                        goto success;
 
                if ((tb->fastreuse > 0 && reuse) ||
                    sk_reuseport_match(tb, sk))
                        goto success;
-               if (inet_csk_bind_conflict(sk, port, tb, tb2, true, true))
+               if (inet_csk_bind_conflict(sk, tb, true, true))
                        goto fail_unlock;
        }
 success:
        inet_csk_update_fastreuse(tb, sk);
 
        if (!inet_csk(sk)->icsk_bind_hash)
-               inet_bind_hash(sk, tb, tb2, port);
+               inet_bind_hash(sk, tb, port);
        WARN_ON(inet_csk(sk)->icsk_bind_hash != tb);
-       WARN_ON(inet_csk(sk)->icsk_bind2_hash != tb2);
        ret = 0;
 
 fail_unlock:
-       if (ret) {
-               if (bhash_created)
-                       inet_bind_bucket_destroy(hinfo->bind_bucket_cachep, tb);
-               if (bhash2_created)
-                       inet_bind2_bucket_destroy(hinfo->bind2_bucket_cachep,
-                                                 tb2);
-       }
        spin_unlock_bh(&head->lock);
        return ret;
 }
@@ -1079,7 +961,6 @@ struct sock *inet_csk_clone_lock(const struct sock *sk,
 
                inet_sk_set_state(newsk, TCP_SYN_RECV);
                newicsk->icsk_bind_hash = NULL;
-               newicsk->icsk_bind2_hash = NULL;
 
                inet_sk(newsk)->inet_dport = inet_rsk(req)->ir_rmt_port;
                inet_sk(newsk)->inet_num = inet_rsk(req)->ir_num;
index e8de5e699b3f591927bfb843d03e85077db960e7..b9d995b5ce24cc259dfc7c8b42b636eca4bfc78e 100644 (file)
@@ -81,41 +81,6 @@ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
        return tb;
 }
 
-struct inet_bind2_bucket *inet_bind2_bucket_create(struct kmem_cache *cachep,
-                                                  struct net *net,
-                                                  struct inet_bind2_hashbucket *head,
-                                                  const unsigned short port,
-                                                  int l3mdev,
-                                                  const struct sock *sk)
-{
-       struct inet_bind2_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
-
-       if (tb) {
-               write_pnet(&tb->ib_net, net);
-               tb->l3mdev    = l3mdev;
-               tb->port      = port;
-#if IS_ENABLED(CONFIG_IPV6)
-               if (sk->sk_family == AF_INET6)
-                       tb->v6_rcv_saddr = sk->sk_v6_rcv_saddr;
-               else
-#endif
-                       tb->rcv_saddr = sk->sk_rcv_saddr;
-               INIT_HLIST_HEAD(&tb->owners);
-               hlist_add_head(&tb->node, &head->chain);
-       }
-       return tb;
-}
-
-static bool bind2_bucket_addr_match(struct inet_bind2_bucket *tb2, struct sock *sk)
-{
-#if IS_ENABLED(CONFIG_IPV6)
-       if (sk->sk_family == AF_INET6)
-               return ipv6_addr_equal(&tb2->v6_rcv_saddr,
-                                      &sk->sk_v6_rcv_saddr);
-#endif
-       return tb2->rcv_saddr == sk->sk_rcv_saddr;
-}
-
 /*
  * Caller must hold hashbucket lock for this tb with local BH disabled
  */
@@ -127,25 +92,12 @@ void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket
        }
 }
 
-/* Caller must hold the lock for the corresponding hashbucket in the bhash table
- * with local BH disabled
- */
-void inet_bind2_bucket_destroy(struct kmem_cache *cachep, struct inet_bind2_bucket *tb)
-{
-       if (hlist_empty(&tb->owners)) {
-               __hlist_del(&tb->node);
-               kmem_cache_free(cachep, tb);
-       }
-}
-
 void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
-                   struct inet_bind2_bucket *tb2, const unsigned short snum)
+                   const unsigned short snum)
 {
        inet_sk(sk)->inet_num = snum;
        sk_add_bind_node(sk, &tb->owners);
        inet_csk(sk)->icsk_bind_hash = tb;
-       sk_add_bind2_node(sk, &tb2->owners);
-       inet_csk(sk)->icsk_bind2_hash = tb2;
 }
 
 /*
@@ -157,7 +109,6 @@ static void __inet_put_port(struct sock *sk)
        const int bhash = inet_bhashfn(sock_net(sk), inet_sk(sk)->inet_num,
                        hashinfo->bhash_size);
        struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash];
-       struct inet_bind2_bucket *tb2;
        struct inet_bind_bucket *tb;
 
        spin_lock(&head->lock);
@@ -166,13 +117,6 @@ static void __inet_put_port(struct sock *sk)
        inet_csk(sk)->icsk_bind_hash = NULL;
        inet_sk(sk)->inet_num = 0;
        inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb);
-
-       if (inet_csk(sk)->icsk_bind2_hash) {
-               tb2 = inet_csk(sk)->icsk_bind2_hash;
-               __sk_del_bind2_node(sk);
-               inet_csk(sk)->icsk_bind2_hash = NULL;
-               inet_bind2_bucket_destroy(hashinfo->bind2_bucket_cachep, tb2);
-       }
        spin_unlock(&head->lock);
 }
 
@@ -189,19 +133,14 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
        struct inet_hashinfo *table = sk->sk_prot->h.hashinfo;
        unsigned short port = inet_sk(child)->inet_num;
        const int bhash = inet_bhashfn(sock_net(sk), port,
-                                      table->bhash_size);
+                       table->bhash_size);
        struct inet_bind_hashbucket *head = &table->bhash[bhash];
-       struct inet_bind2_hashbucket *head_bhash2;
-       bool created_inet_bind_bucket = false;
-       struct net *net = sock_net(sk);
-       struct inet_bind2_bucket *tb2;
        struct inet_bind_bucket *tb;
        int l3mdev;
 
        spin_lock(&head->lock);
        tb = inet_csk(sk)->icsk_bind_hash;
-       tb2 = inet_csk(sk)->icsk_bind2_hash;
-       if (unlikely(!tb || !tb2)) {
+       if (unlikely(!tb)) {
                spin_unlock(&head->lock);
                return -ENOENT;
        }
@@ -214,45 +153,25 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
                 * as that of the child socket. We have to look up or
                 * create a new bind bucket for the child here. */
                inet_bind_bucket_for_each(tb, &head->chain) {
-                       if (check_bind_bucket_match(tb, net, port, l3mdev))
+                       if (net_eq(ib_net(tb), sock_net(sk)) &&
+                           tb->l3mdev == l3mdev && tb->port == port)
                                break;
                }
                if (!tb) {
                        tb = inet_bind_bucket_create(table->bind_bucket_cachep,
-                                                    net, head, port, l3mdev);
+                                                    sock_net(sk), head, port,
+                                                    l3mdev);
                        if (!tb) {
                                spin_unlock(&head->lock);
                                return -ENOMEM;
                        }
-                       created_inet_bind_bucket = true;
                }
                inet_csk_update_fastreuse(tb, child);
-
-               goto bhash2_find;
-       } else if (!bind2_bucket_addr_match(tb2, child)) {
-               l3mdev = inet_sk_bound_l3mdev(sk);
-
-bhash2_find:
-               tb2 = inet_bind2_bucket_find(table, net, port, l3mdev, child,
-                                            &head_bhash2);
-               if (!tb2) {
-                       tb2 = inet_bind2_bucket_create(table->bind2_bucket_cachep,
-                                                      net, head_bhash2, port,
-                                                      l3mdev, child);
-                       if (!tb2)
-                               goto error;
-               }
        }
-       inet_bind_hash(child, tb, tb2, port);
+       inet_bind_hash(child, tb, port);
        spin_unlock(&head->lock);
 
        return 0;
-
-error:
-       if (created_inet_bind_bucket)
-               inet_bind_bucket_destroy(table->bind_bucket_cachep, tb);
-       spin_unlock(&head->lock);
-       return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(__inet_inherit_port);
 
@@ -756,76 +675,6 @@ void inet_unhash(struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(inet_unhash);
 
-static bool check_bind2_bucket_match(struct inet_bind2_bucket *tb,
-                                    struct net *net, unsigned short port,
-                                    int l3mdev, struct sock *sk)
-{
-#if IS_ENABLED(CONFIG_IPV6)
-       if (sk->sk_family == AF_INET6)
-               return net_eq(ib2_net(tb), net) && tb->port == port &&
-                       tb->l3mdev == l3mdev &&
-                       ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr);
-       else
-#endif
-               return net_eq(ib2_net(tb), net) && tb->port == port &&
-                       tb->l3mdev == l3mdev && tb->rcv_saddr == sk->sk_rcv_saddr;
-}
-
-bool check_bind2_bucket_match_nulladdr(struct inet_bind2_bucket *tb,
-                                      struct net *net, const unsigned short port,
-                                      int l3mdev, const struct sock *sk)
-{
-#if IS_ENABLED(CONFIG_IPV6)
-       struct in6_addr nulladdr = {};
-
-       if (sk->sk_family == AF_INET6)
-               return net_eq(ib2_net(tb), net) && tb->port == port &&
-                       tb->l3mdev == l3mdev &&
-                       ipv6_addr_equal(&tb->v6_rcv_saddr, &nulladdr);
-       else
-#endif
-               return net_eq(ib2_net(tb), net) && tb->port == port &&
-                       tb->l3mdev == l3mdev && tb->rcv_saddr == 0;
-}
-
-static struct inet_bind2_hashbucket *
-inet_bhashfn_portaddr(struct inet_hashinfo *hinfo, const struct sock *sk,
-                     const struct net *net, unsigned short port)
-{
-       u32 hash;
-
-#if IS_ENABLED(CONFIG_IPV6)
-       if (sk->sk_family == AF_INET6)
-               hash = ipv6_portaddr_hash(net, &sk->sk_v6_rcv_saddr, port);
-       else
-#endif
-               hash = ipv4_portaddr_hash(net, sk->sk_rcv_saddr, port);
-       return &hinfo->bhash2[hash & (hinfo->bhash_size - 1)];
-}
-
-/* This should only be called when the spinlock for the socket's corresponding
- * bind_hashbucket is held
- */
-struct inet_bind2_bucket *
-inet_bind2_bucket_find(struct inet_hashinfo *hinfo, struct net *net,
-                      const unsigned short port, int l3mdev, struct sock *sk,
-                      struct inet_bind2_hashbucket **head)
-{
-       struct inet_bind2_bucket *bhash2 = NULL;
-       struct inet_bind2_hashbucket *h;
-
-       h = inet_bhashfn_portaddr(hinfo, sk, net, port);
-       inet_bind_bucket_for_each(bhash2, &h->chain) {
-               if (check_bind2_bucket_match(bhash2, net, port, l3mdev, sk))
-                       break;
-       }
-
-       if (head)
-               *head = h;
-
-       return bhash2;
-}
-
 /* RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm
  * Note that we use 32bit integers (vs RFC 'short integers')
  * because 2^16 is not a multiple of num_ephemeral and this
@@ -846,13 +695,10 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 {
        struct inet_hashinfo *hinfo = death_row->hashinfo;
        struct inet_timewait_sock *tw = NULL;
-       struct inet_bind2_hashbucket *head2;
        struct inet_bind_hashbucket *head;
        int port = inet_sk(sk)->inet_num;
        struct net *net = sock_net(sk);
-       struct inet_bind2_bucket *tb2;
        struct inet_bind_bucket *tb;
-       bool tb_created = false;
        u32 remaining, offset;
        int ret, i, low, high;
        int l3mdev;
@@ -909,7 +755,8 @@ other_parity_scan:
                 * the established check is already unique enough.
                 */
                inet_bind_bucket_for_each(tb, &head->chain) {
-                       if (check_bind_bucket_match(tb, net, port, l3mdev)) {
+                       if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+                           tb->port == port) {
                                if (tb->fastreuse >= 0 ||
                                    tb->fastreuseport >= 0)
                                        goto next_port;
@@ -927,7 +774,6 @@ other_parity_scan:
                        spin_unlock_bh(&head->lock);
                        return -ENOMEM;
                }
-               tb_created = true;
                tb->fastreuse = -1;
                tb->fastreuseport = -1;
                goto ok;
@@ -943,17 +789,6 @@ next_port:
        return -EADDRNOTAVAIL;
 
 ok:
-       /* Find the corresponding tb2 bucket since we need to
-        * add the socket to the bhash2 table as well
-        */
-       tb2 = inet_bind2_bucket_find(hinfo, net, port, l3mdev, sk, &head2);
-       if (!tb2) {
-               tb2 = inet_bind2_bucket_create(hinfo->bind2_bucket_cachep, net,
-                                              head2, port, l3mdev, sk);
-               if (!tb2)
-                       goto error;
-       }
-
        /* Here we want to add a little bit of randomness to the next source
         * port that will be chosen. We use a max() with a random here so that
         * on low contention the randomness is maximal and on high contention
@@ -963,7 +798,7 @@ ok:
        WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2);
 
        /* Head lock still held and bh's disabled */
-       inet_bind_hash(sk, tb, tb2, port);
+       inet_bind_hash(sk, tb, port);
        if (sk_unhashed(sk)) {
                inet_sk(sk)->inet_sport = htons(port);
                inet_ehash_nolisten(sk, (struct sock *)tw, NULL);
@@ -975,12 +810,6 @@ ok:
                inet_twsk_deschedule_put(tw);
        local_bh_enable();
        return 0;
-
-error:
-       if (tb_created)
-               inet_bind_bucket_destroy(hinfo->bind_bucket_cachep, tb);
-       spin_unlock_bh(&head->lock);
-       return -ENOMEM;
 }
 
 /*
@@ -1026,10 +855,12 @@ void __init inet_hashinfo2_init(struct inet_hashinfo *h, const char *name,
        init_hashinfo_lhash2(h);
 
        /* this one is used for source ports of outgoing connections */
-       table_perturb = kmalloc_array(INET_TABLE_PERTURB_SIZE,
-                                     sizeof(*table_perturb), GFP_KERNEL);
-       if (!table_perturb)
-               panic("TCP: failed to alloc table_perturb");
+       table_perturb = alloc_large_system_hash("Table-perturb",
+                                               sizeof(*table_perturb),
+                                               INET_TABLE_PERTURB_SIZE,
+                                               0, 0, NULL, NULL,
+                                               INET_TABLE_PERTURB_SIZE,
+                                               INET_TABLE_PERTURB_SIZE);
 }
 
 int inet_hashinfo2_init_mod(struct inet_hashinfo *h)
index 7e474a85deaf560d49230791dca1d0d8319365ed..3b9cd487075af20fa31ac4786a6f124ff080270e 100644 (file)
@@ -629,21 +629,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
        }
 
        if (dev->header_ops) {
-               const int pull_len = tunnel->hlen + sizeof(struct iphdr);
-
                if (skb_cow_head(skb, 0))
                        goto free_skb;
 
                tnl_params = (const struct iphdr *)skb->data;
 
-               if (pull_len > skb_transport_offset(skb))
-                       goto free_skb;
-
                /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
                 * to gre header.
                 */
-               skb_pull(skb, pull_len);
+               skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
                skb_reset_mac_header(skb);
+
+               if (skb->ip_summed == CHECKSUM_PARTIAL &&
+                   skb_checksum_start(skb) < skb->data)
+                       goto free_skb;
        } else {
                if (skb_cow_head(skb, dev->needed_headroom))
                        goto free_skb;
index 9984d23a7f3e1353d2e1fc9053d98c77268c577e..028513d3e2a2bcf18022d9458e46c9a36c46eb2c 100644 (file)
@@ -4604,12 +4604,6 @@ void __init tcp_init(void)
                                  SLAB_HWCACHE_ALIGN | SLAB_PANIC |
                                  SLAB_ACCOUNT,
                                  NULL);
-       tcp_hashinfo.bind2_bucket_cachep =
-               kmem_cache_create("tcp_bind2_bucket",
-                                 sizeof(struct inet_bind2_bucket), 0,
-                                 SLAB_HWCACHE_ALIGN | SLAB_PANIC |
-                                 SLAB_ACCOUNT,
-                                 NULL);
 
        /* Size and allocate the main established and bind bucket
         * hash tables.
@@ -4632,9 +4626,8 @@ void __init tcp_init(void)
        if (inet_ehash_locks_alloc(&tcp_hashinfo))
                panic("TCP: failed to alloc ehash_locks");
        tcp_hashinfo.bhash =
-               alloc_large_system_hash("TCP bind bhash tables",
-                                       sizeof(struct inet_bind_hashbucket) +
-                                       sizeof(struct inet_bind2_hashbucket),
+               alloc_large_system_hash("TCP bind",
+                                       sizeof(struct inet_bind_hashbucket),
                                        tcp_hashinfo.ehash_mask + 1,
                                        17, /* one slot per 128 KB of memory */
                                        0,
@@ -4643,12 +4636,9 @@ void __init tcp_init(void)
                                        0,
                                        64 * 1024);
        tcp_hashinfo.bhash_size = 1U << tcp_hashinfo.bhash_size;
-       tcp_hashinfo.bhash2 =
-               (struct inet_bind2_hashbucket *)(tcp_hashinfo.bhash + tcp_hashinfo.bhash_size);
        for (i = 0; i < tcp_hashinfo.bhash_size; i++) {
                spin_lock_init(&tcp_hashinfo.bhash[i].lock);
                INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
-               INIT_HLIST_HEAD(&tcp_hashinfo.bhash2[i].chain);
        }
 
 
index 2fe5860c21d6ecc616d09cfe98c48419ed506c51..b146ce88c5d0c4f5a019b3a54823b2082920cc4c 100644 (file)
@@ -304,4 +304,3 @@ void __init xfrm4_protocol_init(void)
 {
        xfrm_input_register_afinfo(&xfrm4_input_afinfo);
 }
-EXPORT_SYMBOL(xfrm4_protocol_init);
index 4081b12a01ff22ecf94a6490aef0665808407a6e..77e3f5970ce48def2ddcf1242dde626b55309961 100644 (file)
@@ -1450,7 +1450,7 @@ static int __ip6_append_data(struct sock *sk,
                             struct page_frag *pfrag,
                             int getfrag(void *from, char *to, int offset,
                                         int len, int odd, struct sk_buff *skb),
-                            void *from, int length, int transhdrlen,
+                            void *from, size_t length, int transhdrlen,
                             unsigned int flags, struct ipcm6_cookie *ipc6)
 {
        struct sk_buff *skb, *skb_prev = NULL;
@@ -1798,7 +1798,7 @@ error:
 int ip6_append_data(struct sock *sk,
                    int getfrag(void *from, char *to, int offset, int len,
                                int odd, struct sk_buff *skb),
-                   void *from, int length, int transhdrlen,
+                   void *from, size_t length, int transhdrlen,
                    struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
                    struct rt6_info *rt, unsigned int flags)
 {
@@ -1995,7 +1995,7 @@ EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
 struct sk_buff *ip6_make_skb(struct sock *sk,
                             int getfrag(void *from, char *to, int offset,
                                         int len, int odd, struct sk_buff *skb),
-                            void *from, int length, int transhdrlen,
+                            void *from, size_t length, int transhdrlen,
                             struct ipcm6_cookie *ipc6, struct rt6_info *rt,
                             unsigned int flags, struct inet_cork_full *cork)
 {
index 29bc4e7c3046e2cc2a395ccf2cb452428df72790..6de01185cc68f1263ba72c38bb89f5d7cbbd1eaa 100644 (file)
@@ -399,7 +399,6 @@ int __init seg6_hmac_init(void)
 {
        return seg6_hmac_init_algo();
 }
-EXPORT_SYMBOL(seg6_hmac_init);
 
 int __net_init seg6_hmac_net_init(struct net *net)
 {
index 9fbe243a0e810f392fb4c4c29e2a0c474114af46..98a34287439cc08418255f5baa7eed392cad936c 100644 (file)
@@ -218,6 +218,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
        struct flowi6 fl6;
        int dev_flags = 0;
 
+       memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_iif = skb->dev->ifindex;
        fl6.daddr = nhaddr ? *nhaddr : hdr->daddr;
        fl6.saddr = hdr->saddr;
index c6ff8bf9b55f916e80380bb2e4ea81b11e544a32..9dbd801ddb98c7f0878ffa69fda8113490344fda 100644 (file)
@@ -504,14 +504,15 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        struct ipcm6_cookie ipc6;
        int addr_len = msg->msg_namelen;
        int transhdrlen = 4; /* zero session-id */
-       int ulen = len + transhdrlen;
+       int ulen;
        int err;
 
        /* Rough check on arithmetic overflow,
         * better check is made in ip6_append_data().
         */
-       if (len > INT_MAX)
+       if (len > INT_MAX - transhdrlen)
                return -EMSGSIZE;
+       ulen = len + transhdrlen;
 
        /* Mirror BSD error message compatibility */
        if (msg->msg_flags & MSG_OOB)
index 746be13438eff579cb2d057064f19b643cbbe641..51144fc66889b5d31e9150d8989b4c644f987ee6 100644 (file)
@@ -544,6 +544,7 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type,
        if (msg_type == NFT_MSG_NEWFLOWTABLE)
                nft_activate_next(ctx->net, flowtable);
 
+       INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
        nft_trans_flowtable(trans) = flowtable;
        nft_trans_commit_list_add_tail(ctx->net, trans);
 
@@ -1914,7 +1915,6 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
                goto err_hook_dev;
        }
        hook->ops.dev = dev;
-       hook->inactive = false;
 
        return hook;
 
@@ -2166,7 +2166,7 @@ static int nft_basechain_init(struct nft_base_chain *basechain, u8 family,
        chain->flags |= NFT_CHAIN_BASE | flags;
        basechain->policy = NF_ACCEPT;
        if (chain->flags & NFT_CHAIN_HW_OFFLOAD &&
-           nft_chain_offload_priority(basechain) < 0)
+           !nft_chain_offload_support(basechain))
                return -EOPNOTSUPP;
 
        flow_block_init(&basechain->flow_block);
@@ -7332,7 +7332,7 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net,
                nf_unregister_net_hook(net, &hook->ops);
                if (release_netdev) {
                        list_del(&hook->list);
-                       kfree_rcu(hook);
+                       kfree_rcu(hook, rcu);
                }
        }
 }
@@ -7433,11 +7433,15 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
 
        if (nla[NFTA_FLOWTABLE_FLAGS]) {
                flags = ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS]));
-               if (flags & ~NFT_FLOWTABLE_MASK)
-                       return -EOPNOTSUPP;
+               if (flags & ~NFT_FLOWTABLE_MASK) {
+                       err = -EOPNOTSUPP;
+                       goto err_flowtable_update_hook;
+               }
                if ((flowtable->data.flags & NFT_FLOWTABLE_HW_OFFLOAD) ^
-                   (flags & NFT_FLOWTABLE_HW_OFFLOAD))
-                       return -EOPNOTSUPP;
+                   (flags & NFT_FLOWTABLE_HW_OFFLOAD)) {
+                       err = -EOPNOTSUPP;
+                       goto err_flowtable_update_hook;
+               }
        } else {
                flags = flowtable->data.flags;
        }
@@ -7618,6 +7622,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
 {
        const struct nlattr * const *nla = ctx->nla;
        struct nft_flowtable_hook flowtable_hook;
+       LIST_HEAD(flowtable_del_list);
        struct nft_hook *this, *hook;
        struct nft_trans *trans;
        int err;
@@ -7633,7 +7638,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
                        err = -ENOENT;
                        goto err_flowtable_del_hook;
                }
-               hook->inactive = true;
+               list_move(&hook->list, &flowtable_del_list);
        }
 
        trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
@@ -7646,6 +7651,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
        nft_trans_flowtable(trans) = flowtable;
        nft_trans_flowtable_update(trans) = true;
        INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
+       list_splice(&flowtable_del_list, &nft_trans_flowtable_hooks(trans));
        nft_flowtable_hook_release(&flowtable_hook);
 
        nft_trans_commit_list_add_tail(ctx->net, trans);
@@ -7653,13 +7659,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
        return 0;
 
 err_flowtable_del_hook:
-       list_for_each_entry(this, &flowtable_hook.list, list) {
-               hook = nft_hook_list_find(&flowtable->hook_list, this);
-               if (!hook)
-                       break;
-
-               hook->inactive = false;
-       }
+       list_splice(&flowtable_del_list, &flowtable->hook_list);
        nft_flowtable_hook_release(&flowtable_hook);
 
        return err;
@@ -8329,6 +8329,9 @@ static void nft_commit_release(struct nft_trans *trans)
                nf_tables_chain_destroy(&trans->ctx);
                break;
        case NFT_MSG_DELRULE:
+               if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
+                       nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+
                nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
                break;
        case NFT_MSG_DELSET:
@@ -8563,17 +8566,6 @@ void nft_chain_del(struct nft_chain *chain)
        list_del_rcu(&chain->list);
 }
 
-static void nft_flowtable_hooks_del(struct nft_flowtable *flowtable,
-                                   struct list_head *hook_list)
-{
-       struct nft_hook *hook, *next;
-
-       list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
-               if (hook->inactive)
-                       list_move(&hook->list, hook_list);
-       }
-}
-
 static void nf_tables_module_autoload_cleanup(struct net *net)
 {
        struct nftables_pernet *nft_net = nft_pernet(net);
@@ -8828,6 +8820,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
                        nf_tables_rule_notify(&trans->ctx,
                                              nft_trans_rule(trans),
                                              NFT_MSG_NEWRULE);
+                       if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
+                               nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_DELRULE:
@@ -8918,8 +8913,6 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
                        break;
                case NFT_MSG_DELFLOWTABLE:
                        if (nft_trans_flowtable_update(trans)) {
-                               nft_flowtable_hooks_del(nft_trans_flowtable(trans),
-                                                       &nft_trans_flowtable_hooks(trans));
                                nf_tables_flowtable_notify(&trans->ctx,
                                                           nft_trans_flowtable(trans),
                                                           &nft_trans_flowtable_hooks(trans),
@@ -9000,7 +8993,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
        struct nftables_pernet *nft_net = nft_pernet(net);
        struct nft_trans *trans, *next;
        struct nft_trans_elem *te;
-       struct nft_hook *hook;
 
        if (action == NFNL_ABORT_VALIDATE &&
            nf_tables_validate(net) < 0)
@@ -9131,8 +9123,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
                        break;
                case NFT_MSG_DELFLOWTABLE:
                        if (nft_trans_flowtable_update(trans)) {
-                               list_for_each_entry(hook, &nft_trans_flowtable(trans)->hook_list, list)
-                                       hook->inactive = false;
+                               list_splice(&nft_trans_flowtable_hooks(trans),
+                                           &nft_trans_flowtable(trans)->hook_list);
                        } else {
                                trans->ctx.table->use++;
                                nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
index 2d36952b13920d149110e7d90dff8d7069e78ff8..910ef881c3b853c35e4a2becf7eff31d666556fb 100644 (file)
@@ -208,7 +208,7 @@ static int nft_setup_cb_call(enum tc_setup_type type, void *type_data,
        return 0;
 }
 
-int nft_chain_offload_priority(struct nft_base_chain *basechain)
+static int nft_chain_offload_priority(const struct nft_base_chain *basechain)
 {
        if (basechain->ops.priority <= 0 ||
            basechain->ops.priority > USHRT_MAX)
@@ -217,6 +217,27 @@ int nft_chain_offload_priority(struct nft_base_chain *basechain)
        return 0;
 }
 
+bool nft_chain_offload_support(const struct nft_base_chain *basechain)
+{
+       struct net_device *dev;
+       struct nft_hook *hook;
+
+       if (nft_chain_offload_priority(basechain) < 0)
+               return false;
+
+       list_for_each_entry(hook, &basechain->hook_list, list) {
+               if (hook->ops.pf != NFPROTO_NETDEV ||
+                   hook->ops.hooknum != NF_NETDEV_INGRESS)
+                       return false;
+
+               dev = hook->ops.dev;
+               if (!dev->netdev_ops->ndo_setup_tc && !flow_indr_dev_exists())
+                       return false;
+       }
+
+       return true;
+}
+
 static void nft_flow_cls_offload_setup(struct flow_cls_offload *cls_flow,
                                       const struct nft_base_chain *basechain,
                                       const struct nft_rule *rule,
index 4394df4bc99b4cb64e8c0b7900623c7a43570ddd..e5fd6995e4bf30fd7ef019c49d2f3a29c10cf895 100644 (file)
@@ -335,7 +335,8 @@ static void nft_nat_inet_eval(const struct nft_expr *expr,
 {
        const struct nft_nat *priv = nft_expr_priv(expr);
 
-       if (priv->family == nft_pf(pkt))
+       if (priv->family == nft_pf(pkt) ||
+           priv->family == NFPROTO_INET)
                nft_nat_eval(expr, regs, pkt);
 }
 
index 1b5d73079dc9be13b85150246792ef7aee3455e2..868db4669a2912d01433dddc41f3905a5e7bf2bf 100644 (file)
@@ -373,6 +373,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
        update_ip_l4_checksum(skb, nh, *addr, new_addr);
        csum_replace4(&nh->check, *addr, new_addr);
        skb_clear_hash(skb);
+       ovs_ct_clear(skb, NULL);
        *addr = new_addr;
 }
 
@@ -420,6 +421,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
                update_ipv6_checksum(skb, l4_proto, addr, new_addr);
 
        skb_clear_hash(skb);
+       ovs_ct_clear(skb, NULL);
        memcpy(addr, new_addr, sizeof(__be32[4]));
 }
 
@@ -660,6 +662,7 @@ static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
 static void set_tp_port(struct sk_buff *skb, __be16 *port,
                        __be16 new_port, __sum16 *check)
 {
+       ovs_ct_clear(skb, NULL);
        inet_proto_csum_replace2(check, skb, *port, new_port, false);
        *port = new_port;
 }
@@ -699,6 +702,7 @@ static int set_udp(struct sk_buff *skb, struct sw_flow_key *flow_key,
                uh->dest = dst;
                flow_key->tp.src = src;
                flow_key->tp.dst = dst;
+               ovs_ct_clear(skb, NULL);
        }
 
        skb_clear_hash(skb);
@@ -761,6 +765,8 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *flow_key,
        sh->checksum = old_csum ^ old_correct_csum ^ new_csum;
 
        skb_clear_hash(skb);
+       ovs_ct_clear(skb, NULL);
+
        flow_key->tp.src = sh->source;
        flow_key->tp.dst = sh->dest;
 
index 4a947c13c813a7213679a4aedae894f30a78c542..4e70df91d0f2a08f36c2b19860cf21924739bafb 100644 (file)
@@ -1342,7 +1342,9 @@ int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key)
 
        nf_ct_put(ct);
        nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
-       ovs_ct_fill_key(skb, key, false);
+
+       if (key)
+               ovs_ct_fill_key(skb, key, false);
 
        return 0;
 }
index df194cc070350469f51ea83619c57b70d76e234d..f87a2d8f23a728848b69b462afa8a0a267445777 100644 (file)
@@ -919,7 +919,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 EXPORT_SYMBOL_GPL(xdr_init_encode);
 
 /**
- * xdr_commit_encode - Ensure all data is written to buffer
+ * __xdr_commit_encode - Ensure all data is written to buffer
  * @xdr: pointer to xdr_stream
  *
  * We handle encoding across page boundaries by giving the caller a
@@ -931,26 +931,29 @@ EXPORT_SYMBOL_GPL(xdr_init_encode);
  * required at the end of encoding, or any other time when the xdr_buf
  * data might be read.
  */
-inline void xdr_commit_encode(struct xdr_stream *xdr)
+void __xdr_commit_encode(struct xdr_stream *xdr)
 {
-       int shift = xdr->scratch.iov_len;
+       size_t shift = xdr->scratch.iov_len;
        void *page;
 
-       if (shift == 0)
-               return;
        page = page_address(*xdr->page_ptr);
        memcpy(xdr->scratch.iov_base, page, shift);
        memmove(page, page + shift, (void *)xdr->p - page);
        xdr_reset_scratch_buffer(xdr);
 }
-EXPORT_SYMBOL_GPL(xdr_commit_encode);
+EXPORT_SYMBOL_GPL(__xdr_commit_encode);
 
-static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
-               size_t nbytes)
+/*
+ * The buffer space to be reserved crosses the boundary between
+ * xdr->buf->head and xdr->buf->pages, or between two pages
+ * in xdr->buf->pages.
+ */
+static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
+                                                  size_t nbytes)
 {
-       __be32 *p;
        int space_left;
        int frag1bytes, frag2bytes;
+       void *p;
 
        if (nbytes > PAGE_SIZE)
                goto out_overflow; /* Bigger buffers require special handling */
@@ -964,6 +967,7 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
                xdr->buf->page_len += frag1bytes;
        xdr->page_ptr++;
        xdr->iov = NULL;
+
        /*
         * If the last encode didn't end exactly on a page boundary, the
         * next one will straddle boundaries.  Encode into the next
@@ -972,14 +976,19 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
         * space at the end of the previous buffer:
         */
        xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes);
-       p = page_address(*xdr->page_ptr);
+
        /*
-        * Note this is where the next encode will start after we've
-        * shifted this one back:
+        * xdr->p is where the next encode will start after
+        * xdr_commit_encode() has shifted this one back:
         */
-       xdr->p = (void *)p + frag2bytes;
+       p = page_address(*xdr->page_ptr);
+       xdr->p = p + frag2bytes;
        space_left = xdr->buf->buflen - xdr->buf->len;
-       xdr->end = (void *)p + min_t(int, space_left, PAGE_SIZE);
+       if (space_left - nbytes >= PAGE_SIZE)
+               xdr->end = p + PAGE_SIZE;
+       else
+               xdr->end = p + space_left - frag1bytes;
+
        xdr->buf->page_len += frag2bytes;
        xdr->buf->len += nbytes;
        return p;
index 5f0155fdefc7b10b3a21802876b9890fd6e99e7a..11cf7c6466443e7fcadf7084d4cc138dd820b7dd 100644 (file)
@@ -478,10 +478,10 @@ svc_rdma_build_writes(struct svc_rdma_write_info *info,
                unsigned int write_len;
                u64 offset;
 
-               seg = &info->wi_chunk->ch_segments[info->wi_seg_no];
-               if (!seg)
+               if (info->wi_seg_no >= info->wi_chunk->ch_segcount)
                        goto out_overflow;
 
+               seg = &info->wi_chunk->ch_segments[info->wi_seg_no];
                write_len = min(remaining, seg->rs_length - info->wi_seg_off);
                if (!write_len)
                        goto out_overflow;
index b91ddc110786e258130382d73ae50b2940ec2b54..da176411c1b5fdb418ad8d78b9f5b1e7a6cd4d9c 100644 (file)
@@ -544,7 +544,7 @@ static int do_tls_getsockopt(struct sock *sk, int optname,
                rc = do_tls_getsockopt_conf(sk, optval, optlen,
                                            optname == TLS_TX);
                break;
-       case TLS_TX_ZEROCOPY_SENDFILE:
+       case TLS_TX_ZEROCOPY_RO:
                rc = do_tls_getsockopt_tx_zc(sk, optval, optlen);
                break;
        default:
@@ -731,7 +731,7 @@ static int do_tls_setsockopt(struct sock *sk, int optname, sockptr_t optval,
                                            optname == TLS_TX);
                release_sock(sk);
                break;
-       case TLS_TX_ZEROCOPY_SENDFILE:
+       case TLS_TX_ZEROCOPY_RO:
                lock_sock(sk);
                rc = do_tls_setsockopt_tx_zc(sk, optval, optlen);
                release_sock(sk);
@@ -970,7 +970,7 @@ static int tls_get_info(const struct sock *sk, struct sk_buff *skb)
                goto nla_failure;
 
        if (ctx->tx_conf == TLS_HW && ctx->zerocopy_sendfile) {
-               err = nla_put_flag(skb, TLS_INFO_ZC_SENDFILE);
+               err = nla_put_flag(skb, TLS_INFO_ZC_RO_TX);
                if (err)
                        goto nla_failure;
        }
@@ -994,7 +994,7 @@ static size_t tls_get_info_size(const struct sock *sk)
                nla_total_size(sizeof(u16)) +   /* TLS_INFO_CIPHER */
                nla_total_size(sizeof(u16)) +   /* TLS_INFO_RXCONF */
                nla_total_size(sizeof(u16)) +   /* TLS_INFO_TXCONF */
-               nla_total_size(0) +             /* TLS_INFO_ZC_SENDFILE */
+               nla_total_size(0) +             /* TLS_INFO_ZC_RO_TX */
                0;
 
        return size;
index 654dcef7cfb3849463be9d905ae625319fbae406..2206e6f8902d78a97cba87d52e7696f43b35bec6 100644 (file)
@@ -490,7 +490,7 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
         * -ECONNREFUSED. Otherwise, if we haven't queued any skbs
         * to other and its full, we will hang waiting for POLLOUT.
         */
-       if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
+       if (unix_recvq_full_lockless(other) && !sock_flag(other, SOCK_DEAD))
                return 1;
 
        if (connected)
index e0a4526ab66b3fba2dc5751296aed9e3ad9fa7f7..19ac872a66240040717d4248d9c9171f5126fbe0 100644 (file)
@@ -373,7 +373,8 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
                goto out;
        }
 
-       nb_pkts = xskq_cons_peek_desc_batch(xs->tx, pool, max_entries);
+       max_entries = xskq_cons_nb_entries(xs->tx, max_entries);
+       nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, max_entries);
        if (!nb_pkts) {
                xs->tx->queue_empty_descs++;
                goto out;
@@ -389,7 +390,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
        if (!nb_pkts)
                goto out;
 
-       xskq_cons_release_n(xs->tx, nb_pkts);
+       xskq_cons_release_n(xs->tx, max_entries);
        __xskq_cons_release(xs->tx);
        xs->sk.sk_write_space(&xs->sk);
 
index a794410989cc8333183c5ccdbf76413634268754..fb20bf7207cfb5bb90743b4a19b3c56812f29d10 100644 (file)
@@ -282,14 +282,6 @@ static inline bool xskq_cons_peek_desc(struct xsk_queue *q,
        return xskq_cons_read_desc(q, desc, pool);
 }
 
-static inline u32 xskq_cons_peek_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool,
-                                           u32 max)
-{
-       u32 entries = xskq_cons_nb_entries(q, max);
-
-       return xskq_cons_read_desc_batch(q, pool, entries);
-}
-
 /* To improve performance in the xskq_cons_release functions, only update local state here.
  * Reflect this to global state when we get new entries from the ring in
  * xskq_cons_get_entries() and whenever Rx or Tx processing are completed in the NAPI loop.
index 1f01ac65c0cd4c8d25ee337907f33ce98a4d19ca..cac070aee79157b166a908f81b8d2390eae94e58 100644 (file)
@@ -251,8 +251,8 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
 
 # To make this rule robust against "Argument list too long" error,
 # ensure to add $(obj)/ prefix by a shell command.
-cmd_mod = echo $(call real-search, $*.o, .o, -objs -y -m) | \
-       $(AWK) -v RS='( |\n)' '!x[$$0]++ { print("$(obj)/"$$0) }' > $@
+cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \
+       $(AWK) '!x[$$0]++ { print("$(obj)/"$$0) }' > $@
 
 $(obj)/%.mod: FORCE
        $(call if_changed,mod)
index da745e2743b74dfd6da62a943ceef6b73bbf8044..6ccc2f4674166c2b22d22cf04e9d0c34224a5151 100755 (executable)
@@ -8,11 +8,31 @@
 
 set -e
 
+# catch errors from ${NM}
+set -o pipefail
+
+# Run the last element of a pipeline in the current shell.
+# Without this, the while-loop would be executed in a subshell, and
+# the changes made to 'symbol_types' and 'export_symbols' would be lost.
+shopt -s lastpipe
+
 declare -A symbol_types
 declare -a export_symbols
 
 exit_code=0
 
+# If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows
+# 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by
+# '2>/dev/null'. However, it suppresses real error messages as well. Add a
+# hand-crafted error message here.
+#
+# TODO:
+# Use --quiet instead of 2>/dev/null when we upgrade the minimum version of
+# binutils to 2.37, llvm to 13.0.0.
+# Then, the following line will be really simple:
+#   ${NM} --quiet ${1} |
+
+{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } } |
 while read value type name
 do
        # Skip the line if the number of fields is less than 3.
@@ -37,21 +57,7 @@ do
        if [[ ${name} == __ksymtab_* ]]; then
                export_symbols+=(${name#__ksymtab_})
        fi
-
-       # If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm)
-       # shows 'no symbols' diagnostic (but exits with 0). It is harmless and
-       # hidden by '2>/dev/null'. However, it suppresses real error messages
-       # as well. Add a hand-crafted error message here.
-       #
-       # Use --quiet instead of 2>/dev/null when we upgrade the minimum version
-       # of binutils to 2.37, llvm to 13.0.0.
-       #
-       # Then, the following line will be really simple:
-       #   done < <(${NM} --quiet ${1})
-done < <(${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } )
-
-# Catch error in the process substitution
-wait $!
+done
 
 for name in "${export_symbols[@]}"
 do
index 90e1565b1967156b1fa4bf20d1b709d248bc8608..8843ab3cbaddc7a18e5d9812bff5caa5134442a8 100644 (file)
@@ -24,9 +24,9 @@ class LxConfigDump(gdb.Command):
             filename = arg
 
         try:
-            py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8")
-            py_config_size = gdb.parse_and_eval(
-                    "sizeof(kernel_config_data) - 1 - 8 * 2")
+            py_config_ptr = gdb.parse_and_eval("&kernel_config_data")
+            py_config_ptr_end = gdb.parse_and_eval("&kernel_config_data_end")
+            py_config_size = py_config_ptr_end - py_config_ptr
         except gdb.error as e:
             raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?")
 
index 04c4b96e95ec481f40f8a8d46812c94de79b26ee..f1718cc0d700bb9db486383efe4036633d3691c2 100644 (file)
@@ -34,9 +34,8 @@ generate_deps() {
        local mod=${1%.ko:}
        shift
        local namespaces="$*"
-       local mod_source_files="`cat $mod.mod | sed -n 1p                      \
-                                             | sed -e 's/\.o/\.c/g'           \
-                                             | sed "s|[^ ]* *|${src_prefix}&|g"`"
+       local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod)
+
        for ns in $namespaces; do
                echo "Adding namespace $ns to module $mod.ko."
                generate_deps_for_ns $ns "$mod_source_files"
index fbd34b8e8f578aba003533348c907899779fb62c..7434e9ea926e2ab44b6c1b683c677340ee0c0f8e 100644 (file)
 #include <openssl/err.h>
 #include <openssl/engine.h>
 
+/*
+ * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
+ *
+ * Remove this if/when that API is no longer used
+ */
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 /*
  * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
  * assume that it's not available and its header file is missing and that we
index 0165da386289c315cc581aa45fbd4ecfa5b88693..2b2c8eb258d5bd9b4abc435b8196c02882286c69 100644 (file)
@@ -283,8 +283,8 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
        /* key properties */
        flags = 0;
        flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH;
-       flags |= payload->migratable ? (TPM2_OA_FIXED_TPM |
-                                       TPM2_OA_FIXED_PARENT) : 0;
+       flags |= payload->migratable ? 0 : (TPM2_OA_FIXED_TPM |
+                                           TPM2_OA_FIXED_PARENT);
        tpm_buf_append_u32(&buf, flags);
 
        /* policy */
index beceb89f68d9cb5277c4cfcb091153965b4f8d51..1bbd53321d1338e928195067217f192a19ac1a68 100644 (file)
@@ -2600,8 +2600,9 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
                                }
                        }
                        rc = selinux_add_opt(token, arg, mnt_opts);
+                       kfree(arg);
+                       arg = NULL;
                        if (unlikely(rc)) {
-                               kfree(arg);
                                goto free_opt;
                        }
                } else {
@@ -2792,17 +2793,13 @@ static int selinux_fs_context_parse_param(struct fs_context *fc,
                                          struct fs_parameter *param)
 {
        struct fs_parse_result result;
-       int opt, rc;
+       int opt;
 
        opt = fs_parse(fc, selinux_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
-       rc = selinux_add_opt(opt, param->string, &fc->security);
-       if (!rc)
-               param->string = NULL;
-
-       return rc;
+       return selinux_add_opt(opt, param->string, &fc->security);
 }
 
 /* inode security operations */
index 3e9e9ac804f629813b55de6d84cc8e092e0c4e4c..b7e5032b61c97cf7f245a21461263efa6c596271 100644 (file)
@@ -660,6 +660,7 @@ static const struct hda_vendor_id hda_vendor_ids[] = {
        { 0x14f1, "Conexant" },
        { 0x17e8, "Chrontel" },
        { 0x1854, "LG" },
+       { 0x19e5, "Huawei" },
        { 0x1aec, "Wolfson Microelectronics" },
        { 0x1af4, "QEMU" },
        { 0x434d, "C-Media" },
index 0a83eb6b88b1f8298a9d472c8fd6777557f7390a..a77165bd92a983c35bfa56e6f0ca4407b1ff7aa1 100644 (file)
@@ -2525,6 +2525,9 @@ static const struct pci_device_id azx_ids[] = {
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
        { PCI_DEVICE(0x8086, 0x51cf),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+       /* Meteorlake-P */
+       { PCI_DEVICE(0x8086, 0x7e28),
+         .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
        /* Broxton-P(Apollolake) */
        { PCI_DEVICE(0x8086, 0x5a98),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
index aa360a0af2840411b45e3296079051383537b788..1248d1a51cf0132f27b1c0ee5d00dda6ba68f921 100644 (file)
@@ -1052,6 +1052,13 @@ static int patch_conexant_auto(struct hda_codec *codec)
                snd_hda_pick_fixup(codec, cxt5051_fixup_models,
                                   cxt5051_fixups, cxt_fixups);
                break;
+       case 0x14f15098:
+               codec->pin_amp_workaround = 1;
+               spec->gen.mixer_nid = 0x22;
+               spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
+               snd_hda_pick_fixup(codec, cxt5066_fixup_models,
+                                  cxt5066_fixups, cxt_fixups);
+               break;
        case 0x14f150f2:
                codec->power_save_node = 1;
                fallthrough;
index 31fe41795571280ef6d6c29c637157edb0f321d5..6c209cd26c0cab1ed9e835e118e6bcfaf37a7f05 100644 (file)
@@ -4554,6 +4554,7 @@ HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI",    patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI",        patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),
 HDA_CODEC_ENTRY(0x8086281f, "Raptorlake-P HDMI",       patch_i915_adlp_hdmi),
+HDA_CODEC_ENTRY(0x8086281d, "Meteorlake HDMI", patch_i915_adlp_hdmi),
 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",        patch_i915_byt_hdmi),
 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",   patch_i915_byt_hdmi),
index f3ad454b3fbfd55aba4a0a260453b809583cacf1..b0f954118e72edc23c7ab8eedd140c696bb72b98 100644 (file)
@@ -443,6 +443,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
        case 0x10ec0245:
        case 0x10ec0255:
        case 0x10ec0256:
+       case 0x19e58326:
        case 0x10ec0257:
        case 0x10ec0282:
        case 0x10ec0283:
@@ -580,6 +581,7 @@ static void alc_shutup_pins(struct hda_codec *codec)
        switch (codec->core.vendor_id) {
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
        case 0x10ec0283:
        case 0x10ec0286:
        case 0x10ec0288:
@@ -3247,6 +3249,7 @@ static void alc_disable_headset_jack_key(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_write_coef_idx(codec, 0x48, 0x0);
                alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
                break;
@@ -3275,6 +3278,7 @@ static void alc_enable_headset_jack_key(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_write_coef_idx(codec, 0x48, 0xd011);
                alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
                break;
@@ -4910,6 +4914,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_process_coef_fw(codec, coef0256);
                break;
        case 0x10ec0234:
@@ -5025,6 +5030,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_write_coef_idx(codec, 0x45, 0xc489);
                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
                alc_process_coef_fw(codec, coef0256);
@@ -5175,6 +5181,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_write_coef_idx(codec, 0x1b, 0x0e4b);
                alc_write_coef_idx(codec, 0x45, 0xc089);
                msleep(50);
@@ -5274,6 +5281,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_process_coef_fw(codec, coef0256);
                break;
        case 0x10ec0234:
@@ -5388,6 +5396,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_process_coef_fw(codec, coef0256);
                break;
        case 0x10ec0234:
@@ -5489,6 +5498,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_write_coef_idx(codec, 0x1b, 0x0e4b);
                alc_write_coef_idx(codec, 0x06, 0x6104);
                alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
@@ -5783,6 +5793,7 @@ static void alc255_set_default_jack_type(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_process_coef_fw(codec, alc256fw);
                break;
        }
@@ -6385,6 +6396,7 @@ static void alc_combo_jack_hp_jd_restart(struct hda_codec *codec)
        case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
+       case 0x19e58326:
                alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
                alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
                break;
@@ -9059,6 +9071,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+       SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
        SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -9258,6 +9271,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340),
+       SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
        SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS),
@@ -10095,6 +10109,7 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0230:
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x19e58326:
                spec->codec_variant = ALC269_TYPE_ALC256;
                spec->shutup = alc256_shutup;
                spec->init_hook = alc256_init;
@@ -11545,6 +11560,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
+       HDA_CODEC_ENTRY(0x19e58326, "HW8326", patch_alc269),
        {} /* terminator */
 };
 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
index 920190daa4d1b44021f5a140c279a47128a0ba41..dfe85dc2cd20fbddf8d4f125e87c3abae42795ba 100644 (file)
@@ -444,7 +444,8 @@ static bool cs35l36_volatile_reg(struct device *dev, unsigned int reg)
        }
 }
 
-static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 25, 0);
+static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, 0, 912,
+                                 TLV_DB_MINMAX_ITEM(-10200, 1200));
 static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
 
 static const char * const cs35l36_pcm_sftramp_text[] =  {
index aff618513c7539e89142afa977dab3b82ec389ce..0e933181b5dbb98623c938953e4eb3a3aa9eaf39 100644 (file)
@@ -143,7 +143,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
                        0, 0xA0, 96, adc_att_tlv),
        SOC_DOUBLE_R_SX_TLV("PGA Volume",
                        CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL,
-                       0, 0x1A, 30, pga_tlv),
+                       0, 0x19, 30, pga_tlv),
        SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
        SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
        SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
index 9b182b585be4c838c4ce2f9d36b2ca60b7aab878..10e696406a71b161476ea50fa8e68ca7e6a7f9b8 100644 (file)
@@ -137,7 +137,9 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);
 
 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
 
-static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0);
+static DECLARE_TLV_DB_SCALE(pass_tlv, -6000, 50, 0);
+
+static DECLARE_TLV_DB_SCALE(mix_tlv, -5150, 50, 0);
 
 static DECLARE_TLV_DB_SCALE(beep_tlv, -56, 200, 0);
 
@@ -351,7 +353,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
                              CS42L52_SPKB_VOL, 0, 0x40, 0xC0, hl_tlv),
 
        SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL,
-                             CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pga_tlv),
+                             CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pass_tlv),
 
        SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0),
 
@@ -364,7 +366,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
                              CS42L52_ADCB_VOL, 0, 0xA0, 0x78, ipd_tlv),
        SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
                             CS42L52_ADCA_MIXER_VOL, CS42L52_ADCB_MIXER_VOL,
-                               0, 0x19, 0x7F, ipd_tlv),
+                               0, 0x19, 0x7F, mix_tlv),
 
        SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0),
 
index dc23007336c581b7e7d88ab48ba11bff6f7c53c8..510c94265b1f0da025825b3673bd19fae1d1887c 100644 (file)
@@ -391,9 +391,9 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
        SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
 
        SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
-                             CS42L56_HPB_VOLUME, 0, 0x84, 0x48, hl_tlv),
+                             CS42L56_HPB_VOLUME, 0, 0x44, 0x48, hl_tlv),
        SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
-                             CS42L56_LOB_VOLUME, 0, 0x84, 0x48, hl_tlv),
+                             CS42L56_LOB_VOLUME, 0, 0x44, 0x48, hl_tlv),
 
        SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
                        0, 0x00, 1, tone_tlv),
index 703545273900f6f421f70a1a28474c6fa6a0dd9f..360ca2ffd506968ddc8bfb266b0b6fb52e833728 100644 (file)
@@ -348,22 +348,22 @@ static const struct snd_kcontrol_new cs53l30_snd_controls[] = {
        SOC_ENUM("ADC2 NG Delay", adc2_ng_delay_enum),
 
        SOC_SINGLE_SX_TLV("ADC1A PGA Volume",
-                   CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
+                   CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
        SOC_SINGLE_SX_TLV("ADC1B PGA Volume",
-                   CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
+                   CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
        SOC_SINGLE_SX_TLV("ADC2A PGA Volume",
-                   CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
+                   CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
        SOC_SINGLE_SX_TLV("ADC2B PGA Volume",
-                   CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
+                   CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
 
        SOC_SINGLE_SX_TLV("ADC1A Digital Volume",
-                   CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
+                   CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
        SOC_SINGLE_SX_TLV("ADC1B Digital Volume",
-                   CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
+                   CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
        SOC_SINGLE_SX_TLV("ADC2A Digital Volume",
-                   CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
+                   CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
        SOC_SINGLE_SX_TLV("ADC2B Digital Volume",
-                   CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
+                   CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
 };
 
 static const struct snd_soc_dapm_widget cs53l30_dapm_widgets[] = {
index 3f00ead97006e714abe3dbdf7cc6777fd3083458..dd53dfd87b04ee0c28d9a2419898be5fb9565567 100644 (file)
@@ -161,13 +161,16 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
        if (deemph > 1)
                return -EINVAL;
 
+       if (es8328->deemph == deemph)
+               return 0;
+
        ret = es8328_set_deemph(component);
        if (ret < 0)
                return ret;
 
        es8328->deemph = deemph;
 
-       return 0;
+       return 1;
 }
 
 
index 66bbd8f4f1ad8b39301b2264d17aecbdd98af423..08f6c56dc387f56ec148acaf8be10ca984673901 100644 (file)
@@ -740,6 +740,8 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
                pll_param->pll_int, pll_param->pll_frac,
                pll_param->mclk_scaler, pll_param->pre_factor);
 
+       snd_soc_component_update_bits(component,
+               NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_OFF);
        snd_soc_component_update_bits(component,
                NAU8822_REG_PLL_N, NAU8822_PLLMCLK_DIV2 | NAU8822_PLLN_MASK,
                (pll_param->pre_factor ? NAU8822_PLLMCLK_DIV2 : 0) |
@@ -757,6 +759,8 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
                pll_param->mclk_scaler << NAU8822_MCLKSEL_SFT);
        snd_soc_component_update_bits(component,
                NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK, NAU8822_CLKM_PLL);
+       snd_soc_component_update_bits(component,
+               NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_ON);
 
        return 0;
 }
index 489191ff187ec79e249fd0fe1669edff425da603..b45d42c15de6b679926b3184650854c6dd395b93 100644 (file)
@@ -90,6 +90,9 @@
 #define NAU8822_REFIMP_3K                      0x3
 #define NAU8822_IOBUF_EN                       (0x1 << 2)
 #define NAU8822_ABIAS_EN                       (0x1 << 3)
+#define NAU8822_PLL_EN_MASK                    (0x1 << 5)
+#define NAU8822_PLL_ON                         (0x1 << 5)
+#define NAU8822_PLL_OFF                                (0x0 << 5)
 
 /* NAU8822_REG_AUDIO_INTERFACE (0x4) */
 #define NAU8822_AIFMT_MASK                     (0x3 << 3)
index 34cd5a2a997c69035c25213cacd722b5290c24c5..5cca89364280ade53577b4e1a4942b522893b0fa 100644 (file)
@@ -3868,6 +3868,7 @@ static int wm8962_runtime_suspend(struct device *dev)
 #endif
 
 static const struct dev_pm_ops wm8962_pm = {
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
        SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
 };
 
index 7973a75cac059fbef263c6d47baea23a4349550c..6d7fd88243aa8d6f7cd8e34399b01ec67e80b107 100644 (file)
@@ -333,7 +333,7 @@ int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
-       int ret = 0;
+       int ret = 1;
 
        if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
                return 0;
index fa950dde5310960bf209cde6e88d528a78ec1ea7..e765da9a19e7e13846751eb7685eed9f09ac5de8 100644 (file)
@@ -1293,6 +1293,7 @@ static const struct of_device_id fsl_sai_ids[] = {
        { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data },
        { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data },
        { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data },
+       { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mp_data },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_sai_ids);
index e71d74ec1b0b85cf19c79f5c2dc0e5cf9398127d..f4192df962d60faf89ca1029ee055d028d434875 100644 (file)
@@ -54,22 +54,29 @@ static struct snd_soc_dai_link_component cs35l41_components[] = {
        },
 };
 
+/*
+ * Mapping between ACPI instance id and speaker position.
+ *
+ * Four speakers:
+ *         0: Tweeter left, 1: Woofer left
+ *         2: Tweeter right, 3: Woofer right
+ */
 static struct snd_soc_codec_conf cs35l41_codec_conf[] = {
        {
                .dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME),
-               .name_prefix = "WL",
+               .name_prefix = "TL",
        },
        {
                .dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME),
-               .name_prefix = "WR",
+               .name_prefix = "WL",
        },
        {
                .dlc = COMP_CODEC_CONF(CS35L41_DEV2_NAME),
-               .name_prefix = "TL",
+               .name_prefix = "TR",
        },
        {
                .dlc = COMP_CODEC_CONF(CS35L41_DEV3_NAME),
-               .name_prefix = "TR",
+               .name_prefix = "WR",
        },
 };
 
@@ -101,6 +108,21 @@ static int cs35l41_init(struct snd_soc_pcm_runtime *rtd)
        return ret;
 }
 
+/*
+ * Channel map:
+ *
+ * TL/WL: ASPRX1 on slot 0, ASPRX2 on slot 1 (default)
+ * TR/WR: ASPRX1 on slot 1, ASPRX2 on slot 0
+ */
+static const struct {
+       unsigned int rx[2];
+} cs35l41_channel_map[] = {
+       {.rx = {0, 1}}, /* TL */
+       {.rx = {0, 1}}, /* WL */
+       {.rx = {1, 0}}, /* TR */
+       {.rx = {1, 0}}, /* WR */
+};
+
 static int cs35l41_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params)
 {
@@ -134,6 +156,16 @@ static int cs35l41_hw_params(struct snd_pcm_substream *substream,
                                ret);
                        return ret;
                }
+
+               /* setup channel map */
+               ret = snd_soc_dai_set_channel_map(codec_dai, 0, NULL,
+                                                 ARRAY_SIZE(cs35l41_channel_map[i].rx),
+                                                 (unsigned int *)cs35l41_channel_map[i].rx);
+               if (ret < 0) {
+                       dev_err(codec_dai->dev, "fail to set channel map, ret %d\n",
+                               ret);
+                       return ret;
+               }
        }
 
        return 0;
index f03a7ae49d505929280083e48bab010df3ea8a6d..b41ab7a321ae98a5d9447383d045d7a3a762f5bf 100644 (file)
@@ -898,7 +898,7 @@ static int lpass_platform_cdc_dma_mmap(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        unsigned long size, offset;
 
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        size = vma->vm_end - vma->vm_start;
        offset = vma->vm_pgoff << PAGE_SHIFT;
        return io_remap_pfn_range(vma, vma->vm_start,
index 8d740635a4bb84e16b0f77ff9b263b1ebfac145b..28976098a89e712d1203af958c524de4e4d2d63f 100644 (file)
@@ -318,7 +318,7 @@ sink_prepare:
                        p->walking = false;
                        if (ret < 0) {
                                /* unprepare the source widget */
-                               if (!widget_ops[widget->id].ipc_unprepare && swidget->prepared) {
+                               if (widget_ops[widget->id].ipc_unprepare && swidget->prepared) {
                                        widget_ops[widget->id].ipc_unprepare(swidget);
                                        swidget->prepared = false;
                                }
index 03490a4d4ae722f077b336057b07429901db7501..6bdfa527b7f76b39c4fd04d3d0fdabe9f521c48e 100644 (file)
@@ -150,7 +150,7 @@ static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *bu
 {
        struct sof_client_dev *cdev = file->private_data;
        struct sof_msg_inject_priv *priv = cdev->data;
-       size_t size;
+       ssize_t size;
        int ret;
 
        if (*ppos)
@@ -158,8 +158,10 @@ static ssize_t sof_msg_inject_dfs_write(struct file *file, const char __user *bu
 
        size = simple_write_to_buffer(priv->tx_buffer, priv->max_msg_size,
                                      ppos, buffer, count);
+       if (size < 0)
+               return size;
        if (size != count)
-               return size > 0 ? -EFAULT : size;
+               return -EFAULT;
 
        memset(priv->rx_buffer, 0, priv->max_msg_size);
 
@@ -179,7 +181,7 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file,
        struct sof_client_dev *cdev = file->private_data;
        struct sof_msg_inject_priv *priv = cdev->data;
        struct sof_ipc4_msg *ipc4_msg = priv->tx_buffer;
-       size_t size;
+       ssize_t size;
        int ret;
 
        if (*ppos)
@@ -192,18 +194,20 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file,
        size = simple_write_to_buffer(&ipc4_msg->header_u64,
                                      sizeof(ipc4_msg->header_u64),
                                      ppos, buffer, count);
+       if (size < 0)
+               return size;
        if (size != sizeof(ipc4_msg->header_u64))
-               return size > 0 ? -EFAULT : size;
+               return -EFAULT;
 
        count -= size;
-       if (!count) {
-               /* Copy the payload */
-               size = simple_write_to_buffer(ipc4_msg->data_ptr,
-                                             priv->max_msg_size, ppos, buffer,
-                                             count);
-               if (size != count)
-                       return size > 0 ? -EFAULT : size;
-       }
+       /* Copy the payload */
+       size = simple_write_to_buffer(ipc4_msg->data_ptr,
+                                     priv->max_msg_size, ppos, buffer,
+                                     count);
+       if (size < 0)
+               return size;
+       if (size != count)
+               return -EFAULT;
 
        ipc4_msg->data_size = count;
 
index b470404a5376c7603ee1b6fbe17258033723e5fb..e692ae04436a5adc09b4fe65cbe5dea99e129f14 100644 (file)
@@ -291,6 +291,9 @@ int snd_usb_audioformat_set_sync_ep(struct snd_usb_audio *chip,
        bool is_playback;
        int err;
 
+       if (fmt->sync_ep)
+               return 0; /* already set up */
+
        alts = snd_usb_get_host_interface(chip, fmt->iface, fmt->altsetting);
        if (!alts)
                return 0;
@@ -304,7 +307,7 @@ int snd_usb_audioformat_set_sync_ep(struct snd_usb_audio *chip,
         * Generic sync EP handling
         */
 
-       if (altsd->bNumEndpoints < 2)
+       if (fmt->ep_idx > 0 || altsd->bNumEndpoints < 2)
                return 0;
 
        is_playback = !(get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN);
index 78eb41b621d63fab9fd7381fabaae33e2ce79964..4f56e1784932a29e21d92ee6508b6b54030d7164 100644 (file)
@@ -2658,7 +2658,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
                                        .nr_rates = 2,
                                        .rate_table = (unsigned int[]) {
                                                44100, 48000
-                                       }
+                                       },
+                                       .sync_ep = 0x82,
+                                       .sync_iface = 0,
+                                       .sync_altsetting = 1,
+                                       .sync_ep_idx = 1,
+                                       .implicit_fb = 1,
                                }
                        },
                        {
index 73e643ae94b6f2206d8dac0fdd10477e7c1eb8df..e17de69faa5432dbf288ec846dba2745468aeb7e 100644 (file)
 #define X86_BUG_TAA                    X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
 #define X86_BUG_ITLB_MULTIHIT          X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
 #define X86_BUG_SRBDS                  X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
+#define X86_BUG_MMIO_STALE_DATA                X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
index 403e83b4adc88ea3d61337279920de39f75df6ae..d27e0581b7777ba086a772453cc52f6afacdcdeb 100644 (file)
                                                 * Not susceptible to
                                                 * TSX Async Abort (TAA) vulnerabilities.
                                                 */
+#define ARCH_CAP_SBDR_SSDP_NO          BIT(13) /*
+                                                * Not susceptible to SBDR and SSDP
+                                                * variants of Processor MMIO stale data
+                                                * vulnerabilities.
+                                                */
+#define ARCH_CAP_FBSDP_NO              BIT(14) /*
+                                                * Not susceptible to FBSDP variant of
+                                                * Processor MMIO stale data
+                                                * vulnerabilities.
+                                                */
+#define ARCH_CAP_PSDP_NO               BIT(15) /*
+                                                * Not susceptible to PSDP variant of
+                                                * Processor MMIO stale data
+                                                * vulnerabilities.
+                                                */
+#define ARCH_CAP_FB_CLEAR              BIT(17) /*
+                                                * VERW clears CPU fill buffer
+                                                * even on MDS_NO CPUs.
+                                                */
+#define ARCH_CAP_FB_CLEAR_CTRL         BIT(18) /*
+                                                * MSR_IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]
+                                                * bit available to control VERW
+                                                * behavior.
+                                                */
 
 #define MSR_IA32_FLUSH_CMD             0x0000010b
 #define L1D_FLUSH                      BIT(0)  /*
 #define MSR_IA32_MCU_OPT_CTRL          0x00000123
 #define RNGDS_MITG_DIS                 BIT(0)  /* SRBDS support */
 #define RTM_ALLOW                      BIT(1)  /* TSX development mode */
+#define FB_CLEAR_DIS                   BIT(3)  /* CPU Fill buffer clear disable */
 
 #define MSR_IA32_SYSENTER_CS           0x00000174
 #define MSR_IA32_SYSENTER_ESP          0x00000175
index d9aad15e0d242870f660c8dc19afceeb0c3be100..02bb8cbf91949b2423127f5c962ae2b58eecb167 100644 (file)
@@ -395,6 +395,18 @@ static void test_func_map_prog_compatibility(void)
                                     "./test_attach_probe.o");
 }
 
+static void test_func_replace_global_func(void)
+{
+       const char *prog_name[] = {
+               "freplace/test_pkt_access",
+       };
+
+       test_fexit_bpf2bpf_common("./freplace_global_func.o",
+                                 "./test_pkt_access.o",
+                                 ARRAY_SIZE(prog_name),
+                                 prog_name, false, NULL);
+}
+
 /* NOTE: affect other tests, must run in serial mode */
 void serial_test_fexit_bpf2bpf(void)
 {
@@ -416,4 +428,6 @@ void serial_test_fexit_bpf2bpf(void)
                test_func_replace_multi();
        if (test__start_subtest("fmod_ret_freplace"))
                test_fmod_ret_freplace();
+       if (test__start_subtest("func_replace_global_func"))
+               test_func_replace_global_func();
 }
diff --git a/tools/testing/selftests/bpf/progs/freplace_global_func.c b/tools/testing/selftests/bpf/progs/freplace_global_func.c
new file mode 100644 (file)
index 0000000..96cb61a
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+__noinline
+int test_ctx_global_func(struct __sk_buff *skb)
+{
+       volatile int retval = 1;
+       return retval;
+}
+
+SEC("freplace/test_pkt_access")
+int new_test_pkt_access(struct __sk_buff *skb)
+{
+       return test_ctx_global_func(skb);
+}
+
+char _license[] SEC("license") = "GPL";
index 81470a99ed1c04ab4bfeee5ca438b170327573e8..22423c871ed6173a354faf3d3dc6cb5103515938 100644 (file)
@@ -37,11 +37,38 @@ ifeq ($(ARCH),riscv)
        UNAME_M := riscv
 endif
 
-LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/rbtree.c lib/sparsebit.c lib/test_util.c lib/guest_modes.c lib/perf_test_util.c
-LIBKVM_x86_64 = lib/x86_64/apic.c lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/svm.c lib/x86_64/ucall.c lib/x86_64/handlers.S
-LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S lib/aarch64/spinlock.c lib/aarch64/gic.c lib/aarch64/gic_v3.c lib/aarch64/vgic.c
-LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c
-LIBKVM_riscv = lib/riscv/processor.c lib/riscv/ucall.c
+LIBKVM += lib/assert.c
+LIBKVM += lib/elf.c
+LIBKVM += lib/guest_modes.c
+LIBKVM += lib/io.c
+LIBKVM += lib/kvm_util.c
+LIBKVM += lib/perf_test_util.c
+LIBKVM += lib/rbtree.c
+LIBKVM += lib/sparsebit.c
+LIBKVM += lib/test_util.c
+
+LIBKVM_x86_64 += lib/x86_64/apic.c
+LIBKVM_x86_64 += lib/x86_64/handlers.S
+LIBKVM_x86_64 += lib/x86_64/perf_test_util.c
+LIBKVM_x86_64 += lib/x86_64/processor.c
+LIBKVM_x86_64 += lib/x86_64/svm.c
+LIBKVM_x86_64 += lib/x86_64/ucall.c
+LIBKVM_x86_64 += lib/x86_64/vmx.c
+
+LIBKVM_aarch64 += lib/aarch64/gic.c
+LIBKVM_aarch64 += lib/aarch64/gic_v3.c
+LIBKVM_aarch64 += lib/aarch64/handlers.S
+LIBKVM_aarch64 += lib/aarch64/processor.c
+LIBKVM_aarch64 += lib/aarch64/spinlock.c
+LIBKVM_aarch64 += lib/aarch64/ucall.c
+LIBKVM_aarch64 += lib/aarch64/vgic.c
+
+LIBKVM_s390x += lib/s390x/diag318_test_handler.c
+LIBKVM_s390x += lib/s390x/processor.c
+LIBKVM_s390x += lib/s390x/ucall.c
+
+LIBKVM_riscv += lib/riscv/processor.c
+LIBKVM_riscv += lib/riscv/ucall.c
 
 TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
 TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
@@ -173,12 +200,13 @@ LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
 # $(TEST_GEN_PROGS) starts with $(OUTPUT)/
 include ../lib.mk
 
-STATIC_LIBS := $(OUTPUT)/libkvm.a
 LIBKVM_C := $(filter %.c,$(LIBKVM))
 LIBKVM_S := $(filter %.S,$(LIBKVM))
 LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
 LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
-EXTRA_CLEAN += $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(STATIC_LIBS) cscope.*
+LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ)
+
+EXTRA_CLEAN += $(LIBKVM_OBJS) cscope.*
 
 x := $(shell mkdir -p $(sort $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
 $(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c
@@ -187,13 +215,8 @@ $(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c
 $(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S
        $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
 
-LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ)
-$(OUTPUT)/libkvm.a: $(LIBKVM_OBJS)
-       $(AR) crs $@ $^
-
 x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
-all: $(STATIC_LIBS)
-$(TEST_GEN_PROGS): $(STATIC_LIBS)
+$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
 
 cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
 cscope:
index 7b47ae4f952e68a5003092321814c3265d3bc08f..d60a34cdfaee1fb58195c71e07cf20efbd038166 100644 (file)
@@ -336,8 +336,8 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 static void help(char *name)
 {
        puts("");
-       printf("usage: %s [-h] [-i iterations] [-p offset] [-g]"
-              "[-m mode] [-b vcpu bytes] [-v vcpus] [-o] [-s mem type]"
+       printf("usage: %s [-h] [-i iterations] [-p offset] [-g] "
+              "[-m mode] [-n] [-b vcpu bytes] [-v vcpus] [-o] [-s mem type]"
               "[-x memslots]\n", name);
        puts("");
        printf(" -i: specify iteration counts (default: %"PRIu64")\n",
@@ -351,6 +351,7 @@ static void help(char *name)
        printf(" -p: specify guest physical test memory offset\n"
               "     Warning: a low offset can conflict with the loaded test code.\n");
        guest_modes_help();
+       printf(" -n: Run the vCPUs in nested mode (L2)\n");
        printf(" -b: specify the size of the memory region which should be\n"
               "     dirtied by each vCPU. e.g. 10M or 3G.\n"
               "     (default: 1G)\n");
@@ -387,7 +388,7 @@ int main(int argc, char *argv[])
 
        guest_modes_append_default();
 
-       while ((opt = getopt(argc, argv, "ghi:p:m:b:f:v:os:x:")) != -1) {
+       while ((opt = getopt(argc, argv, "ghi:p:m:nb:f:v:os:x:")) != -1) {
                switch (opt) {
                case 'g':
                        dirty_log_manual_caps = 0;
@@ -401,6 +402,9 @@ int main(int argc, char *argv[])
                case 'm':
                        guest_modes_cmdline(optarg);
                        break;
+               case 'n':
+                       perf_test_args.nested = true;
+                       break;
                case 'b':
                        guest_percpu_mem_size = parse_size(optarg);
                        break;
index a86f953d8d36569389f786797f54b76dcb153114..d822cb670f1cd46e9078ea1613b3abc38106c29c 100644 (file)
@@ -30,10 +30,15 @@ struct perf_test_vcpu_args {
 
 struct perf_test_args {
        struct kvm_vm *vm;
+       /* The starting address and size of the guest test region. */
        uint64_t gpa;
+       uint64_t size;
        uint64_t guest_page_size;
        int wr_fract;
 
+       /* Run vCPUs in L2 instead of L1, if the architecture supports it. */
+       bool nested;
+
        struct perf_test_vcpu_args vcpu_args[KVM_MAX_VCPUS];
 };
 
@@ -49,5 +54,9 @@ 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);
+void perf_test_guest_code(uint32_t vcpu_id);
+
+uint64_t perf_test_nested_pages(int nr_vcpus);
+void perf_test_setup_nested(struct kvm_vm *vm, int nr_vcpus);
 
 #endif /* SELFTEST_KVM_PERF_TEST_UTIL_H */
index d0d51adec76eb88f12564fa38e52d0df2ba535f2..6ce185449259f329cac0f80669466bd49a942547 100644 (file)
@@ -482,13 +482,23 @@ void vcpu_set_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid);
 struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid);
 void vm_xsave_req_perm(int bit);
 
-enum x86_page_size {
-       X86_PAGE_SIZE_4K = 0,
-       X86_PAGE_SIZE_2M,
-       X86_PAGE_SIZE_1G,
+enum pg_level {
+       PG_LEVEL_NONE,
+       PG_LEVEL_4K,
+       PG_LEVEL_2M,
+       PG_LEVEL_1G,
+       PG_LEVEL_512G,
+       PG_LEVEL_NUM
 };
-void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
-                  enum x86_page_size page_size);
+
+#define PG_LEVEL_SHIFT(_level) ((_level - 1) * 9 + 12)
+#define PG_LEVEL_SIZE(_level) (1ull << PG_LEVEL_SHIFT(_level))
+
+#define PG_SIZE_4K PG_LEVEL_SIZE(PG_LEVEL_4K)
+#define PG_SIZE_2M PG_LEVEL_SIZE(PG_LEVEL_2M)
+#define PG_SIZE_1G PG_LEVEL_SIZE(PG_LEVEL_1G)
+
+void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level);
 
 /*
  * Basic CPU control in CR0
@@ -505,9 +515,6 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 #define X86_CR0_CD          (1UL<<30) /* Cache Disable */
 #define X86_CR0_PG          (1UL<<31) /* Paging */
 
-/* VMX_EPT_VPID_CAP bits */
-#define VMX_EPT_VPID_CAP_AD_BITS       (1ULL << 21)
-
 #define XSTATE_XTILE_CFG_BIT           17
 #define XSTATE_XTILE_DATA_BIT          18
 
index 583ceb0d14574ab456c14cf12290a216ca7b32a0..cc3604f8f1d3c52c74ba0f307b69bf7bf7e78f0e 100644 (file)
@@ -96,6 +96,9 @@
 #define VMX_MISC_PREEMPTION_TIMER_RATE_MASK    0x0000001f
 #define VMX_MISC_SAVE_EFER_LMA                 0x00000020
 
+#define VMX_EPT_VPID_CAP_1G_PAGES              0x00020000
+#define VMX_EPT_VPID_CAP_AD_BITS               0x00200000
+
 #define EXIT_REASON_FAILED_VMENTRY     0x80000000
 #define EXIT_REASON_EXCEPTION_NMI      0
 #define EXIT_REASON_EXTERNAL_INTERRUPT 1
@@ -606,6 +609,7 @@ bool load_vmcs(struct vmx_pages *vmx);
 
 bool nested_vmx_supported(void);
 void nested_vmx_check_supported(void);
+bool ept_1g_pages_supported(void);
 
 void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
                   uint64_t nested_paddr, uint64_t paddr);
@@ -613,6 +617,8 @@ void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
                 uint64_t nested_paddr, uint64_t paddr, uint64_t size);
 void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
                        uint32_t memslot);
+void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm,
+                           uint64_t addr, uint64_t size);
 void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
                  uint32_t eptp_memslot);
 void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm *vm);
index 722df3a28791c3b7eb3fd967c9f1ea195f815796..f989ff91f022abf2f84f595f7fea48250bb8f0eb 100644 (file)
@@ -40,7 +40,7 @@ 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)
+void perf_test_guest_code(uint32_t vcpu_id)
 {
        struct perf_test_args *pta = &perf_test_args;
        struct perf_test_vcpu_args *vcpu_args = &pta->vcpu_args[vcpu_id];
@@ -108,8 +108,9 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
 {
        struct perf_test_args *pta = &perf_test_args;
        struct kvm_vm *vm;
-       uint64_t guest_num_pages;
+       uint64_t guest_num_pages, slot0_pages = DEFAULT_GUEST_PHY_PAGES;
        uint64_t backing_src_pagesz = get_backing_src_pagesz(backing_src);
+       uint64_t region_end_gfn;
        int i;
 
        pr_info("Testing guest mode: %s\n", vm_guest_mode_string(mode));
@@ -134,34 +135,54 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
                    "Guest memory cannot be evenly divided into %d slots.",
                    slots);
 
+       /*
+        * If using nested, allocate extra pages for the nested page tables and
+        * in-memory data structures.
+        */
+       if (pta->nested)
+               slot0_pages += perf_test_nested_pages(vcpus);
+
        /*
         * 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,
-                                 guest_num_pages, 0, guest_code, NULL);
+       vm = vm_create_with_vcpus(mode, vcpus, slot0_pages, guest_num_pages, 0,
+                                 perf_test_guest_code, NULL);
 
        pta->vm = vm;
 
+       /* Put the test region at the top guest physical memory. */
+       region_end_gfn = vm_get_max_gfn(vm) + 1;
+
+#ifdef __x86_64__
+       /*
+        * When running vCPUs in L2, restrict the test region to 48 bits to
+        * avoid needing 5-level page tables to identity map L2.
+        */
+       if (pta->nested)
+               region_end_gfn = min(region_end_gfn, (1UL << 48) / pta->guest_page_size);
+#endif
        /*
         * If there should be more memory in the guest test region than there
         * can be pages in the guest, it will definitely cause problems.
         */
-       TEST_ASSERT(guest_num_pages < vm_get_max_gfn(vm),
+       TEST_ASSERT(guest_num_pages < region_end_gfn,
                    "Requested more guest memory than address space allows.\n"
                    "    guest pages: %" PRIx64 " max gfn: %" PRIx64
                    " vcpus: %d wss: %" PRIx64 "]\n",
-                   guest_num_pages, vm_get_max_gfn(vm), vcpus,
+                   guest_num_pages, region_end_gfn - 1, vcpus,
                    vcpu_memory_bytes);
 
-       pta->gpa = (vm_get_max_gfn(vm) - guest_num_pages) * pta->guest_page_size;
+       pta->gpa = (region_end_gfn - guest_num_pages) * pta->guest_page_size;
        pta->gpa = align_down(pta->gpa, backing_src_pagesz);
 #ifdef __s390x__
        /* Align to 1M (segment size) */
        pta->gpa = align_down(pta->gpa, 1 << 20);
 #endif
-       pr_info("guest physical test memory offset: 0x%lx\n", pta->gpa);
+       pta->size = guest_num_pages * pta->guest_page_size;
+       pr_info("guest physical test memory: [0x%lx, 0x%lx)\n",
+               pta->gpa, pta->gpa + pta->size);
 
        /* Add extra memory slots for testing */
        for (i = 0; i < slots; i++) {
@@ -178,6 +199,11 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
 
        perf_test_setup_vcpus(vm, vcpus, vcpu_memory_bytes, partition_vcpu_memory_access);
 
+       if (pta->nested) {
+               pr_info("Configuring vCPUs to run in L2 (nested).\n");
+               perf_test_setup_nested(vm, vcpus);
+       }
+
        ucall_init(vm, NULL);
 
        /* Export the shared variables to the guest. */
@@ -198,6 +224,17 @@ void perf_test_set_wr_fract(struct kvm_vm *vm, int wr_fract)
        sync_global_to_guest(vm, perf_test_args);
 }
 
+uint64_t __weak perf_test_nested_pages(int nr_vcpus)
+{
+       return 0;
+}
+
+void __weak perf_test_setup_nested(struct kvm_vm *vm, int nr_vcpus)
+{
+       pr_info("%s() not support on this architecture, skipping.\n", __func__);
+       exit(KSFT_SKIP);
+}
+
 static void *vcpu_thread_main(void *data)
 {
        struct vcpu_thread *vcpu = data;
diff --git a/tools/testing/selftests/kvm/lib/x86_64/perf_test_util.c b/tools/testing/selftests/kvm/lib/x86_64/perf_test_util.c
new file mode 100644 (file)
index 0000000..e258524
--- /dev/null
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * x86_64-specific extensions to perf_test_util.c.
+ *
+ * Copyright (C) 2022, Google, Inc.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "perf_test_util.h"
+#include "../kvm_util_internal.h"
+#include "processor.h"
+#include "vmx.h"
+
+void perf_test_l2_guest_code(uint64_t vcpu_id)
+{
+       perf_test_guest_code(vcpu_id);
+       vmcall();
+}
+
+extern char perf_test_l2_guest_entry[];
+__asm__(
+"perf_test_l2_guest_entry:"
+"      mov (%rsp), %rdi;"
+"      call perf_test_l2_guest_code;"
+"      ud2;"
+);
+
+static void perf_test_l1_guest_code(struct vmx_pages *vmx, uint64_t vcpu_id)
+{
+#define L2_GUEST_STACK_SIZE 64
+       unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
+       unsigned long *rsp;
+
+       GUEST_ASSERT(vmx->vmcs_gpa);
+       GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+       GUEST_ASSERT(load_vmcs(vmx));
+       GUEST_ASSERT(ept_1g_pages_supported());
+
+       rsp = &l2_guest_stack[L2_GUEST_STACK_SIZE - 1];
+       *rsp = vcpu_id;
+       prepare_vmcs(vmx, perf_test_l2_guest_entry, rsp);
+
+       GUEST_ASSERT(!vmlaunch());
+       GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+       GUEST_DONE();
+}
+
+uint64_t perf_test_nested_pages(int nr_vcpus)
+{
+       /*
+        * 513 page tables is enough to identity-map 256 TiB of L2 with 1G
+        * pages and 4-level paging, plus a few pages per-vCPU for data
+        * structures such as the VMCS.
+        */
+       return 513 + 10 * nr_vcpus;
+}
+
+void perf_test_setup_ept(struct vmx_pages *vmx, struct kvm_vm *vm)
+{
+       uint64_t start, end;
+
+       prepare_eptp(vmx, vm, 0);
+
+       /*
+        * Identity map the first 4G and the test region with 1G pages so that
+        * KVM can shadow the EPT12 with the maximum huge page size supported
+        * by the backing source.
+        */
+       nested_identity_map_1g(vmx, vm, 0, 0x100000000ULL);
+
+       start = align_down(perf_test_args.gpa, PG_SIZE_1G);
+       end = align_up(perf_test_args.gpa + perf_test_args.size, PG_SIZE_1G);
+       nested_identity_map_1g(vmx, vm, start, end - start);
+}
+
+void perf_test_setup_nested(struct kvm_vm *vm, int nr_vcpus)
+{
+       struct vmx_pages *vmx, *vmx0 = NULL;
+       struct kvm_regs regs;
+       vm_vaddr_t vmx_gva;
+       int vcpu_id;
+
+       nested_vmx_check_supported();
+
+       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
+               vmx = vcpu_alloc_vmx(vm, &vmx_gva);
+
+               if (vcpu_id == 0) {
+                       perf_test_setup_ept(vmx, vm);
+                       vmx0 = vmx;
+               } else {
+                       /* Share the same EPT table across all vCPUs. */
+                       vmx->eptp = vmx0->eptp;
+                       vmx->eptp_hva = vmx0->eptp_hva;
+                       vmx->eptp_gpa = vmx0->eptp_gpa;
+               }
+
+               /*
+                * Override the vCPU to run perf_test_l1_guest_code() which will
+                * bounce it into L2 before calling perf_test_guest_code().
+                */
+               vcpu_regs_get(vm, vcpu_id, &regs);
+               regs.rip = (unsigned long) perf_test_l1_guest_code;
+               vcpu_regs_set(vm, vcpu_id, &regs);
+               vcpu_args_set(vm, vcpu_id, 2, vmx_gva, vcpu_id);
+       }
+}
index 33ea5e9955d9bddbe844a36cdbf886d6637f8a53..ead7011ee8f615cc2ea6017bd33925f4772439eb 100644 (file)
@@ -158,7 +158,7 @@ static void *virt_get_pte(struct kvm_vm *vm, uint64_t pt_pfn, uint64_t vaddr,
                          int level)
 {
        uint64_t *page_table = addr_gpa2hva(vm, pt_pfn << vm->page_shift);
-       int index = vaddr >> (vm->page_shift + level * 9) & 0x1ffu;
+       int index = (vaddr >> PG_LEVEL_SHIFT(level)) & 0x1ffu;
 
        return &page_table[index];
 }
@@ -167,14 +167,14 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,
                                       uint64_t pt_pfn,
                                       uint64_t vaddr,
                                       uint64_t paddr,
-                                      int level,
-                                      enum x86_page_size page_size)
+                                      int current_level,
+                                      int target_level)
 {
-       uint64_t *pte = virt_get_pte(vm, pt_pfn, vaddr, level);
+       uint64_t *pte = virt_get_pte(vm, pt_pfn, vaddr, current_level);
 
        if (!(*pte & PTE_PRESENT_MASK)) {
                *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK;
-               if (level == page_size)
+               if (current_level == target_level)
                        *pte |= PTE_LARGE_MASK | (paddr & PHYSICAL_PAGE_MASK);
                else
                        *pte |= vm_alloc_page_table(vm) & PHYSICAL_PAGE_MASK;
@@ -184,20 +184,19 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,
                 * a hugepage at this level, and that there isn't a hugepage at
                 * this level.
                 */
-               TEST_ASSERT(level != page_size,
+               TEST_ASSERT(current_level != target_level,
                            "Cannot create hugepage at level: %u, vaddr: 0x%lx\n",
-                           page_size, vaddr);
+                           current_level, vaddr);
                TEST_ASSERT(!(*pte & PTE_LARGE_MASK),
                            "Cannot create page table at level: %u, vaddr: 0x%lx\n",
-                           level, vaddr);
+                           current_level, vaddr);
        }
        return pte;
 }
 
-void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
-                  enum x86_page_size page_size)
+void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
 {
-       const uint64_t pg_size = 1ull << ((page_size * 9) + 12);
+       const uint64_t pg_size = PG_LEVEL_SIZE(level);
        uint64_t *pml4e, *pdpe, *pde;
        uint64_t *pte;
 
@@ -222,20 +221,20 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
         * early if a hugepage was created.
         */
        pml4e = virt_create_upper_pte(vm, vm->pgd >> vm->page_shift,
-                                     vaddr, paddr, 3, page_size);
+                                     vaddr, paddr, PG_LEVEL_512G, level);
        if (*pml4e & PTE_LARGE_MASK)
                return;
 
-       pdpe = virt_create_upper_pte(vm, PTE_GET_PFN(*pml4e), vaddr, paddr, 2, page_size);
+       pdpe = virt_create_upper_pte(vm, PTE_GET_PFN(*pml4e), vaddr, paddr, PG_LEVEL_1G, level);
        if (*pdpe & PTE_LARGE_MASK)
                return;
 
-       pde = virt_create_upper_pte(vm, PTE_GET_PFN(*pdpe), vaddr, paddr, 1, page_size);
+       pde = virt_create_upper_pte(vm, PTE_GET_PFN(*pdpe), vaddr, paddr, PG_LEVEL_2M, level);
        if (*pde & PTE_LARGE_MASK)
                return;
 
        /* Fill in page table entry. */
-       pte = virt_get_pte(vm, PTE_GET_PFN(*pde), vaddr, 0);
+       pte = virt_get_pte(vm, PTE_GET_PFN(*pde), vaddr, PG_LEVEL_4K);
        TEST_ASSERT(!(*pte & PTE_PRESENT_MASK),
                    "PTE already present for 4k page at vaddr: 0x%lx\n", vaddr);
        *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK);
@@ -243,7 +242,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 
 void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
 {
-       __virt_pg_map(vm, vaddr, paddr, X86_PAGE_SIZE_4K);
+       __virt_pg_map(vm, vaddr, paddr, PG_LEVEL_4K);
 }
 
 static uint64_t *_vm_get_page_table_entry(struct kvm_vm *vm, int vcpuid,
index d089d8b850b5c0daa879718ea18b043c64664ded..b77a01d0a27139b94845286361dc5750417a8f0c 100644 (file)
@@ -198,6 +198,16 @@ bool load_vmcs(struct vmx_pages *vmx)
        return true;
 }
 
+static bool ept_vpid_cap_supported(uint64_t mask)
+{
+       return rdmsr(MSR_IA32_VMX_EPT_VPID_CAP) & mask;
+}
+
+bool ept_1g_pages_supported(void)
+{
+       return ept_vpid_cap_supported(VMX_EPT_VPID_CAP_1G_PAGES);
+}
+
 /*
  * Initialize the control fields to the most basic settings possible.
  */
@@ -215,7 +225,7 @@ static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
                struct eptPageTablePointer eptp = {
                        .memory_type = VMX_BASIC_MEM_TYPE_WB,
                        .page_walk_length = 3, /* + 1 */
-                       .ad_enabled = !!(rdmsr(MSR_IA32_VMX_EPT_VPID_CAP) & VMX_EPT_VPID_CAP_AD_BITS),
+                       .ad_enabled = ept_vpid_cap_supported(VMX_EPT_VPID_CAP_AD_BITS),
                        .address = vmx->eptp_gpa >> PAGE_SHIFT_4K,
                };
 
@@ -392,80 +402,93 @@ void nested_vmx_check_supported(void)
        }
 }
 
-void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
-                  uint64_t nested_paddr, uint64_t paddr)
+static void nested_create_pte(struct kvm_vm *vm,
+                             struct eptPageTableEntry *pte,
+                             uint64_t nested_paddr,
+                             uint64_t paddr,
+                             int current_level,
+                             int target_level)
+{
+       if (!pte->readable) {
+               pte->writable = true;
+               pte->readable = true;
+               pte->executable = true;
+               pte->page_size = (current_level == target_level);
+               if (pte->page_size)
+                       pte->address = paddr >> vm->page_shift;
+               else
+                       pte->address = vm_alloc_page_table(vm) >> vm->page_shift;
+       } else {
+               /*
+                * Entry already present.  Assert that the caller doesn't want
+                * a hugepage at this level, and that there isn't a hugepage at
+                * this level.
+                */
+               TEST_ASSERT(current_level != target_level,
+                           "Cannot create hugepage at level: %u, nested_paddr: 0x%lx\n",
+                           current_level, nested_paddr);
+               TEST_ASSERT(!pte->page_size,
+                           "Cannot create page table at level: %u, nested_paddr: 0x%lx\n",
+                           current_level, nested_paddr);
+       }
+}
+
+
+void __nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+                    uint64_t nested_paddr, uint64_t paddr, int target_level)
 {
-       uint16_t index[4];
-       struct eptPageTableEntry *pml4e;
+       const uint64_t page_size = PG_LEVEL_SIZE(target_level);
+       struct eptPageTableEntry *pt = vmx->eptp_hva, *pte;
+       uint16_t index;
 
        TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
                    "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
 
-       TEST_ASSERT((nested_paddr % vm->page_size) == 0,
+       TEST_ASSERT((nested_paddr >> 48) == 0,
+                   "Nested physical address 0x%lx requires 5-level paging",
+                   nested_paddr);
+       TEST_ASSERT((nested_paddr % page_size) == 0,
                    "Nested physical address not on page boundary,\n"
-                   "  nested_paddr: 0x%lx vm->page_size: 0x%x",
-                   nested_paddr, vm->page_size);
+                   "  nested_paddr: 0x%lx page_size: 0x%lx",
+                   nested_paddr, page_size);
        TEST_ASSERT((nested_paddr >> vm->page_shift) <= vm->max_gfn,
                    "Physical address beyond beyond maximum supported,\n"
                    "  nested_paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
                    paddr, vm->max_gfn, vm->page_size);
-       TEST_ASSERT((paddr % vm->page_size) == 0,
+       TEST_ASSERT((paddr % page_size) == 0,
                    "Physical address not on page boundary,\n"
-                   "  paddr: 0x%lx vm->page_size: 0x%x",
-                   paddr, vm->page_size);
+                   "  paddr: 0x%lx page_size: 0x%lx",
+                   paddr, page_size);
        TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
                    "Physical address beyond beyond maximum supported,\n"
                    "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
                    paddr, vm->max_gfn, vm->page_size);
 
-       index[0] = (nested_paddr >> 12) & 0x1ffu;
-       index[1] = (nested_paddr >> 21) & 0x1ffu;
-       index[2] = (nested_paddr >> 30) & 0x1ffu;
-       index[3] = (nested_paddr >> 39) & 0x1ffu;
-
-       /* Allocate page directory pointer table if not present. */
-       pml4e = vmx->eptp_hva;
-       if (!pml4e[index[3]].readable) {
-               pml4e[index[3]].address = vm_alloc_page_table(vm) >> vm->page_shift;
-               pml4e[index[3]].writable = true;
-               pml4e[index[3]].readable = true;
-               pml4e[index[3]].executable = true;
-       }
+       for (int level = PG_LEVEL_512G; level >= PG_LEVEL_4K; level--) {
+               index = (nested_paddr >> PG_LEVEL_SHIFT(level)) & 0x1ffu;
+               pte = &pt[index];
 
-       /* Allocate page directory table if not present. */
-       struct eptPageTableEntry *pdpe;
-       pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size);
-       if (!pdpe[index[2]].readable) {
-               pdpe[index[2]].address = vm_alloc_page_table(vm) >> vm->page_shift;
-               pdpe[index[2]].writable = true;
-               pdpe[index[2]].readable = true;
-               pdpe[index[2]].executable = true;
-       }
+               nested_create_pte(vm, pte, nested_paddr, paddr, level, target_level);
 
-       /* Allocate page table if not present. */
-       struct eptPageTableEntry *pde;
-       pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size);
-       if (!pde[index[1]].readable) {
-               pde[index[1]].address = vm_alloc_page_table(vm) >> vm->page_shift;
-               pde[index[1]].writable = true;
-               pde[index[1]].readable = true;
-               pde[index[1]].executable = true;
-       }
+               if (pte->page_size)
+                       break;
 
-       /* Fill in page table entry. */
-       struct eptPageTableEntry *pte;
-       pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size);
-       pte[index[0]].address = paddr >> vm->page_shift;
-       pte[index[0]].writable = true;
-       pte[index[0]].readable = true;
-       pte[index[0]].executable = true;
+               pt = addr_gpa2hva(vm, pte->address * vm->page_size);
+       }
 
        /*
         * For now mark these as accessed and dirty because the only
         * testcase we have needs that.  Can be reconsidered later.
         */
-       pte[index[0]].accessed = true;
-       pte[index[0]].dirty = true;
+       pte->accessed = true;
+       pte->dirty = true;
+
+}
+
+void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+                  uint64_t nested_paddr, uint64_t paddr)
+{
+       __nested_pg_map(vmx, vm, nested_paddr, paddr, PG_LEVEL_4K);
 }
 
 /*
@@ -476,7 +499,7 @@ void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
  *   nested_paddr - Nested guest physical address to map
  *   paddr - VM Physical Address
  *   size - The size of the range to map
- *   eptp_memslot - Memory region slot for new virtual translation tables
+ *   level - The level at which to map the range
  *
  * Output Args: None
  *
@@ -485,22 +508,29 @@ void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
  * Within the VM given by vm, creates a nested guest translation for the
  * page range starting at nested_paddr to the page range starting at paddr.
  */
-void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
-               uint64_t nested_paddr, uint64_t paddr, uint64_t size)
+void __nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+                 uint64_t nested_paddr, uint64_t paddr, uint64_t size,
+                 int level)
 {
-       size_t page_size = vm->page_size;
+       size_t page_size = PG_LEVEL_SIZE(level);
        size_t npages = size / page_size;
 
        TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow");
        TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
 
        while (npages--) {
-               nested_pg_map(vmx, vm, nested_paddr, paddr);
+               __nested_pg_map(vmx, vm, nested_paddr, paddr, level);
                nested_paddr += page_size;
                paddr += page_size;
        }
 }
 
+void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+               uint64_t nested_paddr, uint64_t paddr, uint64_t size)
+{
+       __nested_map(vmx, vm, nested_paddr, paddr, size, PG_LEVEL_4K);
+}
+
 /* Prepare an identity extended page table that maps all the
  * physical pages in VM.
  */
@@ -525,6 +555,13 @@ void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
        }
 }
 
+/* Identity map a region with 1GiB Pages. */
+void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm,
+                           uint64_t addr, uint64_t size)
+{
+       __nested_map(vmx, vm, addr, addr, size, PG_LEVEL_1G);
+}
+
 void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
                  uint32_t eptp_memslot)
 {
index 3875c4b23a04f37fd67f88c8774e6aa91caf09a2..15f046e19cb2c21a72cbaeba1ed26382fb690aea 100644 (file)
@@ -244,7 +244,7 @@ int main(int argc, char *argv[])
 #ifdef __x86_64__
                /* Identity map memory in the guest using 1gb pages. */
                for (i = 0; i < slot_size; i += size_1gb)
-                       __virt_pg_map(vm, gpa + i, gpa + i, X86_PAGE_SIZE_1G);
+                       __virt_pg_map(vm, gpa + i, gpa + i, PG_LEVEL_1G);
 #else
                for (i = 0; i < slot_size; i += vm_get_page_size(vm))
                        virt_pg_map(vm, gpa + i, gpa + i);
index e0b2bb1339b162cc1b6bd20deef8d158c44c109c..3330fb183c6800e346a4278555bc764f40292939 100644 (file)
@@ -44,7 +44,7 @@ static inline void nop_loop(void)
 {
        int i;
 
-       for (i = 0; i < 1000000; i++)
+       for (i = 0; i < 100000000; i++)
                asm volatile("nop");
 }
 
@@ -56,12 +56,14 @@ static inline void check_tsc_msr_rdtsc(void)
        tsc_freq = rdmsr(HV_X64_MSR_TSC_FREQUENCY);
        GUEST_ASSERT(tsc_freq > 0);
 
-       /* First, check MSR-based clocksource */
+       /* For increased accuracy, take mean rdtsc() before and afrer rdmsr() */
        r1 = rdtsc();
        t1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
+       r1 = (r1 + rdtsc()) / 2;
        nop_loop();
        r2 = rdtsc();
        t2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
+       r2 = (r2 + rdtsc()) / 2;
 
        GUEST_ASSERT(r2 > r1 && t2 > t1);
 
@@ -181,12 +183,14 @@ static void host_check_tsc_msr_rdtsc(struct kvm_vm *vm)
        tsc_freq = vcpu_get_msr(vm, VCPU_ID, HV_X64_MSR_TSC_FREQUENCY);
        TEST_ASSERT(tsc_freq > 0, "TSC frequency must be nonzero");
 
-       /* First, check MSR-based clocksource */
+       /* For increased accuracy, take mean rdtsc() before and afrer ioctl */
        r1 = rdtsc();
        t1 = vcpu_get_msr(vm, VCPU_ID, HV_X64_MSR_TIME_REF_COUNT);
+       r1 = (r1 + rdtsc()) / 2;
        nop_loop();
        r2 = rdtsc();
        t2 = vcpu_get_msr(vm, VCPU_ID, HV_X64_MSR_TIME_REF_COUNT);
+       r2 = (r2 + rdtsc()) / 2;
 
        TEST_ASSERT(t2 > t1, "Time reference MSR is not monotonic (%ld <= %ld)", t1, t2);
 
index da2325fcad87bf52b65da4652f7c72e536f524a7..bdecd532f9356fa761974d259664c24fed271ef1 100644 (file)
@@ -35,7 +35,7 @@ static void mmu_role_test(u32 *cpuid_reg, u32 evil_cpuid_val)
        run = vcpu_state(vm, VCPU_ID);
 
        /* Map 1gb page without a backing memlot. */
-       __virt_pg_map(vm, MMIO_GPA, MMIO_GPA, X86_PAGE_SIZE_1G);
+       __virt_pg_map(vm, MMIO_GPA, MMIO_GPA, PG_LEVEL_1G);
 
        r = _vcpu_run(vm, VCPU_ID);
 
index b984f8c8d523eb5ef8261c0a428ea098923c098d..a29f796189347e67b4ad20a7fd65e63f5bbfa8a8 100644 (file)
@@ -37,4 +37,3 @@ gro
 ioam6_parser
 toeplitz
 cmsg_sender
-bind_bhash_test
index 464df13831f24cd36fc88fcfd9fbcde1c24732eb..7ea54af55490956895f8583b4afb9576ad0f1048 100644 (file)
@@ -59,7 +59,6 @@ TEST_GEN_FILES += toeplitz
 TEST_GEN_FILES += cmsg_sender
 TEST_GEN_FILES += stress_reuseport_listen
 TEST_PROGS += test_vxlan_vnifiltering.sh
-TEST_GEN_FILES += bind_bhash_test
 
 TEST_FILES := settings
 
@@ -70,5 +69,4 @@ include bpf/Makefile
 
 $(OUTPUT)/reuseport_bpf_numa: LDLIBS += -lnuma
 $(OUTPUT)/tcp_mmap: LDLIBS += -lpthread
-$(OUTPUT)/bind_bhash_test: LDLIBS += -lpthread
 $(OUTPUT)/tcp_inq: LDLIBS += -lpthread
diff --git a/tools/testing/selftests/net/bind_bhash_test.c b/tools/testing/selftests/net/bind_bhash_test.c
deleted file mode 100644 (file)
index 252e737..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This times how long it takes to bind to a port when the port already
- * has multiple sockets in its bhash table.
- *
- * In the setup(), we populate the port's bhash table with
- * MAX_THREADS * MAX_CONNECTIONS number of entries.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <pthread.h>
-
-#define MAX_THREADS 600
-#define MAX_CONNECTIONS 40
-
-static const char *bind_addr = "::1";
-static const char *port;
-
-static int fd_array[MAX_THREADS][MAX_CONNECTIONS];
-
-static int bind_socket(int opt, const char *addr)
-{
-       struct addrinfo *res, hint = {};
-       int sock_fd, reuse = 1, err;
-
-       sock_fd = socket(AF_INET6, SOCK_STREAM, 0);
-       if (sock_fd < 0) {
-               perror("socket fd err");
-               return -1;
-       }
-
-       hint.ai_family = AF_INET6;
-       hint.ai_socktype = SOCK_STREAM;
-
-       err = getaddrinfo(addr, port, &hint, &res);
-       if (err) {
-               perror("getaddrinfo failed");
-               return -1;
-       }
-
-       if (opt) {
-               err = setsockopt(sock_fd, SOL_SOCKET, opt, &reuse, sizeof(reuse));
-               if (err) {
-                       perror("setsockopt failed");
-                       return -1;
-               }
-       }
-
-       err = bind(sock_fd, res->ai_addr, res->ai_addrlen);
-       if (err) {
-               perror("failed to bind to port");
-               return -1;
-       }
-
-       return sock_fd;
-}
-
-static void *setup(void *arg)
-{
-       int sock_fd, i;
-       int *array = (int *)arg;
-
-       for (i = 0; i < MAX_CONNECTIONS; i++) {
-               sock_fd = bind_socket(SO_REUSEADDR | SO_REUSEPORT, bind_addr);
-               if (sock_fd < 0)
-                       return NULL;
-               array[i] = sock_fd;
-       }
-
-       return NULL;
-}
-
-int main(int argc, const char *argv[])
-{
-       int listener_fd, sock_fd, i, j;
-       pthread_t tid[MAX_THREADS];
-       clock_t begin, end;
-
-       if (argc != 2) {
-               printf("Usage: listener <port>\n");
-               return -1;
-       }
-
-       port = argv[1];
-
-       listener_fd = bind_socket(SO_REUSEADDR | SO_REUSEPORT, bind_addr);
-       if (listen(listener_fd, 100) < 0) {
-               perror("listen failed");
-               return -1;
-       }
-
-       /* Set up threads to populate the bhash table entry for the port */
-       for (i = 0; i < MAX_THREADS; i++)
-               pthread_create(&tid[i], NULL, setup, fd_array[i]);
-
-       for (i = 0; i < MAX_THREADS; i++)
-               pthread_join(tid[i], NULL);
-
-       begin = clock();
-
-       /* Bind to the same port on a different address */
-       sock_fd  = bind_socket(0, "2001:0db8:0:f101::1");
-
-       end = clock();
-
-       printf("time spent = %f\n", (double)(end - begin) / CLOCKS_PER_SEC);
-
-       /* clean up */
-       close(sock_fd);
-       close(listener_fd);
-       for (i = 0; i < MAX_THREADS; i++) {
-               for (j = 0; i < MAX_THREADS; i++)
-                       close(fd_array[i][j]);
-       }
-
-       return 0;
-}
index f91bf14bbee7be927e92cff841b39cbcba278903..8a69c91fcca07eb69322b17450f9079cfa4d336d 100644 (file)
@@ -2,6 +2,7 @@
 
 CLANG ?= clang
 CCINCLUDE += -I../../bpf
+CCINCLUDE += -I../../../lib
 CCINCLUDE += -I../../../../../usr/include/
 
 TEST_CUSTOM_PROGS = $(OUTPUT)/bpf/nat6to4.o
@@ -10,5 +11,4 @@ all: $(TEST_CUSTOM_PROGS)
 $(OUTPUT)/%.o: %.c
        $(CLANG) -O2 -target bpf -c $< $(CCINCLUDE) -o $@
 
-clean:
-       rm -f $(TEST_CUSTOM_PROGS)
+EXTRA_CLEAN := $(TEST_CUSTOM_PROGS)
index eb8543b9a5c4025e09ea33f0bd90040fb7f6f02f..924ecb3f1f737ded0e608478c27a6737090f5c26 100755 (executable)
@@ -374,6 +374,45 @@ EOF
        return $lret
 }
 
+test_local_dnat_portonly()
+{
+       local family=$1
+       local daddr=$2
+       local lret=0
+       local sr_s
+       local sr_r
+
+ip netns exec "$ns0" nft -f /dev/stdin <<EOF
+table $family nat {
+       chain output {
+               type nat hook output priority 0; policy accept;
+               meta l4proto tcp dnat to :2000
+
+       }
+}
+EOF
+       if [ $? -ne 0 ]; then
+               if [ $family = "inet" ];then
+                       echo "SKIP: inet port test"
+                       test_inet_nat=false
+                       return
+               fi
+               echo "SKIP: Could not add $family dnat hook"
+               return
+       fi
+
+       echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 &
+       sc_s=$!
+
+       result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT)
+
+       if [ "$result" = "SERVER-inet" ];then
+               echo "PASS: inet port rewrite without l3 address"
+       else
+               echo "ERROR: inet port rewrite"
+               ret=1
+       fi
+}
 
 test_masquerade6()
 {
@@ -1148,6 +1187,10 @@ fi
 reset_counters
 test_local_dnat ip
 test_local_dnat6 ip6
+
+reset_counters
+test_local_dnat_portonly inet 10.0.1.99
+
 reset_counters
 $test_inet_nat && test_local_dnat inet
 $test_inet_nat && test_local_dnat6 inet
index bca07b93eeb0769dc993de5b0a980c40fdd77385..7d1b80988d8aff56b0c0d1970f245bf0eabcd193 100644 (file)
@@ -64,8 +64,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
 else
-QEMU_MACHINE := -cpu cortex-a53 -machine virt
-CFLAGS += -march=armv8-a -mtune=cortex-a53
+QEMU_MACHINE := -cpu max -machine virt
+CFLAGS += -march=armv8-a
 endif
 else ifeq ($(ARCH),aarch64_be)
 CHOST := aarch64_be-linux-musl
@@ -76,8 +76,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
 else
-QEMU_MACHINE := -cpu cortex-a53 -machine virt
-CFLAGS += -march=armv8-a -mtune=cortex-a53
+QEMU_MACHINE := -cpu max -machine virt
+CFLAGS += -march=armv8-a
 endif
 else ifeq ($(ARCH),arm)
 CHOST := arm-linux-musleabi
@@ -88,8 +88,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
 else
-QEMU_MACHINE := -cpu cortex-a15 -machine virt
-CFLAGS += -march=armv7-a -mtune=cortex-a15 -mabi=aapcs-linux
+QEMU_MACHINE := -cpu max -machine virt
+CFLAGS += -march=armv7-a -mabi=aapcs-linux
 endif
 else ifeq ($(ARCH),armeb)
 CHOST := armeb-linux-musleabi
@@ -100,8 +100,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
 else
-QEMU_MACHINE := -cpu cortex-a15 -machine virt
-CFLAGS += -march=armv7-a -mabi=aapcs-linux # We don't pass -mtune=cortex-a15 due to a compiler bug on big endian.
+QEMU_MACHINE := -cpu max -machine virt
+CFLAGS += -march=armv7-a -mabi=aapcs-linux
 LDFLAGS += -Wl,--be8
 endif
 else ifeq ($(ARCH),x86_64)
@@ -112,8 +112,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host -machine q35,accel=kvm
 else
-QEMU_MACHINE := -cpu Skylake-Server -machine q35
-CFLAGS += -march=skylake-avx512
+QEMU_MACHINE := -cpu max -machine q35
 endif
 else ifeq ($(ARCH),i686)
 CHOST := i686-linux-musl
@@ -123,8 +122,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage
 ifeq ($(subst x86_64,i686,$(HOST_ARCH)),$(ARCH))
 QEMU_MACHINE := -cpu host -machine q35,accel=kvm
 else
-QEMU_MACHINE := -cpu coreduo -machine q35
-CFLAGS += -march=prescott
+QEMU_MACHINE := -cpu max -machine q35
 endif
 else ifeq ($(ARCH),mips64)
 CHOST := mips64-linux-musl
@@ -182,7 +180,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host,accel=kvm -machine pseries
 else
-QEMU_MACHINE := -machine pseries
+QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng
 endif
 else ifeq ($(ARCH),powerpc64le)
 CHOST := powerpc64le-linux-musl
@@ -192,7 +190,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host,accel=kvm -machine pseries
 else
-QEMU_MACHINE := -machine pseries
+QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng
 endif
 else ifeq ($(ARCH),powerpc)
 CHOST := powerpc-linux-musl
@@ -247,7 +245,7 @@ QEMU_VPORT_RESULT := virtio-serial-ccw
 ifeq ($(HOST_ARCH),$(ARCH))
 QEMU_MACHINE := -cpu host,accel=kvm -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
 else
-QEMU_MACHINE := -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
+QEMU_MACHINE := -cpu max -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
 endif
 else
 $(error I only build: x86_64, i686, arm, armeb, aarch64, aarch64_be, mips, mipsel, mips64, mips64el, powerpc64, powerpc64le, powerpc, m68k, riscv64, riscv32, s390x)
index 2a0f48fac925ac139a3dcac93e24dfcd5c83a735..c9e128436546f8552794352aec43b5662004bc2a 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/utsname.h>
 #include <sys/sendfile.h>
 #include <sys/sysmacros.h>
+#include <sys/random.h>
 #include <linux/random.h>
 #include <linux/version.h>
 
@@ -58,6 +59,8 @@ static void seed_rng(void)
 {
        int bits = 256, fd;
 
+       if (!getrandom(NULL, 0, GRND_NONBLOCK))
+               return;
        pretty_message("[+] Fake seeding RNG...");
        fd = open("/dev/random", O_WRONLY);
        if (fd < 0)
index a9b5a520a1d22e7de62729bf27f746993049d595..bad88f4b0a0337671299b785bc9409a3ff56b75d 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_TTY=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_SCRIPT=y
 CONFIG_VDSO=y
+CONFIG_STRICT_KERNEL_RWX=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_HYPERVISOR_GUEST=y
 CONFIG_PARAVIRT=y
@@ -65,6 +66,8 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_RANDOM_TRUST_CPU=y
+CONFIG_RANDOM_TRUST_BOOTLOADER=y
 CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_PRINTK_TIME=y
index 64ec2222a1968eb237e45270dd0494632862a637..a49df8988cd6a46660c222f19ae2fb654a873e65 100644 (file)
@@ -3328,9 +3328,11 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
 
        vcpu->stat.generic.blocking = 1;
 
+       preempt_disable();
        kvm_arch_vcpu_blocking(vcpu);
-
        prepare_to_rcuwait(wait);
+       preempt_enable();
+
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);
 
@@ -3340,9 +3342,11 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
                waited = true;
                schedule();
        }
-       finish_rcuwait(wait);
 
+       preempt_disable();
+       finish_rcuwait(wait);
        kvm_arch_vcpu_unblocking(vcpu);
+       preempt_enable();
 
        vcpu->stat.generic.blocking = 0;
 
@@ -4300,8 +4304,11 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
                kvm_put_kvm_no_destroy(kvm);
                mutex_lock(&kvm->lock);
                list_del(&dev->vm_node);
+               if (ops->release)
+                       ops->release(dev);
                mutex_unlock(&kvm->lock);
-               ops->destroy(dev);
+               if (ops->destroy)
+                       ops->destroy(dev);
                return ret;
        }