]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'sched/urgent' into sched/core, to pick up fixes
authorIngo Molnar <mingo@kernel.org>
Tue, 2 Oct 2018 07:43:39 +0000 (09:43 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 2 Oct 2018 07:43:39 +0000 (09:43 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
740 files changed:
Documentation/ABI/stable/sysfs-devices-system-xen_memory
Documentation/admin-guide/kernel-parameters.txt
Documentation/device-mapper/dm-raid.txt
Documentation/devicetree/bindings/input/gpio-keys.txt
Documentation/devicetree/bindings/net/macb.txt
Documentation/filesystems/vfs.txt
Documentation/media/uapi/dvb/video_function_calls.rst
Documentation/process/code-of-conduct.rst [new file with mode: 0644]
Documentation/process/code-of-conflict.rst [deleted file]
Documentation/process/index.rst
Documentation/virtual/kvm/api.txt
Documentation/x86/earlyprintk.txt
MAINTAINERS
Makefile
arch/arm/boot/dts/sama5d3_emac.dtsi
arch/arm64/include/asm/jump_label.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/crash_core.c [new file with mode: 0644]
arch/arm64/kernel/machine_kexec.c
arch/hexagon/include/asm/bitops.h
arch/hexagon/kernel/dma.c
arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
arch/mips/lantiq/xway/dma.c
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/iommu.h
arch/powerpc/include/asm/mmu_context.h
arch/powerpc/include/asm/setup.h
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/tm.S
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_64_vio_hv.c
arch/powerpc/lib/checksum_64.S
arch/powerpc/lib/code-patching.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_iommu.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pkeys.c
arch/powerpc/platforms/powernv/pci-ioda-tce.c
arch/riscv/include/asm/asm-prototypes.h [new file with mode: 0644]
arch/riscv/kernel/setup.c
arch/s390/crypto/paes_s390.c
arch/s390/kvm/kvm-s390.c
arch/s390/mm/gmap.c
arch/x86/boot/compressed/mem_encrypt.S
arch/x86/crypto/aegis128-aesni-glue.c
arch/x86/crypto/aegis128l-aesni-glue.c
arch/x86/crypto/aegis256-aesni-glue.c
arch/x86/crypto/morus1280-sse2-glue.c
arch/x86/crypto/morus640-sse2-glue.c
arch/x86/events/intel/lbr.c
arch/x86/hyperv/hv_apic.c
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/hyperv-tlfs.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/mem_encrypt.h
arch/x86/include/asm/pgtable-2level.h
arch/x86/include/asm/pgtable_64.h
arch/x86/include/uapi/asm/kvm.h
arch/x86/kernel/apm_32.c
arch/x86/kernel/cpu/intel_rdt.h
arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
arch/x86/kernel/eisa.c
arch/x86/kernel/head64.c
arch/x86/kernel/head_64.S
arch/x86/kernel/kvmclock.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/topology.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/init.c
arch/x86/mm/mem_encrypt.c
arch/x86/mm/pgtable.c
arch/x86/platform/efi/efi_32.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/pmu.c
arch/xtensa/Kconfig
arch/xtensa/Makefile
arch/xtensa/platforms/iss/setup.c
block/bio.c
block/blk-cgroup.c
block/blk-core.c
block/blk-mq-tag.c
block/blk-mq.c
block/elevator.c
block/genhd.c
block/partition-generic.c
drivers/android/binder_alloc.c
drivers/ata/libata-core.c
drivers/base/firmware_loader/main.c
drivers/block/floppy.c
drivers/block/null_blk.h
drivers/block/null_blk_main.c
drivers/block/null_blk_zoned.c
drivers/block/xen-blkfront.c
drivers/bluetooth/hci_ldisc.c
drivers/char/ipmi/ipmi_bt_sm.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_ssif.c
drivers/char/ipmi/kcs_bmc.c
drivers/clk/x86/clk-pmc-atom.c
drivers/clocksource/timer-atmel-pit.c
drivers/clocksource/timer-fttmr010.c
drivers/clocksource/timer-ti-32k.c
drivers/cpufreq/qcom-cpufreq-kryo.c
drivers/crypto/ccp/psp-dev.c
drivers/dax/device.c
drivers/dma/mic_x100_dma.c
drivers/firmware/efi/Kconfig
drivers/fpga/dfl-fme-pr.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
drivers/gpu/drm/amd/include/kgd_kfd_interface.h
drivers/gpu/drm/arm/malidp_drv.c
drivers/gpu/drm/arm/malidp_hw.c
drivers/gpu/drm/arm/malidp_hw.h
drivers/gpu/drm/arm/malidp_mw.c
drivers/gpu/drm/arm/malidp_regs.h
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_debugfs.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_panel.c
drivers/gpu/drm/drm_syncobj.c
drivers/gpu/drm/etnaviv/etnaviv_drv.c
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/kvmgt.c
drivers/gpu/drm/i915/gvt/mmio.c
drivers/gpu/drm/i915/gvt/opregion.c
drivers/gpu/drm/i915/gvt/vgpu.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_display.h
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_fbcon.h
drivers/gpu/drm/nouveau/nouveau_vga.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
drivers/gpu/drm/pl111/pl111_vexpress.c
drivers/gpu/drm/sun4i/sun4i_drv.c
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
drivers/gpu/drm/sun4i/sun8i_mixer.c
drivers/gpu/drm/sun4i/sun8i_tcon_top.c
drivers/gpu/drm/udl/udl_fb.c
drivers/gpu/drm/vc4/vc4_plane.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/gpu/vga/vga_switcheroo.c
drivers/hid/hid-apple.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-saitek.c
drivers/hid/hid-sensor-hub.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/intel-ish-hid/ipc/hw-ish.h
drivers/hid/intel-ish-hid/ipc/pci-ish.c
drivers/hv/vmbus_drv.c
drivers/hwmon/nct6775.c
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/pci.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/temperature/maxim_thermocouple.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/rdma_core.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/uverbs_uapi.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/pcie.c
drivers/infiniband/hw/hfi1/pio.c
drivers/infiniband/hw/hfi1/pio.h
drivers/infiniband/hw/hfi1/user_sdma.c
drivers/infiniband/hw/hfi1/verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/devx.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/input/keyboard/atakbd.c
drivers/input/misc/uinput.c
drivers/input/mouse/elantech.c
drivers/input/touchscreen/egalax_ts.c
drivers/iommu/amd_iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-pasid.h
drivers/iommu/rockchip-iommu.c
drivers/md/bcache/bcache.h
drivers/md/bcache/journal.c
drivers/md/bcache/super.c
drivers/md/dm-crypt.c
drivers/md/dm-integrity.c
drivers/md/dm-raid.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin.c
drivers/md/dm-verity-target.c
drivers/media/i2c/mt9v111.c
drivers/media/platform/Kconfig
drivers/media/platform/qcom/camss/camss-csid.c
drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
drivers/media/platform/qcom/camss/camss-csiphy.c
drivers/media/platform/qcom/camss/camss-ispif.c
drivers/media/platform/qcom/camss/camss-vfe-4-1.c
drivers/media/platform/qcom/camss/camss-vfe-4-7.c
drivers/media/platform/qcom/camss/camss.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/mfd/omap-usb-host.c
drivers/misc/hmc6352.c
drivers/misc/ibmvmc.c
drivers/misc/mei/bus.c
drivers/misc/mei/client.c
drivers/misc/mei/hbm.c
drivers/mmc/host/meson-mx-sdio.c
drivers/mmc/host/omap_hsmmc.c
drivers/mtd/devices/m25p80.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/raw/denali.c
drivers/mtd/nand/raw/marvell_nand.c
drivers/net/appletalk/ipddp.c
drivers/net/bonding/bond_main.c
drivers/net/dsa/mv88e6xxx/global1.h
drivers/net/dsa/mv88e6xxx/global1_atu.c
drivers/net/ethernet/amazon/ena/ena_com.c
drivers/net/ethernet/amazon/ena/ena_eth_com.c
drivers/net/ethernet/amazon/ena/ena_eth_com.h
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/amazon/ena/ena_netdev.h
drivers/net/ethernet/apple/bmac.c
drivers/net/ethernet/apple/mace.c
drivers/net/ethernet/apple/macmace.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
drivers/net/ethernet/cirrus/ep93xx_eth.c
drivers/net/ethernet/cirrus/mac89x0.c
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/hp/hp100.c
drivers/net/ethernet/i825xx/ether1.c
drivers/net/ethernet/i825xx/lib82596.c
drivers/net/ethernet/i825xx/sun3_82586.c
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/dev.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c
drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.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/health.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/transobj.c
drivers/net/ethernet/mellanox/mlx5/core/wq.c
drivers/net/ethernet/mellanox/mlx5/core/wq.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/mscc/ocelot_board.c
drivers/net/ethernet/netronome/nfp/flower/action.c
drivers/net/ethernet/netronome/nfp/flower/main.h
drivers/net/ethernet/netronome/nfp/flower/match.c
drivers/net/ethernet/netronome/nfp/flower/offload.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/qed/qed_dcbx.c
drivers/net/ethernet/qlogic/qed/qed_dcbx.h
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_hsi.h
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
drivers/net/ethernet/qualcomm/qca_7k.c
drivers/net/ethernet/qualcomm/qca_spi.c
drivers/net/ethernet/qualcomm/qca_spi.h
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/renesas/Kconfig
drivers/net/ethernet/renesas/Makefile
drivers/net/ethernet/renesas/ravb.h
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/ravb_ptp.c
drivers/net/ethernet/seeq/ether3.c
drivers/net/ethernet/seeq/sgiseeq.c
drivers/net/ethernet/sgi/ioc3-eth.c
drivers/net/ethernet/sgi/meth.c
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/ti/Kconfig
drivers/net/ethernet/wiznet/w5100.c
drivers/net/ethernet/wiznet/w5300.c
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/phy/sfp-bus.c
drivers/net/ppp/pppoe.c
drivers/net/tun.c
drivers/net/usb/qmi_wwan.c
drivers/net/veth.c
drivers/net/xen-netfront.c
drivers/nvme/host/multipath.c
drivers/nvme/target/admin-cmd.c
drivers/nvme/target/rdma.c
drivers/of/base.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/controller/pci-hyperv.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/switch/switchtec.c
drivers/pinctrl/cirrus/pinctrl-madera-core.c
drivers/pinctrl/intel/pinctrl-cannonlake.c
drivers/pinctrl/intel/pinctrl-intel.c
drivers/pinctrl/pinctrl-amd.c
drivers/pinctrl/pinctrl-ingenic.c
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/platform/x86/alienware-wmi.c
drivers/platform/x86/dell-smbios-wmi.c
drivers/regulator/bd71837-regulator.c
drivers/regulator/core.c
drivers/regulator/of_regulator.c
drivers/s390/crypto/ap_bus.c
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/qedi/qedi.h
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qla2xxx/qla_target.h
drivers/scsi/sd.c
drivers/scsi/ufs/ufshcd.c
drivers/soundwire/stream.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-gpio.c
drivers/spi/spi-rspi.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-tegra20-slink.c
drivers/spi/spi.c
drivers/staging/erofs/Kconfig
drivers/staging/erofs/super.c
drivers/staging/fbtft/TODO
drivers/staging/gasket/TODO
drivers/staging/media/mt9t031/Kconfig
drivers/staging/vboxvideo/vbox_drv.c
drivers/staging/vboxvideo/vbox_mode.c
drivers/staging/wilc1000/Makefile
drivers/staging/wilc1000/linux_wlan.c
drivers/staging/wilc1000/wilc_debugfs.c
drivers/staging/wilc1000/wilc_wlan.c
drivers/staging/wilc1000/wilc_wlan_if.h
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_auth.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/iscsi/iscsi_target_login.h
drivers/tty/hvc/hvc_console.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/mvebu-uart.c
drivers/tty/tty_io.c
drivers/tty/vt/vt_ioctl.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.h
drivers/usb/common/common.c
drivers/usb/common/roles.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/message.c
drivers/usb/core/of.c
drivers/usb/core/quirks.c
drivers/usb/core/usb.c
drivers/usb/dwc2/platform.c
drivers/usb/dwc3/dwc3-of-simple.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/udc/fotg210-udc.c
drivers/usb/gadget/udc/net2280.c
drivers/usb/gadget/udc/renesas_usb3.c
drivers/usb/host/u132-hcd.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci.c
drivers/usb/misc/uss720.c
drivers/usb/misc/yurex.c
drivers/usb/mtu3/mtu3_core.c
drivers/usb/mtu3/mtu3_hw_regs.h
drivers/usb/musb/musb_dsps.c
drivers/usb/serial/io_ti.h
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/uas.c
drivers/usb/storage/unusual_devs.h
drivers/usb/typec/bus.c
drivers/usb/typec/class.c
drivers/usb/typec/mux.c
drivers/xen/Kconfig
drivers/xen/cpu_hotplug.c
drivers/xen/events/events_base.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/manage.c
drivers/xen/mem-reservation.c
drivers/xen/xen-balloon.c
fs/cifs/Kconfig
fs/cifs/cifssmb.c
fs/cifs/misc.c
fs/cifs/readdir.c
fs/cifs/smb2pdu.c
fs/dax.c
fs/ext2/inode.c
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/mmp.c
fs/ext4/namei.c
fs/ext4/resize.c
fs/ext4/super.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4trace.h
fs/nfs/pnfs.c
fs/ocfs2/buffer_head_io.c
fs/overlayfs/file.c
fs/overlayfs/inode.c
fs/overlayfs/super.c
fs/proc/kcore.c
fs/pstore/ram_core.c
fs/ubifs/super.c
fs/ubifs/xattr.c
include/asm-generic/io.h
include/drm/drm_drv.h
include/drm/drm_panel.h
include/linux/blkdev.h
include/linux/compiler-gcc.h
include/linux/compiler_types.h
include/linux/fs.h
include/linux/genhd.h
include/linux/hid.h
include/linux/kvm_host.h
include/linux/mfd/da9063/pdata.h
include/linux/mfd/rohm-bd718x7.h
include/linux/mlx5/driver.h
include/linux/mm_types.h
include/linux/mm_types_task.h
include/linux/mod_devicetable.h
include/linux/netpoll.h
include/linux/pci.h
include/linux/regulator/machine.h
include/linux/spi/spi-mem.h
include/linux/stmmac.h
include/linux/uio.h
include/linux/vga_switcheroo.h
include/linux/vm_event_item.h
include/linux/vmacache.h
include/net/netfilter/nf_conntrack_timeout.h
include/net/nfc/hci.h
include/net/tls.h
include/sound/hdaudio.h
include/sound/soc-dapm.h
include/uapi/linux/keyctl.h
include/uapi/linux/kvm.h
include/uapi/linux/perf_event.h
include/uapi/sound/skl-tplg-interface.h
include/xen/mem-reservation.h
kernel/bpf/btf.c
kernel/bpf/sockmap.c
kernel/bpf/verifier.c
kernel/dma/Kconfig
kernel/events/core.c
kernel/events/hw_breakpoint.c
kernel/jump_label.c
kernel/locking/lockdep.c
kernel/locking/mutex.c
kernel/locking/test-ww_mutex.c
kernel/pid.c
kernel/printk/printk.c
kernel/sched/core.c
kernel/sched/deadline.c
kernel/sched/fair.c
kernel/sched/sched.h
kernel/sys.c
kernel/trace/ring_buffer.c
mm/Kconfig
mm/Makefile
mm/debug.c
mm/fadvise.c
mm/migrate.c
mm/readahead.c
mm/shmem.c
mm/vmacache.c
mm/vmscan.c
net/batman-adv/bat_v_elp.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/gateway_client.c
net/batman-adv/main.h
net/batman-adv/network-coding.c
net/batman-adv/soft-interface.c
net/batman-adv/sysfs.c
net/batman-adv/translation-table.c
net/batman-adv/tvlv.c
net/bluetooth/smp.c
net/core/devlink.c
net/core/ethtool.c
net/core/filter.c
net/core/neighbour.c
net/core/netpoll.c
net/core/rtnetlink.c
net/core/skbuff.c
net/ipv4/af_inet.c
net/ipv4/ip_fragment.c
net/ipv4/ip_gre.c
net/ipv4/ip_tunnel.c
net/ipv4/netfilter/Kconfig
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/ip6_offload.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/route.c
net/ipv6/udp.c
net/iucv/af_iucv.c
net/iucv/iucv.c
net/mpls/af_mpls.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_generic.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_icmp.c
net/netfilter/nf_conntrack_proto_icmpv6.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nfnetlink_queue.c
net/netfilter/nft_ct.c
net/netfilter/xt_CHECKSUM.c
net/netfilter/xt_cluster.c
net/netfilter/xt_hashlimit.c
net/netlabel/netlabel_unlabeled.c
net/nfc/hci/core.c
net/rds/bind.c
net/rds/ib.h
net/sched/act_sample.c
net/sched/act_tunnel_key.c
net/sched/cls_api.c
net/sctp/transport.c
net/smc/af_smc.c
net/smc/smc_clc.c
net/smc/smc_close.c
net/smc/smc_pnet.c
net/socket.c
net/tipc/netlink_compat.c
net/tipc/socket.c
net/tipc/socket.h
net/tls/tls_device.c
net/tls/tls_device_fallback.c
net/tls/tls_main.c
net/tls/tls_sw.c
scripts/subarch.include [new file with mode: 0644]
security/Kconfig
security/keys/dh.c
sound/firewire/bebob/bebob.c
sound/firewire/bebob/bebob_maudio.c
sound/firewire/digi00x/digi00x.c
sound/firewire/fireface/ff-protocol-ff400.c
sound/firewire/fireworks/fireworks.c
sound/firewire/oxfw/oxfw.c
sound/firewire/tascam/tascam.c
sound/hda/hdac_controller.c
sound/pci/emu10k1/emufx.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.h
sound/soc/amd/acp-pcm-dma.c
sound/soc/codecs/cs4265.c
sound/soc/codecs/max98373.c
sound/soc/codecs/rt5514.c
sound/soc/codecs/rt5682.c
sound/soc/codecs/sigmadsp.c
sound/soc/codecs/tas6424.c
sound/soc/codecs/wm8804-i2c.c
sound/soc/codecs/wm9712.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/skylake/skl.c
sound/soc/qcom/qdsp6/q6routing.c
sound/soc/sh/rcar/adg.c
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/dma.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/ssi.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
tools/arch/arm/include/uapi/asm/kvm.h
tools/arch/arm64/include/uapi/asm/kvm.h
tools/arch/s390/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/hv/hv_kvp_daemon.c
tools/include/linux/lockdep.h
tools/include/linux/nmi.h [new file with mode: 0644]
tools/include/tools/libc_compat.h
tools/include/uapi/asm-generic/unistd.h
tools/include/uapi/drm/drm.h
tools/include/uapi/linux/if_link.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/linux/vhost.h
tools/lib/bpf/Build
tools/lib/bpf/libbpf.c
tools/lib/bpf/str_error.c [new file with mode: 0644]
tools/lib/bpf/str_error.h [new file with mode: 0644]
tools/perf/Documentation/Makefile
tools/perf/Makefile.perf
tools/perf/arch/arm64/Makefile
tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
tools/perf/arch/powerpc/util/sym-handling.c
tools/perf/arch/x86/include/arch-tests.h
tools/perf/arch/x86/tests/Build
tools/perf/arch/x86/tests/arch-tests.c
tools/perf/arch/x86/tests/bp-modify.c [new file with mode: 0644]
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/evsel.c
tools/perf/util/map.c
tools/perf/util/trace-event-info.c
tools/perf/util/trace-event-parse.c
tools/testing/selftests/android/Makefile
tools/testing/selftests/android/config [moved from tools/testing/selftests/android/ion/config with 100% similarity]
tools/testing/selftests/android/ion/Makefile
tools/testing/selftests/bpf/test_maps.c
tools/testing/selftests/cgroup/.gitignore
tools/testing/selftests/cgroup/cgroup_util.c
tools/testing/selftests/cgroup/cgroup_util.h
tools/testing/selftests/cgroup/test_memcontrol.c
tools/testing/selftests/efivarfs/config [new file with mode: 0644]
tools/testing/selftests/futex/functional/Makefile
tools/testing/selftests/gpio/Makefile
tools/testing/selftests/kselftest.h
tools/testing/selftests/kvm/.gitignore
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/platform_info_test.c [new file with mode: 0644]
tools/testing/selftests/lib.mk
tools/testing/selftests/memory-hotplug/config
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/pmtu.sh
tools/testing/selftests/net/tls.c
tools/testing/selftests/networking/timestamping/Makefile
tools/testing/selftests/powerpc/alignment/Makefile
tools/testing/selftests/powerpc/benchmarks/Makefile
tools/testing/selftests/powerpc/cache_shape/Makefile
tools/testing/selftests/powerpc/copyloops/Makefile
tools/testing/selftests/powerpc/dscr/Makefile
tools/testing/selftests/powerpc/math/Makefile
tools/testing/selftests/powerpc/mm/Makefile
tools/testing/selftests/powerpc/pmu/Makefile
tools/testing/selftests/powerpc/pmu/ebb/Makefile
tools/testing/selftests/powerpc/primitives/Makefile
tools/testing/selftests/powerpc/ptrace/Makefile
tools/testing/selftests/powerpc/signal/Makefile
tools/testing/selftests/powerpc/stringloops/Makefile
tools/testing/selftests/powerpc/switch_endian/Makefile
tools/testing/selftests/powerpc/syscalls/Makefile
tools/testing/selftests/powerpc/tm/Makefile
tools/testing/selftests/powerpc/vphn/Makefile
tools/testing/selftests/vm/Makefile

index caa311d59ac1d24c92643f37b396407a1ab654f0..6d83f95a8a8e131c9a2f0454cd39128ffd3d7723 100644 (file)
@@ -75,3 +75,12 @@ Contact:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 Description:
                Amount (in KiB) of low (or normal) memory in the
                balloon.
+
+What:          /sys/devices/system/xen_memory/xen_memory0/scrub_pages
+Date:          September 2018
+KernelVersion: 4.20
+Contact:       xen-devel@lists.xenproject.org
+Description:
+               Control scrubbing pages before returning them to Xen for others domains
+               use. Can be set with xen_scrub_pages cmdline
+               parameter. Default value controlled with CONFIG_XEN_SCRUB_PAGES_DEFAULT.
index 64a3bf54b97492e3b2b25508a7785d1f1e9e4186..92eb1f42240d7168354dc7129898e2500ef95c1a 100644 (file)
                        Disables the PV optimizations forcing the HVM guest to
                        run as generic HVM guest with no PV drivers.
 
+       xen_scrub_pages=        [XEN]
+                       Boolean option to control scrubbing pages before giving them back
+                       to Xen, for use by other domains. Can be also changed at runtime
+                       with /sys/devices/system/xen_memory/xen_memory0/scrub_pages.
+                       Default value controlled with CONFIG_XEN_SCRUB_PAGES_DEFAULT.
+
        xirc2ps_cs=     [NET,PCMCIA]
                        Format:
                        <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
index 390c145f01d717fc9bc9499fe4f0fc5d8dbc1257..52a719b49afd4fdbbb1dc5adfb86972b458ed79b 100644 (file)
@@ -348,3 +348,7 @@ Version History
 1.13.1  Fix deadlock caused by early md_stop_writes().  Also fix size an
        state races.
 1.13.2  Fix raid redundancy validation and avoid keeping raid set frozen
+1.14.0  Fix reshape race on small devices.  Fix stripe adding reshape
+       deadlock/potential data corruption.  Update superblock when
+       specific devices are requested via rebuild.  Fix RAID leg
+       rebuild errors.
index 996ce84352cbf11627adc17c13d079cc17601de1..7cccc49b6beade0d60adaafc228b3ed8ecfa34e0 100644 (file)
@@ -1,4 +1,4 @@
-Device-Tree bindings for input/gpio_keys.c keyboard driver
+Device-Tree bindings for input/keyboard/gpio_keys.c keyboard driver
 
 Required properties:
        - compatible = "gpio-keys";
index 457d5ae16f23490b21bbcd6171734f8aa8858b94..3e17ac1d5d58caa2c89dae53648c5b1d33efe0dd 100644 (file)
@@ -10,6 +10,7 @@ Required properties:
   Use "cdns,pc302-gem" for Picochip picoXcell pc302 and later devices based on
   the Cadence GEM, or the generic form: "cdns,gem".
   Use "atmel,sama5d2-gem" for the GEM IP (10/100) available on Atmel sama5d2 SoCs.
+  Use "atmel,sama5d3-macb" for the 10/100Mbit IP available on Atmel sama5d3 SoCs.
   Use "atmel,sama5d3-gem" for the Gigabit IP available on Atmel sama5d3 SoCs.
   Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs.
   Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
index 4b2084d0f1fb26c9b86bd7e2e587590bc1c1b31a..a6c6a8af48a296cf9b7197c8f065370814efd90d 100644 (file)
@@ -848,7 +848,7 @@ struct file_operations
 ----------------------
 
 This describes how the VFS can manipulate an open file. As of kernel
-4.1, the following members are defined:
+4.18, the following members are defined:
 
 struct file_operations {
        struct module *owner;
@@ -858,11 +858,11 @@ struct file_operations {
        ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
        ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
        int (*iterate) (struct file *, struct dir_context *);
+       int (*iterate_shared) (struct file *, struct dir_context *);
        __poll_t (*poll) (struct file *, struct poll_table_struct *);
        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
        long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
-       int (*mremap)(struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *, fl_owner_t id);
        int (*release) (struct inode *, struct file *);
@@ -882,6 +882,10 @@ struct file_operations {
 #ifndef CONFIG_MMU
        unsigned (*mmap_capabilities)(struct file *);
 #endif
+       ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int);
+       int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
+       int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
+       int (*fadvise)(struct file *, loff_t, loff_t, int);
 };
 
 Again, all methods are called without any locks being held, unless
@@ -899,6 +903,9 @@ otherwise noted.
 
   iterate: called when the VFS needs to read the directory contents
 
+  iterate_shared: called when the VFS needs to read the directory contents
+       when filesystem supports concurrent dir iterators
+
   poll: called by the VFS when a process wants to check if there is
        activity on this file and (optionally) go to sleep until there
        is activity. Called by the select(2) and poll(2) system calls
@@ -951,6 +958,16 @@ otherwise noted.
 
   fallocate: called by the VFS to preallocate blocks or punch a hole.
 
+  copy_file_range: called by the copy_file_range(2) system call.
+
+  clone_file_range: called by the ioctl(2) system call for FICLONERANGE and
+       FICLONE commands.
+
+  dedupe_file_range: called by the ioctl(2) system call for FIDEDUPERANGE
+       command.
+
+  fadvise: possibly called by the fadvise64() system call.
+
 Note that the file operations are implemented by the specific
 filesystem in which the inode resides. When opening a device node
 (character or block special) most filesystems will call special
index 3f4f6c9ffad7113c0c65ab717bf5d01bb8b00c7d..a4222b6cd2d3b7ffa558a9efee9db8c41ea3d58a 100644 (file)
@@ -33,4 +33,3 @@ Video Function Calls
     video-clear-buffer
     video-set-streamtype
     video-set-format
-    video-set-attributes
diff --git a/Documentation/process/code-of-conduct.rst b/Documentation/process/code-of-conduct.rst
new file mode 100644 (file)
index 0000000..ab7c24b
--- /dev/null
@@ -0,0 +1,81 @@
+Contributor Covenant Code of Conduct
+++++++++++++++++++++++++++++++++++++
+
+Our Pledge
+==========
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and
+expression, level of experience, education, socio-economic status, nationality,
+personal appearance, race, religion, or sexual identity and orientation.
+
+Our Standards
+=============
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+  advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others’ private information, such as a physical or electronic
+  address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+
+Our Responsibilities
+====================
+
+Maintainers are responsible for clarifying the standards of acceptable behavior
+and are expected to take appropriate and fair corrective action in response to
+any instances of unacceptable behavior.
+
+Maintainers have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, or to ban temporarily or permanently any
+contributor for other behaviors that they deem inappropriate, threatening,
+offensive, or harmful.
+
+Scope
+=====
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+Enforcement
+===========
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the Technical Advisory Board (TAB) at
+<tab@lists.linux-foundation.org>. All complaints will be reviewed and
+investigated and will result in a response that is deemed necessary and
+appropriate to the circumstances. The TAB is obligated to maintain
+confidentiality with regard to the reporter of an incident.  Further details of
+specific enforcement policies may be posted separately.
+
+Maintainers who do not follow or enforce the Code of Conduct in good faith may
+face temporary or permanent repercussions as determined by other members of the
+project’s leadership.
+
+Attribution
+===========
+
+This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
diff --git a/Documentation/process/code-of-conflict.rst b/Documentation/process/code-of-conflict.rst
deleted file mode 100644 (file)
index 47b6de7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-Code of Conflict
-----------------
-
-The Linux kernel development effort is a very personal process compared
-to "traditional" ways of developing software.  Your code and ideas
-behind it will be carefully reviewed, often resulting in critique and
-criticism.  The review will almost always require improvements to the
-code before it can be included in the kernel.  Know that this happens
-because everyone involved wants to see the best possible solution for
-the overall success of Linux.  This development process has been proven
-to create the most robust operating system kernel ever, and we do not
-want to do anything to cause the quality of submission and eventual
-result to ever decrease.
-
-If however, anyone feels personally abused, threatened, or otherwise
-uncomfortable due to this process, that is not acceptable.  If so,
-please contact the Linux Foundation's Technical Advisory Board at
-<tab@lists.linux-foundation.org>, or the individual members, and they
-will work to resolve the issue to the best of their ability.  For more
-information on who is on the Technical Advisory Board and what their
-role is, please see:
-
-       - http://www.linuxfoundation.org/projects/linux/tab
-
-As a reviewer of code, please strive to keep things civil and focused on
-the technical issues involved.  We are all humans, and frustrations can
-be high on both sides of the process.  Try to keep in mind the immortal
-words of Bill and Ted, "Be excellent to each other."
index 37bd0628b6ee90989a8471cff080c78cc32c69cb..9ae3e317bddf917b1a177d705af15a369508a4bb 100644 (file)
@@ -20,7 +20,7 @@ Below are the essential guides that every developer should read.
    :maxdepth: 1
 
    howto
-   code-of-conflict
+   code-of-conduct
    development-process
    submitting-patches
    coding-style
index c664064f76fb60ccc434988266776697660d0a5f..647f94128a85e47183f0ba7ffd6cbfc90fe1e6f5 100644 (file)
@@ -4510,7 +4510,8 @@ Do not enable KVM_FEATURE_PV_UNHALT if you disable HLT exits.
 Architectures: s390
 Parameters: none
 Returns: 0 on success, -EINVAL if hpage module parameter was not set
-        or cmma is enabled
+        or cmma is enabled, or the VM has the KVM_VM_S390_UCONTROL
+        flag set
 
 With this capability the KVM support for memory backing with 1m pages
 through hugetlbfs can be enabled for a VM. After the capability is
@@ -4521,6 +4522,15 @@ hpage module parameter is not set to 1, -EINVAL is returned.
 While it is generally possible to create a huge page backed VM without
 this capability, the VM will not be able to run.
 
+7.14 KVM_CAP_MSR_PLATFORM_INFO
+
+Architectures: x86
+Parameters: args[0] whether feature should be enabled or not
+
+With this capability, a guest may read the MSR_PLATFORM_INFO MSR. Otherwise,
+a #GP would be raised when the guest tries to access. Currently, this
+capability does not enable write permissions of this MSR for the guest.
+
 8. Other capabilities.
 ----------------------
 
index 688e3eeed21dced8dcb05ece8586475e54077548..46933e06c972b79fe77b97be97e1600dd014074b 100644 (file)
@@ -35,25 +35,25 @@ and two USB cables, connected like this:
 ( If your system does not list a debug port capability then you probably
   won't be able to use the USB debug key. )
 
- b.) You also need a Netchip USB debug cable/key:
+ b.) You also need a NetChip USB debug cable/key:
 
         http://www.plxtech.com/products/NET2000/NET20DC/default.asp
 
-     This is a small blue plastic connector with two USB connections,
+     This is a small blue plastic connector with two USB connections;
      it draws power from its USB connections.
 
  c.) You need a second client/console system with a high speed USB 2.0
      port.
 
- d.) The Netchip device must be plugged directly into the physical
+ d.) The NetChip device must be plugged directly into the physical
      debug port on the "host/target" system.  You cannot use a USB hub in
      between the physical debug port and the "host/target" system.
 
      The EHCI debug controller is bound to a specific physical USB
-     port and the Netchip device will only work as an early printk
+     port and the NetChip device will only work as an early printk
      device in this port.  The EHCI host controllers are electrically
      wired such that the EHCI debug controller is hooked up to the
-     first physical and there is no way to change this via software.
+     first physical port and there is no way to change this via software.
      You can find the physical port through experimentation by trying
      each physical port on the system and rebooting.  Or you can try
      and use lsusb or look at the kernel info messages emitted by the
@@ -65,9 +65,9 @@ and two USB cables, connected like this:
      to the hardware vendor, because there is no reason not to wire
      this port into one of the physically accessible ports.
 
- e.) It is also important to note, that many versions of the Netchip
+ e.) It is also important to note, that many versions of the NetChip
      device require the "client/console" system to be plugged into the
-     right and side of the device (with the product logo facing up and
+     right hand side of the device (with the product logo facing up and
      readable left to right).  The reason being is that the 5 volt
      power supply is taken from only one side of the device and it
      must be the side that does not get rebooted.
@@ -81,13 +81,18 @@ and two USB cables, connected like this:
       CONFIG_EARLY_PRINTK_DBGP=y
 
     And you need to add the boot command line: "earlyprintk=dbgp".
+
     (If you are using Grub, append it to the 'kernel' line in
-     /etc/grub.conf)
+     /etc/grub.conf.  If you are using Grub2 on a BIOS firmware system,
+     append it to the 'linux' line in /boot/grub2/grub.cfg. If you are
+     using Grub2 on an EFI firmware system, append it to the 'linux'
+     or 'linuxefi' line in /boot/grub2/grub.cfg or
+     /boot/efi/EFI/<distro>/grub.cfg.)
 
     On systems with more than one EHCI debug controller you must
     specify the correct EHCI debug controller number.  The ordering
     comes from the PCI bus enumeration of the EHCI controllers.  The
-    default with no number argument is "0" the first EHCI debug
+    default with no number argument is "0" or the first EHCI debug
     controller.  To use the second EHCI debug controller, you would
     use the command line: "earlyprintk=dbgp1"
 
@@ -111,7 +116,7 @@ and two USB cables, connected like this:
     see the raw output.
 
  c.) On Nvidia Southbridge based systems: the kernel will try to probe
-     and find out which port has debug device connected.
+     and find out which port has debug device connected.
 
 3. Testing that it works fine:
 
index d870cb57c887a1c5fa773a8fd9d614c54cb3cce0..a255240d145226afdadaed4cb24e006061942f07 100644 (file)
@@ -5625,6 +5625,8 @@ F:        lib/fault-inject.c
 
 FBTFT Framebuffer drivers
 M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+L:     dri-devel@lists.freedesktop.org
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/staging/fbtft/
 
@@ -6060,7 +6062,7 @@ F:        Documentation/gcc-plugins.txt
 
 GASKET DRIVER FRAMEWORK
 M:     Rob Springer <rspringer@google.com>
-M:     John Joseph <jnjoseph@google.com>
+M:     Todd Poynor <toddpoynor@google.com>
 M:     Ben Chan <benchan@chromium.org>
 S:     Maintained
 F:     drivers/staging/gasket/
@@ -7016,6 +7018,20 @@ F:       drivers/crypto/vmx/aes*
 F:     drivers/crypto/vmx/ghash*
 F:     drivers/crypto/vmx/ppc-xlate.pl
 
+IBM Power PCI Hotplug Driver for RPA-compliant PPC64 platform
+M:     Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+L:     linux-pci@vger.kernel.org
+L:     linuxppc-dev@lists.ozlabs.org
+S:     Supported
+F:     drivers/pci/hotplug/rpaphp*
+
+IBM Power IO DLPAR Driver for RPA-compliant PPC64 platform
+M:     Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+L:     linux-pci@vger.kernel.org
+L:     linuxppc-dev@lists.ozlabs.org
+S:     Supported
+F:     drivers/pci/hotplug/rpadlpar*
+
 IBM ServeRAID RAID DRIVER
 S:     Orphan
 F:     drivers/scsi/ips.*
@@ -8300,7 +8316,7 @@ F:        include/linux/libata.h
 F:     Documentation/devicetree/bindings/ata/
 
 LIBLOCKDEP
-M:     Sasha Levin <alexander.levin@verizon.com>
+M:     Sasha Levin <alexander.levin@microsoft.com>
 S:     Maintained
 F:     tools/lib/lockdep/
 
@@ -9700,13 +9716,6 @@ Q:       http://patchwork.linuxtv.org/project/linux-media/list/
 S:     Maintained
 F:     drivers/media/dvb-frontends/mn88473*
 
-PCI DRIVER FOR MOBIVEIL PCIE IP
-M:     Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
-L:     linux-pci@vger.kernel.org
-S:     Supported
-F:     Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
-F:     drivers/pci/controller/pcie-mobiveil.c
-
 MODULE SUPPORT
 M:     Jessica Yu <jeyu@kernel.org>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
@@ -11121,6 +11130,13 @@ F:     include/uapi/linux/switchtec_ioctl.h
 F:     include/linux/switchtec.h
 F:     drivers/ntb/hw/mscc/
 
+PCI DRIVER FOR MOBIVEIL PCIE IP
+M:     Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
+L:     linux-pci@vger.kernel.org
+S:     Supported
+F:     Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
+F:     drivers/pci/controller/pcie-mobiveil.c
+
 PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
 M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 M:     Jason Cooper <jason@lakedaemon.net>
@@ -11154,7 +11170,7 @@ F:      drivers/pci/controller/dwc/pci-exynos.c
 
 PCI DRIVER FOR SYNOPSYS DESIGNWARE
 M:     Jingoo Han <jingoohan1@gmail.com>
-M:     Joao Pinto <Joao.Pinto@synopsys.com>
+M:     Gustavo Pimentel <gustavo.pimentel@synopsys.com>
 L:     linux-pci@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/pci/designware-pcie.txt
@@ -11187,8 +11203,14 @@ F:     tools/pci/
 
 PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
 M:     Russell Currey <ruscur@russell.cc>
+M:     Sam Bobroff <sbobroff@linux.ibm.com>
+M:     Oliver O'Halloran <oohall@gmail.com>
 L:     linuxppc-dev@lists.ozlabs.org
 S:     Supported
+F:     Documentation/PCI/pci-error-recovery.txt
+F:     drivers/pci/pcie/aer.c
+F:     drivers/pci/pcie/dpc.c
+F:     drivers/pci/pcie/err.c
 F:     Documentation/powerpc/eeh-pci-error-recovery.txt
 F:     arch/powerpc/kernel/eeh*.c
 F:     arch/powerpc/platforms/*/eeh*.c
@@ -11346,10 +11368,10 @@ S:    Maintained
 F:     drivers/platform/x86/peaq-wmi.c
 
 PER-CPU MEMORY ALLOCATOR
+M:     Dennis Zhou <dennis@kernel.org>
 M:     Tejun Heo <tj@kernel.org>
 M:     Christoph Lameter <cl@linux.com>
-M:     Dennis Zhou <dennisszhou@gmail.com>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git
 S:     Maintained
 F:     include/linux/percpu*.h
 F:     mm/percpu*.c
@@ -12244,6 +12266,7 @@ F:      Documentation/networking/rds.txt
 
 RDT - RESOURCE ALLOCATION
 M:     Fenghua Yu <fenghua.yu@intel.com>
+M:     Reinette Chatre <reinette.chatre@intel.com>
 L:     linux-kernel@vger.kernel.org
 S:     Supported
 F:     arch/x86/kernel/cpu/intel_rdt*
@@ -13433,9 +13456,8 @@ F:      drivers/i2c/busses/i2c-synquacer.c
 F:     Documentation/devicetree/bindings/i2c/i2c-synquacer.txt
 
 SOCIONEXT UNIPHIER SOUND DRIVER
-M:     Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
-S:     Maintained
+S:     Orphan
 F:     sound/soc/uniphier/
 
 SOEKRIS NET48XX LED SUPPORT
@@ -15897,6 +15919,7 @@ F:      net/x25/
 X86 ARCHITECTURE (32-BIT AND 64-BIT)
 M:     Thomas Gleixner <tglx@linutronix.de>
 M:     Ingo Molnar <mingo@redhat.com>
+M:     Borislav Petkov <bp@alien8.de>
 R:     "H. Peter Anvin" <hpa@zytor.com>
 M:     x86@kernel.org
 L:     linux-kernel@vger.kernel.org
@@ -15925,6 +15948,15 @@ M:     Borislav Petkov <bp@alien8.de>
 S:     Maintained
 F:     arch/x86/kernel/cpu/microcode/*
 
+X86 MM
+M:     Dave Hansen <dave.hansen@linux.intel.com>
+M:     Andy Lutomirski <luto@kernel.org>
+M:     Peter Zijlstra <peterz@infradead.org>
+L:     linux-kernel@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/mm
+S:     Maintained
+F:     arch/x86/mm/
+
 X86 PLATFORM DRIVERS
 M:     Darren Hart <dvhart@infradead.org>
 M:     Andy Shevchenko <andy@infradead.org>
index 4d5c883a98e5a018b4ac301cd420a5745886d500..0c90c435497921f581a04c56b5c73d51f4df7383 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 19
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc5
 NAME = Merciless Moray
 
 # *DOCUMENTATION*
@@ -299,19 +299,7 @@ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
 
-# SUBARCH tells the usermode build what the underlying arch is.  That is set
-# first, and if a usermode build is happening, the "ARCH=um" on the command
-# line overrides the setting of ARCH below.  If a native build is happening,
-# then ARCH is assigned, getting whatever value it gets normally, and
-# SUBARCH is subsequently ignored.
-
-SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
-                                 -e s/sun4u/sparc64/ \
-                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
-                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
-                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-                                 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
-                                 -e s/riscv.*/riscv/)
+include scripts/subarch.include
 
 # Cross compiling and selecting different set of gcc/bin-utils
 # ---------------------------------------------------------------------------
@@ -616,6 +604,11 @@ CFLAGS_GCOV        := -fprofile-arcs -ftest-coverage \
        $(call cc-disable-warning,maybe-uninitialized,)
 export CFLAGS_GCOV
 
+# The arch Makefiles can override CC_FLAGS_FTRACE. We may also append it later.
+ifdef CONFIG_FUNCTION_TRACER
+  CC_FLAGS_FTRACE := -pg
+endif
+
 # The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default
 # values of the respective KBUILD_* variables
 ARCH_CPPFLAGS :=
@@ -755,9 +748,6 @@ KBUILD_CFLAGS       += $(call cc-option, -femit-struct-debug-baseonly) \
 endif
 
 ifdef CONFIG_FUNCTION_TRACER
-ifndef CC_FLAGS_FTRACE
-CC_FLAGS_FTRACE := -pg
-endif
 ifdef CONFIG_FTRACE_MCOUNT_RECORD
   # gcc 5 supports generating the mcount tables directly
   ifeq ($(call cc-option-yn,-mrecord-mcount),y)
index 7cb235ef0fb6dba30e77d6c91a0b9eafda6359a3..6e9e1c2f9def9fa6c675db355a1095276e73c1fe 100644 (file)
@@ -41,7 +41,7 @@ macb1_clk: macb1_clk {
                        };
 
                        macb1: ethernet@f802c000 {
-                               compatible = "cdns,at91sam9260-macb", "cdns,macb";
+                               compatible = "atmel,sama5d3-macb", "cdns,at91sam9260-macb", "cdns,macb";
                                reg = <0xf802c000 0x100>;
                                interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
                                pinctrl-names = "default";
index 1b5e0e843c3af8e8035c8f48ef518a3505adb881..7e2b3e360086311427a0bc77ec609b77b43b740d 100644 (file)
@@ -28,7 +28,7 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
 {
-       asm goto("1: nop\n\t"
+       asm_volatile_goto("1: nop\n\t"
                 ".pushsection __jump_table,  \"aw\"\n\t"
                 ".align 3\n\t"
                 ".quad 1b, %l[l_yes], %c0\n\t"
@@ -42,7 +42,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
 
 static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
 {
-       asm goto("1: b %l[l_yes]\n\t"
+       asm_volatile_goto("1: b %l[l_yes]\n\t"
                 ".pushsection __jump_table,  \"aw\"\n\t"
                 ".align 3\n\t"
                 ".quad 1b, %l[l_yes], %c0\n\t"
index 95ac7374d723e7fa48338caba5a32d6e9818377a..4c8b13bede80f98195ba1090fea11601a6d3df22 100644 (file)
@@ -54,6 +54,7 @@ arm64-obj-$(CONFIG_KEXEC)             += machine_kexec.o relocate_kernel.o    \
 arm64-obj-$(CONFIG_ARM64_RELOC_TEST)   += arm64-reloc-test.o
 arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
 arm64-obj-$(CONFIG_CRASH_DUMP)         += crash_dump.o
+arm64-obj-$(CONFIG_CRASH_CORE)         += crash_core.o
 arm64-obj-$(CONFIG_ARM_SDE_INTERFACE)  += sdei.o
 arm64-obj-$(CONFIG_ARM64_SSBD)         += ssbd.o
 
diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/crash_core.c
new file mode 100644 (file)
index 0000000..ca4c3e1
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Linaro.
+ * Copyright (C) Huawei Futurewei Technologies.
+ */
+
+#include <linux/crash_core.h>
+#include <asm/memory.h>
+
+void arch_crash_save_vmcoreinfo(void)
+{
+       VMCOREINFO_NUMBER(VA_BITS);
+       /* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
+       vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
+                                               kimage_voffset);
+       vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
+                                               PHYS_OFFSET);
+       vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+}
index f6a5c6bc14348592cefc9967685af7de9afbe4d7..922add8adb7498ff4609725782d09a56b46781d6 100644 (file)
@@ -358,14 +358,3 @@ void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
        }
 }
 #endif /* CONFIG_HIBERNATION */
-
-void arch_crash_save_vmcoreinfo(void)
-{
-       VMCOREINFO_NUMBER(VA_BITS);
-       /* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
-       vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
-                                               kimage_voffset);
-       vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
-                                               PHYS_OFFSET);
-       vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
-}
index 5e4a59b3ec1bb042f25de860a8489340a7add291..2691a1857d203db2522ae178fe744225c71d2da9 100644 (file)
@@ -211,7 +211,7 @@ static inline long ffz(int x)
  * This is defined the same way as ffs.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static inline long fls(int x)
+static inline int fls(int x)
 {
        int r;
 
@@ -232,7 +232,7 @@ static inline long fls(int x)
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-static inline long ffs(int x)
+static inline int ffs(int x)
 {
        int r;
 
index 77459df34e2e7e18b29eb62e097641d7f3c1a6d9..7ebe7ad19d155803dfa50087471e3bcd000f22c6 100644 (file)
@@ -60,7 +60,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
                        panic("Can't create %s() memory pool!", __func__);
                else
                        gen_pool_add(coherent_pool,
-                               pfn_to_virt(max_low_pfn),
+                               (unsigned long)pfn_to_virt(max_low_pfn),
                                hexagon_coherent_pool_size, -1);
        }
 
index 4901833498f7e3878b458d23afb876e7812a95f1..8441b2698e6472e9454aec3bb730e94b029fdd21 100644 (file)
@@ -40,6 +40,7 @@ struct ltq_dma_channel {
        int desc;                       /* the current descriptor */
        struct ltq_dma_desc *desc_base; /* the descriptor base */
        int phys;                       /* physical addr */
+       struct device *dev;
 };
 
 enum {
index 4b9fbb6744adecfe17fdba69649e8f95f875dfcb..664f2f7f55c1c06f34e58a551fa917a27f1f9dff 100644 (file)
@@ -130,7 +130,7 @@ ltq_dma_alloc(struct ltq_dma_channel *ch)
        unsigned long flags;
 
        ch->desc = 0;
-       ch->desc_base = dma_zalloc_coherent(NULL,
+       ch->desc_base = dma_zalloc_coherent(ch->dev,
                                LTQ_DESC_NUM * LTQ_DESC_SIZE,
                                &ch->phys, GFP_ATOMIC);
 
@@ -182,7 +182,7 @@ ltq_dma_free(struct ltq_dma_channel *ch)
        if (!ch->desc_base)
                return;
        ltq_dma_close(ch);
-       dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE,
+       dma_free_coherent(ch->dev, LTQ_DESC_NUM * LTQ_DESC_SIZE,
                ch->desc_base, ch->phys);
 }
 EXPORT_SYMBOL_GPL(ltq_dma_free);
index 13a688fc8cd0c90177493aee7f3b2f1806843dd3..2fdc865ca3741e89b0e356724467c7846fc42a80 100644 (file)
@@ -1051,7 +1051,6 @@ static inline void vmemmap_remove_mapping(unsigned long start,
        return hash__vmemmap_remove_mapping(start, page_size);
 }
 #endif
-struct page *realmode_pfn_to_page(unsigned long pfn);
 
 static inline pte_t pmd_pte(pmd_t pmd)
 {
index ab3a4fba38e397ca7240eadacd98fa1e8beee73f..3d4b88cb859924cf2fe438a49c7be2e6febbaa12 100644 (file)
@@ -220,8 +220,6 @@ extern void iommu_del_device(struct device *dev);
 extern int __init tce_iommu_bus_notifier_init(void);
 extern long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
                unsigned long *hpa, enum dma_data_direction *direction);
-extern long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
-               unsigned long *hpa, enum dma_data_direction *direction);
 #else
 static inline void iommu_register_group(struct iommu_table_group *table_group,
                                        int pci_domain_number,
index b2f89b621b159148c6d836e3c9c3d47a89aafe47..b694d6af115080765cad72b749bea690dbb6fb79 100644 (file)
@@ -38,6 +38,7 @@ extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
                unsigned long ua, unsigned int pageshift, unsigned long *hpa);
 extern long mm_iommu_ua_to_hpa_rm(struct mm_iommu_table_group_mem_t *mem,
                unsigned long ua, unsigned int pageshift, unsigned long *hpa);
+extern void mm_iommu_ua_mark_dirty_rm(struct mm_struct *mm, unsigned long ua);
 extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem);
 extern void mm_iommu_mapped_dec(struct mm_iommu_table_group_mem_t *mem);
 #endif
index 1a951b00465d739f0b7268803d9c1a25e92e947f..1fffbba8d6a5e64a5fefdb06a6ecab29f4ec66e5 100644 (file)
@@ -9,6 +9,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
 
 extern unsigned int rtas_data;
 extern unsigned long long memory_limit;
+extern bool init_mem_is_free;
 extern unsigned long klimit;
 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
 
index ea04dfb8c0927f71e1a89937526f3e1f2d7fd241..2d8fc8c9da7a1f210816bd9734c3d8453d8fc04e 100644 (file)
@@ -1314,9 +1314,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100)
 
 #ifdef CONFIG_PPC_DENORMALISATION
        mfspr   r10,SPRN_HSRR1
-       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
        andis.  r10,r10,(HSRR1_DENORM)@h /* denorm? */
-       addi    r11,r11,-4              /* HSRR0 is next instruction */
        bne+    denorm_assist
 #endif
 
@@ -1382,6 +1380,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
  */
        XVCPSGNDP32(32)
 denorm_done:
+       mfspr   r11,SPRN_HSRR0
+       subi    r11,r11,4
        mtspr   SPRN_HSRR0,r11
        mtcrf   0x80,r9
        ld      r9,PACA_EXGEN+EX_R9(r13)
index af7a20dc6e0934e0945c95e21c7b1eb07e11fdd1..19b4c628f3beced4211da41d48c528085254fee9 100644 (file)
@@ -1013,31 +1013,6 @@ long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
 }
 EXPORT_SYMBOL_GPL(iommu_tce_xchg);
 
-#ifdef CONFIG_PPC_BOOK3S_64
-long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
-               unsigned long *hpa, enum dma_data_direction *direction)
-{
-       long ret;
-
-       ret = tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
-
-       if (!ret && ((*direction == DMA_FROM_DEVICE) ||
-                       (*direction == DMA_BIDIRECTIONAL))) {
-               struct page *pg = realmode_pfn_to_page(*hpa >> PAGE_SHIFT);
-
-               if (likely(pg)) {
-                       SetPageDirty(pg);
-               } else {
-                       tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
-                       ret = -EFAULT;
-               }
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(iommu_tce_xchg_rm);
-#endif
-
 int iommu_take_ownership(struct iommu_table *tbl)
 {
        unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;
index 6bffbc5affe76ba7847ceb74b69e16cc53ac4178..7716374786bd97c7e56390ea587e967d75c68a2e 100644 (file)
@@ -176,13 +176,27 @@ _GLOBAL(tm_reclaim)
        std     r1, PACATMSCRATCH(r13)
        ld      r1, PACAR1(r13)
 
-       /* Store the PPR in r11 and reset to decent value */
        std     r11, GPR11(r1)                  /* Temporary stash */
 
+       /*
+        * Move the saved user r1 to the kernel stack in case PACATMSCRATCH is
+        * clobbered by an exception once we turn on MSR_RI below.
+        */
+       ld      r11, PACATMSCRATCH(r13)
+       std     r11, GPR1(r1)
+
+       /*
+        * Store r13 away so we can free up the scratch SPR for the SLB fault
+        * handler (needed once we start accessing the thread_struct).
+        */
+       GET_SCRATCH0(r11)
+       std     r11, GPR13(r1)
+
        /* Reset MSR RI so we can take SLB faults again */
        li      r11, MSR_RI
        mtmsrd  r11, 1
 
+       /* Store the PPR in r11 and reset to decent value */
        mfspr   r11, SPRN_PPR
        HMT_MEDIUM
 
@@ -207,11 +221,11 @@ _GLOBAL(tm_reclaim)
        SAVE_GPR(8, r7)                         /* user r8 */
        SAVE_GPR(9, r7)                         /* user r9 */
        SAVE_GPR(10, r7)                        /* user r10 */
-       ld      r3, PACATMSCRATCH(r13)          /* user r1 */
+       ld      r3, GPR1(r1)                    /* user r1 */
        ld      r4, GPR7(r1)                    /* user r7 */
        ld      r5, GPR11(r1)                   /* user r11 */
        ld      r6, GPR12(r1)                   /* user r12 */
-       GET_SCRATCH0(8)                         /* user r13 */
+       ld      r8, GPR13(r1)                   /* user r13 */
        std     r3, GPR1(r7)
        std     r4, GPR7(r7)
        std     r5, GPR11(r7)
index fd6e8c13685f4c0223749647ad04c34a71ad4589..933c574e1cf795d65855b60d763c62edf4d1996a 100644 (file)
@@ -525,8 +525,8 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                                   unsigned long ea, unsigned long dsisr)
 {
        struct kvm *kvm = vcpu->kvm;
-       unsigned long mmu_seq, pte_size;
-       unsigned long gpa, gfn, hva, pfn;
+       unsigned long mmu_seq;
+       unsigned long gpa, gfn, hva;
        struct kvm_memory_slot *memslot;
        struct page *page = NULL;
        long ret;
@@ -623,9 +623,10 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
         */
        hva = gfn_to_hva_memslot(memslot, gfn);
        if (upgrade_p && __get_user_pages_fast(hva, 1, 1, &page) == 1) {
-               pfn = page_to_pfn(page);
                upgrade_write = true;
        } else {
+               unsigned long pfn;
+
                /* Call KVM generic code to do the slow-path check */
                pfn = __gfn_to_pfn_memslot(memslot, gfn, false, NULL,
                                           writing, upgrade_p);
@@ -639,63 +640,45 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                }
        }
 
-       /* See if we can insert a 1GB or 2MB large PTE here */
-       level = 0;
-       if (page && PageCompound(page)) {
-               pte_size = PAGE_SIZE << compound_order(compound_head(page));
-               if (pte_size >= PUD_SIZE &&
-                   (gpa & (PUD_SIZE - PAGE_SIZE)) ==
-                   (hva & (PUD_SIZE - PAGE_SIZE))) {
-                       level = 2;
-                       pfn &= ~((PUD_SIZE >> PAGE_SHIFT) - 1);
-               } else if (pte_size >= PMD_SIZE &&
-                          (gpa & (PMD_SIZE - PAGE_SIZE)) ==
-                          (hva & (PMD_SIZE - PAGE_SIZE))) {
-                       level = 1;
-                       pfn &= ~((PMD_SIZE >> PAGE_SHIFT) - 1);
-               }
-       }
-
        /*
-        * Compute the PTE value that we need to insert.
+        * Read the PTE from the process' radix tree and use that
+        * so we get the shift and attribute bits.
         */
-       if (page) {
-               pgflags = _PAGE_READ | _PAGE_EXEC | _PAGE_PRESENT | _PAGE_PTE |
-                       _PAGE_ACCESSED;
-               if (writing || upgrade_write)
-                       pgflags |= _PAGE_WRITE | _PAGE_DIRTY;
-               pte = pfn_pte(pfn, __pgprot(pgflags));
+       local_irq_disable();
+       ptep = __find_linux_pte(vcpu->arch.pgdir, hva, NULL, &shift);
+       pte = *ptep;
+       local_irq_enable();
+
+       /* Get pte level from shift/size */
+       if (shift == PUD_SHIFT &&
+           (gpa & (PUD_SIZE - PAGE_SIZE)) ==
+           (hva & (PUD_SIZE - PAGE_SIZE))) {
+               level = 2;
+       } else if (shift == PMD_SHIFT &&
+                  (gpa & (PMD_SIZE - PAGE_SIZE)) ==
+                  (hva & (PMD_SIZE - PAGE_SIZE))) {
+               level = 1;
        } else {
-               /*
-                * Read the PTE from the process' radix tree and use that
-                * so we get the attribute bits.
-                */
-               local_irq_disable();
-               ptep = __find_linux_pte(vcpu->arch.pgdir, hva, NULL, &shift);
-               pte = *ptep;
-               local_irq_enable();
-               if (shift == PUD_SHIFT &&
-                   (gpa & (PUD_SIZE - PAGE_SIZE)) ==
-                   (hva & (PUD_SIZE - PAGE_SIZE))) {
-                       level = 2;
-               } else if (shift == PMD_SHIFT &&
-                          (gpa & (PMD_SIZE - PAGE_SIZE)) ==
-                          (hva & (PMD_SIZE - PAGE_SIZE))) {
-                       level = 1;
-               } else if (shift && shift != PAGE_SHIFT) {
-                       /* Adjust PFN */
-                       unsigned long mask = (1ul << shift) - PAGE_SIZE;
-                       pte = __pte(pte_val(pte) | (hva & mask));
-               }
-               pte = __pte(pte_val(pte) | _PAGE_EXEC | _PAGE_ACCESSED);
-               if (writing || upgrade_write) {
-                       if (pte_val(pte) & _PAGE_WRITE)
-                               pte = __pte(pte_val(pte) | _PAGE_DIRTY);
-               } else {
-                       pte = __pte(pte_val(pte) & ~(_PAGE_WRITE | _PAGE_DIRTY));
+               level = 0;
+               if (shift > PAGE_SHIFT) {
+                       /*
+                        * If the pte maps more than one page, bring over
+                        * bits from the virtual address to get the real
+                        * address of the specific single page we want.
+                        */
+                       unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
+                       pte = __pte(pte_val(pte) | (hva & rpnmask));
                }
        }
 
+       pte = __pte(pte_val(pte) | _PAGE_EXEC | _PAGE_ACCESSED);
+       if (writing || upgrade_write) {
+               if (pte_val(pte) & _PAGE_WRITE)
+                       pte = __pte(pte_val(pte) | _PAGE_DIRTY);
+       } else {
+               pte = __pte(pte_val(pte) & ~(_PAGE_WRITE | _PAGE_DIRTY));
+       }
+
        /* Allocate space in the tree and write the PTE */
        ret = kvmppc_create_pte(kvm, pte, gpa, level, mmu_seq);
 
index 506a4d40045883026a9046919d23e695f35bc219..6821ead4b4ebc128a9a772a712feefb213b1bad0 100644 (file)
@@ -187,12 +187,35 @@ long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
 EXPORT_SYMBOL_GPL(kvmppc_gpa_to_ua);
 
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
-static void kvmppc_rm_clear_tce(struct iommu_table *tbl, unsigned long entry)
+static long iommu_tce_xchg_rm(struct mm_struct *mm, struct iommu_table *tbl,
+               unsigned long entry, unsigned long *hpa,
+               enum dma_data_direction *direction)
+{
+       long ret;
+
+       ret = tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
+
+       if (!ret && ((*direction == DMA_FROM_DEVICE) ||
+                               (*direction == DMA_BIDIRECTIONAL))) {
+               __be64 *pua = IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry);
+               /*
+                * kvmppc_rm_tce_iommu_do_map() updates the UA cache after
+                * calling this so we still get here a valid UA.
+                */
+               if (pua && *pua)
+                       mm_iommu_ua_mark_dirty_rm(mm, be64_to_cpu(*pua));
+       }
+
+       return ret;
+}
+
+static void kvmppc_rm_clear_tce(struct kvm *kvm, struct iommu_table *tbl,
+               unsigned long entry)
 {
        unsigned long hpa = 0;
        enum dma_data_direction dir = DMA_NONE;
 
-       iommu_tce_xchg_rm(tbl, entry, &hpa, &dir);
+       iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
 }
 
 static long kvmppc_rm_tce_iommu_mapped_dec(struct kvm *kvm,
@@ -224,7 +247,7 @@ static long kvmppc_rm_tce_iommu_do_unmap(struct kvm *kvm,
        unsigned long hpa = 0;
        long ret;
 
-       if (iommu_tce_xchg_rm(tbl, entry, &hpa, &dir))
+       if (iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir))
                /*
                 * real mode xchg can fail if struct page crosses
                 * a page boundary
@@ -236,7 +259,7 @@ static long kvmppc_rm_tce_iommu_do_unmap(struct kvm *kvm,
 
        ret = kvmppc_rm_tce_iommu_mapped_dec(kvm, tbl, entry);
        if (ret)
-               iommu_tce_xchg_rm(tbl, entry, &hpa, &dir);
+               iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
 
        return ret;
 }
@@ -282,7 +305,7 @@ static long kvmppc_rm_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl,
        if (WARN_ON_ONCE_RM(mm_iommu_mapped_inc(mem)))
                return H_CLOSED;
 
-       ret = iommu_tce_xchg_rm(tbl, entry, &hpa, &dir);
+       ret = iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
        if (ret) {
                mm_iommu_mapped_dec(mem);
                /*
@@ -371,7 +394,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
                        return ret;
 
                WARN_ON_ONCE_RM(1);
-               kvmppc_rm_clear_tce(stit->tbl, entry);
+               kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
        }
 
        kvmppc_tce_put(stt, entry, tce);
@@ -520,7 +543,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
                                goto unlock_exit;
 
                        WARN_ON_ONCE_RM(1);
-                       kvmppc_rm_clear_tce(stit->tbl, entry);
+                       kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
                }
 
                kvmppc_tce_put(stt, entry + i, tce);
@@ -571,7 +594,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
                                return ret;
 
                        WARN_ON_ONCE_RM(1);
-                       kvmppc_rm_clear_tce(stit->tbl, entry);
+                       kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
                }
        }
 
index 886ed94b9c13307f5fc739e899274704faa89a15..d05c8af4ac51fe4c696469664e4bf6ceb9dd7d64 100644 (file)
@@ -443,6 +443,9 @@ _GLOBAL(csum_ipv6_magic)
        addc    r0, r8, r9
        ld      r10, 0(r4)
        ld      r11, 8(r4)
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       rotldi  r5, r5, 8
+#endif
        adde    r0, r0, r10
        add     r5, r5, r7
        adde    r0, r0, r11
index 850f3b8f4da5e55346afbbe939987b0a0642aa7d..6ae2777c220d4062860ecd64c567d754bf00da8a 100644 (file)
@@ -28,6 +28,12 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
 {
        int err;
 
+       /* Make sure we aren't patching a freed init section */
+       if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
+               pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr);
+               return 0;
+       }
+
        __put_user_size(instr, patch_addr, 4, err);
        if (err)
                return err;
index 51ce091914f9760b85853d7f197bceb5ef73e02a..7a9886f98b0c12e8df43fe0e8a897a7d4cbeac9d 100644 (file)
@@ -308,55 +308,6 @@ void register_page_bootmem_memmap(unsigned long section_nr,
 {
 }
 
-/*
- * We do not have access to the sparsemem vmemmap, so we fallback to
- * walking the list of sparsemem blocks which we already maintain for
- * the sake of crashdump. In the long run, we might want to maintain
- * a tree if performance of that linear walk becomes a problem.
- *
- * realmode_pfn_to_page functions can fail due to:
- * 1) As real sparsemem blocks do not lay in RAM continously (they
- * are in virtual address space which is not available in the real mode),
- * the requested page struct can be split between blocks so get_page/put_page
- * may fail.
- * 2) When huge pages are used, the get_page/put_page API will fail
- * in real mode as the linked addresses in the page struct are virtual
- * too.
- */
-struct page *realmode_pfn_to_page(unsigned long pfn)
-{
-       struct vmemmap_backing *vmem_back;
-       struct page *page;
-       unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
-       unsigned long pg_va = (unsigned long) pfn_to_page(pfn);
-
-       for (vmem_back = vmemmap_list; vmem_back; vmem_back = vmem_back->list) {
-               if (pg_va < vmem_back->virt_addr)
-                       continue;
-
-               /* After vmemmap_list entry free is possible, need check all */
-               if ((pg_va + sizeof(struct page)) <=
-                               (vmem_back->virt_addr + page_size)) {
-                       page = (struct page *) (vmem_back->phys + pg_va -
-                               vmem_back->virt_addr);
-                       return page;
-               }
-       }
-
-       /* Probably that page struct is split between real pages */
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
-
-#else
-
-struct page *realmode_pfn_to_page(unsigned long pfn)
-{
-       struct page *page = pfn_to_page(pfn);
-       return page;
-}
-EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
-
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 #ifdef CONFIG_PPC_BOOK3S_64
index 5c8530d0c611898f012e2cc8f300a7112715c351..04ccb274a6205bba58357d5897105ada90f81c0f 100644 (file)
@@ -63,6 +63,7 @@
 #endif
 
 unsigned long long memory_limit;
+bool init_mem_is_free;
 
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
@@ -396,6 +397,7 @@ void free_initmem(void)
 {
        ppc_md.progress = ppc_printk_progress;
        mark_initmem_nx();
+       init_mem_is_free = true;
        free_initmem_default(POISON_FREE_INITMEM);
 }
 
index c9ee9e23845f20d3f3b4b523e40a2a453d30ed7c..56c2234cc6ae70b8c7c27c64897bb3560ad86219 100644 (file)
 #include <linux/migrate.h>
 #include <linux/hugetlb.h>
 #include <linux/swap.h>
+#include <linux/sizes.h>
 #include <asm/mmu_context.h>
 #include <asm/pte-walk.h>
 
 static DEFINE_MUTEX(mem_list_mutex);
 
+#define MM_IOMMU_TABLE_GROUP_PAGE_DIRTY        0x1
+#define MM_IOMMU_TABLE_GROUP_PAGE_MASK ~(SZ_4K - 1)
+
 struct mm_iommu_table_group_mem_t {
        struct list_head next;
        struct rcu_head rcu;
@@ -263,6 +267,9 @@ static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem)
                if (!page)
                        continue;
 
+               if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
+                       SetPageDirty(page);
+
                put_page(page);
                mem->hpas[i] = 0;
        }
@@ -360,7 +367,6 @@ struct mm_iommu_table_group_mem_t *mm_iommu_lookup_rm(struct mm_struct *mm,
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(mm_iommu_lookup_rm);
 
 struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
                unsigned long ua, unsigned long entries)
@@ -390,7 +396,7 @@ long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
        if (pageshift > mem->pageshift)
                return -EFAULT;
 
-       *hpa = *va | (ua & ~PAGE_MASK);
+       *hpa = (*va & MM_IOMMU_TABLE_GROUP_PAGE_MASK) | (ua & ~PAGE_MASK);
 
        return 0;
 }
@@ -413,11 +419,31 @@ long mm_iommu_ua_to_hpa_rm(struct mm_iommu_table_group_mem_t *mem,
        if (!pa)
                return -EFAULT;
 
-       *hpa = *pa | (ua & ~PAGE_MASK);
+       *hpa = (*pa & MM_IOMMU_TABLE_GROUP_PAGE_MASK) | (ua & ~PAGE_MASK);
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(mm_iommu_ua_to_hpa_rm);
+
+extern void mm_iommu_ua_mark_dirty_rm(struct mm_struct *mm, unsigned long ua)
+{
+       struct mm_iommu_table_group_mem_t *mem;
+       long entry;
+       void *va;
+       unsigned long *pa;
+
+       mem = mm_iommu_lookup_rm(mm, ua, PAGE_SIZE);
+       if (!mem)
+               return;
+
+       entry = (ua - mem->ua) >> PAGE_SHIFT;
+       va = &mem->hpas[entry];
+
+       pa = (void *) vmalloc_to_phys(va);
+       if (!pa)
+               return;
+
+       *pa |= MM_IOMMU_TABLE_GROUP_PAGE_DIRTY;
+}
 
 long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem)
 {
index 35ac5422903a0ee5494c92b637bcc64604c7cba3..59d07bd5374a968f938135b6c0691b0245dd7da0 100644 (file)
@@ -1204,7 +1204,9 @@ int find_and_online_cpu_nid(int cpu)
        int new_nid;
 
        /* Use associativity from first thread for all siblings */
-       vphn_get_associativity(cpu, associativity);
+       if (vphn_get_associativity(cpu, associativity))
+               return cpu_to_node(cpu);
+
        new_nid = associativity_to_nid(associativity);
        if (new_nid < 0 || !node_possible(new_nid))
                new_nid = first_online_node;
@@ -1452,7 +1454,8 @@ static struct timer_list topology_timer;
 
 static void reset_topology_timer(void)
 {
-       mod_timer(&topology_timer, jiffies + topology_timer_secs * HZ);
+       if (vphn_enabled)
+               mod_timer(&topology_timer, jiffies + topology_timer_secs * HZ);
 }
 
 #ifdef CONFIG_SMP
index 333b1f80c435435cbf703a477e4bb60f6181a058..b271b283c785e3a07589ea81c6b8e40e7def5a69 100644 (file)
@@ -45,7 +45,7 @@ static void scan_pkey_feature(void)
         * Since any pkey can be used for data or execute, we will just treat
         * all keys as equal and track them as one entity.
         */
-       pkeys_total = be32_to_cpu(vals[0]);
+       pkeys_total = vals[0];
        pkeys_devtree_defined = true;
 }
 
index 6c5db1acbe8dffaba711faf55d13b2baa6c6a965..fe9691040f54c26561949c469738f277c90069e6 100644 (file)
@@ -276,7 +276,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
        level_shift = entries_shift + 3;
        level_shift = max_t(unsigned int, level_shift, PAGE_SHIFT);
 
-       if ((level_shift - 3) * levels + page_shift >= 60)
+       if ((level_shift - 3) * levels + page_shift >= 55)
                return -EINVAL;
 
        /* Allocate TCE table */
diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h
new file mode 100644 (file)
index 0000000..c9fecd1
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_PROTOTYPES_H
+
+#include <linux/ftrace.h>
+#include <asm-generic/asm-prototypes.h>
+
+#endif /* _ASM_RISCV_PROTOTYPES_H */
index db20dc630e7efbadeb8ebeb497d5685a3cbad682..aee6031230306a934747c64edb4b61f6928e9e8b 100644 (file)
@@ -85,15 +85,8 @@ atomic_t hart_lottery;
 #ifdef CONFIG_BLK_DEV_INITRD
 static void __init setup_initrd(void)
 {
-       extern char __initramfs_start[];
-       extern unsigned long __initramfs_size;
        unsigned long size;
 
-       if (__initramfs_size > 0) {
-               initrd_start = (unsigned long)(&__initramfs_start);
-               initrd_end = initrd_start + __initramfs_size;
-       }
-
        if (initrd_start >= initrd_end) {
                printk(KERN_INFO "initrd not found or empty");
                goto disable;
index 80b27294c1de0844f07d01c5aecbb5410a38602e..ab9a0ebecc199b52507246b47db7b79dd0420058 100644 (file)
@@ -208,7 +208,7 @@ static int cbc_paes_crypt(struct blkcipher_desc *desc, unsigned long modifier,
                              walk->dst.virt.addr, walk->src.virt.addr, n);
                if (k)
                        ret = blkcipher_walk_done(desc, walk, nbytes - k);
-               if (n < k) {
+               if (k < n) {
                        if (__cbc_paes_set_key(ctx) != 0)
                                return blkcipher_walk_done(desc, walk, -EIO);
                        memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
index f69333fd2fa3818c5eeb8bff9240f67e29f37ef0..ac5da6b0b862a3d725297890b7feb6cae6d06788 100644 (file)
@@ -481,7 +481,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                break;
        case KVM_CAP_S390_HPAGE_1M:
                r = 0;
-               if (hpage)
+               if (hpage && !kvm_is_ucontrol(kvm))
                        r = 1;
                break;
        case KVM_CAP_S390_MEM_OP:
@@ -691,7 +691,7 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
                mutex_lock(&kvm->lock);
                if (kvm->created_vcpus)
                        r = -EBUSY;
-               else if (!hpage || kvm->arch.use_cmma)
+               else if (!hpage || kvm->arch.use_cmma || kvm_is_ucontrol(kvm))
                        r = -EINVAL;
                else {
                        r = 0;
index bb44990c8212080cf24c9409362735fd4f1b569c..911c7ded35f15a2706b293ac2533b02b4906c4aa 100644 (file)
@@ -708,11 +708,13 @@ void gmap_discard(struct gmap *gmap, unsigned long from, unsigned long to)
                vmaddr |= gaddr & ~PMD_MASK;
                /* Find vma in the parent mm */
                vma = find_vma(gmap->mm, vmaddr);
+               if (!vma)
+                       continue;
                /*
                 * We do not discard pages that are backed by
                 * hugetlbfs, so we don't have to refault them.
                 */
-               if (vma && is_vm_hugetlb_page(vma))
+               if (is_vm_hugetlb_page(vma))
                        continue;
                size = min(to - gaddr, PMD_SIZE - (gaddr & ~PMD_MASK));
                zap_page_range(vma, vmaddr, size);
index eaa843a52907ffd8a166c09e98c1594627aff4ac..a480356e0ed886006749d69488c5af625828bf6d 100644 (file)
@@ -25,20 +25,6 @@ ENTRY(get_sev_encryption_bit)
        push    %ebx
        push    %ecx
        push    %edx
-       push    %edi
-
-       /*
-        * RIP-relative addressing is needed to access the encryption bit
-        * variable. Since we are running in 32-bit mode we need this call/pop
-        * sequence to get the proper relative addressing.
-        */
-       call    1f
-1:     popl    %edi
-       subl    $1b, %edi
-
-       movl    enc_bit(%edi), %eax
-       cmpl    $0, %eax
-       jge     .Lsev_exit
 
        /* Check if running under a hypervisor */
        movl    $1, %eax
@@ -69,15 +55,12 @@ ENTRY(get_sev_encryption_bit)
 
        movl    %ebx, %eax
        andl    $0x3f, %eax             /* Return the encryption bit location */
-       movl    %eax, enc_bit(%edi)
        jmp     .Lsev_exit
 
 .Lno_sev:
        xor     %eax, %eax
-       movl    %eax, enc_bit(%edi)
 
 .Lsev_exit:
-       pop     %edi
        pop     %edx
        pop     %ecx
        pop     %ebx
@@ -113,8 +96,6 @@ ENTRY(set_sev_encryption_mask)
 ENDPROC(set_sev_encryption_mask)
 
        .data
-enc_bit:
-       .int    0xffffffff
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
        .balign 8
index acd11b3bf639e0a50013014e5eaeca6b11083c28..2a356b948720e10f93d49765a071c3c6dd6edb36 100644 (file)
@@ -379,7 +379,6 @@ static int __init crypto_aegis128_aesni_module_init(void)
 {
        if (!boot_cpu_has(X86_FEATURE_XMM2) ||
            !boot_cpu_has(X86_FEATURE_AES) ||
-           !boot_cpu_has(X86_FEATURE_OSXSAVE) ||
            !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL))
                return -ENODEV;
 
index 2071c3d1ae07575143cc4d6262e92eaeef9ba560..dbe8bb980da15c46cb3c815d0ab529cd2522a346 100644 (file)
@@ -379,7 +379,6 @@ static int __init crypto_aegis128l_aesni_module_init(void)
 {
        if (!boot_cpu_has(X86_FEATURE_XMM2) ||
            !boot_cpu_has(X86_FEATURE_AES) ||
-           !boot_cpu_has(X86_FEATURE_OSXSAVE) ||
            !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL))
                return -ENODEV;
 
index b5f2a8fd5a713ca986e2d3ef24aa1b69d421ced2..8bebda2de92fe3f4453cb453596faeb4dfbfd6bb 100644 (file)
@@ -379,7 +379,6 @@ static int __init crypto_aegis256_aesni_module_init(void)
 {
        if (!boot_cpu_has(X86_FEATURE_XMM2) ||
            !boot_cpu_has(X86_FEATURE_AES) ||
-           !boot_cpu_has(X86_FEATURE_OSXSAVE) ||
            !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL))
                return -ENODEV;
 
index 95cf857d2cbb1943ba8ce356c48416837f1655d9..f40244eaf14d23211c122e309247865ebcbe9965 100644 (file)
@@ -40,7 +40,6 @@ MORUS1280_DECLARE_ALGS(sse2, "morus1280-sse2", 350);
 static int __init crypto_morus1280_sse2_module_init(void)
 {
        if (!boot_cpu_has(X86_FEATURE_XMM2) ||
-           !boot_cpu_has(X86_FEATURE_OSXSAVE) ||
            !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL))
                return -ENODEV;
 
index 615fb7bc9a323d949d038a8496125eab0c4bc4ba..9afaf8f8565a6eb9dc7b29a99c68ca1b153fad48 100644 (file)
@@ -40,7 +40,6 @@ MORUS640_DECLARE_ALGS(sse2, "morus640-sse2", 400);
 static int __init crypto_morus640_sse2_module_init(void)
 {
        if (!boot_cpu_has(X86_FEATURE_XMM2) ||
-           !boot_cpu_has(X86_FEATURE_OSXSAVE) ||
            !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL))
                return -ENODEV;
 
index f3e006bed9a75f94aa8bb9aa388d3037a2d71cbe..c88ed39582a10095b41b364bf6532b0f5298c6e2 100644 (file)
@@ -1272,4 +1272,8 @@ void intel_pmu_lbr_init_knl(void)
 
        x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
        x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
+
+       /* Knights Landing does have MISPREDICT bit */
+       if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP)
+               x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS;
 }
index 5b0f613428c252291379e9bbb7cc664c929ce07f..2c43e3055948e8b7927083138c01e311e1ea77e5 100644 (file)
@@ -95,8 +95,8 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
  */
 static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
 {
-       struct ipi_arg_ex **arg;
-       struct ipi_arg_ex *ipi_arg;
+       struct hv_send_ipi_ex **arg;
+       struct hv_send_ipi_ex *ipi_arg;
        unsigned long flags;
        int nr_bank = 0;
        int ret = 1;
@@ -105,7 +105,7 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
                return false;
 
        local_irq_save(flags);
-       arg = (struct ipi_arg_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+       arg = (struct hv_send_ipi_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
 
        ipi_arg = *arg;
        if (unlikely(!ipi_arg))
@@ -135,7 +135,7 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
 static bool __send_ipi_mask(const struct cpumask *mask, int vector)
 {
        int cur_cpu, vcpu;
-       struct ipi_arg_non_ex ipi_arg;
+       struct hv_send_ipi ipi_arg;
        int ret = 1;
 
        trace_hyperv_send_ipi_mask(mask, vector);
index e203169931c721b7958c940694458c11a270b982..6390bd8c141b44cd988dd21bc4b5b3efbbf1688b 100644 (file)
 #ifndef _ASM_X86_FIXMAP_H
 #define _ASM_X86_FIXMAP_H
 
+/*
+ * Exposed to assembly code for setting up initial page tables. Cannot be
+ * calculated in assembly code (fixmap entries are an enum), but is sanity
+ * checked in the actual fixmap C code to make sure that the fixmap is
+ * covered fully.
+ */
+#define FIXMAP_PMD_NUM 2
+/* fixmap starts downwards from the 507th entry in level2_fixmap_pgt */
+#define FIXMAP_PMD_TOP 507
+
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
 #include <asm/acpi.h>
index e977b6b3a538fc91859edd9be856a5d8592b018a..00e01d215f74ca7d235d355a511b7f977f636356 100644 (file)
@@ -726,19 +726,21 @@ struct hv_enlightened_vmcs {
 #define HV_STIMER_AUTOENABLE           (1ULL << 3)
 #define HV_STIMER_SINT(config)         (__u8)(((config) >> 16) & 0x0F)
 
-struct ipi_arg_non_ex {
-       u32 vector;
-       u32 reserved;
-       u64 cpu_mask;
-};
-
 struct hv_vpset {
        u64 format;
        u64 valid_bank_mask;
        u64 bank_contents[];
 };
 
-struct ipi_arg_ex {
+/* HvCallSendSyntheticClusterIpi hypercall */
+struct hv_send_ipi {
+       u32 vector;
+       u32 reserved;
+       u64 cpu_mask;
+};
+
+/* HvCallSendSyntheticClusterIpiEx hypercall */
+struct hv_send_ipi_ex {
        u32 vector;
        u32 reserved;
        struct hv_vpset vp_set;
index 8e90488c3d56895f62080666e2141df1731092f3..09b2e3e2cf1bec5f7b745590b187521c8576eacc 100644 (file)
@@ -869,6 +869,8 @@ struct kvm_arch {
 
        bool x2apic_format;
        bool x2apic_broadcast_quirk_disabled;
+
+       bool guest_can_read_msr_platform_info;
 };
 
 struct kvm_vm_stat {
@@ -1022,6 +1024,7 @@ struct kvm_x86_ops {
        void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
        void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
        void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr);
+       bool (*guest_apic_has_interrupt)(struct kvm_vcpu *vcpu);
        void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
        void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
        void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
@@ -1055,6 +1058,7 @@ struct kvm_x86_ops {
        bool (*umip_emulated)(void);
 
        int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
+       void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
 
        void (*sched_in)(struct kvm_vcpu *kvm, int cpu);
 
@@ -1482,6 +1486,7 @@ extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn);
 
 int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
 int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
+void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
 
 int kvm_is_in_guest(void);
 
index c0643831706e12aaf490c709dbedc428d2bc75f4..616f8e637bc32c2bd48dfc9964c6e94cb6cbc2cb 100644 (file)
@@ -48,10 +48,13 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size);
 
 /* Architecture __weak replacement functions */
 void __init mem_encrypt_init(void);
+void __init mem_encrypt_free_decrypted_mem(void);
 
 bool sme_active(void);
 bool sev_active(void);
 
+#define __bss_decrypted __attribute__((__section__(".bss..decrypted")))
+
 #else  /* !CONFIG_AMD_MEM_ENCRYPT */
 
 #define sme_me_mask    0ULL
@@ -77,6 +80,8 @@ early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0;
 static inline int __init
 early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; }
 
+#define __bss_decrypted
+
 #endif /* CONFIG_AMD_MEM_ENCRYPT */
 
 /*
@@ -88,6 +93,8 @@ early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0;
 #define __sme_pa(x)            (__pa(x) | sme_me_mask)
 #define __sme_pa_nodebug(x)    (__pa_nodebug(x) | sme_me_mask)
 
+extern char __start_bss_decrypted[], __end_bss_decrypted[], __start_bss_decrypted_unused[];
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __X86_MEM_ENCRYPT_H__ */
index 24c6cf5f16b72eb536a9ee279b15e54f0d22af80..60d0f90153178b3fb104360536854d676f7429ee 100644 (file)
@@ -19,9 +19,6 @@ static inline void native_set_pte(pte_t *ptep , pte_t pte)
 
 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
-       pmd.pud.p4d.pgd = pti_set_user_pgtbl(&pmdp->pud.p4d.pgd, pmd.pud.p4d.pgd);
-#endif
        *pmdp = pmd;
 }
 
@@ -61,9 +58,6 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp)
 #ifdef CONFIG_SMP
 static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
 {
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
-       pti_set_user_pgtbl(&xp->pud.p4d.pgd, __pgd(0));
-#endif
        return __pmd(xchg((pmdval_t *)xp, 0));
 }
 #else
@@ -73,9 +67,6 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
 #ifdef CONFIG_SMP
 static inline pud_t native_pudp_get_and_clear(pud_t *xp)
 {
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
-       pti_set_user_pgtbl(&xp->p4d.pgd, __pgd(0));
-#endif
        return __pud(xchg((pudval_t *)xp, 0));
 }
 #else
index ce2b59047cb839053043508d75ea47f8a726c8b9..9c85b54bf03cad528c20e98df3bc31771b6e5e25 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <linux/bitops.h>
 #include <linux/threads.h>
+#include <asm/fixmap.h>
 
 extern p4d_t level4_kernel_pgt[512];
 extern p4d_t level4_ident_pgt[512];
@@ -22,7 +23,7 @@ extern pud_t level3_ident_pgt[512];
 extern pmd_t level2_kernel_pgt[512];
 extern pmd_t level2_fixmap_pgt[512];
 extern pmd_t level2_ident_pgt[512];
-extern pte_t level1_fixmap_pgt[512];
+extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM];
 extern pgd_t init_top_pgt[];
 
 #define swapper_pg_dir init_top_pgt
index 86299efa804adbfc35d3338f9fe75083e6cdf5af..fd23d5778ea17f04e4c1b178fbcb2ffb3718dec0 100644 (file)
@@ -377,6 +377,7 @@ struct kvm_sync_regs {
 
 #define KVM_X86_QUIRK_LINT0_REENABLED  (1 << 0)
 #define KVM_X86_QUIRK_CD_NW_CLEARED    (1 << 1)
+#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE  (1 << 2)
 
 #define KVM_STATE_NESTED_GUEST_MODE    0x00000001
 #define KVM_STATE_NESTED_RUN_PENDING   0x00000002
index ec00d1ff5098b3701b1f1af324be2576676b7786..f7151cd03cb08145a5c596d28c676abaf8e1f1bf 100644 (file)
@@ -1640,6 +1640,7 @@ static int do_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 static int proc_apm_show(struct seq_file *m, void *v)
 {
        unsigned short  bx;
@@ -1719,6 +1720,7 @@ static int proc_apm_show(struct seq_file *m, void *v)
                   units);
        return 0;
 }
+#endif
 
 static int apm(void *unused)
 {
index 4e588f36228f8731b08dffc501288700f481cafe..285eb3ec4200e5377d8462eb87ecd4a943341f6b 100644 (file)
@@ -382,6 +382,11 @@ static inline bool is_mbm_event(int e)
                e <= QOS_L3_MBM_LOCAL_EVENT_ID);
 }
 
+struct rdt_parse_data {
+       struct rdtgroup         *rdtgrp;
+       char                    *buf;
+};
+
 /**
  * struct rdt_resource - attributes of an RDT resource
  * @rid:               The index of the resource
@@ -423,16 +428,19 @@ struct rdt_resource {
        struct rdt_cache        cache;
        struct rdt_membw        membw;
        const char              *format_str;
-       int (*parse_ctrlval)    (void *data, struct rdt_resource *r,
-                                struct rdt_domain *d);
+       int (*parse_ctrlval)(struct rdt_parse_data *data,
+                            struct rdt_resource *r,
+                            struct rdt_domain *d);
        struct list_head        evt_list;
        int                     num_rmid;
        unsigned int            mon_scale;
        unsigned long           fflags;
 };
 
-int parse_cbm(void *_data, struct rdt_resource *r, struct rdt_domain *d);
-int parse_bw(void *_buf, struct rdt_resource *r,  struct rdt_domain *d);
+int parse_cbm(struct rdt_parse_data *data, struct rdt_resource *r,
+             struct rdt_domain *d);
+int parse_bw(struct rdt_parse_data *data, struct rdt_resource *r,
+            struct rdt_domain *d);
 
 extern struct mutex rdtgroup_mutex;
 
@@ -536,6 +544,7 @@ int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp);
 void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp);
 struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r);
 int update_domains(struct rdt_resource *r, int closid);
+int closids_supported(void);
 void closid_free(int closid);
 int alloc_rmid(void);
 void free_rmid(u32 rmid);
index af358ca0516057c8fa7945272867afd737125654..0f53049719cd670f3b31a444863f5af378645b7d 100644 (file)
@@ -64,19 +64,19 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
        return true;
 }
 
-int parse_bw(void *_buf, struct rdt_resource *r, struct rdt_domain *d)
+int parse_bw(struct rdt_parse_data *data, struct rdt_resource *r,
+            struct rdt_domain *d)
 {
-       unsigned long data;
-       char *buf = _buf;
+       unsigned long bw_val;
 
        if (d->have_new_ctrl) {
                rdt_last_cmd_printf("duplicate domain %d\n", d->id);
                return -EINVAL;
        }
 
-       if (!bw_validate(buf, &data, r))
+       if (!bw_validate(data->buf, &bw_val, r))
                return -EINVAL;
-       d->new_ctrl = data;
+       d->new_ctrl = bw_val;
        d->have_new_ctrl = true;
 
        return 0;
@@ -123,18 +123,13 @@ static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)
        return true;
 }
 
-struct rdt_cbm_parse_data {
-       struct rdtgroup         *rdtgrp;
-       char                    *buf;
-};
-
 /*
  * Read one cache bit mask (hex). Check that it is valid for the current
  * resource type.
  */
-int parse_cbm(void *_data, struct rdt_resource *r, struct rdt_domain *d)
+int parse_cbm(struct rdt_parse_data *data, struct rdt_resource *r,
+             struct rdt_domain *d)
 {
-       struct rdt_cbm_parse_data *data = _data;
        struct rdtgroup *rdtgrp = data->rdtgrp;
        u32 cbm_val;
 
@@ -195,11 +190,17 @@ int parse_cbm(void *_data, struct rdt_resource *r, struct rdt_domain *d)
 static int parse_line(char *line, struct rdt_resource *r,
                      struct rdtgroup *rdtgrp)
 {
-       struct rdt_cbm_parse_data data;
+       struct rdt_parse_data data;
        char *dom = NULL, *id;
        struct rdt_domain *d;
        unsigned long dom_id;
 
+       if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP &&
+           r->rid == RDT_RESOURCE_MBA) {
+               rdt_last_cmd_puts("Cannot pseudo-lock MBA resource\n");
+               return -EINVAL;
+       }
+
 next:
        if (!line || line[0] == '\0')
                return 0;
index b799c00bef09a50f3b6127111bc269dbd075a99c..1b8e86a5d5e11ef3f0742a512fd652086c0fcf6f 100644 (file)
@@ -97,6 +97,12 @@ void rdt_last_cmd_printf(const char *fmt, ...)
  *   limited as the number of resources grows.
  */
 static int closid_free_map;
+static int closid_free_map_len;
+
+int closids_supported(void)
+{
+       return closid_free_map_len;
+}
 
 static void closid_init(void)
 {
@@ -111,6 +117,7 @@ static void closid_init(void)
 
        /* CLOSID 0 is always reserved for the default group */
        closid_free_map &= ~1;
+       closid_free_map_len = rdt_min_closid;
 }
 
 static int closid_alloc(void)
@@ -802,7 +809,7 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
                sw_shareable = 0;
                exclusive = 0;
                seq_printf(seq, "%d=", dom->id);
-               for (i = 0; i < r->num_closid; i++, ctrl++) {
+               for (i = 0; i < closids_supported(); i++, ctrl++) {
                        if (!closid_allocated(i))
                                continue;
                        mode = rdtgroup_mode_by_closid(i);
@@ -989,7 +996,7 @@ bool rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_domain *d,
 
        /* Check for overlap with other resource groups */
        ctrl = d->ctrl_val;
-       for (i = 0; i < r->num_closid; i++, ctrl++) {
+       for (i = 0; i < closids_supported(); i++, ctrl++) {
                ctrl_b = (unsigned long *)ctrl;
                mode = rdtgroup_mode_by_closid(i);
                if (closid_allocated(i) && i != closid &&
@@ -1024,16 +1031,27 @@ static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
 {
        int closid = rdtgrp->closid;
        struct rdt_resource *r;
+       bool has_cache = false;
        struct rdt_domain *d;
 
        for_each_alloc_enabled_rdt_resource(r) {
+               if (r->rid == RDT_RESOURCE_MBA)
+                       continue;
+               has_cache = true;
                list_for_each_entry(d, &r->domains, list) {
                        if (rdtgroup_cbm_overlaps(r, d, d->ctrl_val[closid],
-                                                 rdtgrp->closid, false))
+                                                 rdtgrp->closid, false)) {
+                               rdt_last_cmd_puts("schemata overlaps\n");
                                return false;
+                       }
                }
        }
 
+       if (!has_cache) {
+               rdt_last_cmd_puts("cannot be exclusive without CAT/CDP\n");
+               return false;
+       }
+
        return true;
 }
 
@@ -1085,7 +1103,6 @@ static ssize_t rdtgroup_mode_write(struct kernfs_open_file *of,
                rdtgrp->mode = RDT_MODE_SHAREABLE;
        } else if (!strcmp(buf, "exclusive")) {
                if (!rdtgroup_mode_test_exclusive(rdtgrp)) {
-                       rdt_last_cmd_printf("schemata overlaps\n");
                        ret = -EINVAL;
                        goto out;
                }
@@ -1155,8 +1172,8 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
        struct rdt_resource *r;
        struct rdt_domain *d;
        unsigned int size;
-       bool sep = false;
-       u32 cbm;
+       bool sep;
+       u32 ctrl;
 
        rdtgrp = rdtgroup_kn_lock_live(of->kn);
        if (!rdtgrp) {
@@ -1174,6 +1191,7 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
        }
 
        for_each_alloc_enabled_rdt_resource(r) {
+               sep = false;
                seq_printf(s, "%*s:", max_name_width, r->name);
                list_for_each_entry(d, &r->domains, list) {
                        if (sep)
@@ -1181,8 +1199,13 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
                        if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
                                size = 0;
                        } else {
-                               cbm = d->ctrl_val[rdtgrp->closid];
-                               size = rdtgroup_cbm_to_size(r, d, cbm);
+                               ctrl = (!is_mba_sc(r) ?
+                                               d->ctrl_val[rdtgrp->closid] :
+                                               d->mbps_val[rdtgrp->closid]);
+                               if (r->rid == RDT_RESOURCE_MBA)
+                                       size = ctrl;
+                               else
+                                       size = rdtgroup_cbm_to_size(r, d, ctrl);
                        }
                        seq_printf(s, "%d=%u", d->id, size);
                        sep = true;
@@ -2336,12 +2359,18 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
        u32 *ctrl;
 
        for_each_alloc_enabled_rdt_resource(r) {
+               /*
+                * Only initialize default allocations for CBM cache
+                * resources
+                */
+               if (r->rid == RDT_RESOURCE_MBA)
+                       continue;
                list_for_each_entry(d, &r->domains, list) {
                        d->have_new_ctrl = false;
                        d->new_ctrl = r->cache.shareable_bits;
                        used_b = r->cache.shareable_bits;
                        ctrl = d->ctrl_val;
-                       for (i = 0; i < r->num_closid; i++, ctrl++) {
+                       for (i = 0; i < closids_supported(); i++, ctrl++) {
                                if (closid_allocated(i) && i != closid) {
                                        mode = rdtgroup_mode_by_closid(i);
                                        if (mode == RDT_MODE_PSEUDO_LOCKSETUP)
@@ -2373,6 +2402,12 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
        }
 
        for_each_alloc_enabled_rdt_resource(r) {
+               /*
+                * Only initialize default allocations for CBM cache
+                * resources
+                */
+               if (r->rid == RDT_RESOURCE_MBA)
+                       continue;
                ret = update_domains(r, rdtgrp->closid);
                if (ret < 0) {
                        rdt_last_cmd_puts("failed to initialize allocations\n");
index f260e452e4f8726237618efe4b9526938d31d81d..e8c8c5d78dbdd38b1089f5dc87cf3450644fe487 100644 (file)
@@ -7,11 +7,17 @@
 #include <linux/eisa.h>
 #include <linux/io.h>
 
+#include <xen/xen.h>
+
 static __init int eisa_bus_probe(void)
 {
-       void __iomem *p = ioremap(0x0FFFD9, 4);
+       void __iomem *p;
+
+       if (xen_pv_domain() && !xen_initial_domain())
+               return 0;
 
-       if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
+       p = ioremap(0x0FFFD9, 4);
+       if (p && readl(p) == 'E' + ('I' << 8) + ('S' << 16) + ('A' << 24))
                EISA_bus = 1;
        iounmap(p);
        return 0;
index 8047379e575ad39cb47cdbb055131e9bb094bb4d..ddee1f0870c4b091cae110f35d92a2d87a05d8b6 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/bootparam_utils.h>
 #include <asm/microcode.h>
 #include <asm/kasan.h>
+#include <asm/fixmap.h>
 
 /*
  * Manage page tables very early on.
@@ -112,6 +113,7 @@ static bool __head check_la57_support(unsigned long physaddr)
 unsigned long __head __startup_64(unsigned long physaddr,
                                  struct boot_params *bp)
 {
+       unsigned long vaddr, vaddr_end;
        unsigned long load_delta, *p;
        unsigned long pgtable_flags;
        pgdval_t *pgd;
@@ -165,7 +167,8 @@ unsigned long __head __startup_64(unsigned long physaddr,
        pud[511] += load_delta;
 
        pmd = fixup_pointer(level2_fixmap_pgt, physaddr);
-       pmd[506] += load_delta;
+       for (i = FIXMAP_PMD_TOP; i > FIXMAP_PMD_TOP - FIXMAP_PMD_NUM; i--)
+               pmd[i] += load_delta;
 
        /*
         * Set up the identity mapping for the switchover.  These
@@ -234,6 +237,21 @@ unsigned long __head __startup_64(unsigned long physaddr,
        /* Encrypt the kernel and related (if SME is active) */
        sme_encrypt_kernel(bp);
 
+       /*
+        * Clear the memory encryption mask from the .bss..decrypted section.
+        * The bss section will be memset to zero later in the initialization so
+        * there is no need to zero it after changing the memory encryption
+        * attribute.
+        */
+       if (mem_encrypt_active()) {
+               vaddr = (unsigned long)__start_bss_decrypted;
+               vaddr_end = (unsigned long)__end_bss_decrypted;
+               for (; vaddr < vaddr_end; vaddr += PMD_SIZE) {
+                       i = pmd_index(vaddr);
+                       pmd[i] -= sme_get_me_mask();
+               }
+       }
+
        /*
         * Return the SME encryption mask (if SME is active) to be used as a
         * modifier for the initial pgdir entry programmed into CR3.
index 15ebc2fc166e66c954106ce7c7db3d73d377adae..a3618cf04cf627c9ce54b592f2580646e18deda1 100644 (file)
@@ -24,6 +24,7 @@
 #include "../entry/calling.h"
 #include <asm/export.h>
 #include <asm/nospec-branch.h>
+#include <asm/fixmap.h>
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/asm-offsets.h>
@@ -445,13 +446,20 @@ NEXT_PAGE(level2_kernel_pgt)
                KERNEL_IMAGE_SIZE/PMD_SIZE)
 
 NEXT_PAGE(level2_fixmap_pgt)
-       .fill   506,8,0
-       .quad   level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
-       /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
-       .fill   5,8,0
+       .fill   (512 - 4 - FIXMAP_PMD_NUM),8,0
+       pgtno = 0
+       .rept (FIXMAP_PMD_NUM)
+       .quad level1_fixmap_pgt + (pgtno << PAGE_SHIFT) - __START_KERNEL_map \
+               + _PAGE_TABLE_NOENC;
+       pgtno = pgtno + 1
+       .endr
+       /* 6 MB reserved space + a 2MB hole */
+       .fill   4,8,0
 
 NEXT_PAGE(level1_fixmap_pgt)
+       .rept (FIXMAP_PMD_NUM)
        .fill   512,8,0
+       .endr
 
 #undef PMDS
 
index 1e6764648af3ed9d49c0714002587031b2555563..013fe3d21dbb3f4d5f834f74e0ca3d791a6f0b06 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/sched/clock.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/set_memory.h>
 
 #include <asm/hypervisor.h>
 #include <asm/mem_encrypt.h>
@@ -61,9 +62,10 @@ early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall);
        (PAGE_SIZE / sizeof(struct pvclock_vsyscall_time_info))
 
 static struct pvclock_vsyscall_time_info
-                       hv_clock_boot[HVC_BOOT_ARRAY_SIZE] __aligned(PAGE_SIZE);
-static struct pvclock_wall_clock wall_clock;
+                       hv_clock_boot[HVC_BOOT_ARRAY_SIZE] __bss_decrypted __aligned(PAGE_SIZE);
+static struct pvclock_wall_clock wall_clock __bss_decrypted;
 static DEFINE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu);
+static struct pvclock_vsyscall_time_info *hvclock_mem;
 
 static inline struct pvclock_vcpu_time_info *this_cpu_pvti(void)
 {
@@ -236,6 +238,45 @@ static void kvm_shutdown(void)
        native_machine_shutdown();
 }
 
+static void __init kvmclock_init_mem(void)
+{
+       unsigned long ncpus;
+       unsigned int order;
+       struct page *p;
+       int r;
+
+       if (HVC_BOOT_ARRAY_SIZE >= num_possible_cpus())
+               return;
+
+       ncpus = num_possible_cpus() - HVC_BOOT_ARRAY_SIZE;
+       order = get_order(ncpus * sizeof(*hvclock_mem));
+
+       p = alloc_pages(GFP_KERNEL, order);
+       if (!p) {
+               pr_warn("%s: failed to alloc %d pages", __func__, (1U << order));
+               return;
+       }
+
+       hvclock_mem = page_address(p);
+
+       /*
+        * hvclock is shared between the guest and the hypervisor, must
+        * be mapped decrypted.
+        */
+       if (sev_active()) {
+               r = set_memory_decrypted((unsigned long) hvclock_mem,
+                                        1UL << order);
+               if (r) {
+                       __free_pages(p, order);
+                       hvclock_mem = NULL;
+                       pr_warn("kvmclock: set_memory_decrypted() failed. Disabling\n");
+                       return;
+               }
+       }
+
+       memset(hvclock_mem, 0, PAGE_SIZE << order);
+}
+
 static int __init kvm_setup_vsyscall_timeinfo(void)
 {
 #ifdef CONFIG_X86_64
@@ -250,6 +291,9 @@ static int __init kvm_setup_vsyscall_timeinfo(void)
 
        kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK;
 #endif
+
+       kvmclock_init_mem();
+
        return 0;
 }
 early_initcall(kvm_setup_vsyscall_timeinfo);
@@ -269,8 +313,10 @@ static int kvmclock_setup_percpu(unsigned int cpu)
        /* Use the static page for the first CPUs, allocate otherwise */
        if (cpu < HVC_BOOT_ARRAY_SIZE)
                p = &hv_clock_boot[cpu];
+       else if (hvclock_mem)
+               p = hvclock_mem + cpu - HVC_BOOT_ARRAY_SIZE;
        else
-               p = kzalloc(sizeof(*p), GFP_KERNEL);
+               return -ENOMEM;
 
        per_cpu(hv_clock_per_cpu, cpu) = p;
        return p ? 0 : -ENOMEM;
index afdb303285f874d481c7de2fbe7fd9f80873a424..8dc69d82567e1ab1aecd09421c92df1cbd7329dd 100644 (file)
@@ -91,7 +91,7 @@ unsigned paravirt_patch_call(void *insnbuf,
 
        if (len < 5) {
 #ifdef CONFIG_RETPOLINE
-               WARN_ONCE("Failing to patch indirect CALL in %ps\n", (void *)addr);
+               WARN_ONCE(1, "Failing to patch indirect CALL in %ps\n", (void *)addr);
 #endif
                return len;     /* call too long for patch site */
        }
@@ -111,7 +111,7 @@ unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
 
        if (len < 5) {
 #ifdef CONFIG_RETPOLINE
-               WARN_ONCE("Failing to patch indirect JMP in %ps\n", (void *)addr);
+               WARN_ONCE(1, "Failing to patch indirect JMP in %ps\n", (void *)addr);
 #endif
                return len;     /* call too long for patch site */
        }
index 12cbe2b88c0f3cb14754e6bce2d058b5d0bb63a7..738bf42b0218f54bf08e46eb1eb5159fd8686e44 100644 (file)
@@ -111,8 +111,10 @@ int arch_register_cpu(int num)
        /*
         * Currently CPU0 is only hotpluggable on Intel platforms. Other
         * vendors can add hotplug support later.
+        * Xen PV guests don't support CPU0 hotplug at all.
         */
-       if (c->x86_vendor != X86_VENDOR_INTEL)
+       if (c->x86_vendor != X86_VENDOR_INTEL ||
+           boot_cpu_has(X86_FEATURE_XENPV))
                cpu0_hotpluggable = 0;
 
        /*
index 8bde0a419f8689620db0a34cc9df0eaa135132c6..5dd3317d761f4065b0fc8f7cdcac4e08be600f0e 100644 (file)
@@ -65,6 +65,23 @@ jiffies_64 = jiffies;
 #define ALIGN_ENTRY_TEXT_BEGIN . = ALIGN(PMD_SIZE);
 #define ALIGN_ENTRY_TEXT_END   . = ALIGN(PMD_SIZE);
 
+/*
+ * This section contains data which will be mapped as decrypted. Memory
+ * encryption operates on a page basis. Make this section PMD-aligned
+ * to avoid splitting the pages while mapping the section early.
+ *
+ * Note: We use a separate section so that only this section gets
+ * decrypted to avoid exposing more than we wish.
+ */
+#define BSS_DECRYPTED                                          \
+       . = ALIGN(PMD_SIZE);                                    \
+       __start_bss_decrypted = .;                              \
+       *(.bss..decrypted);                                     \
+       . = ALIGN(PAGE_SIZE);                                   \
+       __start_bss_decrypted_unused = .;                       \
+       . = ALIGN(PMD_SIZE);                                    \
+       __end_bss_decrypted = .;                                \
+
 #else
 
 #define X86_ALIGN_RODATA_BEGIN
@@ -74,6 +91,7 @@ jiffies_64 = jiffies;
 
 #define ALIGN_ENTRY_TEXT_BEGIN
 #define ALIGN_ENTRY_TEXT_END
+#define BSS_DECRYPTED
 
 #endif
 
@@ -355,6 +373,7 @@ SECTIONS
                __bss_start = .;
                *(.bss..page_aligned)
                *(.bss)
+               BSS_DECRYPTED
                . = ALIGN(PAGE_SIZE);
                __bss_stop = .;
        }
index 17c0472c5b344faaaac3153ff53c4600a3fcd81e..fbb0e6df121b2f3d8c3a4d89c43e8cac3ca694e8 100644 (file)
@@ -1344,9 +1344,8 @@ EXPORT_SYMBOL_GPL(kvm_lapic_reg_read);
 
 static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
 {
-       return kvm_apic_hw_enabled(apic) &&
-           addr >= apic->base_address &&
-           addr < apic->base_address + LAPIC_MMIO_LENGTH;
+       return addr >= apic->base_address &&
+               addr < apic->base_address + LAPIC_MMIO_LENGTH;
 }
 
 static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
@@ -1358,6 +1357,15 @@ static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
        if (!apic_mmio_in_range(apic, address))
                return -EOPNOTSUPP;
 
+       if (!kvm_apic_hw_enabled(apic) || apic_x2apic_mode(apic)) {
+               if (!kvm_check_has_quirk(vcpu->kvm,
+                                        KVM_X86_QUIRK_LAPIC_MMIO_HOLE))
+                       return -EOPNOTSUPP;
+
+               memset(data, 0xff, len);
+               return 0;
+       }
+
        kvm_lapic_reg_read(apic, offset, len, data);
 
        return 0;
@@ -1917,6 +1925,14 @@ static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
        if (!apic_mmio_in_range(apic, address))
                return -EOPNOTSUPP;
 
+       if (!kvm_apic_hw_enabled(apic) || apic_x2apic_mode(apic)) {
+               if (!kvm_check_has_quirk(vcpu->kvm,
+                                        KVM_X86_QUIRK_LAPIC_MMIO_HOLE))
+                       return -EOPNOTSUPP;
+
+               return 0;
+       }
+
        /*
         * APIC register must be aligned on 128-bits boundary.
         * 32/64/128 bits registers must be accessed thru 32 bits.
index e24ea7067373af69d258c46995007b0446a69fdc..d7e9bce6ff61c74d3d36fe6c9d4981e7136e0405 100644 (file)
@@ -899,7 +899,7 @@ static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu)
 {
        /*
         * Make sure the write to vcpu->mode is not reordered in front of
-        * reads to sptes.  If it does, kvm_commit_zap_page() can see us
+        * reads to sptes.  If it does, kvm_mmu_commit_zap_page() can see us
         * OUTSIDE_GUEST_MODE and proceed to free the shadow page table.
         */
        smp_store_release(&vcpu->mode, OUTSIDE_GUEST_MODE);
@@ -5417,7 +5417,12 @@ void kvm_mmu_setup(struct kvm_vcpu *vcpu)
 {
        MMU_WARN_ON(VALID_PAGE(vcpu->arch.mmu.root_hpa));
 
-       kvm_init_mmu(vcpu, true);
+       /*
+        * kvm_mmu_setup() is called only on vCPU initialization.  
+        * Therefore, no need to reset mmu roots as they are not yet
+        * initialized.
+        */
+       kvm_init_mmu(vcpu, false);
 }
 
 static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm,
index 89c4c5aa15f16c71af5404f302a627313a61fd96..d96092b35936991c839ef5d66a5f58561ebdc149 100644 (file)
@@ -1226,8 +1226,7 @@ static __init int sev_hardware_setup(void)
        min_sev_asid = cpuid_edx(0x8000001F);
 
        /* Initialize SEV ASID bitmap */
-       sev_asid_bitmap = kcalloc(BITS_TO_LONGS(max_sev_asid),
-                               sizeof(unsigned long), GFP_KERNEL);
+       sev_asid_bitmap = bitmap_zalloc(max_sev_asid, GFP_KERNEL);
        if (!sev_asid_bitmap)
                return 1;
 
@@ -1405,7 +1404,7 @@ static __exit void svm_hardware_unsetup(void)
        int cpu;
 
        if (svm_sev_enabled())
-               kfree(sev_asid_bitmap);
+               bitmap_free(sev_asid_bitmap);
 
        for_each_possible_cpu(cpu)
                svm_cpu_uninit(cpu);
@@ -7149,6 +7148,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .check_intercept = svm_check_intercept,
        .handle_external_intr = svm_handle_external_intr,
 
+       .request_immediate_exit = __kvm_request_immediate_exit,
+
        .sched_in = svm_sched_in,
 
        .pmu_ops = &amd_pmu_ops,
index 533a327372c876df0b1c2b99ea3558e2aaa92df4..06412ba46aa36eaca6cd1f111a6b8df6d795d969 100644 (file)
@@ -397,6 +397,7 @@ struct loaded_vmcs {
        int cpu;
        bool launched;
        bool nmi_known_unmasked;
+       bool hv_timer_armed;
        /* Support for vnmi-less CPUs */
        int soft_vnmi_blocked;
        ktime_t entry_time;
@@ -1019,6 +1020,8 @@ struct vcpu_vmx {
        int ple_window;
        bool ple_window_dirty;
 
+       bool req_immediate_exit;
+
        /* Support for PML */
 #define PML_ENTITY_NUM         512
        struct page *pml_pg;
@@ -2864,6 +2867,8 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
        u16 fs_sel, gs_sel;
        int i;
 
+       vmx->req_immediate_exit = false;
+
        if (vmx->loaded_cpu_state)
                return;
 
@@ -5393,9 +5398,10 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
                 * To use VMXON (and later other VMX instructions), a guest
                 * must first be able to turn on cr4.VMXE (see handle_vmon()).
                 * So basically the check on whether to allow nested VMX
-                * is here.
+                * is here.  We operate under the default treatment of SMM,
+                * so VMX cannot be enabled under SMM.
                 */
-               if (!nested_vmx_allowed(vcpu))
+               if (!nested_vmx_allowed(vcpu) || is_smm(vcpu))
                        return 1;
        }
 
@@ -6183,6 +6189,27 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
        nested_mark_vmcs12_pages_dirty(vcpu);
 }
 
+static bool vmx_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       void *vapic_page;
+       u32 vppr;
+       int rvi;
+
+       if (WARN_ON_ONCE(!is_guest_mode(vcpu)) ||
+               !nested_cpu_has_vid(get_vmcs12(vcpu)) ||
+               WARN_ON_ONCE(!vmx->nested.virtual_apic_page))
+               return false;
+
+       rvi = vmcs_read16(GUEST_INTR_STATUS) & 0xff;
+
+       vapic_page = kmap(vmx->nested.virtual_apic_page);
+       vppr = *((u32 *)(vapic_page + APIC_PROCPRI));
+       kunmap(vmx->nested.virtual_apic_page);
+
+       return ((rvi & 0xf0) > (vppr & 0xf0));
+}
+
 static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
                                                     bool nested)
 {
@@ -7966,6 +7993,9 @@ static __init int hardware_setup(void)
                kvm_x86_ops->enable_log_dirty_pt_masked = NULL;
        }
 
+       if (!cpu_has_vmx_preemption_timer())
+               kvm_x86_ops->request_immediate_exit = __kvm_request_immediate_exit;
+
        if (cpu_has_vmx_preemption_timer() && enable_preemption_timer) {
                u64 vmx_msr;
 
@@ -9208,7 +9238,8 @@ static int handle_pml_full(struct kvm_vcpu *vcpu)
 
 static int handle_preemption_timer(struct kvm_vcpu *vcpu)
 {
-       kvm_lapic_expired_hv_timer(vcpu);
+       if (!to_vmx(vcpu)->req_immediate_exit)
+               kvm_lapic_expired_hv_timer(vcpu);
        return 1;
 }
 
@@ -10595,24 +10626,43 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
                                        msrs[i].host, false);
 }
 
-static void vmx_arm_hv_timer(struct kvm_vcpu *vcpu)
+static void vmx_arm_hv_timer(struct vcpu_vmx *vmx, u32 val)
+{
+       vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, val);
+       if (!vmx->loaded_vmcs->hv_timer_armed)
+               vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
+                             PIN_BASED_VMX_PREEMPTION_TIMER);
+       vmx->loaded_vmcs->hv_timer_armed = true;
+}
+
+static void vmx_update_hv_timer(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        u64 tscl;
        u32 delta_tsc;
 
-       if (vmx->hv_deadline_tsc == -1)
+       if (vmx->req_immediate_exit) {
+               vmx_arm_hv_timer(vmx, 0);
                return;
+       }
 
-       tscl = rdtsc();
-       if (vmx->hv_deadline_tsc > tscl)
-               /* sure to be 32 bit only because checked on set_hv_timer */
-               delta_tsc = (u32)((vmx->hv_deadline_tsc - tscl) >>
-                       cpu_preemption_timer_multi);
-       else
-               delta_tsc = 0;
+       if (vmx->hv_deadline_tsc != -1) {
+               tscl = rdtsc();
+               if (vmx->hv_deadline_tsc > tscl)
+                       /* set_hv_timer ensures the delta fits in 32-bits */
+                       delta_tsc = (u32)((vmx->hv_deadline_tsc - tscl) >>
+                               cpu_preemption_timer_multi);
+               else
+                       delta_tsc = 0;
 
-       vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, delta_tsc);
+               vmx_arm_hv_timer(vmx, delta_tsc);
+               return;
+       }
+
+       if (vmx->loaded_vmcs->hv_timer_armed)
+               vmcs_clear_bits(PIN_BASED_VM_EXEC_CONTROL,
+                               PIN_BASED_VMX_PREEMPTION_TIMER);
+       vmx->loaded_vmcs->hv_timer_armed = false;
 }
 
 static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
@@ -10672,7 +10722,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
 
        atomic_switch_perf_msrs(vmx);
 
-       vmx_arm_hv_timer(vcpu);
+       vmx_update_hv_timer(vcpu);
 
        /*
         * If this vCPU has touched SPEC_CTRL, restore the guest's value if
@@ -11427,16 +11477,18 @@ static void vmx_start_preemption_timer(struct kvm_vcpu *vcpu)
        u64 preemption_timeout = get_vmcs12(vcpu)->vmx_preemption_timer_value;
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
-       if (vcpu->arch.virtual_tsc_khz == 0)
-               return;
-
-       /* Make sure short timeouts reliably trigger an immediate vmexit.
-        * hrtimer_start does not guarantee this. */
-       if (preemption_timeout <= 1) {
+       /*
+        * A timer value of zero is architecturally guaranteed to cause
+        * a VMExit prior to executing any instructions in the guest.
+        */
+       if (preemption_timeout == 0) {
                vmx_preemption_timer_fn(&vmx->nested.preemption_timer);
                return;
        }
 
+       if (vcpu->arch.virtual_tsc_khz == 0)
+               return;
+
        preemption_timeout <<= VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE;
        preemption_timeout *= 1000000;
        do_div(preemption_timeout, vcpu->arch.virtual_tsc_khz);
@@ -11646,11 +11698,15 @@ static int nested_vmx_check_apicv_controls(struct kvm_vcpu *vcpu,
         * bits 15:8 should be zero in posted_intr_nv,
         * the descriptor address has been already checked
         * in nested_get_vmcs12_pages.
+        *
+        * bits 5:0 of posted_intr_desc_addr should be zero.
         */
        if (nested_cpu_has_posted_intr(vmcs12) &&
           (!nested_cpu_has_vid(vmcs12) ||
            !nested_exit_intr_ack_set(vcpu) ||
-           vmcs12->posted_intr_nv & 0xff00))
+           (vmcs12->posted_intr_nv & 0xff00) ||
+           (vmcs12->posted_intr_desc_addr & 0x3f) ||
+           (!page_address_valid(vcpu, vmcs12->posted_intr_desc_addr))))
                return -EINVAL;
 
        /* tpr shadow is needed by all apicv features. */
@@ -12076,11 +12132,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
 
        exec_control = vmcs12->pin_based_vm_exec_control;
 
-       /* Preemption timer setting is only taken from vmcs01.  */
-       exec_control &= ~PIN_BASED_VMX_PREEMPTION_TIMER;
+       /* Preemption timer setting is computed directly in vmx_vcpu_run.  */
        exec_control |= vmcs_config.pin_based_exec_ctrl;
-       if (vmx->hv_deadline_tsc == -1)
-               exec_control &= ~PIN_BASED_VMX_PREEMPTION_TIMER;
+       exec_control &= ~PIN_BASED_VMX_PREEMPTION_TIMER;
+       vmx->loaded_vmcs->hv_timer_armed = false;
 
        /* Posted interrupts setting is only taken from vmcs12.  */
        if (nested_cpu_has_posted_intr(vmcs12)) {
@@ -12318,6 +12373,9 @@ static int check_vmentry_prereqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
            vmcs12->guest_activity_state != GUEST_ACTIVITY_HLT)
                return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
 
+       if (nested_cpu_has_vpid(vmcs12) && !vmcs12->virtual_processor_id)
+               return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
+
        if (nested_vmx_check_io_bitmap_controls(vcpu, vmcs12))
                return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
 
@@ -12863,6 +12921,11 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
        return 0;
 }
 
+static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu)
+{
+       to_vmx(vcpu)->req_immediate_exit = true;
+}
+
 static u32 vmx_get_preemption_timer_value(struct kvm_vcpu *vcpu)
 {
        ktime_t remaining =
@@ -13253,12 +13316,7 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
        vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, vmx->msr_autoload.host.nr);
        vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, vmx->msr_autoload.guest.nr);
        vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
-       if (vmx->hv_deadline_tsc == -1)
-               vmcs_clear_bits(PIN_BASED_VM_EXEC_CONTROL,
-                               PIN_BASED_VMX_PREEMPTION_TIMER);
-       else
-               vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
-                             PIN_BASED_VMX_PREEMPTION_TIMER);
+
        if (kvm_has_tsc_control)
                decache_tsc_multiplier(vmx);
 
@@ -13462,18 +13520,12 @@ static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc)
                return -ERANGE;
 
        vmx->hv_deadline_tsc = tscl + delta_tsc;
-       vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
-                       PIN_BASED_VMX_PREEMPTION_TIMER);
-
        return delta_tsc == 0;
 }
 
 static void vmx_cancel_hv_timer(struct kvm_vcpu *vcpu)
 {
-       struct vcpu_vmx *vmx = to_vmx(vcpu);
-       vmx->hv_deadline_tsc = -1;
-       vmcs_clear_bits(PIN_BASED_VM_EXEC_CONTROL,
-                       PIN_BASED_VMX_PREEMPTION_TIMER);
+       to_vmx(vcpu)->hv_deadline_tsc = -1;
 }
 #endif
 
@@ -13954,6 +14006,14 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
            ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON))
                return -EINVAL;
 
+       /*
+        * SMM temporarily disables VMX, so we cannot be in guest mode,
+        * nor can VMLAUNCH/VMRESUME be pending.  Outside SMM, SMM flags
+        * must be zero.
+        */
+       if (is_smm(vcpu) ? kvm_state->flags : kvm_state->vmx.smm.flags)
+               return -EINVAL;
+
        if ((kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) &&
            !(kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON))
                return -EINVAL;
@@ -14097,6 +14157,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .apicv_post_state_restore = vmx_apicv_post_state_restore,
        .hwapic_irr_update = vmx_hwapic_irr_update,
        .hwapic_isr_update = vmx_hwapic_isr_update,
+       .guest_apic_has_interrupt = vmx_guest_apic_has_interrupt,
        .sync_pir_to_irr = vmx_sync_pir_to_irr,
        .deliver_posted_interrupt = vmx_deliver_posted_interrupt,
 
@@ -14130,6 +14191,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .umip_emulated = vmx_umip_emulated,
 
        .check_nested_events = vmx_check_nested_events,
+       .request_immediate_exit = vmx_request_immediate_exit,
 
        .sched_in = vmx_sched_in,
 
index 542f6315444d75aa365ca04dba4bddd7bfb369d3..edbf00ec56b34f7765551280e2872b28d1cb0740 100644 (file)
@@ -628,7 +628,7 @@ bool pdptrs_changed(struct kvm_vcpu *vcpu)
        gfn_t gfn;
        int r;
 
-       if (is_long_mode(vcpu) || !is_pae(vcpu))
+       if (is_long_mode(vcpu) || !is_pae(vcpu) || !is_paging(vcpu))
                return false;
 
        if (!test_bit(VCPU_EXREG_PDPTR,
@@ -2537,7 +2537,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_PLATFORM_INFO:
                if (!msr_info->host_initiated ||
-                   data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
                    (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
                     cpuid_fault_enabled(vcpu)))
                        return 1;
@@ -2780,6 +2779,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                msr_info->data = vcpu->arch.osvw.status;
                break;
        case MSR_PLATFORM_INFO:
+               if (!msr_info->host_initiated &&
+                   !vcpu->kvm->arch.guest_can_read_msr_platform_info)
+                       return 1;
                msr_info->data = vcpu->arch.msr_platform_info;
                break;
        case MSR_MISC_FEATURES_ENABLES:
@@ -2927,6 +2929,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_SPLIT_IRQCHIP:
        case KVM_CAP_IMMEDIATE_EXIT:
        case KVM_CAP_GET_MSR_FEATURES:
+       case KVM_CAP_MSR_PLATFORM_INFO:
                r = 1;
                break;
        case KVM_CAP_SYNC_REGS:
@@ -4007,19 +4010,23 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                        break;
 
                BUILD_BUG_ON(sizeof(user_data_size) != sizeof(user_kvm_nested_state->size));
+               r = -EFAULT;
                if (get_user(user_data_size, &user_kvm_nested_state->size))
-                       return -EFAULT;
+                       break;
 
                r = kvm_x86_ops->get_nested_state(vcpu, user_kvm_nested_state,
                                                  user_data_size);
                if (r < 0)
-                       return r;
+                       break;
 
                if (r > user_data_size) {
                        if (put_user(r, &user_kvm_nested_state->size))
-                               return -EFAULT;
-                       return -E2BIG;
+                               r = -EFAULT;
+                       else
+                               r = -E2BIG;
+                       break;
                }
+
                r = 0;
                break;
        }
@@ -4031,19 +4038,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                if (!kvm_x86_ops->set_nested_state)
                        break;
 
+               r = -EFAULT;
                if (copy_from_user(&kvm_state, user_kvm_nested_state, sizeof(kvm_state)))
-                       return -EFAULT;
+                       break;
 
+               r = -EINVAL;
                if (kvm_state.size < sizeof(kvm_state))
-                       return -EINVAL;
+                       break;
 
                if (kvm_state.flags &
                    ~(KVM_STATE_NESTED_RUN_PENDING | KVM_STATE_NESTED_GUEST_MODE))
-                       return -EINVAL;
+                       break;
 
                /* nested_run_pending implies guest_mode.  */
                if (kvm_state.flags == KVM_STATE_NESTED_RUN_PENDING)
-                       return -EINVAL;
+                       break;
 
                r = kvm_x86_ops->set_nested_state(vcpu, user_kvm_nested_state, &kvm_state);
                break;
@@ -4350,6 +4359,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
                        kvm->arch.pause_in_guest = true;
                r = 0;
                break;
+       case KVM_CAP_MSR_PLATFORM_INFO:
+               kvm->arch.guest_can_read_msr_platform_info = cap->args[0];
+               r = 0;
+               break;
        default:
                r = -EINVAL;
                break;
@@ -7361,6 +7374,12 @@ void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_reload_apic_access_page);
 
+void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
+{
+       smp_send_reschedule(vcpu->cpu);
+}
+EXPORT_SYMBOL_GPL(__kvm_request_immediate_exit);
+
 /*
  * Returns 1 to let vcpu_run() continue the guest execution loop without
  * exiting to the userspace.  Otherwise, the value will be returned to the
@@ -7565,7 +7584,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 
        if (req_immediate_exit) {
                kvm_make_request(KVM_REQ_EVENT, vcpu);
-               smp_send_reschedule(vcpu->cpu);
+               kvm_x86_ops->request_immediate_exit(vcpu);
        }
 
        trace_kvm_entry(vcpu->vcpu_id);
@@ -7829,6 +7848,29 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
        return 0;
 }
 
+/* Swap (qemu) user FPU context for the guest FPU context. */
+static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
+{
+       preempt_disable();
+       copy_fpregs_to_fpstate(&vcpu->arch.user_fpu);
+       /* PKRU is separately restored in kvm_x86_ops->run.  */
+       __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state,
+                               ~XFEATURE_MASK_PKRU);
+       preempt_enable();
+       trace_kvm_fpu(1);
+}
+
+/* When vcpu_run ends, restore user space FPU context. */
+static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
+{
+       preempt_disable();
+       copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu);
+       copy_kernel_to_fpregs(&vcpu->arch.user_fpu.state);
+       preempt_enable();
+       ++vcpu->stat.fpu_reload;
+       trace_kvm_fpu(0);
+}
+
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
        int r;
@@ -8177,7 +8219,7 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
                kvm_update_cpuid(vcpu);
 
        idx = srcu_read_lock(&vcpu->kvm->srcu);
-       if (!is_long_mode(vcpu) && is_pae(vcpu)) {
+       if (!is_long_mode(vcpu) && is_pae(vcpu) && is_paging(vcpu)) {
                load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu));
                mmu_reset_needed = 1;
        }
@@ -8406,29 +8448,6 @@ static void fx_init(struct kvm_vcpu *vcpu)
        vcpu->arch.cr0 |= X86_CR0_ET;
 }
 
-/* Swap (qemu) user FPU context for the guest FPU context. */
-void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
-{
-       preempt_disable();
-       copy_fpregs_to_fpstate(&vcpu->arch.user_fpu);
-       /* PKRU is separately restored in kvm_x86_ops->run.  */
-       __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state,
-                               ~XFEATURE_MASK_PKRU);
-       preempt_enable();
-       trace_kvm_fpu(1);
-}
-
-/* When vcpu_run ends, restore user space FPU context. */
-void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
-{
-       preempt_disable();
-       copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu);
-       copy_kernel_to_fpregs(&vcpu->arch.user_fpu.state);
-       preempt_enable();
-       ++vcpu->stat.fpu_reload;
-       trace_kvm_fpu(0);
-}
-
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 {
        void *wbinvd_dirty_mask = vcpu->arch.wbinvd_dirty_mask;
@@ -8852,6 +8871,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        kvm->arch.kvmclock_offset = -ktime_get_boot_ns();
        pvclock_update_vm_gtod_copy(kvm);
 
+       kvm->arch.guest_can_read_msr_platform_info = true;
+
        INIT_DELAYED_WORK(&kvm->arch.kvmclock_update_work, kvmclock_update_fn);
        INIT_DELAYED_WORK(&kvm->arch.kvmclock_sync_work, kvmclock_sync_fn);
 
@@ -9200,6 +9221,13 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
        kvm_page_track_flush_slot(kvm, slot);
 }
 
+static inline bool kvm_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
+{
+       return (is_guest_mode(vcpu) &&
+                       kvm_x86_ops->guest_apic_has_interrupt &&
+                       kvm_x86_ops->guest_apic_has_interrupt(vcpu));
+}
+
 static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
 {
        if (!list_empty_careful(&vcpu->async_pf.done))
@@ -9224,7 +9252,8 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
                return true;
 
        if (kvm_arch_interrupt_allowed(vcpu) &&
-           kvm_cpu_has_interrupt(vcpu))
+           (kvm_cpu_has_interrupt(vcpu) ||
+           kvm_guest_apic_has_interrupt(vcpu)))
                return true;
 
        if (kvm_hv_has_stimer_pending(vcpu))
index 7a8fc26c11155edac84372e2af7133e0bea07c36..faca978ebf9d8b46b6437f908b9ae506d3489da2 100644 (file)
@@ -815,10 +815,14 @@ void free_kernel_image_pages(void *begin, void *end)
                set_memory_np_noalias(begin_ul, len_pages);
 }
 
+void __weak mem_encrypt_free_decrypted_mem(void) { }
+
 void __ref free_initmem(void)
 {
        e820__reallocate_tables();
 
+       mem_encrypt_free_decrypted_mem();
+
        free_kernel_image_pages(&__init_begin, &__init_end);
 }
 
index b2de398d1fd3380003860215a22686cde5bdcada..006f373f54aba1c06f352886034a894216abb082 100644 (file)
@@ -348,6 +348,30 @@ bool sev_active(void)
 EXPORT_SYMBOL(sev_active);
 
 /* Architecture __weak replacement functions */
+void __init mem_encrypt_free_decrypted_mem(void)
+{
+       unsigned long vaddr, vaddr_end, npages;
+       int r;
+
+       vaddr = (unsigned long)__start_bss_decrypted_unused;
+       vaddr_end = (unsigned long)__end_bss_decrypted;
+       npages = (vaddr_end - vaddr) >> PAGE_SHIFT;
+
+       /*
+        * The unused memory range was mapped decrypted, change the encryption
+        * attribute from decrypted to encrypted before freeing it.
+        */
+       if (mem_encrypt_active()) {
+               r = set_memory_encrypted(vaddr, npages);
+               if (r) {
+                       pr_warn("failed to free unused decrypted pages\n");
+                       return;
+               }
+       }
+
+       free_init_pages("unused decrypted", vaddr, vaddr_end);
+}
+
 void __init mem_encrypt_init(void)
 {
        if (!sme_me_mask)
index ae394552fb945def068d2c877a153e9d7f040228..089e78c4effd1fce3a9d7fdd886cddb88aadd281 100644 (file)
@@ -637,6 +637,15 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
 {
        unsigned long address = __fix_to_virt(idx);
 
+#ifdef CONFIG_X86_64
+       /*
+       * Ensure that the static initial page tables are covering the
+       * fixmap completely.
+       */
+       BUILD_BUG_ON(__end_of_permanent_fixed_addresses >
+                    (FIXMAP_PMD_NUM * PTRS_PER_PTE));
+#endif
+
        if (idx >= __end_of_fixed_addresses) {
                BUG();
                return;
index 05ca1422246336c6d3c923c22f06ad87113ac1d3..9959657127f476ae3018894ffc31909ee2c6d79e 100644 (file)
@@ -85,10 +85,9 @@ pgd_t * __init efi_call_phys_prolog(void)
 
 void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
+       load_fixmap_gdt(0);
        load_cr3(save_pgd);
        __flush_tlb_all();
-
-       load_fixmap_gdt(0);
 }
 
 void __init efi_runtime_update_mappings(void)
index 2fe5c9b1816bbd5e6f0adcc9385bcdf09b173154..dd461c0167ef026e466fd99f3815c4c71c65c16f 100644 (file)
@@ -1907,7 +1907,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
        /* L3_k[511] -> level2_fixmap_pgt */
        convert_pfn_mfn(level3_kernel_pgt);
 
-       /* L3_k[511][506] -> level1_fixmap_pgt */
+       /* L3_k[511][508-FIXMAP_PMD_NUM ... 507] -> level1_fixmap_pgt */
        convert_pfn_mfn(level2_fixmap_pgt);
 
        /* We get [511][511] and have Xen's version of level2_kernel_pgt */
@@ -1952,7 +1952,11 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
        set_page_prot(level2_ident_pgt, PAGE_KERNEL_RO);
        set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
        set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
-       set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
+
+       for (i = 0; i < FIXMAP_PMD_NUM; i++) {
+               set_page_prot(level1_fixmap_pgt + i * PTRS_PER_PTE,
+                             PAGE_KERNEL_RO);
+       }
 
        /* Pin down new L4 */
        pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
index 7d00d4ad44d44d62f9a6a089a2c8d4a649e6aa08..95997e6c06960073c75b713cb2be76ec74c0886c 100644 (file)
@@ -478,7 +478,7 @@ static void xen_convert_regs(const struct xen_pmu_regs *xen_regs,
 irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id)
 {
        int err, ret = IRQ_NONE;
-       struct pt_regs regs;
+       struct pt_regs regs = {0};
        const struct xen_pmu_data *xenpmu_data = get_xenpmu_data();
        uint8_t xenpmu_flags = get_xenpmu_flags();
 
index 04d038f3b6fab86fed6e458b136f8fc46c05feeb..b9ad83a0ee5dbf1604acc3c4edc90698e7eea1a6 100644 (file)
@@ -4,6 +4,7 @@ config ZONE_DMA
 
 config XTENSA
        def_bool y
+       select ARCH_HAS_SG_CHAIN
        select ARCH_HAS_SYNC_DMA_FOR_CPU
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_NO_COHERENT_DMA_MMAP if !MMU
index 295c120ed099d26f198b32342ba1bfb59f59075e..d67e30faff9c83b519702e15e1ea4ad70eed52d8 100644 (file)
@@ -64,11 +64,7 @@ endif
 vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y))
 plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y))
 
-ifeq ($(KBUILD_SRC),)
-KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(vardirs) $(plfdirs))
-else
 KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(vardirs) $(plfdirs))
-endif
 
 KBUILD_DEFCONFIG := iss_defconfig
 
index f4bbb28026f8be3006890fe236989db791c79e1d..58709e89a8ed1f41ed7acaad204d4d91e973386a 100644 (file)
@@ -78,23 +78,28 @@ static struct notifier_block iss_panic_block = {
 
 void __init platform_setup(char **p_cmdline)
 {
+       static void *argv[COMMAND_LINE_SIZE / sizeof(void *)] __initdata;
+       static char cmdline[COMMAND_LINE_SIZE] __initdata;
        int argc = simc_argc();
        int argv_size = simc_argv_size();
 
        if (argc > 1) {
-               void **argv = alloc_bootmem(argv_size);
-               char *cmdline = alloc_bootmem(argv_size);
-               int i;
+               if (argv_size > sizeof(argv)) {
+                       pr_err("%s: command line too long: argv_size = %d\n",
+                              __func__, argv_size);
+               } else {
+                       int i;
 
-               cmdline[0] = 0;
-               simc_argv((void *)argv);
+                       cmdline[0] = 0;
+                       simc_argv((void *)argv);
 
-               for (i = 1; i < argc; ++i) {
-                       if (i > 1)
-                               strcat(cmdline, " ");
-                       strcat(cmdline, argv[i]);
+                       for (i = 1; i < argc; ++i) {
+                               if (i > 1)
+                                       strcat(cmdline, " ");
+                               strcat(cmdline, argv[i]);
+                       }
+                       *p_cmdline = cmdline;
                }
-               *p_cmdline = cmdline;
        }
 
        atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
index 8c680a776171c8c1bc7dcbefee2d4b6bb9cc5ebc..0093bed81c0e85882066499dcd92c5e94bd8a35d 100644 (file)
@@ -1684,7 +1684,7 @@ void generic_end_io_acct(struct request_queue *q, int req_op,
        const int sgrp = op_stat_group(req_op);
        int cpu = part_stat_lock();
 
-       part_stat_add(cpu, part, ticks[sgrp], duration);
+       part_stat_add(cpu, part, nsecs[sgrp], jiffies_to_nsecs(duration));
        part_round_stats(q, cpu, part);
        part_dec_in_flight(q, part, op_is_write(req_op));
 
index c19f9078da1ed9b17295eb4fcce108b1d5658c93..c630e02836a80d7d406778208c659aebda8fcf06 100644 (file)
@@ -1510,8 +1510,10 @@ int blkcg_policy_register(struct blkcg_policy *pol)
        for (i = 0; i < BLKCG_MAX_POLS; i++)
                if (!blkcg_policy[i])
                        break;
-       if (i >= BLKCG_MAX_POLS)
+       if (i >= BLKCG_MAX_POLS) {
+               pr_warn("blkcg_policy_register: BLKCG_MAX_POLS too small\n");
                goto err_unlock;
+       }
 
        /* Make sure cpd/pd_alloc_fn and cpd/pd_free_fn in pairs */
        if ((!pol->cpd_alloc_fn ^ !pol->cpd_free_fn) ||
index 4dbc93f43b38231657ec2c97e836b5063a7265cf..cff0a60ee20066c2fc2d7c4fb2da0bc9ea7c50da 100644 (file)
@@ -2733,17 +2733,15 @@ void blk_account_io_done(struct request *req, u64 now)
         * containing request is enough.
         */
        if (blk_do_io_stat(req) && !(req->rq_flags & RQF_FLUSH_SEQ)) {
-               unsigned long duration;
                const int sgrp = op_stat_group(req_op(req));
                struct hd_struct *part;
                int cpu;
 
-               duration = nsecs_to_jiffies(now - req->start_time_ns);
                cpu = part_stat_lock();
                part = req->part;
 
                part_stat_inc(cpu, part, ios[sgrp]);
-               part_stat_add(cpu, part, ticks[sgrp], duration);
+               part_stat_add(cpu, part, nsecs[sgrp], now - req->start_time_ns);
                part_round_stats(req->q, cpu, part);
                part_dec_in_flight(req->q, part, rq_data_dir(req));
 
index 94e1ed667b6ea383a99f1cd76d6917af0d2a1ba6..41317c50a44628e9ef4930e9f17ad6d8297c9190 100644 (file)
@@ -322,16 +322,11 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
 
        /*
         * __blk_mq_update_nr_hw_queues will update the nr_hw_queues and
-        * queue_hw_ctx after freeze the queue. So we could use q_usage_counter
-        * to avoid race with it. __blk_mq_update_nr_hw_queues will users
-        * synchronize_rcu to ensure all of the users go out of the critical
-        * section below and see zeroed q_usage_counter.
+        * queue_hw_ctx after freeze the queue, so we use q_usage_counter
+        * to avoid race with it.
         */
-       rcu_read_lock();
-       if (percpu_ref_is_zero(&q->q_usage_counter)) {
-               rcu_read_unlock();
+       if (!percpu_ref_tryget(&q->q_usage_counter))
                return;
-       }
 
        queue_for_each_hw_ctx(q, hctx, i) {
                struct blk_mq_tags *tags = hctx->tags;
@@ -347,7 +342,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
                        bt_for_each(hctx, &tags->breserved_tags, fn, priv, true);
                bt_for_each(hctx, &tags->bitmap_tags, fn, priv, false);
        }
-       rcu_read_unlock();
+       blk_queue_exit(q);
 }
 
 static int bt_alloc(struct sbitmap_queue *bt, unsigned int depth,
index 85a1c1a59c72716ce2e31c280d7fd43d5c6e61e9..e3c39ea8e17b04b0787e53959cd4f68cb1a43f3d 100644 (file)
@@ -1628,7 +1628,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
                BUG_ON(!rq->q);
                if (rq->mq_ctx != this_ctx) {
                        if (this_ctx) {
-                               trace_block_unplug(this_q, depth, from_schedule);
+                               trace_block_unplug(this_q, depth, !from_schedule);
                                blk_mq_sched_insert_requests(this_q, this_ctx,
                                                                &ctx_list,
                                                                from_schedule);
@@ -1648,7 +1648,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
         * on 'ctx_list'. Do those.
         */
        if (this_ctx) {
-               trace_block_unplug(this_q, depth, from_schedule);
+               trace_block_unplug(this_q, depth, !from_schedule);
                blk_mq_sched_insert_requests(this_q, this_ctx, &ctx_list,
                                                from_schedule);
        }
index 6a06b5d040e5dd8ffab230a3f3ae74bfa6935233..fae58b2f906fc5e0352c3f3194780abe13369784 100644 (file)
@@ -609,7 +609,7 @@ void elv_drain_elevator(struct request_queue *q)
 
        while (e->type->ops.sq.elevator_dispatch_fn(q, 1))
                ;
-       if (q->nr_sorted && printed++ < 10) {
+       if (q->nr_sorted && !blk_queue_is_zoned(q) && printed++ < 10 ) {
                printk(KERN_ERR "%s: forced dispatching is broken "
                       "(nr_sorted=%u), please report this\n",
                       q->elevator->type->elevator_name, q->nr_sorted);
index 8cc719a37b32f0500f081b46e12b91635204e9da..be5bab20b2abf278fd7d7370c1a082de0928b1ed 100644 (file)
@@ -1343,18 +1343,18 @@ static int diskstats_show(struct seq_file *seqf, void *v)
                           part_stat_read(hd, ios[STAT_READ]),
                           part_stat_read(hd, merges[STAT_READ]),
                           part_stat_read(hd, sectors[STAT_READ]),
-                          jiffies_to_msecs(part_stat_read(hd, ticks[STAT_READ])),
+                          (unsigned int)part_stat_read_msecs(hd, STAT_READ),
                           part_stat_read(hd, ios[STAT_WRITE]),
                           part_stat_read(hd, merges[STAT_WRITE]),
                           part_stat_read(hd, sectors[STAT_WRITE]),
-                          jiffies_to_msecs(part_stat_read(hd, ticks[STAT_WRITE])),
+                          (unsigned int)part_stat_read_msecs(hd, STAT_WRITE),
                           inflight[0],
                           jiffies_to_msecs(part_stat_read(hd, io_ticks)),
                           jiffies_to_msecs(part_stat_read(hd, time_in_queue)),
                           part_stat_read(hd, ios[STAT_DISCARD]),
                           part_stat_read(hd, merges[STAT_DISCARD]),
                           part_stat_read(hd, sectors[STAT_DISCARD]),
-                          jiffies_to_msecs(part_stat_read(hd, ticks[STAT_DISCARD]))
+                          (unsigned int)part_stat_read_msecs(hd, STAT_DISCARD)
                        );
        }
        disk_part_iter_exit(&piter);
index 5a8975a1201c6b34a07db3f57f76c3f072fb0d9e..d3d14e81fb12dc3cc518852d5c7ca33054e42756 100644 (file)
@@ -136,18 +136,18 @@ ssize_t part_stat_show(struct device *dev,
                part_stat_read(p, ios[STAT_READ]),
                part_stat_read(p, merges[STAT_READ]),
                (unsigned long long)part_stat_read(p, sectors[STAT_READ]),
-               jiffies_to_msecs(part_stat_read(p, ticks[STAT_READ])),
+               (unsigned int)part_stat_read_msecs(p, STAT_READ),
                part_stat_read(p, ios[STAT_WRITE]),
                part_stat_read(p, merges[STAT_WRITE]),
                (unsigned long long)part_stat_read(p, sectors[STAT_WRITE]),
-               jiffies_to_msecs(part_stat_read(p, ticks[STAT_WRITE])),
+               (unsigned int)part_stat_read_msecs(p, STAT_WRITE),
                inflight[0],
                jiffies_to_msecs(part_stat_read(p, io_ticks)),
                jiffies_to_msecs(part_stat_read(p, time_in_queue)),
                part_stat_read(p, ios[STAT_DISCARD]),
                part_stat_read(p, merges[STAT_DISCARD]),
                (unsigned long long)part_stat_read(p, sectors[STAT_DISCARD]),
-               jiffies_to_msecs(part_stat_read(p, ticks[STAT_DISCARD])));
+               (unsigned int)part_stat_read_msecs(p, STAT_DISCARD));
 }
 
 ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
index 3f3b7b253445a1fb87dfefdfaae9ad744b82d50d..64fd96eada31f42e5677a72de837fafa2987165b 100644 (file)
@@ -332,6 +332,35 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
        return vma ? -ENOMEM : -ESRCH;
 }
 
+
+static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
+               struct vm_area_struct *vma)
+{
+       if (vma)
+               alloc->vma_vm_mm = vma->vm_mm;
+       /*
+        * If we see alloc->vma is not NULL, buffer data structures set up
+        * completely. Look at smp_rmb side binder_alloc_get_vma.
+        * We also want to guarantee new alloc->vma_vm_mm is always visible
+        * if alloc->vma is set.
+        */
+       smp_wmb();
+       alloc->vma = vma;
+}
+
+static inline struct vm_area_struct *binder_alloc_get_vma(
+               struct binder_alloc *alloc)
+{
+       struct vm_area_struct *vma = NULL;
+
+       if (alloc->vma) {
+               /* Look at description in binder_alloc_set_vma */
+               smp_rmb();
+               vma = alloc->vma;
+       }
+       return vma;
+}
+
 static struct binder_buffer *binder_alloc_new_buf_locked(
                                struct binder_alloc *alloc,
                                size_t data_size,
@@ -348,7 +377,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
        size_t size, data_offsets_size;
        int ret;
 
-       if (alloc->vma == NULL) {
+       if (!binder_alloc_get_vma(alloc)) {
                binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
                                   "%d: binder_alloc_buf, no vma\n",
                                   alloc->pid);
@@ -723,9 +752,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
        buffer->free = 1;
        binder_insert_free_buffer(alloc, buffer);
        alloc->free_async_space = alloc->buffer_size / 2;
-       barrier();
-       alloc->vma = vma;
-       alloc->vma_vm_mm = vma->vm_mm;
+       binder_alloc_set_vma(alloc, vma);
        mmgrab(alloc->vma_vm_mm);
 
        return 0;
@@ -754,10 +781,10 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
        int buffers, page_count;
        struct binder_buffer *buffer;
 
-       BUG_ON(alloc->vma);
-
        buffers = 0;
        mutex_lock(&alloc->mutex);
+       BUG_ON(alloc->vma);
+
        while ((n = rb_first(&alloc->allocated_buffers))) {
                buffer = rb_entry(n, struct binder_buffer, rb_node);
 
@@ -900,7 +927,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
  */
 void binder_alloc_vma_close(struct binder_alloc *alloc)
 {
-       WRITE_ONCE(alloc->vma, NULL);
+       binder_alloc_set_vma(alloc, NULL);
 }
 
 /**
@@ -935,7 +962,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
 
        index = page - alloc->pages;
        page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
-       vma = alloc->vma;
+       vma = binder_alloc_get_vma(alloc);
        if (vma) {
                if (!mmget_not_zero(alloc->vma_vm_mm))
                        goto err_mmget;
index 599e01bcdef22b7064853b30b31ad5f3e6a9b432..a9dd4ea7467df60912baca1fd7ebfeb91c9d2988 100644 (file)
@@ -5359,10 +5359,20 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
  */
 int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active)
 {
+       u64 done_mask, ap_qc_active = ap->qc_active;
        int nr_done = 0;
-       u64 done_mask;
 
-       done_mask = ap->qc_active ^ qc_active;
+       /*
+        * If the internal tag is set on ap->qc_active, then we care about
+        * bit0 on the passed in qc_active mask. Move that bit up to match
+        * the internal tag.
+        */
+       if (ap_qc_active & (1ULL << ATA_TAG_INTERNAL)) {
+               qc_active |= (qc_active & 0x01) << ATA_TAG_INTERNAL;
+               qc_active ^= qc_active & 0x01;
+       }
+
+       done_mask = ap_qc_active ^ qc_active;
 
        if (unlikely(done_mask & qc_active)) {
                ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n",
index 0943e7065e0eadbc1348b3bfdcf7aed15b495c62..b3c0498ee4331f4c2a47a72fb74bce9328b4486e 100644 (file)
@@ -209,21 +209,24 @@ static struct fw_priv *__lookup_fw_priv(const char *fw_name)
 static int alloc_lookup_fw_priv(const char *fw_name,
                                struct firmware_cache *fwc,
                                struct fw_priv **fw_priv, void *dbuf,
-                               size_t size)
+                               size_t size, enum fw_opt opt_flags)
 {
        struct fw_priv *tmp;
 
        spin_lock(&fwc->lock);
-       tmp = __lookup_fw_priv(fw_name);
-       if (tmp) {
-               kref_get(&tmp->ref);
-               spin_unlock(&fwc->lock);
-               *fw_priv = tmp;
-               pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n");
-               return 1;
+       if (!(opt_flags & FW_OPT_NOCACHE)) {
+               tmp = __lookup_fw_priv(fw_name);
+               if (tmp) {
+                       kref_get(&tmp->ref);
+                       spin_unlock(&fwc->lock);
+                       *fw_priv = tmp;
+                       pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n");
+                       return 1;
+               }
        }
+
        tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size);
-       if (tmp)
+       if (tmp && !(opt_flags & FW_OPT_NOCACHE))
                list_add(&tmp->list, &fwc->head);
        spin_unlock(&fwc->lock);
 
@@ -493,7 +496,8 @@ int assign_fw(struct firmware *fw, struct device *device,
  */
 static int
 _request_firmware_prepare(struct firmware **firmware_p, const char *name,
-                         struct device *device, void *dbuf, size_t size)
+                         struct device *device, void *dbuf, size_t size,
+                         enum fw_opt opt_flags)
 {
        struct firmware *firmware;
        struct fw_priv *fw_priv;
@@ -511,7 +515,8 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
                return 0; /* assigned */
        }
 
-       ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size);
+       ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size,
+                                 opt_flags);
 
        /*
         * bind with 'priv' now to avoid warning in failure path
@@ -571,7 +576,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
                goto out;
        }
 
-       ret = _request_firmware_prepare(&fw, name, device, buf, size);
+       ret = _request_firmware_prepare(&fw, name, device, buf, size,
+                                       opt_flags);
        if (ret <= 0) /* error or already assigned */
                goto out;
 
index 48f622728ce6a1a6006109b711b6d9077ce56cdf..f2b6f4da10341e77cc0280f48560405fecf8b85e 100644 (file)
@@ -3467,6 +3467,9 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
                                          (struct floppy_struct **)&outparam);
                if (ret)
                        return ret;
+               memcpy(&inparam.g, outparam,
+                               offsetof(struct floppy_struct, name));
+               outparam = &inparam.g;
                break;
        case FDMSGON:
                UDP->flags |= FTD_MSG;
index d81781f22dba0930d3e7bbf10b2a02e46704a982..34e0030f059281148043ccb70a2b9b2e64b4216b 100644 (file)
@@ -87,10 +87,10 @@ struct nullb {
 #ifdef CONFIG_BLK_DEV_ZONED
 int null_zone_init(struct nullb_device *dev);
 void null_zone_exit(struct nullb_device *dev);
-blk_status_t null_zone_report(struct nullb *nullb,
-                                           struct nullb_cmd *cmd);
-void null_zone_write(struct nullb_cmd *cmd);
-void null_zone_reset(struct nullb_cmd *cmd);
+blk_status_t null_zone_report(struct nullb *nullb, struct bio *bio);
+void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+                       unsigned int nr_sectors);
+void null_zone_reset(struct nullb_cmd *cmd, sector_t sector);
 #else
 static inline int null_zone_init(struct nullb_device *dev)
 {
@@ -98,11 +98,14 @@ static inline int null_zone_init(struct nullb_device *dev)
 }
 static inline void null_zone_exit(struct nullb_device *dev) {}
 static inline blk_status_t null_zone_report(struct nullb *nullb,
-                                           struct nullb_cmd *cmd)
+                                           struct bio *bio)
 {
        return BLK_STS_NOTSUPP;
 }
-static inline void null_zone_write(struct nullb_cmd *cmd) {}
-static inline void null_zone_reset(struct nullb_cmd *cmd) {}
+static inline void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+                                  unsigned int nr_sectors)
+{
+}
+static inline void null_zone_reset(struct nullb_cmd *cmd, sector_t sector) {}
 #endif /* CONFIG_BLK_DEV_ZONED */
 #endif /* __NULL_BLK_H */
index 6127e3ff7b4b343816baca729606511cb653d404..093b614d652445a337db00ea8beaded767073415 100644 (file)
@@ -1157,16 +1157,33 @@ static void null_restart_queue_async(struct nullb *nullb)
        }
 }
 
+static bool cmd_report_zone(struct nullb *nullb, struct nullb_cmd *cmd)
+{
+       struct nullb_device *dev = cmd->nq->dev;
+
+       if (dev->queue_mode == NULL_Q_BIO) {
+               if (bio_op(cmd->bio) == REQ_OP_ZONE_REPORT) {
+                       cmd->error = null_zone_report(nullb, cmd->bio);
+                       return true;
+               }
+       } else {
+               if (req_op(cmd->rq) == REQ_OP_ZONE_REPORT) {
+                       cmd->error = null_zone_report(nullb, cmd->rq->bio);
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static blk_status_t null_handle_cmd(struct nullb_cmd *cmd)
 {
        struct nullb_device *dev = cmd->nq->dev;
        struct nullb *nullb = dev->nullb;
        int err = 0;
 
-       if (req_op(cmd->rq) == REQ_OP_ZONE_REPORT) {
-               cmd->error = null_zone_report(nullb, cmd);
+       if (cmd_report_zone(nullb, cmd))
                goto out;
-       }
 
        if (test_bit(NULLB_DEV_FL_THROTTLED, &dev->flags)) {
                struct request *rq = cmd->rq;
@@ -1234,10 +1251,24 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd)
        cmd->error = errno_to_blk_status(err);
 
        if (!cmd->error && dev->zoned) {
-               if (req_op(cmd->rq) == REQ_OP_WRITE)
-                       null_zone_write(cmd);
-               else if (req_op(cmd->rq) == REQ_OP_ZONE_RESET)
-                       null_zone_reset(cmd);
+               sector_t sector;
+               unsigned int nr_sectors;
+               int op;
+
+               if (dev->queue_mode == NULL_Q_BIO) {
+                       op = bio_op(cmd->bio);
+                       sector = cmd->bio->bi_iter.bi_sector;
+                       nr_sectors = cmd->bio->bi_iter.bi_size >> 9;
+               } else {
+                       op = req_op(cmd->rq);
+                       sector = blk_rq_pos(cmd->rq);
+                       nr_sectors = blk_rq_sectors(cmd->rq);
+               }
+
+               if (op == REQ_OP_WRITE)
+                       null_zone_write(cmd, sector, nr_sectors);
+               else if (op == REQ_OP_ZONE_RESET)
+                       null_zone_reset(cmd, sector);
        }
 out:
        /* Complete IO by inline, softirq or timer */
index a979ca00d7be4327f636168ef044c5a82d849744..7c6b86d987002b73251a9725d71af5b281987c9f 100644 (file)
@@ -48,8 +48,8 @@ void null_zone_exit(struct nullb_device *dev)
        kvfree(dev->zones);
 }
 
-static void null_zone_fill_rq(struct nullb_device *dev, struct request *rq,
-                             unsigned int zno, unsigned int nr_zones)
+static void null_zone_fill_bio(struct nullb_device *dev, struct bio *bio,
+                              unsigned int zno, unsigned int nr_zones)
 {
        struct blk_zone_report_hdr *hdr = NULL;
        struct bio_vec bvec;
@@ -57,7 +57,7 @@ static void null_zone_fill_rq(struct nullb_device *dev, struct request *rq,
        void *addr;
        unsigned int zones_to_cpy;
 
-       bio_for_each_segment(bvec, rq->bio, iter) {
+       bio_for_each_segment(bvec, bio, iter) {
                addr = kmap_atomic(bvec.bv_page);
 
                zones_to_cpy = bvec.bv_len / sizeof(struct blk_zone);
@@ -84,29 +84,24 @@ static void null_zone_fill_rq(struct nullb_device *dev, struct request *rq,
        }
 }
 
-blk_status_t null_zone_report(struct nullb *nullb,
-                                    struct nullb_cmd *cmd)
+blk_status_t null_zone_report(struct nullb *nullb, struct bio *bio)
 {
        struct nullb_device *dev = nullb->dev;
-       struct request *rq = cmd->rq;
-       unsigned int zno = null_zone_no(dev, blk_rq_pos(rq));
+       unsigned int zno = null_zone_no(dev, bio->bi_iter.bi_sector);
        unsigned int nr_zones = dev->nr_zones - zno;
-       unsigned int max_zones = (blk_rq_bytes(rq) /
-                                       sizeof(struct blk_zone)) - 1;
+       unsigned int max_zones;
 
+       max_zones = (bio->bi_iter.bi_size / sizeof(struct blk_zone)) - 1;
        nr_zones = min_t(unsigned int, nr_zones, max_zones);
-
-       null_zone_fill_rq(nullb->dev, rq, zno, nr_zones);
+       null_zone_fill_bio(nullb->dev, bio, zno, nr_zones);
 
        return BLK_STS_OK;
 }
 
-void null_zone_write(struct nullb_cmd *cmd)
+void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+                    unsigned int nr_sectors)
 {
        struct nullb_device *dev = cmd->nq->dev;
-       struct request *rq = cmd->rq;
-       sector_t sector = blk_rq_pos(rq);
-       unsigned int rq_sectors = blk_rq_sectors(rq);
        unsigned int zno = null_zone_no(dev, sector);
        struct blk_zone *zone = &dev->zones[zno];
 
@@ -118,7 +113,7 @@ void null_zone_write(struct nullb_cmd *cmd)
        case BLK_ZONE_COND_EMPTY:
        case BLK_ZONE_COND_IMP_OPEN:
                /* Writes must be at the write pointer position */
-               if (blk_rq_pos(rq) != zone->wp) {
+               if (sector != zone->wp) {
                        cmd->error = BLK_STS_IOERR;
                        break;
                }
@@ -126,7 +121,7 @@ void null_zone_write(struct nullb_cmd *cmd)
                if (zone->cond == BLK_ZONE_COND_EMPTY)
                        zone->cond = BLK_ZONE_COND_IMP_OPEN;
 
-               zone->wp += rq_sectors;
+               zone->wp += nr_sectors;
                if (zone->wp == zone->start + zone->len)
                        zone->cond = BLK_ZONE_COND_FULL;
                break;
@@ -137,11 +132,10 @@ void null_zone_write(struct nullb_cmd *cmd)
        }
 }
 
-void null_zone_reset(struct nullb_cmd *cmd)
+void null_zone_reset(struct nullb_cmd *cmd, sector_t sector)
 {
        struct nullb_device *dev = cmd->nq->dev;
-       struct request *rq = cmd->rq;
-       unsigned int zno = null_zone_no(dev, blk_rq_pos(rq));
+       unsigned int zno = null_zone_no(dev, sector);
        struct blk_zone *zone = &dev->zones[zno];
 
        zone->cond = BLK_ZONE_COND_EMPTY;
index a71d817e900ddc07ff45d240f0ae290ff408b6cd..429d20131c7e228f81bcbd6dd72ed8a21290c14f 100644 (file)
@@ -2670,8 +2670,8 @@ static void purge_persistent_grants(struct blkfront_info *info)
                        list_del(&gnt_list_entry->node);
                        gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
                        rinfo->persistent_gnts_c--;
-                       __free_page(gnt_list_entry->page);
-                       kfree(gnt_list_entry);
+                       gnt_list_entry->gref = GRANT_INVALID_REF;
+                       list_add_tail(&gnt_list_entry->node, &rinfo->grants);
                }
 
                spin_unlock_irqrestore(&rinfo->ring_lock, flags);
index 963bb0309e25d34a44382bc3a8e9e0556cca72d1..ea6238ed5c0eaa095ada2c2b0f88aea27707dcbf 100644 (file)
@@ -543,6 +543,8 @@ static void hci_uart_tty_close(struct tty_struct *tty)
        }
        clear_bit(HCI_UART_PROTO_SET, &hu->flags);
 
+       percpu_free_rwsem(&hu->proto_lock);
+
        kfree(hu);
 }
 
index a3397664f80014b881387e1faa855a8102a0caa5..97d6856c9c0f98b3b7adf4ecd1d83805034c1e4b 100644 (file)
@@ -59,8 +59,6 @@ enum bt_states {
        BT_STATE_RESET3,
        BT_STATE_RESTART,
        BT_STATE_PRINTME,
-       BT_STATE_CAPABILITIES_BEGIN,
-       BT_STATE_CAPABILITIES_END,
        BT_STATE_LONG_BUSY      /* BT doesn't get hosed :-) */
 };
 
@@ -86,7 +84,6 @@ struct si_sm_data {
        int             error_retries;  /* end of "common" fields */
        int             nonzero_status; /* hung BMCs stay all 0 */
        enum bt_states  complete;       /* to divert the state machine */
-       int             BT_CAP_outreqs;
        long            BT_CAP_req2rsp;
        int             BT_CAP_retries; /* Recommended retries */
 };
@@ -137,8 +134,6 @@ static char *state2txt(unsigned char state)
        case BT_STATE_RESET3:           return("RESET3");
        case BT_STATE_RESTART:          return("RESTART");
        case BT_STATE_LONG_BUSY:        return("LONG_BUSY");
-       case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
-       case BT_STATE_CAPABILITIES_END: return("CAP_END");
        }
        return("BAD STATE");
 }
@@ -185,7 +180,6 @@ static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
        bt->complete = BT_STATE_IDLE;   /* end here */
        bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * USEC_PER_SEC;
        bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
-       /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
        return 3; /* We claim 3 bytes of space; ought to check SPMI table */
 }
 
@@ -451,7 +445,7 @@ static enum si_sm_result error_recovery(struct si_sm_data *bt,
 
 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
 {
-       unsigned char status, BT_CAP[8];
+       unsigned char status;
        static enum bt_states last_printed = BT_STATE_PRINTME;
        int i;
 
@@ -504,12 +498,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
                if (status & BT_H_BUSY)         /* clear a leftover H_BUSY */
                        BT_CONTROL(BT_H_BUSY);
 
-               bt->timeout = bt->BT_CAP_req2rsp;
-
-               /* Read BT capabilities if it hasn't been done yet */
-               if (!bt->BT_CAP_outreqs)
-                       BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
-                                       SI_SM_CALL_WITHOUT_DELAY);
                BT_SI_SM_RETURN(SI_SM_IDLE);
 
        case BT_STATE_XACTION_START:
@@ -614,37 +602,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
                BT_STATE_CHANGE(BT_STATE_XACTION_START,
                                SI_SM_CALL_WITH_DELAY);
 
-       /*
-        * Get BT Capabilities, using timing of upper level state machine.
-        * Set outreqs to prevent infinite loop on timeout.
-        */
-       case BT_STATE_CAPABILITIES_BEGIN:
-               bt->BT_CAP_outreqs = 1;
-               {
-                       unsigned char GetBT_CAP[] = { 0x18, 0x36 };
-                       bt->state = BT_STATE_IDLE;
-                       bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
-               }
-               bt->complete = BT_STATE_CAPABILITIES_END;
-               BT_STATE_CHANGE(BT_STATE_XACTION_START,
-                               SI_SM_CALL_WITH_DELAY);
-
-       case BT_STATE_CAPABILITIES_END:
-               i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
-               bt_init_data(bt, bt->io);
-               if ((i == 8) && !BT_CAP[2]) {
-                       bt->BT_CAP_outreqs = BT_CAP[3];
-                       bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC;
-                       bt->BT_CAP_retries = BT_CAP[7];
-               } else
-                       printk(KERN_WARNING "IPMI BT: using default values\n");
-               if (!bt->BT_CAP_outreqs)
-                       bt->BT_CAP_outreqs = 1;
-               printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
-                       bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries);
-               bt->timeout = bt->BT_CAP_req2rsp;
-               return SI_SM_CALL_WITHOUT_DELAY;
-
        default:        /* should never occur */
                return error_recovery(bt,
                                      status,
@@ -655,6 +612,11 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
 
 static int bt_detect(struct si_sm_data *bt)
 {
+       unsigned char GetBT_CAP[] = { 0x18, 0x36 };
+       unsigned char BT_CAP[8];
+       enum si_sm_result smi_result;
+       int rv;
+
        /*
         * It's impossible for the BT status and interrupt registers to be
         * all 1's, (assuming a properly functioning, self-initialized BMC)
@@ -665,6 +627,48 @@ static int bt_detect(struct si_sm_data *bt)
        if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
                return 1;
        reset_flags(bt);
+
+       /*
+        * Try getting the BT capabilities here.
+        */
+       rv = bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
+       if (rv) {
+               dev_warn(bt->io->dev,
+                        "Can't start capabilities transaction: %d\n", rv);
+               goto out_no_bt_cap;
+       }
+
+       smi_result = SI_SM_CALL_WITHOUT_DELAY;
+       for (;;) {
+               if (smi_result == SI_SM_CALL_WITH_DELAY ||
+                   smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
+                       schedule_timeout_uninterruptible(1);
+                       smi_result = bt_event(bt, jiffies_to_usecs(1));
+               } else if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
+                       smi_result = bt_event(bt, 0);
+               } else
+                       break;
+       }
+
+       rv = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
+       bt_init_data(bt, bt->io);
+       if (rv < 8) {
+               dev_warn(bt->io->dev, "bt cap response too short: %d\n", rv);
+               goto out_no_bt_cap;
+       }
+
+       if (BT_CAP[2]) {
+               dev_warn(bt->io->dev, "Error fetching bt cap: %x\n", BT_CAP[2]);
+out_no_bt_cap:
+               dev_warn(bt->io->dev, "using default values\n");
+       } else {
+               bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC;
+               bt->BT_CAP_retries = BT_CAP[7];
+       }
+
+       dev_info(bt->io->dev, "req2rsp=%ld secs retries=%d\n",
+                bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries);
+
        return 0;
 }
 
index 51832b8a2c6283f9b1ccfd07a60997fdade8d4cf..7fc9612070a1f1abe43b489f226c84a9c4c50632 100644 (file)
@@ -3381,39 +3381,45 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
 
        rv = handlers->start_processing(send_info, intf);
        if (rv)
-               goto out;
+               goto out_err;
 
        rv = __bmc_get_device_id(intf, NULL, &id, NULL, NULL, i);
        if (rv) {
                dev_err(si_dev, "Unable to get the device id: %d\n", rv);
-               goto out;
+               goto out_err_started;
        }
 
        mutex_lock(&intf->bmc_reg_mutex);
        rv = __scan_channels(intf, &id);
        mutex_unlock(&intf->bmc_reg_mutex);
+       if (rv)
+               goto out_err_bmc_reg;
 
- out:
-       if (rv) {
-               ipmi_bmc_unregister(intf);
-               list_del_rcu(&intf->link);
-               mutex_unlock(&ipmi_interfaces_mutex);
-               synchronize_srcu(&ipmi_interfaces_srcu);
-               cleanup_srcu_struct(&intf->users_srcu);
-               kref_put(&intf->refcount, intf_free);
-       } else {
-               /*
-                * Keep memory order straight for RCU readers.  Make
-                * sure everything else is committed to memory before
-                * setting intf_num to mark the interface valid.
-                */
-               smp_wmb();
-               intf->intf_num = i;
-               mutex_unlock(&ipmi_interfaces_mutex);
+       /*
+        * Keep memory order straight for RCU readers.  Make
+        * sure everything else is committed to memory before
+        * setting intf_num to mark the interface valid.
+        */
+       smp_wmb();
+       intf->intf_num = i;
+       mutex_unlock(&ipmi_interfaces_mutex);
 
-               /* After this point the interface is legal to use. */
-               call_smi_watchers(i, intf->si_dev);
-       }
+       /* After this point the interface is legal to use. */
+       call_smi_watchers(i, intf->si_dev);
+
+       return 0;
+
+ out_err_bmc_reg:
+       ipmi_bmc_unregister(intf);
+ out_err_started:
+       if (intf->handlers->shutdown)
+               intf->handlers->shutdown(intf->send_info);
+ out_err:
+       list_del_rcu(&intf->link);
+       mutex_unlock(&ipmi_interfaces_mutex);
+       synchronize_srcu(&ipmi_interfaces_srcu);
+       cleanup_srcu_struct(&intf->users_srcu);
+       kref_put(&intf->refcount, intf_free);
 
        return rv;
 }
@@ -3504,7 +3510,8 @@ void ipmi_unregister_smi(struct ipmi_smi *intf)
        }
        srcu_read_unlock(&intf->users_srcu, index);
 
-       intf->handlers->shutdown(intf->send_info);
+       if (intf->handlers->shutdown)
+               intf->handlers->shutdown(intf->send_info);
 
        cleanup_smi_msgs(intf);
 
index 90ec010bffbd9776c012586b4e01b24cdd0bd2d6..5faa917df1b629647cb7fecd291a1d1b8d80eae9 100644 (file)
@@ -2083,18 +2083,9 @@ static int try_smi_init(struct smi_info *new_smi)
                 si_to_str[new_smi->io.si_type]);
 
        WARN_ON(new_smi->io.dev->init_name != NULL);
-       kfree(init_name);
-
-       return 0;
-
-out_err:
-       if (new_smi->intf) {
-               ipmi_unregister_smi(new_smi->intf);
-               new_smi->intf = NULL;
-       }
 
+ out_err:
        kfree(init_name);
-
        return rv;
 }
 
@@ -2227,6 +2218,8 @@ static void shutdown_smi(void *send_info)
 
        kfree(smi_info->si_sm);
        smi_info->si_sm = NULL;
+
+       smi_info->intf = NULL;
 }
 
 /*
@@ -2240,10 +2233,8 @@ static void cleanup_one_si(struct smi_info *smi_info)
 
        list_del(&smi_info->link);
 
-       if (smi_info->intf) {
+       if (smi_info->intf)
                ipmi_unregister_smi(smi_info->intf);
-               smi_info->intf = NULL;
-       }
 
        if (smi_info->pdev) {
                if (smi_info->pdev_registered)
index 18e4650c233b1de514ee836dfc28021f35953a5b..29e67a80fb208f804e4ed1fb0a560142002c7ffc 100644 (file)
@@ -181,6 +181,8 @@ struct ssif_addr_info {
        struct device *dev;
        struct i2c_client *client;
 
+       struct i2c_client *added_client;
+
        struct mutex clients_mutex;
        struct list_head clients;
 
@@ -1214,18 +1216,11 @@ static void shutdown_ssif(void *send_info)
                complete(&ssif_info->wake_thread);
                kthread_stop(ssif_info->thread);
        }
-
-       /*
-        * No message can be outstanding now, we have removed the
-        * upper layer and it permitted us to do so.
-        */
-       kfree(ssif_info);
 }
 
 static int ssif_remove(struct i2c_client *client)
 {
        struct ssif_info *ssif_info = i2c_get_clientdata(client);
-       struct ipmi_smi *intf;
        struct ssif_addr_info *addr_info;
 
        if (!ssif_info)
@@ -1235,9 +1230,7 @@ static int ssif_remove(struct i2c_client *client)
         * After this point, we won't deliver anything asychronously
         * to the message handler.  We can unregister ourself.
         */
-       intf = ssif_info->intf;
-       ssif_info->intf = NULL;
-       ipmi_unregister_smi(intf);
+       ipmi_unregister_smi(ssif_info->intf);
 
        list_for_each_entry(addr_info, &ssif_infos, link) {
                if (addr_info->client == client) {
@@ -1246,6 +1239,8 @@ static int ssif_remove(struct i2c_client *client)
                }
        }
 
+       kfree(ssif_info);
+
        return 0;
 }
 
@@ -1648,15 +1643,9 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
  out:
        if (rv) {
-               /*
-                * Note that if addr_info->client is assigned, we
-                * leave it.  The i2c client hangs around even if we
-                * return a failure here, and the failure here is not
-                * propagated back to the i2c code.  This seems to be
-                * design intent, strange as it may be.  But if we
-                * don't leave it, ssif_platform_remove will not remove
-                * the client like it should.
-                */
+               if (addr_info)
+                       addr_info->client = NULL;
+
                dev_err(&client->dev, "Unable to start IPMI SSIF: %d\n", rv);
                kfree(ssif_info);
        }
@@ -1676,7 +1665,8 @@ static int ssif_adapter_handler(struct device *adev, void *opaque)
        if (adev->type != &i2c_adapter_type)
                return 0;
 
-       i2c_new_device(to_i2c_adapter(adev), &addr_info->binfo);
+       addr_info->added_client = i2c_new_device(to_i2c_adapter(adev),
+                                                &addr_info->binfo);
 
        if (!addr_info->adapter_name)
                return 1; /* Only try the first I2C adapter by default. */
@@ -1849,7 +1839,7 @@ static int ssif_platform_remove(struct platform_device *dev)
                return 0;
 
        mutex_lock(&ssif_infos_mutex);
-       i2c_unregister_device(addr_info->client);
+       i2c_unregister_device(addr_info->added_client);
 
        list_del(&addr_info->link);
        kfree(addr_info);
index bb882ab161fe1bbb4b678cc9bf105b77273296e3..e6124bd548df211317e7a69fa42da99849382e69 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "kcs_bmc.h"
 
+#define DEVICE_NAME "ipmi-kcs"
+
 #define KCS_MSG_BUFSIZ    1000
 
 #define KCS_ZERO_DATA     0
@@ -429,8 +431,6 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel)
        if (!kcs_bmc)
                return NULL;
 
-       dev_set_name(dev, "ipmi-kcs%u", channel);
-
        spin_lock_init(&kcs_bmc->lock);
        kcs_bmc->channel = channel;
 
@@ -444,7 +444,8 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel)
                return NULL;
 
        kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
-       kcs_bmc->miscdev.name = dev_name(dev);
+       kcs_bmc->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%u",
+                                              DEVICE_NAME, channel);
        kcs_bmc->miscdev.fops = &kcs_bmc_fops;
 
        return kcs_bmc;
index 08ef69945ffbf425efa001d48c6c9b5b0f4333eb..d977193842dfed1fead553dd2240013c5a0d380a 100644 (file)
@@ -55,6 +55,7 @@ struct clk_plt_data {
        u8 nparents;
        struct clk_plt *clks[PMC_CLK_NUM];
        struct clk_lookup *mclk_lookup;
+       struct clk_lookup *ether_clk_lookup;
 };
 
 /* Return an index in parent table */
@@ -186,13 +187,6 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
        pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
        spin_lock_init(&pclk->lock);
 
-       /*
-        * If the clock was already enabled by the firmware mark it as critical
-        * to avoid it being gated by the clock framework if no driver owns it.
-        */
-       if (plt_clk_is_enabled(&pclk->hw))
-               init.flags |= CLK_IS_CRITICAL;
-
        ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
        if (ret) {
                pclk = ERR_PTR(ret);
@@ -351,11 +345,20 @@ static int plt_clk_probe(struct platform_device *pdev)
                goto err_unreg_clk_plt;
        }
 
+       data->ether_clk_lookup = clkdev_hw_create(&data->clks[4]->hw,
+                                                 "ether_clk", NULL);
+       if (!data->ether_clk_lookup) {
+               err = -ENOMEM;
+               goto err_drop_mclk;
+       }
+
        plt_clk_free_parent_names_loop(parent_names, data->nparents);
 
        platform_set_drvdata(pdev, data);
        return 0;
 
+err_drop_mclk:
+       clkdev_drop(data->mclk_lookup);
 err_unreg_clk_plt:
        plt_clk_unregister_loop(data, i);
        plt_clk_unregister_parents(data);
@@ -369,6 +372,7 @@ static int plt_clk_remove(struct platform_device *pdev)
 
        data = platform_get_drvdata(pdev);
 
+       clkdev_drop(data->ether_clk_lookup);
        clkdev_drop(data->mclk_lookup);
        plt_clk_unregister_loop(data, PMC_CLK_NUM);
        plt_clk_unregister_parents(data);
index ec8a4376f74fb4f9da1f369a968df457064315e2..2fab18fae4fcbbeeb44cfbc4f2517258cd3dc505 100644 (file)
@@ -180,26 +180,29 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
        data->base = of_iomap(node, 0);
        if (!data->base) {
                pr_err("Could not map PIT address\n");
-               return -ENXIO;
+               ret = -ENXIO;
+               goto exit;
        }
 
        data->mck = of_clk_get(node, 0);
        if (IS_ERR(data->mck)) {
                pr_err("Unable to get mck clk\n");
-               return PTR_ERR(data->mck);
+               ret = PTR_ERR(data->mck);
+               goto exit;
        }
 
        ret = clk_prepare_enable(data->mck);
        if (ret) {
                pr_err("Unable to enable mck\n");
-               return ret;
+               goto exit;
        }
 
        /* Get the interrupts property */
        data->irq = irq_of_parse_and_map(node, 0);
        if (!data->irq) {
                pr_err("Unable to get IRQ from DT\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto exit;
        }
 
        /*
@@ -227,7 +230,7 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
        ret = clocksource_register_hz(&data->clksrc, pit_rate);
        if (ret) {
                pr_err("Failed to register clocksource\n");
-               return ret;
+               goto exit;
        }
 
        /* Set up irq handler */
@@ -236,7 +239,8 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
                          "at91_tick", data);
        if (ret) {
                pr_err("Unable to setup IRQ\n");
-               return ret;
+               clocksource_unregister(&data->clksrc);
+               goto exit;
        }
 
        /* Set up and register clockevents */
@@ -254,6 +258,10 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
        clockevents_register_device(&data->clkevt);
 
        return 0;
+
+exit:
+       kfree(data);
+       return ret;
 }
 TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
                       at91sam926x_pit_dt_init);
index c020038ebfab2242ed844a143f3ce6706985685c..cf93f6419b5142e397747be406138dacf3278a5c 100644 (file)
@@ -130,13 +130,17 @@ static int fttmr010_timer_set_next_event(unsigned long cycles,
        cr &= ~fttmr010->t1_enable_val;
        writel(cr, fttmr010->base + TIMER_CR);
 
-       /* Setup the match register forward/backward in time */
-       cr = readl(fttmr010->base + TIMER1_COUNT);
-       if (fttmr010->count_down)
-               cr -= cycles;
-       else
-               cr += cycles;
-       writel(cr, fttmr010->base + TIMER1_MATCH1);
+       if (fttmr010->count_down) {
+               /*
+                * ASPEED Timer Controller will load TIMER1_LOAD register
+                * into TIMER1_COUNT register when the timer is re-enabled.
+                */
+               writel(cycles, fttmr010->base + TIMER1_LOAD);
+       } else {
+               /* Setup the match register forward in time */
+               cr = readl(fttmr010->base + TIMER1_COUNT);
+               writel(cr + cycles, fttmr010->base + TIMER1_MATCH1);
+       }
 
        /* Start */
        cr = readl(fttmr010->base + TIMER_CR);
index 29e2e1a78a43372ee96e64bb9b93d6b21b5288f7..6949a9113dbb417aec69b444f365746220943e16 100644 (file)
@@ -97,6 +97,9 @@ static int __init ti_32k_timer_init(struct device_node *np)
                return -ENXIO;
        }
 
+       if (!of_machine_is_compatible("ti,am43"))
+               ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
+
        ti_32k_timer.counter = ti_32k_timer.base;
 
        /*
index a1830fa25fc5bd5eed0c627592c3a11c29e121da..2a3675c24032bc8059c4c591698d6a7b5218cf1d 100644 (file)
@@ -44,7 +44,7 @@ enum _msm8996_version {
 
 struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
 
-static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
+static enum _msm8996_version qcom_cpufreq_kryo_get_msm_id(void)
 {
        size_t len;
        u32 *msm_id;
@@ -222,7 +222,7 @@ static int __init qcom_cpufreq_kryo_init(void)
 }
 module_init(qcom_cpufreq_kryo_init);
 
-static void __init qcom_cpufreq_kryo_exit(void)
+static void __exit qcom_cpufreq_kryo_exit(void)
 {
        platform_device_unregister(kryo_cpufreq_pdev);
        platform_driver_unregister(&qcom_cpufreq_kryo_driver);
index 218739b961fe37b8c633443173d3026e19df0a69..72790d88236d4d73b56c5f1d26efcbfadc033c6b 100644 (file)
@@ -38,6 +38,17 @@ static DEFINE_MUTEX(sev_cmd_mutex);
 static struct sev_misc_dev *misc_dev;
 static struct psp_device *psp_master;
 
+static int psp_cmd_timeout = 100;
+module_param(psp_cmd_timeout, int, 0644);
+MODULE_PARM_DESC(psp_cmd_timeout, " default timeout value, in seconds, for PSP commands");
+
+static int psp_probe_timeout = 5;
+module_param(psp_probe_timeout, int, 0644);
+MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe");
+
+static bool psp_dead;
+static int psp_timeout;
+
 static struct psp_device *psp_alloc_struct(struct sp_device *sp)
 {
        struct device *dev = sp->dev;
@@ -82,10 +93,19 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
+static int sev_wait_cmd_ioc(struct psp_device *psp,
+                           unsigned int *reg, unsigned int timeout)
 {
-       wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
+       int ret;
+
+       ret = wait_event_timeout(psp->sev_int_queue,
+                       psp->sev_int_rcvd, timeout * HZ);
+       if (!ret)
+               return -ETIMEDOUT;
+
        *reg = ioread32(psp->io_regs + psp->vdata->cmdresp_reg);
+
+       return 0;
 }
 
 static int sev_cmd_buffer_len(int cmd)
@@ -133,12 +153,15 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
        if (!psp)
                return -ENODEV;
 
+       if (psp_dead)
+               return -EBUSY;
+
        /* Get the physical address of the command buffer */
        phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0;
        phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0;
 
-       dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x\n",
-               cmd, phys_msb, phys_lsb);
+       dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n",
+               cmd, phys_msb, phys_lsb, psp_timeout);
 
        print_hex_dump_debug("(in):  ", DUMP_PREFIX_OFFSET, 16, 2, data,
                             sev_cmd_buffer_len(cmd), false);
@@ -154,7 +177,18 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
        iowrite32(reg, psp->io_regs + psp->vdata->cmdresp_reg);
 
        /* wait for command completion */
-       sev_wait_cmd_ioc(psp, &reg);
+       ret = sev_wait_cmd_ioc(psp, &reg, psp_timeout);
+       if (ret) {
+               if (psp_ret)
+                       *psp_ret = 0;
+
+               dev_err(psp->dev, "sev command %#x timed out, disabling PSP \n", cmd);
+               psp_dead = true;
+
+               return ret;
+       }
+
+       psp_timeout = psp_cmd_timeout;
 
        if (psp_ret)
                *psp_ret = reg & PSP_CMDRESP_ERR_MASK;
@@ -888,6 +922,8 @@ void psp_pci_init(void)
 
        psp_master = sp->psp_data;
 
+       psp_timeout = psp_probe_timeout;
+
        if (sev_get_api_version())
                goto err;
 
index bbe4d72ca105b001e36b1d09d382ee9e3a89ee7c..948806e57cee33f74024adb442f398579319b89d 100644 (file)
@@ -535,6 +535,11 @@ static unsigned long dax_get_unmapped_area(struct file *filp,
        return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
 }
 
+static const struct address_space_operations dev_dax_aops = {
+       .set_page_dirty         = noop_set_page_dirty,
+       .invalidatepage         = noop_invalidatepage,
+};
+
 static int dax_open(struct inode *inode, struct file *filp)
 {
        struct dax_device *dax_dev = inode_dax(inode);
@@ -544,6 +549,7 @@ static int dax_open(struct inode *inode, struct file *filp)
        dev_dbg(&dev_dax->dev, "trace\n");
        inode->i_mapping = __dax_inode->i_mapping;
        inode->i_mapping->host = __dax_inode;
+       inode->i_mapping->a_ops = &dev_dax_aops;
        filp->f_mapping = inode->i_mapping;
        filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping);
        filp->private_data = dev_dax;
index b76cb17d879c635efbfec026da59a5c608ff0a6e..adfd316db1a892a5f0bbae831ae6569c8c2ba270 100644 (file)
@@ -639,7 +639,7 @@ static struct mic_dma_device *mic_dma_dev_reg(struct mbus_device *mbdev,
        int ret;
        struct device *dev = &mbdev->dev;
 
-       mic_dma_dev = kzalloc(sizeof(*mic_dma_dev), GFP_KERNEL);
+       mic_dma_dev = devm_kzalloc(dev, sizeof(*mic_dma_dev), GFP_KERNEL);
        if (!mic_dma_dev) {
                ret = -ENOMEM;
                goto alloc_error;
@@ -664,7 +664,6 @@ static struct mic_dma_device *mic_dma_dev_reg(struct mbus_device *mbdev,
 reg_error:
        mic_dma_uninit(mic_dma_dev);
 init_error:
-       kfree(mic_dma_dev);
        mic_dma_dev = NULL;
 alloc_error:
        dev_err(dev, "Error at %s %d ret=%d\n", __func__, __LINE__, ret);
@@ -674,7 +673,6 @@ static struct mic_dma_device *mic_dma_dev_reg(struct mbus_device *mbdev,
 static void mic_dma_dev_unreg(struct mic_dma_device *mic_dma_dev)
 {
        mic_dma_uninit(mic_dma_dev);
-       kfree(mic_dma_dev);
 }
 
 /* DEBUGFS CODE */
index d8e159feb573f1a6cdc171bc90b5948b72cc45bd..89110dfc7127c5f13d3b8fbdf29a10507d6f16d4 100644 (file)
@@ -90,14 +90,17 @@ config EFI_ARMSTUB
 config EFI_ARMSTUB_DTB_LOADER
        bool "Enable the DTB loader"
        depends on EFI_ARMSTUB
+       default y
        help
          Select this config option to add support for the dtb= command
          line parameter, allowing a device tree blob to be loaded into
          memory from the EFI System Partition by the stub.
 
-         The device tree is typically provided by the platform or by
-         the bootloader, so this option is mostly for development
-         purposes only.
+         If the device tree is provided by the platform or by
+         the bootloader this option may not be needed.
+         But, for various development reasons and to maintain existing
+         functionality for bootloaders that do not have such support
+         this option is necessary.
 
 config EFI_BOOTLOADER_CONTROL
        tristate "EFI Bootloader Control"
index fc9fd2d0482f4d8356f4ae8e1acfacdfdbfe3b65..0b840531ef33a2e1f387d15f550fb808df5ae8bf 100644 (file)
@@ -420,7 +420,7 @@ static int pr_mgmt_init(struct platform_device *pdev,
                /* Create region for each port */
                fme_region = dfl_fme_create_region(pdata, mgr,
                                                   fme_br->br, i);
-               if (!fme_region) {
+               if (IS_ERR(fme_region)) {
                        ret = PTR_ERR(fme_region);
                        goto destroy_region;
                }
index f8bbbb3a95043ebee9d5d02471b83e98fb923a0c..0c791e35acf02f3c71e17c77126ec1f9e97c6fe5 100644 (file)
@@ -272,7 +272,7 @@ void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd)
 
 int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
                        void **mem_obj, uint64_t *gpu_addr,
-                       void **cpu_ptr)
+                       void **cpu_ptr, bool mqd_gfx9)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct amdgpu_bo *bo = NULL;
@@ -287,6 +287,10 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
        bp.flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC;
        bp.type = ttm_bo_type_kernel;
        bp.resv = NULL;
+
+       if (mqd_gfx9)
+               bp.flags |= AMDGPU_GEM_CREATE_MQD_GFX9;
+
        r = amdgpu_bo_create(adev, &bp, &bo);
        if (r) {
                dev_err(adev->dev,
index 2f379c183ed20be8af61e839ebbd75b9890a8593..cc9aeab5468c8559b5b47fa56e452d6b2feb4d11 100644 (file)
@@ -136,7 +136,7 @@ void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd);
 /* Shared API */
 int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
                        void **mem_obj, uint64_t *gpu_addr,
-                       void **cpu_ptr);
+                       void **cpu_ptr, bool mqd_gfx9);
 void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj);
 void get_local_mem_info(struct kgd_dev *kgd,
                        struct kfd_local_mem_info *mem_info);
index ea3f698aef5eaec1353492b636c81eb2d2f84b78..9803b91f3e77d6bc6859f225eccbfc2b5d71598b 100644 (file)
@@ -685,7 +685,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
 
        while (true) {
                temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
-               if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT)
+               if (temp & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
                        break;
                if (time_after(jiffies, end_jiffies))
                        return -ETIME;
index 693ec5ea4950a8a76653df1085472078314def56..8816c697b2053c7c28f119f1362443d7b9ad6e98 100644 (file)
@@ -367,12 +367,14 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
                                break;
                        case CHIP_POLARIS10:
                                if (type == CGS_UCODE_ID_SMU) {
-                                       if ((adev->pdev->device == 0x67df) &&
-                                           ((adev->pdev->revision == 0xe0) ||
-                                            (adev->pdev->revision == 0xe3) ||
-                                            (adev->pdev->revision == 0xe4) ||
-                                            (adev->pdev->revision == 0xe5) ||
-                                            (adev->pdev->revision == 0xe7) ||
+                                       if (((adev->pdev->device == 0x67df) &&
+                                            ((adev->pdev->revision == 0xe0) ||
+                                             (adev->pdev->revision == 0xe3) ||
+                                             (adev->pdev->revision == 0xe4) ||
+                                             (adev->pdev->revision == 0xe5) ||
+                                             (adev->pdev->revision == 0xe7) ||
+                                             (adev->pdev->revision == 0xef))) ||
+                                           ((adev->pdev->device == 0x6fdf) &&
                                             (adev->pdev->revision == 0xef))) {
                                                info->is_kicker = true;
                                                strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
index b6e9df11115d358734d686af7b26a9eec0a6de64..b31d121a876bf32e64c51ad23ead9b08713f74bb 100644 (file)
@@ -39,6 +39,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
 {
        struct drm_gem_object *gobj;
        unsigned long size;
+       int r;
 
        gobj = drm_gem_object_lookup(p->filp, data->handle);
        if (gobj == NULL)
@@ -50,20 +51,26 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
        p->uf_entry.tv.shared = true;
        p->uf_entry.user_pages = NULL;
 
-       size = amdgpu_bo_size(p->uf_entry.robj);
-       if (size != PAGE_SIZE || (data->offset + 8) > size)
-               return -EINVAL;
-
-       *offset = data->offset;
-
        drm_gem_object_put_unlocked(gobj);
 
+       size = amdgpu_bo_size(p->uf_entry.robj);
+       if (size != PAGE_SIZE || (data->offset + 8) > size) {
+               r = -EINVAL;
+               goto error_unref;
+       }
+
        if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
-               amdgpu_bo_unref(&p->uf_entry.robj);
-               return -EINVAL;
+               r = -EINVAL;
+               goto error_unref;
        }
 
+       *offset = data->offset;
+
        return 0;
+
+error_unref:
+       amdgpu_bo_unref(&p->uf_entry.robj);
+       return r;
 }
 
 static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p,
@@ -1262,10 +1269,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 error_abort:
        dma_fence_put(&job->base.s_fence->finished);
        job->base.s_fence = NULL;
+       amdgpu_mn_unlock(p->mn);
 
 error_unlock:
        amdgpu_job_free(job);
-       amdgpu_mn_unlock(p->mn);
        return r;
 }
 
index 8ab5ccbc14ace34f6618452b01432bafd55cb5a3..39bf2ce548c61e2cabb2ad65aa9036d07f963093 100644 (file)
@@ -2063,6 +2063,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
        static enum amd_ip_block_type ip_order[] = {
                AMD_IP_BLOCK_TYPE_GMC,
                AMD_IP_BLOCK_TYPE_COMMON,
+               AMD_IP_BLOCK_TYPE_PSP,
                AMD_IP_BLOCK_TYPE_IH,
        };
 
@@ -2093,7 +2094,6 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
 
        static enum amd_ip_block_type ip_order[] = {
                AMD_IP_BLOCK_TYPE_SMC,
-               AMD_IP_BLOCK_TYPE_PSP,
                AMD_IP_BLOCK_TYPE_DCE,
                AMD_IP_BLOCK_TYPE_GFX,
                AMD_IP_BLOCK_TYPE_SDMA,
index 8843a06360fa7bd7e9620c76012b83b21e51f8c7..0f41d8647376a23234905751fdef534bfed8bd5a 100644 (file)
@@ -740,6 +740,7 @@ static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x67CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
        {0x1002, 0x67CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
        {0x1002, 0x67CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
+       {0x1002, 0x6FDF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
        /* Polaris12 */
        {0x1002, 0x6980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
        {0x1002, 0x6981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
index 0cc5190f4f36e4a1b192a17b274bbd4fe38c00b6..5f3f540738187c6db03a7975bced71ea4163c9e0 100644 (file)
@@ -258,6 +258,8 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
 {
        int i;
 
+       cancel_delayed_work_sync(&adev->vce.idle_work);
+
        if (adev->vce.vcpu_bo == NULL)
                return 0;
 
@@ -268,7 +270,6 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
        if (i == AMDGPU_MAX_VCE_HANDLES)
                return 0;
 
-       cancel_delayed_work_sync(&adev->vce.idle_work);
        /* TODO: suspending running encoding sessions isn't supported */
        return -EINVAL;
 }
index fd654a4406db964da6611f6c2d3d9db1fb283519..400fc74bbae27e878aebe4e6e27f6eaf22ca8e15 100644 (file)
@@ -153,11 +153,11 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
        unsigned size;
        void *ptr;
 
+       cancel_delayed_work_sync(&adev->vcn.idle_work);
+
        if (adev->vcn.vcpu_bo == NULL)
                return 0;
 
-       cancel_delayed_work_sync(&adev->vcn.idle_work);
-
        size = amdgpu_bo_size(adev->vcn.vcpu_bo);
        ptr = adev->vcn.cpu_addr;
 
index e7ca4623cfb946f41b0e3e1ffb107a3f295daedb..7c3b634d8d5f4117698ca46542eba887b85c4692 100644 (file)
@@ -70,6 +70,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0100, 0x00000100),
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
+       SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000),
        SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
        SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CLK_CTRL, 0xffffffff, 0x3f000100),
        SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GFX_IB_CNTL, 0x800f0100, 0x00000100),
@@ -81,7 +82,8 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
        SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
        SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_IB_CNTL, 0x800f0100, 0x00000100),
        SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
-       SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0)
+       SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0),
+       SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_WATERMK, 0xfc000000, 0x00000000)
 };
 
 static const struct soc15_reg_golden golden_settings_sdma_vg10[] = {
@@ -109,7 +111,8 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] =
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0111, 0x00000100),
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
-       SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0)
+       SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
+       SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
 };
 
 static const struct soc15_reg_golden golden_settings_sdma_4_2[] =
index 1b048715ab8a1df42a391a527823b98212534be5..29ac74f40dceb729436907215427298ae9190909 100644 (file)
@@ -457,7 +457,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 
        if (kfd->kfd2kgd->init_gtt_mem_allocation(
                        kfd->kgd, size, &kfd->gtt_mem,
-                       &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)){
+                       &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr,
+                       false)) {
                dev_err(kfd_device, "Could not allocate %d bytes\n", size);
                goto out;
        }
index 7a61f38c09e65bfd9b33d668799efd9d79ab7aab..01494752c36a8c7ba08ce83569677f47e828723c 100644 (file)
@@ -62,9 +62,20 @@ int kfd_iommu_device_init(struct kfd_dev *kfd)
        struct amd_iommu_device_info iommu_info;
        unsigned int pasid_limit;
        int err;
+       struct kfd_topology_device *top_dev;
 
-       if (!kfd->device_info->needs_iommu_device)
+       top_dev = kfd_topology_device_by_id(kfd->id);
+
+       /*
+        * Overwrite ATS capability according to needs_iommu_device to fix
+        * potential missing corresponding bit in CRAT of BIOS.
+        */
+       if (!kfd->device_info->needs_iommu_device) {
+               top_dev->node_props.capability &= ~HSA_CAP_ATS_PRESENT;
                return 0;
+       }
+
+       top_dev->node_props.capability |= HSA_CAP_ATS_PRESENT;
 
        iommu_info.flags = 0;
        err = amd_iommu_device_info(kfd->pdev, &iommu_info);
index f5fc3675f21eda3d7c769aed2130a9360382afad..0cedb37cf513563dc6fea50e6b40ef0889c3bb61 100644 (file)
@@ -88,7 +88,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
                                ALIGN(sizeof(struct v9_mqd), PAGE_SIZE),
                        &((*mqd_mem_obj)->gtt_mem),
                        &((*mqd_mem_obj)->gpu_addr),
-                       (void *)&((*mqd_mem_obj)->cpu_ptr));
+                       (void *)&((*mqd_mem_obj)->cpu_ptr), true);
        } else
                retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct v9_mqd),
                                mqd_mem_obj);
index f971710f1c91b2edec3670f0a36e837ef947190c..92b285ca73aabb1b225f37e17bd36a9f05e9641e 100644 (file)
@@ -806,6 +806,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu);
 int kfd_topology_remove_device(struct kfd_dev *gpu);
 struct kfd_topology_device *kfd_topology_device_by_proximity_domain(
                                                uint32_t proximity_domain);
+struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id);
 struct kfd_dev *kfd_device_by_id(uint32_t gpu_id);
 struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev);
 int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev);
index bc95d4dfee2e930800426c85bd5c6831efc6294f..80f5db4ef75fd03ded8df14abce8348964386d69 100644 (file)
@@ -63,22 +63,33 @@ struct kfd_topology_device *kfd_topology_device_by_proximity_domain(
        return device;
 }
 
-struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
+struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id)
 {
-       struct kfd_topology_device *top_dev;
-       struct kfd_dev *device = NULL;
+       struct kfd_topology_device *top_dev = NULL;
+       struct kfd_topology_device *ret = NULL;
 
        down_read(&topology_lock);
 
        list_for_each_entry(top_dev, &topology_device_list, list)
                if (top_dev->gpu_id == gpu_id) {
-                       device = top_dev->gpu;
+                       ret = top_dev;
                        break;
                }
 
        up_read(&topology_lock);
 
-       return device;
+       return ret;
+}
+
+struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
+{
+       struct kfd_topology_device *top_dev;
+
+       top_dev = kfd_topology_device_by_id(gpu_id);
+       if (!top_dev)
+               return NULL;
+
+       return top_dev->gpu;
 }
 
 struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev)
index 800f481a6995fce0129bb316e078d2dcd8ab9eeb..96875950845a4aa7d30fdf24014c8f08472dbe2f 100644 (file)
@@ -641,6 +641,87 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
        return NULL;
 }
 
+static void emulated_link_detect(struct dc_link *link)
+{
+       struct dc_sink_init_data sink_init_data = { 0 };
+       struct display_sink_capability sink_caps = { 0 };
+       enum dc_edid_status edid_status;
+       struct dc_context *dc_ctx = link->ctx;
+       struct dc_sink *sink = NULL;
+       struct dc_sink *prev_sink = NULL;
+
+       link->type = dc_connection_none;
+       prev_sink = link->local_sink;
+
+       if (prev_sink != NULL)
+               dc_sink_retain(prev_sink);
+
+       switch (link->connector_signal) {
+       case SIGNAL_TYPE_HDMI_TYPE_A: {
+               sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
+               sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
+               break;
+       }
+
+       case SIGNAL_TYPE_DVI_SINGLE_LINK: {
+               sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
+               sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
+               break;
+       }
+
+       case SIGNAL_TYPE_DVI_DUAL_LINK: {
+               sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
+               sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
+               break;
+       }
+
+       case SIGNAL_TYPE_LVDS: {
+               sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
+               sink_caps.signal = SIGNAL_TYPE_LVDS;
+               break;
+       }
+
+       case SIGNAL_TYPE_EDP: {
+               sink_caps.transaction_type =
+                       DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
+               sink_caps.signal = SIGNAL_TYPE_EDP;
+               break;
+       }
+
+       case SIGNAL_TYPE_DISPLAY_PORT: {
+               sink_caps.transaction_type =
+                       DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
+               sink_caps.signal = SIGNAL_TYPE_VIRTUAL;
+               break;
+       }
+
+       default:
+               DC_ERROR("Invalid connector type! signal:%d\n",
+                       link->connector_signal);
+               return;
+       }
+
+       sink_init_data.link = link;
+       sink_init_data.sink_signal = sink_caps.signal;
+
+       sink = dc_sink_create(&sink_init_data);
+       if (!sink) {
+               DC_ERROR("Failed to create sink!\n");
+               return;
+       }
+
+       link->local_sink = sink;
+
+       edid_status = dm_helpers_read_local_edid(
+                       link->ctx,
+                       link,
+                       sink);
+
+       if (edid_status != EDID_OK)
+               DC_ERROR("Failed to read EDID");
+
+}
+
 static int dm_resume(void *handle)
 {
        struct amdgpu_device *adev = handle;
@@ -654,6 +735,7 @@ static int dm_resume(void *handle)
        struct drm_plane *plane;
        struct drm_plane_state *new_plane_state;
        struct dm_plane_state *dm_new_plane_state;
+       enum dc_connection_type new_connection_type = dc_connection_none;
        int ret;
        int i;
 
@@ -684,7 +766,13 @@ static int dm_resume(void *handle)
                        continue;
 
                mutex_lock(&aconnector->hpd_lock);
-               dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
+               if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
+                       DRM_ERROR("KMS: Failed to detect connector\n");
+
+               if (aconnector->base.force && new_connection_type == dc_connection_none)
+                       emulated_link_detect(aconnector->dc_link);
+               else
+                       dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
 
                if (aconnector->fake_enable && aconnector->dc_link->local_sink)
                        aconnector->fake_enable = false;
@@ -922,6 +1010,7 @@ static void handle_hpd_irq(void *param)
        struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
        struct drm_connector *connector = &aconnector->base;
        struct drm_device *dev = connector->dev;
+       enum dc_connection_type new_connection_type = dc_connection_none;
 
        /* In case of failure or MST no need to update connector status or notify the OS
         * since (for MST case) MST does this in it's own context.
@@ -931,7 +1020,21 @@ static void handle_hpd_irq(void *param)
        if (aconnector->fake_enable)
                aconnector->fake_enable = false;
 
-       if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
+       if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
+               DRM_ERROR("KMS: Failed to detect connector\n");
+
+       if (aconnector->base.force && new_connection_type == dc_connection_none) {
+               emulated_link_detect(aconnector->dc_link);
+
+
+               drm_modeset_lock_all(dev);
+               dm_restore_drm_connector_state(dev, connector);
+               drm_modeset_unlock_all(dev);
+
+               if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
+                       drm_kms_helper_hotplug_event(dev);
+
+       } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
                amdgpu_dm_update_connector_after_detect(aconnector);
 
 
@@ -1031,6 +1134,7 @@ static void handle_hpd_rx_irq(void *param)
        struct drm_device *dev = connector->dev;
        struct dc_link *dc_link = aconnector->dc_link;
        bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
+       enum dc_connection_type new_connection_type = dc_connection_none;
 
        /* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
         * conflict, after implement i2c helper, this mutex should be
@@ -1042,7 +1146,24 @@ static void handle_hpd_rx_irq(void *param)
        if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
                        !is_mst_root_connector) {
                /* Downstream Port status changed. */
-               if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
+               if (!dc_link_detect_sink(dc_link, &new_connection_type))
+                       DRM_ERROR("KMS: Failed to detect connector\n");
+
+               if (aconnector->base.force && new_connection_type == dc_connection_none) {
+                       emulated_link_detect(dc_link);
+
+                       if (aconnector->fake_enable)
+                               aconnector->fake_enable = false;
+
+                       amdgpu_dm_update_connector_after_detect(aconnector);
+
+
+                       drm_modeset_lock_all(dev);
+                       dm_restore_drm_connector_state(dev, connector);
+                       drm_modeset_unlock_all(dev);
+
+                       drm_kms_helper_hotplug_event(dev);
+               } else if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
 
                        if (aconnector->fake_enable)
                                aconnector->fake_enable = false;
@@ -1433,6 +1554,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
        struct amdgpu_mode_info *mode_info = &adev->mode_info;
        uint32_t link_cnt;
        int32_t total_overlay_planes, total_primary_planes;
+       enum dc_connection_type new_connection_type = dc_connection_none;
 
        link_cnt = dm->dc->caps.max_links;
        if (amdgpu_dm_mode_config_init(dm->adev)) {
@@ -1499,7 +1621,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 
                link = dc_get_link_at_index(dm->dc, i);
 
-               if (dc_link_detect(link, DETECT_REASON_BOOT)) {
+               if (!dc_link_detect_sink(link, &new_connection_type))
+                       DRM_ERROR("KMS: Failed to detect connector\n");
+
+               if (aconnector->base.force && new_connection_type == dc_connection_none) {
+                       emulated_link_detect(link);
+                       amdgpu_dm_update_connector_after_detect(aconnector);
+
+               } else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
                        amdgpu_dm_update_connector_after_detect(aconnector);
                        register_backlight_device(dm, link);
                }
@@ -2494,7 +2623,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
        if (dm_state && dm_state->freesync_capable)
                stream->ignore_msa_timing_param = true;
 finish:
-       if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL)
+       if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON)
                dc_sink_release(sink);
 
        return stream;
index 37eaf72ace549d6f132b9fc5933da434fc164396..fced3c1c2ef5f6ac117a993714de8bf24da2258a 100644 (file)
@@ -195,7 +195,7 @@ static bool program_hpd_filter(
        return result;
 }
 
-static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
+bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
 {
        uint32_t is_hpd_high = 0;
        struct gpio *hpd_pin;
@@ -604,7 +604,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
        if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
                return false;
 
-       if (false == detect_sink(link, &new_connection_type)) {
+       if (false == dc_link_detect_sink(link, &new_connection_type)) {
                BREAK_TO_DEBUGGER();
                return false;
        }
index d43cefbc43d3b195c40ad6f6829eadeaeb96daee..1b48ab9aea897cd28422a57c11909a769cd7a6a3 100644 (file)
@@ -215,6 +215,7 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
 
 bool dc_link_is_dp_sink_present(struct dc_link *link);
 
+bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type);
 /*
  * DPCD access interfaces
  */
index 14384d9675a8c4cc23fc67162f9f3f9cd7a17a22..b2f308766a9e8e5cfc6c34dea6e9b4515cf7fc8d 100644 (file)
@@ -2560,7 +2560,7 @@ static void pplib_apply_display_requirements(
        dc->prev_display_config = *pp_display_cfg;
 }
 
-void dce110_set_bandwidth(
+static void dce110_set_bandwidth(
                struct dc *dc,
                struct dc_state *context,
                bool decrease_allowed)
index e4c5db75c4c656b010e16ab490286801bb94bfb4..d6db3dbd90153ba4a3f9511eb494552b143b4255 100644 (file)
@@ -68,11 +68,6 @@ void dce110_fill_display_configs(
        const struct dc_state *context,
        struct dm_pp_display_configuration *pp_display_cfg);
 
-void dce110_set_bandwidth(
-               struct dc *dc,
-               struct dc_state *context,
-               bool decrease_allowed);
-
 uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
 
 void dp_receiver_power_ctrl(struct dc_link *link, bool on);
index 5853522a618298a6bdc20df629f1c494d13468ae..eb0f5f9a973b9b2f79793023d8f1cdf21aae787c 100644 (file)
@@ -244,17 +244,6 @@ static void dce120_update_dchub(
        dh_data->dchub_info_valid = false;
 }
 
-static void dce120_set_bandwidth(
-               struct dc *dc,
-               struct dc_state *context,
-               bool decrease_allowed)
-{
-       if (context->stream_count <= 0)
-               return;
-
-       dce110_set_bandwidth(dc, context, decrease_allowed);
-}
-
 void dce120_hw_sequencer_construct(struct dc *dc)
 {
        /* All registers used by dce11.2 match those in dce11 in offset and
@@ -263,6 +252,5 @@ void dce120_hw_sequencer_construct(struct dc *dc)
        dce110_hw_sequencer_construct(dc);
        dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating;
        dc->hwss.update_dchub = dce120_update_dchub;
-       dc->hwss.set_bandwidth = dce120_set_bandwidth;
 }
 
index 14391b06080ce4566ebbae1d8fd1a8313ac36bc8..43b82e14007ef0d7d1f9ac9bf8d8a121cb490c28 100644 (file)
@@ -292,7 +292,7 @@ struct tile_config {
 struct kfd2kgd_calls {
        int (*init_gtt_mem_allocation)(struct kgd_dev *kgd, size_t size,
                                        void **mem_obj, uint64_t *gpu_addr,
-                                       void **cpu_ptr);
+                                       void **cpu_ptr, bool mqd_gfx9);
 
        void (*free_gtt_mem)(struct kgd_dev *kgd, void *mem_obj);
 
index 08b5bb219816ad38f929a23ccb69b378cba2101f..94d6dabec2dc80ee47794430d0642de6846fbfe4 100644 (file)
@@ -754,6 +754,7 @@ static int malidp_bind(struct device *dev)
        drm->irq_enabled = true;
 
        ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
+       drm_crtc_vblank_reset(&malidp->crtc);
        if (ret < 0) {
                DRM_ERROR("failed to initialise vblank\n");
                goto vblank_fail;
index c94a4422e0e9100a607a8b817878c25942ce77bd..2781e462c1ed5dd7b275ad0d9b9cccc1cc258a1f 100644 (file)
@@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev,
 
 static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
                                     dma_addr_t *addrs, s32 *pitches,
-                                    int num_planes, u16 w, u16 h, u32 fmt_id)
+                                    int num_planes, u16 w, u16 h, u32 fmt_id,
+                                    const s16 *rgb2yuv_coeffs)
 {
        u32 base = MALIDP500_SE_MEMWRITE_BASE;
        u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
 
        malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
                        MALIDP500_SE_MEMWRITE_OUT_SIZE);
+
+       if (rgb2yuv_coeffs) {
+               int i;
+
+               for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+                       malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
+                                       MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
+               }
+       }
+
        malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
 
        return 0;
@@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev,
 
 static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
                                     dma_addr_t *addrs, s32 *pitches,
-                                    int num_planes, u16 w, u16 h, u32 fmt_id)
+                                    int num_planes, u16 w, u16 h, u32 fmt_id,
+                                    const s16 *rgb2yuv_coeffs)
 {
        u32 base = MALIDP550_SE_MEMWRITE_BASE;
        u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
        malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
                          MALIDP550_SE_CONTROL);
 
+       if (rgb2yuv_coeffs) {
+               int i;
+
+               for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+                       malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
+                                       MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
+               }
+       }
+
        return 0;
 }
 
index ad2e96915d44a253c8d77dc2e5d98c22c758fc5c..9fc94c08190f23184985e3beb40f4cc88dc2e430 100644 (file)
@@ -191,7 +191,8 @@ struct malidp_hw {
         * @param fmt_id - internal format ID of output buffer
         */
        int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
-                              s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id);
+                              s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id,
+                              const s16 *rgb2yuv_coeffs);
 
        /*
         * Disable the writing to memory of the next frame's content.
index ba6ae66387c9129063cc894ed99c5dc0854a4c07..91472e5e0c8b8a3b0c19a2fb5f860fac83ffcb5b 100644 (file)
@@ -26,6 +26,8 @@ struct malidp_mw_connector_state {
        s32 pitches[2];
        u8 format;
        u8 n_planes;
+       bool rgb2yuv_initialized;
+       const s16 *rgb2yuv_coeffs;
 };
 
 static int malidp_mw_connector_get_modes(struct drm_connector *connector)
@@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector *connector)
 static struct drm_connector_state *
 malidp_mw_connector_duplicate_state(struct drm_connector *connector)
 {
-       struct malidp_mw_connector_state *mw_state;
+       struct malidp_mw_connector_state *mw_state, *mw_current_state;
 
        if (WARN_ON(!connector->state))
                return NULL;
@@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector)
        if (!mw_state)
                return NULL;
 
-       /* No need to preserve any of our driver-local data */
+       mw_current_state = to_mw_state(connector->state);
+       mw_state->rgb2yuv_coeffs = mw_current_state->rgb2yuv_coeffs;
+       mw_state->rgb2yuv_initialized = mw_current_state->rgb2yuv_initialized;
+
        __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
 
        return &mw_state->base;
@@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = {
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
+static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = {
+       47,  157,   16,
+       -26,  -87,  112,
+       112, -102,  -10,
+       16,  128,  128
+};
+
 static int
 malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
                               struct drm_crtc_state *crtc_state,
@@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
        }
        mw_state->n_planes = n_planes;
 
+       if (fb->format->is_yuv)
+               mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;
+
        return 0;
 }
 
@@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
 
                drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
                conn_state->writeback_job = NULL;
-
                hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
                                           mw_state->pitches, mw_state->n_planes,
-                                          fb->width, fb->height, mw_state->format);
+                                          fb->width, fb->height, mw_state->format,
+                                          !mw_state->rgb2yuv_initialized ?
+                                          mw_state->rgb2yuv_coeffs : NULL);
+               mw_state->rgb2yuv_initialized = !!mw_state->rgb2yuv_coeffs;
        } else {
                DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
                hwdev->hw->disable_memwrite(hwdev);
index 3579d36b2a717aedc436cd574b8639f9ea1d7d9b..6ffe849774f2edbec087aabe640ba0f61720b6f2 100644 (file)
 #define MALIDP500_SE_BASE              0x00c00
 #define MALIDP500_SE_CONTROL           0x00c0c
 #define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
+#define MALIDP500_SE_RGB_YUV_COEFFS    0x00C74
 #define MALIDP500_SE_MEMWRITE_BASE     0x00e00
 #define MALIDP500_DC_IRQ_BASE          0x00f00
 #define MALIDP500_CONFIG_VALID         0x00f00
 #define MALIDP550_SE_CONTROL           0x08010
 #define   MALIDP550_SE_MEMWRITE_ONESHOT        (1 << 7)
 #define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
+#define MALIDP550_SE_RGB_YUV_COEFFS    0x08078
 #define MALIDP550_SE_MEMWRITE_BASE     0x08100
 #define MALIDP550_DC_BASE              0x0c000
 #define MALIDP550_DC_CONTROL           0x0c010
index 3eb061e11e2efb2caa36738b6425d2f789c19f6d..018fcdb353d254293456b613af5ed0e25ec07caa 100644 (file)
@@ -2067,7 +2067,7 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
 
-       if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
+       if (!drm_drv_uses_atomic_modeset(dev))
                return;
 
        list_for_each_entry(plane, &config->plane_list, head) {
index 6f28fe58f1696ca5010915149173e966df35ffc7..373bd4c2b698ba1ebcb3b4572cb6c84b3ce448fe 100644 (file)
@@ -151,7 +151,7 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
                return ret;
        }
 
-       if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
+       if (drm_drv_uses_atomic_modeset(dev)) {
                ret = drm_atomic_debugfs_init(minor);
                if (ret) {
                        DRM_ERROR("Failed to create atomic debugfs files\n");
index 4b0dd20bccb8f3cc2b7da96eb4c4203dabf2815f..16ec93b75dbfaf87fca050d84dfe8ee292226424 100644 (file)
@@ -2370,7 +2370,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 {
        int c, o;
        struct drm_connector *connector;
-       const struct drm_connector_helper_funcs *connector_funcs;
        int my_score, best_score, score;
        struct drm_fb_helper_crtc **crtcs, *crtc;
        struct drm_fb_helper_connector *fb_helper_conn;
@@ -2399,8 +2398,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
        if (drm_has_preferred_mode(fb_helper_conn, width, height))
                my_score++;
 
-       connector_funcs = connector->helper_private;
-
        /*
         * select a crtc for this connector and then attempt to configure
         * remaining connectors
index b902361dee6e1db300c10ce5798de7bada296b65..1d9a9d2fe0e098c4f00b59816b92d262c9620073 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/err.h>
 #include <linux/module.h>
 
-#include <drm/drm_device.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_panel.h>
 
@@ -105,13 +104,6 @@ int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
        if (panel->connector)
                return -EBUSY;
 
-       panel->link = device_link_add(connector->dev->dev, panel->dev, 0);
-       if (!panel->link) {
-               dev_err(panel->dev, "failed to link panel to %s\n",
-                       dev_name(connector->dev->dev));
-               return -EINVAL;
-       }
-
        panel->connector = connector;
        panel->drm = connector->dev;
 
@@ -133,8 +125,6 @@ EXPORT_SYMBOL(drm_panel_attach);
  */
 int drm_panel_detach(struct drm_panel *panel)
 {
-       device_link_del(panel->link);
-
        panel->connector = NULL;
        panel->drm = NULL;
 
index adb3cb27d31e6fa6aa1f0c3102c7d8ede5599169..759278fef35ae6ee4f9889b09c0dfffef2af8ca8 100644 (file)
@@ -97,6 +97,8 @@ static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
 {
        int ret;
 
+       WARN_ON(*fence);
+
        *fence = drm_syncobj_fence_get(syncobj);
        if (*fence)
                return 1;
@@ -743,6 +745,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 
        if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
                for (i = 0; i < count; ++i) {
+                       if (entries[i].fence)
+                               continue;
+
                        drm_syncobj_fence_get_or_add_callback(syncobjs[i],
                                                              &entries[i].fence,
                                                              &entries[i].syncobj_cb,
index 9b2720b41571f245a1ba5ad677bb0566d95ca207..83c1f46670bfea9dcbe95e42da598c8665576b03 100644 (file)
@@ -592,8 +592,6 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct component_match *match = NULL;
 
-       dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-
        if (!dev->platform_data) {
                struct device_node *core_node;
 
@@ -655,13 +653,30 @@ static int __init etnaviv_init(void)
        for_each_compatible_node(np, NULL, "vivante,gc") {
                if (!of_device_is_available(np))
                        continue;
-               pdev = platform_device_register_simple("etnaviv", -1,
-                                                      NULL, 0);
-               if (IS_ERR(pdev)) {
-                       ret = PTR_ERR(pdev);
+
+               pdev = platform_device_alloc("etnaviv", -1);
+               if (!pdev) {
+                       ret = -ENOMEM;
+                       of_node_put(np);
+                       goto unregister_platform_driver;
+               }
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+               /*
+                * Apply the same DMA configuration to the virtual etnaviv
+                * device as the GPU we found. This assumes that all Vivante
+                * GPUs in the system share the same DMA constraints.
+                */
+               of_dma_configure(&pdev->dev, np, true);
+
+               ret = platform_device_add(pdev);
+               if (ret) {
+                       platform_device_put(pdev);
                        of_node_put(np);
                        goto unregister_platform_driver;
                }
+
                etnaviv_drm = pdev;
                of_node_put(np);
                break;
index 72afa518edd91157f6a221f277536c0f96e30899..94c1089ecf59ee46178a6e73be6f73d6307936a0 100644 (file)
@@ -3210,6 +3210,7 @@ static int init_bxt_mmio_info(struct intel_gvt *gvt)
        MMIO_D(BXT_DSI_PLL_ENABLE, D_BXT);
 
        MMIO_D(GEN9_CLKGATE_DIS_0, D_BXT);
+       MMIO_D(GEN9_CLKGATE_DIS_4, D_BXT);
 
        MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_A), D_BXT);
        MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B), D_BXT);
index a45f46d8537f15bd187fd4195d7de2c6b6dffd2a..9ad89e38f6c07643f2176afade5c223388ada755 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/mm.h>
 #include <linux/mmu_context.h>
+#include <linux/sched/mm.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
@@ -1792,16 +1793,21 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
        info = (struct kvmgt_guest_info *)handle;
        kvm = info->kvm;
 
-       if (kthread)
+       if (kthread) {
+               if (!mmget_not_zero(kvm->mm))
+                       return -EFAULT;
                use_mm(kvm->mm);
+       }
 
        idx = srcu_read_lock(&kvm->srcu);
        ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
                      kvm_read_guest(kvm, gpa, buf, len);
        srcu_read_unlock(&kvm->srcu, idx);
 
-       if (kthread)
+       if (kthread) {
                unuse_mm(kvm->mm);
+               mmput(kvm->mm);
+       }
 
        return ret;
 }
@@ -1827,6 +1833,8 @@ static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
 {
        struct kvmgt_guest_info *info;
        struct kvm *kvm;
+       int idx;
+       bool ret;
 
        if (!handle_valid(handle))
                return false;
@@ -1834,8 +1842,11 @@ static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
        info = (struct kvmgt_guest_info *)handle;
        kvm = info->kvm;
 
-       return kvm_is_visible_gfn(kvm, gfn);
+       idx = srcu_read_lock(&kvm->srcu);
+       ret = kvm_is_visible_gfn(kvm, gfn);
+       srcu_read_unlock(&kvm->srcu, idx);
 
+       return ret;
 }
 
 struct intel_gvt_mpt kvmgt_mpt = {
index 994366035364b7576db8ed2ec1036d417cc39d9c..9bb9a85c992ca16a13552af798d8e47e3061dd52 100644 (file)
@@ -244,6 +244,34 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr)
 
                /* set the bit 0:2(Core C-State ) to C0 */
                vgpu_vreg_t(vgpu, GEN6_GT_CORE_STATUS) = 0;
+
+               if (IS_BROXTON(vgpu->gvt->dev_priv)) {
+                       vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &=
+                                   ~(BIT(0) | BIT(1));
+                       vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
+                                   ~PHY_POWER_GOOD;
+                       vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &=
+                                   ~PHY_POWER_GOOD;
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &=
+                                   ~BIT(30);
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &=
+                                   ~BIT(30);
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &=
+                                   ~BXT_PHY_LANE_ENABLED;
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |=
+                                   BXT_PHY_CMNLANE_POWERDOWN_ACK |
+                                   BXT_PHY_LANE_POWERDOWN_ACK;
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &=
+                                   ~BXT_PHY_LANE_ENABLED;
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |=
+                                   BXT_PHY_CMNLANE_POWERDOWN_ACK |
+                                   BXT_PHY_LANE_POWERDOWN_ACK;
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &=
+                                   ~BXT_PHY_LANE_ENABLED;
+                       vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
+                                   BXT_PHY_CMNLANE_POWERDOWN_ACK |
+                                   BXT_PHY_LANE_POWERDOWN_ACK;
+               }
        } else {
 #define GVT_GEN8_MMIO_RESET_OFFSET             (0x44200)
                /* only reset the engine related, so starting with 0x44200
index fa75a2eead9070fbfd1894b659b37f84eed9e11a..b0d3a43ccd033761dfefdf077e09526a98aff3c0 100644 (file)
@@ -42,8 +42,6 @@
 #define DEVICE_TYPE_EFP3   0x20
 #define DEVICE_TYPE_EFP4   0x10
 
-#define DEV_SIZE       38
-
 struct opregion_header {
        u8 signature[16];
        u32 size;
@@ -63,6 +61,10 @@ struct bdb_data_header {
        u16 size; /* data size */
 } __packed;
 
+/* For supporting windows guest with opregion, here hardcode the emulated
+ * bdb header version as '186', and the corresponding child_device_config
+ * length should be '33' but not '38'.
+ */
 struct efp_child_device_config {
        u16 handle;
        u16 device_type;
@@ -109,12 +111,6 @@ struct efp_child_device_config {
        u8 mipi_bridge_type; /* 171 */
        u16 device_class_ext;
        u8 dvo_function;
-       u8 dp_usb_type_c:1; /* 195 */
-       u8 skip6:7;
-       u8 dp_usb_type_c_2x_gpio_index; /* 195 */
-       u16 dp_usb_type_c_2x_gpio_pin; /* 195 */
-       u8 iboost_dp:4; /* 196 */
-       u8 iboost_hdmi:4; /* 196 */
 } __packed;
 
 struct vbt {
@@ -155,7 +151,7 @@ static void virt_vbt_generation(struct vbt *v)
        v->header.bdb_offset = offsetof(struct vbt, bdb_header);
 
        strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK");
-       v->bdb_header.version = 186; /* child_dev_size = 38 */
+       v->bdb_header.version = 186; /* child_dev_size = 33 */
        v->bdb_header.header_size = sizeof(v->bdb_header);
 
        v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header)
@@ -169,11 +165,13 @@ static void virt_vbt_generation(struct vbt *v)
 
        /* child device */
        num_child = 4; /* each port has one child */
+       v->general_definitions.child_dev_size =
+               sizeof(struct efp_child_device_config);
        v->general_definitions_header.id = BDB_GENERAL_DEFINITIONS;
        /* size will include child devices */
        v->general_definitions_header.size =
-               sizeof(struct bdb_general_definitions) + num_child * DEV_SIZE;
-       v->general_definitions.child_dev_size = DEV_SIZE;
+               sizeof(struct bdb_general_definitions) +
+                       num_child * v->general_definitions.child_dev_size;
 
        /* portA */
        v->child0.handle = DEVICE_TYPE_EFP1;
index a4e8e3cf74fd58b400331bc608516e9414e458d3..c628be05fbfe907a1bce89fd4727df79906fe63f 100644 (file)
@@ -281,6 +281,7 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
        intel_vgpu_clean_submission(vgpu);
        intel_vgpu_clean_display(vgpu);
        intel_vgpu_clean_opregion(vgpu);
+       intel_vgpu_reset_ggtt(vgpu, true);
        intel_vgpu_clean_gtt(vgpu);
        intel_gvt_hypervisor_detach_vgpu(vgpu);
        intel_vgpu_free_resource(vgpu);
index 4a3c8ee9a9732cccc4e1ce1cc42197b0c662cc73..d2951096bca0d48caaf10abf1827ef81152abdc8 100644 (file)
@@ -5079,10 +5079,14 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
                mutex_lock(&dev_priv->pcu_lock);
                WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
                mutex_unlock(&dev_priv->pcu_lock);
-               /* wait for pcode to finish disabling IPS, which may take up to 42ms */
+               /*
+                * Wait for PCODE to finish disabling IPS. The BSpec specified
+                * 42ms timeout value leads to occasional timeouts so use 100ms
+                * instead.
+                */
                if (intel_wait_for_register(dev_priv,
                                            IPS_CTL, IPS_ENABLE, 0,
-                                           42))
+                                           100))
                        DRM_ERROR("Timed out waiting for IPS disable\n");
        } else {
                I915_WRITE(IPS_CTL, 0);
index c2f10d8993296471833e4a5d8a0cd69463a992b4..443dfaefd7a6b413c4664b132fe5db59a9297f24 100644 (file)
@@ -181,8 +181,9 @@ struct intel_overlay {
        u32 brightness, contrast, saturation;
        u32 old_xscale, old_yscale;
        /* register access */
-       u32 flip_addr;
        struct drm_i915_gem_object *reg_bo;
+       struct overlay_registers __iomem *regs;
+       u32 flip_addr;
        /* flip handling */
        struct i915_gem_active last_flip;
 };
@@ -210,29 +211,6 @@ static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
                                  PCI_DEVFN(0, 0), I830_CLOCK_GATE, val);
 }
 
-static struct overlay_registers __iomem *
-intel_overlay_map_regs(struct intel_overlay *overlay)
-{
-       struct drm_i915_private *dev_priv = overlay->i915;
-       struct overlay_registers __iomem *regs;
-
-       if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
-               regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
-       else
-               regs = io_mapping_map_wc(&dev_priv->ggtt.iomap,
-                                        overlay->flip_addr,
-                                        PAGE_SIZE);
-
-       return regs;
-}
-
-static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
-                                    struct overlay_registers __iomem *regs)
-{
-       if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
-               io_mapping_unmap(regs);
-}
-
 static void intel_overlay_submit_request(struct intel_overlay *overlay,
                                         struct i915_request *rq,
                                         i915_gem_retire_fn retire)
@@ -784,13 +762,13 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
                                      struct drm_i915_gem_object *new_bo,
                                      struct put_image_params *params)
 {
-       int ret, tmp_width;
-       struct overlay_registers __iomem *regs;
-       bool scale_changed = false;
+       struct overlay_registers __iomem *regs = overlay->regs;
        struct drm_i915_private *dev_priv = overlay->i915;
        u32 swidth, swidthsw, sheight, ostride;
        enum pipe pipe = overlay->crtc->pipe;
+       bool scale_changed = false;
        struct i915_vma *vma;
+       int ret, tmp_width;
 
        lockdep_assert_held(&dev_priv->drm.struct_mutex);
        WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
@@ -815,30 +793,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 
        if (!overlay->active) {
                u32 oconfig;
-               regs = intel_overlay_map_regs(overlay);
-               if (!regs) {
-                       ret = -ENOMEM;
-                       goto out_unpin;
-               }
+
                oconfig = OCONF_CC_OUT_8BIT;
                if (IS_GEN4(dev_priv))
                        oconfig |= OCONF_CSC_MODE_BT709;
                oconfig |= pipe == 0 ?
                        OCONF_PIPE_A : OCONF_PIPE_B;
                iowrite32(oconfig, &regs->OCONFIG);
-               intel_overlay_unmap_regs(overlay, regs);
 
                ret = intel_overlay_on(overlay);
                if (ret != 0)
                        goto out_unpin;
        }
 
-       regs = intel_overlay_map_regs(overlay);
-       if (!regs) {
-               ret = -ENOMEM;
-               goto out_unpin;
-       }
-
        iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
        iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
 
@@ -882,8 +849,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 
        iowrite32(overlay_cmd_reg(params), &regs->OCMD);
 
-       intel_overlay_unmap_regs(overlay, regs);
-
        ret = intel_overlay_continue(overlay, vma, scale_changed);
        if (ret)
                goto out_unpin;
@@ -901,7 +866,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 int intel_overlay_switch_off(struct intel_overlay *overlay)
 {
        struct drm_i915_private *dev_priv = overlay->i915;
-       struct overlay_registers __iomem *regs;
        int ret;
 
        lockdep_assert_held(&dev_priv->drm.struct_mutex);
@@ -918,9 +882,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
        if (ret != 0)
                return ret;
 
-       regs = intel_overlay_map_regs(overlay);
-       iowrite32(0, &regs->OCMD);
-       intel_overlay_unmap_regs(overlay, regs);
+       iowrite32(0, &overlay->regs->OCMD);
 
        return intel_overlay_off(overlay);
 }
@@ -1305,7 +1267,6 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
        struct drm_intel_overlay_attrs *attrs = data;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_overlay *overlay;
-       struct overlay_registers __iomem *regs;
        int ret;
 
        overlay = dev_priv->overlay;
@@ -1345,15 +1306,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
                overlay->contrast   = attrs->contrast;
                overlay->saturation = attrs->saturation;
 
-               regs = intel_overlay_map_regs(overlay);
-               if (!regs) {
-                       ret = -ENOMEM;
-                       goto out_unlock;
-               }
-
-               update_reg_attrs(overlay, regs);
-
-               intel_overlay_unmap_regs(overlay, regs);
+               update_reg_attrs(overlay, overlay->regs);
 
                if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
                        if (IS_GEN2(dev_priv))
@@ -1386,12 +1339,47 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
        return ret;
 }
 
+static int get_registers(struct intel_overlay *overlay, bool use_phys)
+{
+       struct drm_i915_gem_object *obj;
+       struct i915_vma *vma;
+       int err;
+
+       obj = i915_gem_object_create_stolen(overlay->i915, PAGE_SIZE);
+       if (obj == NULL)
+               obj = i915_gem_object_create_internal(overlay->i915, PAGE_SIZE);
+       if (IS_ERR(obj))
+               return PTR_ERR(obj);
+
+       vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
+       if (IS_ERR(vma)) {
+               err = PTR_ERR(vma);
+               goto err_put_bo;
+       }
+
+       if (use_phys)
+               overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl);
+       else
+               overlay->flip_addr = i915_ggtt_offset(vma);
+       overlay->regs = i915_vma_pin_iomap(vma);
+       i915_vma_unpin(vma);
+
+       if (IS_ERR(overlay->regs)) {
+               err = PTR_ERR(overlay->regs);
+               goto err_put_bo;
+       }
+
+       overlay->reg_bo = obj;
+       return 0;
+
+err_put_bo:
+       i915_gem_object_put(obj);
+       return err;
+}
+
 void intel_setup_overlay(struct drm_i915_private *dev_priv)
 {
        struct intel_overlay *overlay;
-       struct drm_i915_gem_object *reg_bo;
-       struct overlay_registers __iomem *regs;
-       struct i915_vma *vma = NULL;
        int ret;
 
        if (!HAS_OVERLAY(dev_priv))
@@ -1401,46 +1389,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
        if (!overlay)
                return;
 
-       mutex_lock(&dev_priv->drm.struct_mutex);
-       if (WARN_ON(dev_priv->overlay))
-               goto out_free;
-
        overlay->i915 = dev_priv;
 
-       reg_bo = NULL;
-       if (!OVERLAY_NEEDS_PHYSICAL(dev_priv))
-               reg_bo = i915_gem_object_create_stolen(dev_priv, PAGE_SIZE);
-       if (reg_bo == NULL)
-               reg_bo = i915_gem_object_create(dev_priv, PAGE_SIZE);
-       if (IS_ERR(reg_bo))
-               goto out_free;
-       overlay->reg_bo = reg_bo;
-
-       if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) {
-               ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
-               if (ret) {
-                       DRM_ERROR("failed to attach phys overlay regs\n");
-                       goto out_free_bo;
-               }
-               overlay->flip_addr = reg_bo->phys_handle->busaddr;
-       } else {
-               vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
-                                              0, PAGE_SIZE, PIN_MAPPABLE);
-               if (IS_ERR(vma)) {
-                       DRM_ERROR("failed to pin overlay register bo\n");
-                       ret = PTR_ERR(vma);
-                       goto out_free_bo;
-               }
-               overlay->flip_addr = i915_ggtt_offset(vma);
-
-               ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
-               if (ret) {
-                       DRM_ERROR("failed to move overlay register bo into the GTT\n");
-                       goto out_unpin_bo;
-               }
-       }
-
-       /* init all values */
        overlay->color_key = 0x0101fe;
        overlay->color_key_enabled = true;
        overlay->brightness = -19;
@@ -1449,44 +1399,51 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
 
        init_request_active(&overlay->last_flip, NULL);
 
-       regs = intel_overlay_map_regs(overlay);
-       if (!regs)
-               goto out_unpin_bo;
+       mutex_lock(&dev_priv->drm.struct_mutex);
+
+       ret = get_registers(overlay, OVERLAY_NEEDS_PHYSICAL(dev_priv));
+       if (ret)
+               goto out_free;
+
+       ret = i915_gem_object_set_to_gtt_domain(overlay->reg_bo, true);
+       if (ret)
+               goto out_reg_bo;
 
-       memset_io(regs, 0, sizeof(struct overlay_registers));
-       update_polyphase_filter(regs);
-       update_reg_attrs(overlay, regs);
+       mutex_unlock(&dev_priv->drm.struct_mutex);
 
-       intel_overlay_unmap_regs(overlay, regs);
+       memset_io(overlay->regs, 0, sizeof(struct overlay_registers));
+       update_polyphase_filter(overlay->regs);
+       update_reg_attrs(overlay, overlay->regs);
 
        dev_priv->overlay = overlay;
-       mutex_unlock(&dev_priv->drm.struct_mutex);
-       DRM_INFO("initialized overlay support\n");
+       DRM_INFO("Initialized overlay support.\n");
        return;
 
-out_unpin_bo:
-       if (vma)
-               i915_vma_unpin(vma);
-out_free_bo:
-       i915_gem_object_put(reg_bo);
+out_reg_bo:
+       i915_gem_object_put(overlay->reg_bo);
 out_free:
        mutex_unlock(&dev_priv->drm.struct_mutex);
        kfree(overlay);
-       return;
 }
 
 void intel_cleanup_overlay(struct drm_i915_private *dev_priv)
 {
-       if (!dev_priv->overlay)
+       struct intel_overlay *overlay;
+
+       overlay = fetch_and_zero(&dev_priv->overlay);
+       if (!overlay)
                return;
 
-       /* The bo's should be free'd by the generic code already.
+       /*
+        * The bo's should be free'd by the generic code already.
         * Furthermore modesetting teardown happens beforehand so the
-        * hardware should be off already */
-       WARN_ON(dev_priv->overlay->active);
+        * hardware should be off already.
+        */
+       WARN_ON(overlay->active);
+
+       i915_gem_object_put(overlay->reg_bo);
 
-       i915_gem_object_put(dev_priv->overlay->reg_bo);
-       kfree(dev_priv->overlay);
+       kfree(overlay);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
@@ -1498,37 +1455,11 @@ struct intel_overlay_error_state {
        u32 isr;
 };
 
-static struct overlay_registers __iomem *
-intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
-{
-       struct drm_i915_private *dev_priv = overlay->i915;
-       struct overlay_registers __iomem *regs;
-
-       if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
-               /* Cast to make sparse happy, but it's wc memory anyway, so
-                * equivalent to the wc io mapping on X86. */
-               regs = (struct overlay_registers __iomem *)
-                       overlay->reg_bo->phys_handle->vaddr;
-       else
-               regs = io_mapping_map_atomic_wc(&dev_priv->ggtt.iomap,
-                                               overlay->flip_addr);
-
-       return regs;
-}
-
-static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
-                                       struct overlay_registers __iomem *regs)
-{
-       if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
-               io_mapping_unmap_atomic(regs);
-}
-
 struct intel_overlay_error_state *
 intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
 {
        struct intel_overlay *overlay = dev_priv->overlay;
        struct intel_overlay_error_state *error;
-       struct overlay_registers __iomem *regs;
 
        if (!overlay || !overlay->active)
                return NULL;
@@ -1541,18 +1472,9 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
        error->isr = I915_READ(ISR);
        error->base = overlay->flip_addr;
 
-       regs = intel_overlay_map_regs_atomic(overlay);
-       if (!regs)
-               goto err;
-
-       memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
-       intel_overlay_unmap_regs_atomic(overlay, regs);
+       memcpy_fromio(&error->regs, overlay->regs, sizeof(error->regs));
 
        return error;
-
-err:
-       kfree(error);
-       return NULL;
 }
 
 void
index 8412119bd94058b7197c531c49fc7ad88a9e6fab..5691dfa1db6fe388bcf50b2db79c3aa5a05a7696 100644 (file)
@@ -1123,17 +1123,21 @@ nv50_mstm_enable(struct nv50_mstm *mstm, u8 dpcd, int state)
        int ret;
 
        if (dpcd >= 0x12) {
-               ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CTRL, &dpcd);
+               /* Even if we're enabling MST, start with disabling the
+                * branching unit to clear any sink-side MST topology state
+                * that wasn't set by us
+                */
+               ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL, 0);
                if (ret < 0)
                        return ret;
 
-               dpcd &= ~DP_MST_EN;
-               if (state)
-                       dpcd |= DP_MST_EN;
-
-               ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL, dpcd);
-               if (ret < 0)
-                       return ret;
+               if (state) {
+                       /* Now, start initializing */
+                       ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL,
+                                                DP_MST_EN);
+                       if (ret < 0)
+                               return ret;
+               }
        }
 
        return nvif_mthd(disp, 0, &args, sizeof(args));
@@ -1142,31 +1146,58 @@ nv50_mstm_enable(struct nv50_mstm *mstm, u8 dpcd, int state)
 int
 nv50_mstm_detect(struct nv50_mstm *mstm, u8 dpcd[8], int allow)
 {
-       int ret, state = 0;
+       struct drm_dp_aux *aux;
+       int ret;
+       bool old_state, new_state;
+       u8 mstm_ctrl;
 
        if (!mstm)
                return 0;
 
-       if (dpcd[0] >= 0x12) {
-               ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CAP, &dpcd[1]);
+       mutex_lock(&mstm->mgr.lock);
+
+       old_state = mstm->mgr.mst_state;
+       new_state = old_state;
+       aux = mstm->mgr.aux;
+
+       if (old_state) {
+               /* Just check that the MST hub is still as we expect it */
+               ret = drm_dp_dpcd_readb(aux, DP_MSTM_CTRL, &mstm_ctrl);
+               if (ret < 0 || !(mstm_ctrl & DP_MST_EN)) {
+                       DRM_DEBUG_KMS("Hub gone, disabling MST topology\n");
+                       new_state = false;
+               }
+       } else if (dpcd[0] >= 0x12) {
+               ret = drm_dp_dpcd_readb(aux, DP_MSTM_CAP, &dpcd[1]);
                if (ret < 0)
-                       return ret;
+                       goto probe_error;
 
                if (!(dpcd[1] & DP_MST_CAP))
                        dpcd[0] = 0x11;
                else
-                       state = allow;
+                       new_state = allow;
+       }
+
+       if (new_state == old_state) {
+               mutex_unlock(&mstm->mgr.lock);
+               return new_state;
        }
 
-       ret = nv50_mstm_enable(mstm, dpcd[0], state);
+       ret = nv50_mstm_enable(mstm, dpcd[0], new_state);
        if (ret)
-               return ret;
+               goto probe_error;
+
+       mutex_unlock(&mstm->mgr.lock);
 
-       ret = drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, state);
+       ret = drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, new_state);
        if (ret)
                return nv50_mstm_enable(mstm, dpcd[0], 0);
 
-       return mstm->mgr.mst_state;
+       return new_state;
+
+probe_error:
+       mutex_unlock(&mstm->mgr.lock);
+       return ret;
 }
 
 static void
@@ -2074,7 +2105,7 @@ nv50_disp_atomic_state_alloc(struct drm_device *dev)
 static const struct drm_mode_config_funcs
 nv50_disp_func = {
        .fb_create = nouveau_user_framebuffer_create,
-       .output_poll_changed = drm_fb_helper_output_poll_changed,
+       .output_poll_changed = nouveau_fbcon_output_poll_changed,
        .atomic_check = nv50_disp_atomic_check,
        .atomic_commit = nv50_disp_atomic_commit,
        .atomic_state_alloc = nv50_disp_atomic_state_alloc,
index 51932c72334ef6529abb18bc44762cc01ba2d176..247f72cc4d10a4547309effb6b8904e9c0d60d49 100644 (file)
@@ -409,59 +409,45 @@ static struct nouveau_encoder *
 nouveau_connector_ddc_detect(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct nouveau_connector *nv_connector = nouveau_connector(connector);
-       struct nouveau_drm *drm = nouveau_drm(dev);
-       struct nvkm_gpio *gpio = nvxx_gpio(&drm->client.device);
-       struct nouveau_encoder *nv_encoder = NULL;
+       struct nouveau_encoder *nv_encoder = NULL, *found = NULL;
        struct drm_encoder *encoder;
-       int i, panel = -ENODEV;
-
-       /* eDP panels need powering on by us (if the VBIOS doesn't default it
-        * to on) before doing any AUX channel transactions.  LVDS panel power
-        * is handled by the SOR itself, and not required for LVDS DDC.
-        */
-       if (nv_connector->type == DCB_CONNECTOR_eDP) {
-               panel = nvkm_gpio_get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
-               if (panel == 0) {
-                       nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
-                       msleep(300);
-               }
-       }
+       int i, ret;
+       bool switcheroo_ddc = false;
 
        drm_connector_for_each_possible_encoder(connector, encoder, i) {
                nv_encoder = nouveau_encoder(encoder);
 
-               if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
-                       int ret = nouveau_dp_detect(nv_encoder);
+               switch (nv_encoder->dcb->type) {
+               case DCB_OUTPUT_DP:
+                       ret = nouveau_dp_detect(nv_encoder);
                        if (ret == NOUVEAU_DP_MST)
                                return NULL;
-                       if (ret == NOUVEAU_DP_SST)
-                               break;
-               } else
-               if ((vga_switcheroo_handler_flags() &
-                    VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
-                   nv_encoder->dcb->type == DCB_OUTPUT_LVDS &&
-                   nv_encoder->i2c) {
-                       int ret;
-                       vga_switcheroo_lock_ddc(dev->pdev);
-                       ret = nvkm_probe_i2c(nv_encoder->i2c, 0x50);
-                       vga_switcheroo_unlock_ddc(dev->pdev);
-                       if (ret)
+                       else if (ret == NOUVEAU_DP_SST)
+                               found = nv_encoder;
+
+                       break;
+               case DCB_OUTPUT_LVDS:
+                       switcheroo_ddc = !!(vga_switcheroo_handler_flags() &
+                                           VGA_SWITCHEROO_CAN_SWITCH_DDC);
+               /* fall-through */
+               default:
+                       if (!nv_encoder->i2c)
                                break;
-               } else
-               if (nv_encoder->i2c) {
+
+                       if (switcheroo_ddc)
+                               vga_switcheroo_lock_ddc(dev->pdev);
                        if (nvkm_probe_i2c(nv_encoder->i2c, 0x50))
-                               break;
+                               found = nv_encoder;
+                       if (switcheroo_ddc)
+                               vga_switcheroo_unlock_ddc(dev->pdev);
+
+                       break;
                }
+               if (found)
+                       break;
        }
 
-       /* eDP panel not detected, restore panel power GPIO to previous
-        * state to avoid confusing the SOR for other output types.
-        */
-       if (!nv_encoder && panel == 0)
-               nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
-
-       return nv_encoder;
+       return found;
 }
 
 static struct nouveau_encoder *
@@ -555,12 +541,16 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
                nv_connector->edid = NULL;
        }
 
-       /* Outputs are only polled while runtime active, so acquiring a
-        * runtime PM ref here is unnecessary (and would deadlock upon
-        * runtime suspend because it waits for polling to finish).
+       /* Outputs are only polled while runtime active, so resuming the
+        * device here is unnecessary (and would deadlock upon runtime suspend
+        * because it waits for polling to finish). We do however, want to
+        * prevent the autosuspend timer from elapsing during this operation
+        * if possible.
         */
-       if (!drm_kms_helper_is_poll_worker()) {
-               ret = pm_runtime_get_sync(connector->dev->dev);
+       if (drm_kms_helper_is_poll_worker()) {
+               pm_runtime_get_noresume(dev->dev);
+       } else {
+               ret = pm_runtime_get_sync(dev->dev);
                if (ret < 0 && ret != -EACCES)
                        return conn_status;
        }
@@ -638,10 +628,8 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
 
  out:
 
-       if (!drm_kms_helper_is_poll_worker()) {
-               pm_runtime_mark_last_busy(connector->dev->dev);
-               pm_runtime_put_autosuspend(connector->dev->dev);
-       }
+       pm_runtime_mark_last_busy(dev->dev);
+       pm_runtime_put_autosuspend(dev->dev);
 
        return conn_status;
 }
@@ -1105,6 +1093,26 @@ nouveau_connector_hotplug(struct nvif_notify *notify)
        const struct nvif_notify_conn_rep_v0 *rep = notify->data;
        const char *name = connector->name;
        struct nouveau_encoder *nv_encoder;
+       int ret;
+
+       ret = pm_runtime_get(drm->dev->dev);
+       if (ret == 0) {
+               /* We can't block here if there's a pending PM request
+                * running, as we'll deadlock nouveau_display_fini() when it
+                * calls nvif_put() on our nvif_notify struct. So, simply
+                * defer the hotplug event until the device finishes resuming
+                */
+               NV_DEBUG(drm, "Deferring HPD on %s until runtime resume\n",
+                        name);
+               schedule_work(&drm->hpd_work);
+
+               pm_runtime_put_noidle(drm->dev->dev);
+               return NVIF_NOTIFY_KEEP;
+       } else if (ret != 1 && ret != -EACCES) {
+               NV_WARN(drm, "HPD on %s dropped due to RPM failure: %d\n",
+                       name, ret);
+               return NVIF_NOTIFY_DROP;
+       }
 
        if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) {
                NV_DEBUG(drm, "service %s\n", name);
@@ -1122,6 +1130,8 @@ nouveau_connector_hotplug(struct nvif_notify *notify)
                drm_helper_hpd_irq_event(connector->dev);
        }
 
+       pm_runtime_mark_last_busy(drm->dev->dev);
+       pm_runtime_put_autosuspend(drm->dev->dev);
        return NVIF_NOTIFY_KEEP;
 }
 
index 139368b31916b0f5a680916f0bc261ece493ec8f..540c0cbbfcee41bf3fdae2fa339d71373e58a133 100644 (file)
@@ -293,7 +293,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
 
 static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
        .fb_create = nouveau_user_framebuffer_create,
-       .output_poll_changed = drm_fb_helper_output_poll_changed,
+       .output_poll_changed = nouveau_fbcon_output_poll_changed,
 };
 
 
@@ -355,8 +355,6 @@ nouveau_display_hpd_work(struct work_struct *work)
        pm_runtime_get_sync(drm->dev->dev);
 
        drm_helper_hpd_irq_event(drm->dev);
-       /* enable polling for external displays */
-       drm_kms_helper_poll_enable(drm->dev);
 
        pm_runtime_mark_last_busy(drm->dev->dev);
        pm_runtime_put_sync(drm->dev->dev);
@@ -379,15 +377,29 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val,
 {
        struct nouveau_drm *drm = container_of(nb, typeof(*drm), acpi_nb);
        struct acpi_bus_event *info = data;
+       int ret;
 
        if (!strcmp(info->device_class, ACPI_VIDEO_CLASS)) {
                if (info->type == ACPI_VIDEO_NOTIFY_PROBE) {
-                       /*
-                        * This may be the only indication we receive of a
-                        * connector hotplug on a runtime suspended GPU,
-                        * schedule hpd_work to check.
-                        */
-                       schedule_work(&drm->hpd_work);
+                       ret = pm_runtime_get(drm->dev->dev);
+                       if (ret == 1 || ret == -EACCES) {
+                               /* If the GPU is already awake, or in a state
+                                * where we can't wake it up, it can handle
+                                * it's own hotplug events.
+                                */
+                               pm_runtime_put_autosuspend(drm->dev->dev);
+                       } else if (ret == 0) {
+                               /* This may be the only indication we receive
+                                * of a connector hotplug on a runtime
+                                * suspended GPU, schedule hpd_work to check.
+                                */
+                               NV_DEBUG(drm, "ACPI requested connector reprobe\n");
+                               schedule_work(&drm->hpd_work);
+                               pm_runtime_put_noidle(drm->dev->dev);
+                       } else {
+                               NV_WARN(drm, "Dropped ACPI reprobe event due to RPM error: %d\n",
+                                       ret);
+                       }
 
                        /* acpi-video should not generate keypresses for this */
                        return NOTIFY_BAD;
@@ -411,6 +423,11 @@ nouveau_display_init(struct drm_device *dev)
        if (ret)
                return ret;
 
+       /* enable connector detection and polling for connectors without HPD
+        * support
+        */
+       drm_kms_helper_poll_enable(dev);
+
        /* enable hotplug interrupts */
        drm_connector_list_iter_begin(dev, &conn_iter);
        nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
@@ -425,7 +442,7 @@ nouveau_display_init(struct drm_device *dev)
 }
 
 void
-nouveau_display_fini(struct drm_device *dev, bool suspend)
+nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
 {
        struct nouveau_display *disp = nouveau_display(dev);
        struct nouveau_drm *drm = nouveau_drm(dev);
@@ -450,6 +467,9 @@ nouveau_display_fini(struct drm_device *dev, bool suspend)
        }
        drm_connector_list_iter_end(&conn_iter);
 
+       if (!runtime)
+               cancel_work_sync(&drm->hpd_work);
+
        drm_kms_helper_poll_disable(dev);
        disp->fini(dev);
 }
@@ -618,11 +638,11 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
                        }
                }
 
-               nouveau_display_fini(dev, true);
+               nouveau_display_fini(dev, true, runtime);
                return 0;
        }
 
-       nouveau_display_fini(dev, true);
+       nouveau_display_fini(dev, true, runtime);
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_framebuffer *nouveau_fb;
index 54aa7c3fa42dddfa96b684d308def526da9c4d1d..ff92b54ce448467b290a0c61f59d3e259fed19df 100644 (file)
@@ -62,7 +62,7 @@ nouveau_display(struct drm_device *dev)
 int  nouveau_display_create(struct drm_device *dev);
 void nouveau_display_destroy(struct drm_device *dev);
 int  nouveau_display_init(struct drm_device *dev);
-void nouveau_display_fini(struct drm_device *dev, bool suspend);
+void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime);
 int  nouveau_display_suspend(struct drm_device *dev, bool runtime);
 void nouveau_display_resume(struct drm_device *dev, bool runtime);
 int  nouveau_display_vblank_enable(struct drm_device *, unsigned int);
index c7ec86d6c3c910fdb73a7774eb921a414c156363..74d2283f2c28e7bb06f97856f93b610d12522a04 100644 (file)
@@ -230,7 +230,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
                mutex_unlock(&drm->master.lock);
        }
        if (ret) {
-               NV_ERROR(drm, "Client allocation failed: %d\n", ret);
+               NV_PRINTK(err, cli, "Client allocation failed: %d\n", ret);
                goto done;
        }
 
@@ -240,37 +240,37 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
                               }, sizeof(struct nv_device_v0),
                               &cli->device);
        if (ret) {
-               NV_ERROR(drm, "Device allocation failed: %d\n", ret);
+               NV_PRINTK(err, cli, "Device allocation failed: %d\n", ret);
                goto done;
        }
 
        ret = nvif_mclass(&cli->device.object, mmus);
        if (ret < 0) {
-               NV_ERROR(drm, "No supported MMU class\n");
+               NV_PRINTK(err, cli, "No supported MMU class\n");
                goto done;
        }
 
        ret = nvif_mmu_init(&cli->device.object, mmus[ret].oclass, &cli->mmu);
        if (ret) {
-               NV_ERROR(drm, "MMU allocation failed: %d\n", ret);
+               NV_PRINTK(err, cli, "MMU allocation failed: %d\n", ret);
                goto done;
        }
 
        ret = nvif_mclass(&cli->mmu.object, vmms);
        if (ret < 0) {
-               NV_ERROR(drm, "No supported VMM class\n");
+               NV_PRINTK(err, cli, "No supported VMM class\n");
                goto done;
        }
 
        ret = nouveau_vmm_init(cli, vmms[ret].oclass, &cli->vmm);
        if (ret) {
-               NV_ERROR(drm, "VMM allocation failed: %d\n", ret);
+               NV_PRINTK(err, cli, "VMM allocation failed: %d\n", ret);
                goto done;
        }
 
        ret = nvif_mclass(&cli->mmu.object, mems);
        if (ret < 0) {
-               NV_ERROR(drm, "No supported MEM class\n");
+               NV_PRINTK(err, cli, "No supported MEM class\n");
                goto done;
        }
 
@@ -592,10 +592,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
                pm_runtime_allow(dev->dev);
                pm_runtime_mark_last_busy(dev->dev);
                pm_runtime_put(dev->dev);
-       } else {
-               /* enable polling for external displays */
-               drm_kms_helper_poll_enable(dev);
        }
+
        return 0;
 
 fail_dispinit:
@@ -629,7 +627,7 @@ nouveau_drm_unload(struct drm_device *dev)
        nouveau_debugfs_fini(drm);
 
        if (dev->mode_config.num_crtc)
-               nouveau_display_fini(dev, false);
+               nouveau_display_fini(dev, false, false);
        nouveau_display_destroy(dev);
 
        nouveau_bios_takedown(dev);
@@ -835,7 +833,6 @@ nouveau_pmops_runtime_suspend(struct device *dev)
                return -EBUSY;
        }
 
-       drm_kms_helper_poll_disable(drm_dev);
        nouveau_switcheroo_optimus_dsm();
        ret = nouveau_do_suspend(drm_dev, true);
        pci_save_state(pdev);
index 844498c4267cb691ecde39083740ca6d08a86390..0f64c0a1d4b30236243e6229afa19d990592f86c 100644 (file)
@@ -466,6 +466,7 @@ nouveau_fbcon_set_suspend_work(struct work_struct *work)
        console_unlock();
 
        if (state == FBINFO_STATE_RUNNING) {
+               nouveau_fbcon_hotplug_resume(drm->fbcon);
                pm_runtime_mark_last_busy(drm->dev->dev);
                pm_runtime_put_sync(drm->dev->dev);
        }
@@ -487,6 +488,61 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
        schedule_work(&drm->fbcon_work);
 }
 
+void
+nouveau_fbcon_output_poll_changed(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_drm(dev);
+       struct nouveau_fbdev *fbcon = drm->fbcon;
+       int ret;
+
+       if (!fbcon)
+               return;
+
+       mutex_lock(&fbcon->hotplug_lock);
+
+       ret = pm_runtime_get(dev->dev);
+       if (ret == 1 || ret == -EACCES) {
+               drm_fb_helper_hotplug_event(&fbcon->helper);
+
+               pm_runtime_mark_last_busy(dev->dev);
+               pm_runtime_put_autosuspend(dev->dev);
+       } else if (ret == 0) {
+               /* If the GPU was already in the process of suspending before
+                * this event happened, then we can't block here as we'll
+                * deadlock the runtime pmops since they wait for us to
+                * finish. So, just defer this event for when we runtime
+                * resume again. It will be handled by fbcon_work.
+                */
+               NV_DEBUG(drm, "fbcon HPD event deferred until runtime resume\n");
+               fbcon->hotplug_waiting = true;
+               pm_runtime_put_noidle(drm->dev->dev);
+       } else {
+               DRM_WARN("fbcon HPD event lost due to RPM failure: %d\n",
+                        ret);
+       }
+
+       mutex_unlock(&fbcon->hotplug_lock);
+}
+
+void
+nouveau_fbcon_hotplug_resume(struct nouveau_fbdev *fbcon)
+{
+       struct nouveau_drm *drm;
+
+       if (!fbcon)
+               return;
+       drm = nouveau_drm(fbcon->helper.dev);
+
+       mutex_lock(&fbcon->hotplug_lock);
+       if (fbcon->hotplug_waiting) {
+               fbcon->hotplug_waiting = false;
+
+               NV_DEBUG(drm, "Handling deferred fbcon HPD events\n");
+               drm_fb_helper_hotplug_event(&fbcon->helper);
+       }
+       mutex_unlock(&fbcon->hotplug_lock);
+}
+
 int
 nouveau_fbcon_init(struct drm_device *dev)
 {
@@ -505,6 +561,7 @@ nouveau_fbcon_init(struct drm_device *dev)
 
        drm->fbcon = fbcon;
        INIT_WORK(&drm->fbcon_work, nouveau_fbcon_set_suspend_work);
+       mutex_init(&fbcon->hotplug_lock);
 
        drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs);
 
index a6f192ea3fa6758934f2a54054f10708d2c73f14..db9d52047ef8dfbfc77fa96fcdb250c16f18e951 100644 (file)
@@ -41,6 +41,9 @@ struct nouveau_fbdev {
        struct nvif_object gdi;
        struct nvif_object blit;
        struct nvif_object twod;
+
+       struct mutex hotplug_lock;
+       bool hotplug_waiting;
 };
 
 void nouveau_fbcon_restore(void);
@@ -68,6 +71,8 @@ void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
 void nouveau_fbcon_accel_save_disable(struct drm_device *dev);
 void nouveau_fbcon_accel_restore(struct drm_device *dev);
 
+void nouveau_fbcon_output_poll_changed(struct drm_device *dev);
+void nouveau_fbcon_hotplug_resume(struct nouveau_fbdev *fbcon);
 extern int nouveau_nofbaccel;
 
 #endif /* __NV50_FBCON_H__ */
index 3da5a4305aa4847a32c0abf398a50e7a0dc90b7e..8f1ce4833230a1e693f0a76387022289fc1317d3 100644 (file)
@@ -46,12 +46,10 @@ nouveau_switcheroo_set_state(struct pci_dev *pdev,
                pr_err("VGA switcheroo: switched nouveau on\n");
                dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                nouveau_pmops_resume(&pdev->dev);
-               drm_kms_helper_poll_enable(dev);
                dev->switch_power_state = DRM_SWITCH_POWER_ON;
        } else {
                pr_err("VGA switcheroo: switched nouveau off\n");
                dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
-               drm_kms_helper_poll_disable(dev);
                nouveau_switcheroo_optimus_dsm();
                nouveau_pmops_suspend(&pdev->dev);
                dev->switch_power_state = DRM_SWITCH_POWER_OFF;
index 32fa94a9773f558686cf8a698ac3de53305a6007..cbd33e87b799a70b6085707de74bafaefe047e24 100644 (file)
@@ -275,6 +275,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
        struct nvkm_outp *outp, *outt, *pair;
        struct nvkm_conn *conn;
        struct nvkm_head *head;
+       struct nvkm_ior *ior;
        struct nvbios_connE connE;
        struct dcb_output dcbE;
        u8  hpd = 0, ver, hdr;
@@ -399,6 +400,19 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
                        return ret;
        }
 
+       /* Enforce identity-mapped SOR assignment for panels, which have
+        * certain bits (ie. backlight controls) wired to a specific SOR.
+        */
+       list_for_each_entry(outp, &disp->outp, head) {
+               if (outp->conn->info.type == DCB_CONNECTOR_LVDS ||
+                   outp->conn->info.type == DCB_CONNECTOR_eDP) {
+                       ior = nvkm_ior_find(disp, SOR, ffs(outp->info.or) - 1);
+                       if (!WARN_ON(!ior))
+                               ior->identity = true;
+                       outp->identity = true;
+               }
+       }
+
        i = 0;
        list_for_each_entry(head, &disp->head, head)
                i = max(i, head->id + 1);
index 7c5bed29ffef164224825a3f9e0eaac7aa786239..5f301e632599b471c54291797b59c0d51e18be9a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <subdev/bios.h>
 #include <subdev/bios/init.h>
+#include <subdev/gpio.h>
 #include <subdev/i2c.h>
 
 #include <nvif/event.h>
@@ -412,14 +413,10 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
 }
 
 static void
-nvkm_dp_release(struct nvkm_outp *outp, struct nvkm_ior *ior)
+nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior)
 {
        struct nvkm_dp *dp = nvkm_dp(outp);
 
-       /* Prevent link from being retrained if sink sends an IRQ. */
-       atomic_set(&dp->lt.done, 0);
-       ior->dp.nr = 0;
-
        /* Execute DisableLT script from DP Info Table. */
        nvbios_init(&ior->disp->engine.subdev, dp->info.script[4],
                init.outp = &dp->outp.info;
@@ -428,6 +425,16 @@ nvkm_dp_release(struct nvkm_outp *outp, struct nvkm_ior *ior)
        );
 }
 
+static void
+nvkm_dp_release(struct nvkm_outp *outp)
+{
+       struct nvkm_dp *dp = nvkm_dp(outp);
+
+       /* Prevent link from being retrained if sink sends an IRQ. */
+       atomic_set(&dp->lt.done, 0);
+       dp->outp.ior->dp.nr = 0;
+}
+
 static int
 nvkm_dp_acquire(struct nvkm_outp *outp)
 {
@@ -491,7 +498,7 @@ nvkm_dp_acquire(struct nvkm_outp *outp)
        return ret;
 }
 
-static void
+static bool
 nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
 {
        struct nvkm_i2c_aux *aux = dp->aux;
@@ -505,7 +512,7 @@ nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
 
                if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, dp->dpcd,
                                sizeof(dp->dpcd)))
-                       return;
+                       return true;
        }
 
        if (dp->present) {
@@ -515,6 +522,7 @@ nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
        }
 
        atomic_set(&dp->lt.done, 0);
+       return false;
 }
 
 static int
@@ -555,9 +563,38 @@ nvkm_dp_fini(struct nvkm_outp *outp)
 static void
 nvkm_dp_init(struct nvkm_outp *outp)
 {
+       struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio;
        struct nvkm_dp *dp = nvkm_dp(outp);
+
        nvkm_notify_put(&dp->outp.conn->hpd);
-       nvkm_dp_enable(dp, true);
+
+       /* eDP panels need powering on by us (if the VBIOS doesn't default it
+        * to on) before doing any AUX channel transactions.  LVDS panel power
+        * is handled by the SOR itself, and not required for LVDS DDC.
+        */
+       if (dp->outp.conn->info.type == DCB_CONNECTOR_eDP) {
+               int power = nvkm_gpio_get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
+               if (power == 0)
+                       nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
+
+               /* We delay here unconditionally, even if already powered,
+                * because some laptop panels having a significant resume
+                * delay before the panel begins responding.
+                *
+                * This is likely a bit of a hack, but no better idea for
+                * handling this at the moment.
+                */
+               msleep(300);
+
+               /* If the eDP panel can't be detected, we need to restore
+                * the panel power GPIO to avoid breaking another output.
+                */
+               if (!nvkm_dp_enable(dp, true) && power == 0)
+                       nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 0);
+       } else {
+               nvkm_dp_enable(dp, true);
+       }
+
        nvkm_notify_get(&dp->hpd);
 }
 
@@ -576,6 +613,7 @@ nvkm_dp_func = {
        .fini = nvkm_dp_fini,
        .acquire = nvkm_dp_acquire,
        .release = nvkm_dp_release,
+       .disable = nvkm_dp_disable,
 };
 
 static int
index e0b4e0c5704ee8560a5584832da069ae59f699e1..19911211a12aa55a200ac75bc2f88958598d96bd 100644 (file)
@@ -16,6 +16,7 @@ struct nvkm_ior {
        char name[8];
 
        struct list_head head;
+       bool identity;
 
        struct nvkm_ior_state {
                struct nvkm_outp *outp;
index f89c7b977aa5d269b3a91a0026610eb036c0463e..def005dd5fdaae020fd3ef7404e9f58b5369e082 100644 (file)
@@ -501,11 +501,11 @@ nv50_disp_super_2_0(struct nv50_disp *disp, struct nvkm_head *head)
        nv50_disp_super_ied_off(head, ior, 2);
 
        /* If we're shutting down the OR's only active head, execute
-        * the output path's release function.
+        * the output path's disable function.
         */
        if (ior->arm.head == (1 << head->id)) {
-               if ((outp = ior->arm.outp) && outp->func->release)
-                       outp->func->release(outp, ior);
+               if ((outp = ior->arm.outp) && outp->func->disable)
+                       outp->func->disable(outp, ior);
        }
 }
 
index be9e7f8c3b2392fa96643f91391e606196ad7a67..c62030c96fba0932decd996fd46f3f9a308864d9 100644 (file)
@@ -93,6 +93,8 @@ nvkm_outp_release(struct nvkm_outp *outp, u8 user)
        if (ior) {
                outp->acquired &= ~user;
                if (!outp->acquired) {
+                       if (outp->func->release && outp->ior)
+                               outp->func->release(outp);
                        outp->ior->asy.outp = NULL;
                        outp->ior = NULL;
                }
@@ -127,17 +129,26 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user)
        if (proto == UNKNOWN)
                return -ENOSYS;
 
+       /* Deal with panels requiring identity-mapped SOR assignment. */
+       if (outp->identity) {
+               ior = nvkm_ior_find(outp->disp, SOR, ffs(outp->info.or) - 1);
+               if (WARN_ON(!ior))
+                       return -ENOSPC;
+               return nvkm_outp_acquire_ior(outp, user, ior);
+       }
+
        /* First preference is to reuse the OR that is currently armed
         * on HW, if any, in order to prevent unnecessary switching.
         */
        list_for_each_entry(ior, &outp->disp->ior, head) {
-               if (!ior->asy.outp && ior->arm.outp == outp)
+               if (!ior->identity && !ior->asy.outp && ior->arm.outp == outp)
                        return nvkm_outp_acquire_ior(outp, user, ior);
        }
 
        /* Failing that, a completely unused OR is the next best thing. */
        list_for_each_entry(ior, &outp->disp->ior, head) {
-               if (!ior->asy.outp && ior->type == type && !ior->arm.outp &&
+               if (!ior->identity &&
+                   !ior->asy.outp && ior->type == type && !ior->arm.outp &&
                    (ior->func->route.set || ior->id == __ffs(outp->info.or)))
                        return nvkm_outp_acquire_ior(outp, user, ior);
        }
@@ -146,7 +157,7 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user)
         * but will be released during the next modeset.
         */
        list_for_each_entry(ior, &outp->disp->ior, head) {
-               if (!ior->asy.outp && ior->type == type &&
+               if (!ior->identity && !ior->asy.outp && ior->type == type &&
                    (ior->func->route.set || ior->id == __ffs(outp->info.or)))
                        return nvkm_outp_acquire_ior(outp, user, ior);
        }
@@ -245,7 +256,6 @@ nvkm_outp_ctor(const struct nvkm_outp_func *func, struct nvkm_disp *disp,
        outp->index = index;
        outp->info = *dcbE;
        outp->i2c = nvkm_i2c_bus_find(i2c, dcbE->i2c_index);
-       outp->or = ffs(outp->info.or) - 1;
 
        OUTP_DBG(outp, "type %02x loc %d or %d link %d con %x "
                       "edid %x bus %d head %x",
index ea84d7d5741ad5a5e771483a225f6fea8a663223..6c8aa5cfed9d839b561a473e0883df827d16eb3c 100644 (file)
@@ -13,10 +13,10 @@ struct nvkm_outp {
        struct dcb_output info;
 
        struct nvkm_i2c_bus *i2c;
-       int or;
 
        struct list_head head;
        struct nvkm_conn *conn;
+       bool identity;
 
        /* Assembly state. */
 #define NVKM_OUTP_PRIV 1
@@ -41,7 +41,8 @@ struct nvkm_outp_func {
        void (*init)(struct nvkm_outp *);
        void (*fini)(struct nvkm_outp *);
        int (*acquire)(struct nvkm_outp *);
-       void (*release)(struct nvkm_outp *, struct nvkm_ior *);
+       void (*release)(struct nvkm_outp *);
+       void (*disable)(struct nvkm_outp *, struct nvkm_ior *);
 };
 
 #define OUTP_MSG(o,l,f,a...) do {                                              \
index b80618e354919b11b00b6c88b12dbc648ba4680f..17235e940ca9e354226836b4bb9e8582a48e1f90 100644 (file)
@@ -86,10 +86,8 @@ pmu_load(struct nv50_devinit *init, u8 type, bool post,
        struct nvkm_bios *bios = subdev->device->bios;
        struct nvbios_pmuR pmu;
 
-       if (!nvbios_pmuRm(bios, type, &pmu)) {
-               nvkm_error(subdev, "VBIOS PMU fuc %02x not found\n", type);
+       if (!nvbios_pmuRm(bios, type, &pmu))
                return -EINVAL;
-       }
 
        if (!post)
                return 0;
@@ -124,29 +122,30 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
                return -EINVAL;
        }
 
+       /* Upload DEVINIT application from VBIOS onto PMU. */
        ret = pmu_load(init, 0x04, post, &exec, &args);
-       if (ret)
+       if (ret) {
+               nvkm_error(subdev, "VBIOS PMU/DEVINIT not found\n");
                return ret;
+       }
 
-       /* upload first chunk of init data */
+       /* Upload tables required by opcodes in boot scripts. */
        if (post) {
-               // devinit tables
                u32 pmu = pmu_args(init, args + 0x08, 0x08);
                u32 img = nvbios_rd16(bios, bit_I.offset + 0x14);
                u32 len = nvbios_rd16(bios, bit_I.offset + 0x16);
                pmu_data(init, pmu, img, len);
        }
 
-       /* upload second chunk of init data */
+       /* Upload boot scripts. */
        if (post) {
-               // devinit boot scripts
                u32 pmu = pmu_args(init, args + 0x08, 0x10);
                u32 img = nvbios_rd16(bios, bit_I.offset + 0x18);
                u32 len = nvbios_rd16(bios, bit_I.offset + 0x1a);
                pmu_data(init, pmu, img, len);
        }
 
-       /* execute init tables */
+       /* Execute DEVINIT. */
        if (post) {
                nvkm_wr32(device, 0x10a040, 0x00005000);
                pmu_exec(init, exec);
@@ -157,8 +156,11 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
                        return -ETIMEDOUT;
        }
 
-       /* load and execute some other ucode image (bios therm?) */
-       return pmu_load(init, 0x01, post, NULL, NULL);
+       /* Optional: Execute PRE_OS application on PMU, which should at
+        * least take care of fans until a full PMU has been loaded.
+        */
+       pmu_load(init, 0x01, post, NULL, NULL);
+       return 0;
 }
 
 static const struct nvkm_devinit_func
index de269eb482dd03cc7c2fd8b5a707d1566b1360e5..7459def78d504f006a2f7f0b625ba3372238b7ec 100644 (file)
@@ -1423,7 +1423,7 @@ nvkm_vmm_get(struct nvkm_vmm *vmm, u8 page, u64 size, struct nvkm_vma **pvma)
 void
 nvkm_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst)
 {
-       if (vmm->func->part && inst) {
+       if (inst && vmm->func->part) {
                mutex_lock(&vmm->mutex);
                vmm->func->part(vmm, inst);
                mutex_unlock(&vmm->mutex);
index a534b225e31b33b20184dab5c72fd7d98970f9f4..5fa0441bb6df8fea7fd54433a7f7b68cfa28d3be 100644 (file)
@@ -111,7 +111,8 @@ static int vexpress_muxfpga_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id vexpress_muxfpga_match[] = {
-       { .compatible = "arm,vexpress-muxfpga", }
+       { .compatible = "arm,vexpress-muxfpga", },
+       {}
 };
 
 static struct platform_driver vexpress_muxfpga_driver = {
index dd19d674055c625c20e4e78cfdc61b50fefa6743..8b0cd08034e0c74bb80f57fca43710228077b29c 100644 (file)
@@ -418,7 +418,6 @@ static const struct of_device_id sun4i_drv_of_table[] = {
        { .compatible = "allwinner,sun8i-a33-display-engine" },
        { .compatible = "allwinner,sun8i-a83t-display-engine" },
        { .compatible = "allwinner,sun8i-h3-display-engine" },
-       { .compatible = "allwinner,sun8i-r40-display-engine" },
        { .compatible = "allwinner,sun8i-v3s-display-engine" },
        { .compatible = "allwinner,sun9i-a80-display-engine" },
        { }
index 82502b351aec8b6a9983b0fa8f88e6bb3106be15..a564b5dfe082839896833db50ffbabbcfbe014ee 100644 (file)
@@ -398,7 +398,6 @@ static struct regmap_config sun8i_hdmi_phy_regmap_config = {
 
 static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
        .has_phy_clk = true,
-       .has_second_pll = true,
        .phy_init = &sun8i_hdmi_phy_init_h3,
        .phy_disable = &sun8i_hdmi_phy_disable_h3,
        .phy_config = &sun8i_hdmi_phy_config_h3,
index fc3713608f78d9742bb0364f7d81f2e3db10bd55..cb65b0ed53fd0e520a77327e185d0011e619b915 100644 (file)
@@ -545,22 +545,6 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
        .vi_num         = 1,
 };
 
-static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
-       .ccsc           = 0,
-       .mod_rate       = 297000000,
-       .scaler_mask    = 0xf,
-       .ui_num         = 3,
-       .vi_num         = 1,
-};
-
-static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
-       .ccsc           = 1,
-       .mod_rate       = 297000000,
-       .scaler_mask    = 0x3,
-       .ui_num         = 1,
-       .vi_num         = 1,
-};
-
 static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
        .vi_num = 2,
        .ui_num = 1,
@@ -582,14 +566,6 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
                .compatible = "allwinner,sun8i-h3-de2-mixer-0",
                .data = &sun8i_h3_mixer0_cfg,
        },
-       {
-               .compatible = "allwinner,sun8i-r40-de2-mixer-0",
-               .data = &sun8i_r40_mixer0_cfg,
-       },
-       {
-               .compatible = "allwinner,sun8i-r40-de2-mixer-1",
-               .data = &sun8i_r40_mixer1_cfg,
-       },
        {
                .compatible = "allwinner,sun8i-v3s-de2-mixer",
                .data = &sun8i_v3s_mixer_cfg,
index 55fe398d8290d9107e9f803ad583122c5eb12522..d5240b777a8fdfc6da3aa5b9f57acab5597985ab 100644 (file)
@@ -253,7 +253,6 @@ static int sun8i_tcon_top_remove(struct platform_device *pdev)
 
 /* sun4i_drv uses this list to check if a device node is a TCON TOP */
 const struct of_device_id sun8i_tcon_top_of_table[] = {
-       { .compatible = "allwinner,sun8i-r40-tcon-top" },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
index dbb62f6eb48a5fba107acd9981b3cfae45f8f6a4..dd9ffded223b5fb09c025d518d5090b27716b560 100644 (file)
@@ -432,9 +432,11 @@ static void udl_fbdev_destroy(struct drm_device *dev,
 {
        drm_fb_helper_unregister_fbi(&ufbdev->helper);
        drm_fb_helper_fini(&ufbdev->helper);
-       drm_framebuffer_unregister_private(&ufbdev->ufb.base);
-       drm_framebuffer_cleanup(&ufbdev->ufb.base);
-       drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
+       if (ufbdev->ufb.obj) {
+               drm_framebuffer_unregister_private(&ufbdev->ufb.base);
+               drm_framebuffer_cleanup(&ufbdev->ufb.base);
+               drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
+       }
 }
 
 int udl_fbdev_init(struct drm_device *dev)
index cfb50fedfa2b3a49bd37198f093eff841ecd3603..a3275fa66b7b9754c32580857e5b23fba0c58ec5 100644 (file)
@@ -297,6 +297,9 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
        vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0],
                                                       vc4_state->crtc_h);
 
+       vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE &&
+                              vc4_state->y_scaling[0] == VC4_SCALING_NONE);
+
        if (num_planes > 1) {
                vc4_state->is_yuv = true;
 
@@ -312,24 +315,17 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
                        vc4_get_scaling_mode(vc4_state->src_h[1],
                                             vc4_state->crtc_h);
 
-               /* YUV conversion requires that scaling be enabled,
-                * even on a plane that's otherwise 1:1.  Choose TPZ
-                * for simplicity.
+               /* YUV conversion requires that horizontal scaling be enabled,
+                * even on a plane that's otherwise 1:1. Looks like only PPF
+                * works in that case, so let's pick that one.
                 */
-               if (vc4_state->x_scaling[0] == VC4_SCALING_NONE)
-                       vc4_state->x_scaling[0] = VC4_SCALING_TPZ;
-               if (vc4_state->y_scaling[0] == VC4_SCALING_NONE)
-                       vc4_state->y_scaling[0] = VC4_SCALING_TPZ;
+               if (vc4_state->is_unity)
+                       vc4_state->x_scaling[0] = VC4_SCALING_PPF;
        } else {
                vc4_state->x_scaling[1] = VC4_SCALING_NONE;
                vc4_state->y_scaling[1] = VC4_SCALING_NONE;
        }
 
-       vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE &&
-                              vc4_state->y_scaling[0] == VC4_SCALING_NONE &&
-                              vc4_state->x_scaling[1] == VC4_SCALING_NONE &&
-                              vc4_state->y_scaling[1] == VC4_SCALING_NONE);
-
        /* No configuring scaling on the cursor plane, since it gets
           non-vblank-synced updates, and scaling requires requires
           LBM changes which have to be vblank-synced.
@@ -672,7 +668,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
                vc4_dlist_write(vc4_state, SCALER_CSC2_ITR_R_601_5);
        }
 
-       if (!vc4_state->is_unity) {
+       if (vc4_state->x_scaling[0] != VC4_SCALING_NONE ||
+           vc4_state->x_scaling[1] != VC4_SCALING_NONE ||
+           vc4_state->y_scaling[0] != VC4_SCALING_NONE ||
+           vc4_state->y_scaling[1] != VC4_SCALING_NONE) {
                /* LBM Base Address. */
                if (vc4_state->y_scaling[0] != VC4_SCALING_NONE ||
                    vc4_state->y_scaling[1] != VC4_SCALING_NONE) {
index 1f134570b7599483e2768cfcbe785409f2b7ba04..f0ab6b2313bbed89f5879fd27a6e2c268fc8c613 100644 (file)
@@ -3729,7 +3729,7 @@ int vmw_validate_single_buffer(struct vmw_private *dev_priv,
 {
        struct vmw_buffer_object *vbo =
                container_of(bo, struct vmw_buffer_object, base);
-       struct ttm_operation_ctx ctx = { interruptible, true };
+       struct ttm_operation_ctx ctx = { interruptible, false };
        int ret;
 
        if (vbo->pin_count > 0)
index 23beff5d8e3c37e6904314db295cc9896657a38f..6a712a8d59e93b68fb68c98358af37b5e20d7680 100644 (file)
@@ -1512,21 +1512,19 @@ static int vmw_kms_check_display_memory(struct drm_device *dev,
                                        struct drm_rect *rects)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
-       struct drm_mode_config *mode_config = &dev->mode_config;
        struct drm_rect bounding_box = {0};
        u64 total_pixels = 0, pixel_mem, bb_mem;
        int i;
 
        for (i = 0; i < num_rects; i++) {
                /*
-                * Currently this check is limiting the topology within max
-                * texture/screentarget size. This should change in future when
-                * user-space support multiple fb with topology.
+                * For STDU only individual screen (screen target) is limited by
+                * SCREENTARGET_MAX_WIDTH/HEIGHT registers.
                 */
-               if (rects[i].x1 < 0 ||  rects[i].y1 < 0 ||
-                   rects[i].x2 > mode_config->max_width ||
-                   rects[i].y2 > mode_config->max_height) {
-                       DRM_ERROR("Invalid GUI layout.\n");
+               if (dev_priv->active_display_unit == vmw_du_screen_target &&
+                   (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width ||
+                    drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) {
+                       DRM_ERROR("Screen size not supported.\n");
                        return -EINVAL;
                }
 
@@ -1615,7 +1613,7 @@ static int vmw_kms_check_topology(struct drm_device *dev,
                struct drm_connector_state *conn_state;
                struct vmw_connector_state *vmw_conn_state;
 
-               if (!new_crtc_state->enable && old_crtc_state->enable) {
+               if (!new_crtc_state->enable) {
                        rects[i].x1 = 0;
                        rects[i].y1 = 0;
                        rects[i].x2 = 0;
@@ -2216,12 +2214,16 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
        if (dev_priv->assume_16bpp)
                assumed_bpp = 2;
 
+       max_width  = min(max_width,  dev_priv->texture_max_width);
+       max_height = min(max_height, dev_priv->texture_max_height);
+
+       /*
+        * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/
+        * HEIGHT registers.
+        */
        if (dev_priv->active_display_unit == vmw_du_screen_target) {
                max_width  = min(max_width,  dev_priv->stdu_max_width);
-               max_width  = min(max_width,  dev_priv->texture_max_width);
-
                max_height = min(max_height, dev_priv->stdu_max_height);
-               max_height = min(max_height, dev_priv->texture_max_height);
        }
 
        /* Add preferred mode */
@@ -2376,6 +2378,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
+       struct drm_mode_config *mode_config = &dev->mode_config;
        struct drm_vmw_update_layout_arg *arg =
                (struct drm_vmw_update_layout_arg *)data;
        void __user *user_rects;
@@ -2421,6 +2424,21 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                drm_rects[i].y1 = curr_rect.y;
                drm_rects[i].x2 = curr_rect.x + curr_rect.w;
                drm_rects[i].y2 = curr_rect.y + curr_rect.h;
+
+               /*
+                * Currently this check is limiting the topology within
+                * mode_config->max (which actually is max texture size
+                * supported by virtual device). This limit is here to address
+                * window managers that create a big framebuffer for whole
+                * topology.
+                */
+               if (drm_rects[i].x1 < 0 ||  drm_rects[i].y1 < 0 ||
+                   drm_rects[i].x2 > mode_config->max_width ||
+                   drm_rects[i].y2 > mode_config->max_height) {
+                       DRM_ERROR("Invalid GUI layout.\n");
+                       ret = -EINVAL;
+                       goto out_free;
+               }
        }
 
        ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects);
index 93f6b96ca7bbbe179dfa74957dd854c04b06b17c..f30e839f7bfd2d946bbe908e20211719646ff8b5 100644 (file)
@@ -1600,31 +1600,6 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
 
        dev_priv->active_display_unit = vmw_du_screen_target;
 
-       if (dev_priv->capabilities & SVGA_CAP_3D) {
-               /*
-                * For 3D VMs, display (scanout) buffer size is the smaller of
-                * max texture and max STDU
-                */
-               uint32_t max_width, max_height;
-
-               max_width = min(dev_priv->texture_max_width,
-                               dev_priv->stdu_max_width);
-               max_height = min(dev_priv->texture_max_height,
-                                dev_priv->stdu_max_height);
-
-               dev->mode_config.max_width = max_width;
-               dev->mode_config.max_height = max_height;
-       } else {
-               /*
-                * Given various display aspect ratios, there's no way to
-                * estimate these using prim_bb_mem.  So just set these to
-                * something arbitrarily large and we will reject any layout
-                * that doesn't fit prim_bb_mem later
-                */
-               dev->mode_config.max_width = 8192;
-               dev->mode_config.max_height = 8192;
-       }
-
        vmw_kms_create_implicit_placement_property(dev_priv, false);
 
        for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) {
index e125233e074bf82a1128543ca5c8f9fd2b28604c..80a01cd4c051338654b629f3205b32259dd53ba3 100644 (file)
@@ -1404,22 +1404,17 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
        *srf_out = NULL;
 
        if (for_scanout) {
-               uint32_t max_width, max_height;
-
                if (!svga3dsurface_is_screen_target_format(format)) {
                        DRM_ERROR("Invalid Screen Target surface format.");
                        return -EINVAL;
                }
 
-               max_width = min(dev_priv->texture_max_width,
-                               dev_priv->stdu_max_width);
-               max_height = min(dev_priv->texture_max_height,
-                                dev_priv->stdu_max_height);
-
-               if (size.width > max_width || size.height > max_height) {
+               if (size.width > dev_priv->texture_max_width ||
+                   size.height > dev_priv->texture_max_height) {
                        DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u",
                                  size.width, size.height,
-                                 max_width, max_height);
+                                 dev_priv->texture_max_width,
+                                 dev_priv->texture_max_height);
                        return -EINVAL;
                }
        } else {
@@ -1495,8 +1490,17 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
        if (srf->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)
                srf->res.backup_size += sizeof(SVGA3dDXSOState);
 
+       /*
+        * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with
+        * size greater than STDU max width/height. This is really a workaround
+        * to support creation of big framebuffer requested by some user-space
+        * for whole topology. That big framebuffer won't really be used for
+        * binding with screen target as during prepare_fb a separate surface is
+        * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag.
+        */
        if (dev_priv->active_display_unit == vmw_du_screen_target &&
-           for_scanout)
+           for_scanout && size.width <= dev_priv->stdu_max_width &&
+           size.height <= dev_priv->stdu_max_height)
                srf->flags |= SVGA3D_SURFACE_SCREENTARGET;
 
        /*
index a96bf46bc483fa42e2cd2e185a345ed24356b606..cf2a18571d484d078dc1eabc59a3d6ff0f11ab07 100644 (file)
@@ -215,6 +215,8 @@ static void vga_switcheroo_enable(void)
                        return;
 
                client->id = ret | ID_BIT_AUDIO;
+               if (client->ops->gpu_bound)
+                       client->ops->gpu_bound(client->pdev, ret);
        }
 
        vga_switcheroo_debugfs_init(&vgasr_priv);
index 25b7bd56ae1156aa209980f65a00d2c5a6efebf2..1cb41992aaa1f650f89cbf5ace72bd46786d7abc 100644 (file)
@@ -335,7 +335,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
                struct hid_field *field, struct hid_usage *usage,
                unsigned long **bit, int *max)
 {
-       if (usage->hid == (HID_UP_CUSTOM | 0x0003)) {
+       if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
+                       usage->hid == (HID_UP_MSVENDOR | 0x0003)) {
                /* The fn key on Apple USB keyboards */
                set_bit(EV_REP, hi->input->evbit);
                hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
@@ -472,6 +473,12 @@ static const struct hid_device_id apple_devices[] = {
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI),
                .driver_data = APPLE_HAS_FN },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI),
+               .driver_data = APPLE_HAS_FN },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI),
+               .driver_data = APPLE_HAS_FN },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI),
+               .driver_data = APPLE_HAS_FN },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
                .driver_data = APPLE_HAS_FN },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
index 3da354af7a0aac6ca129124eb6e511ea32c9535b..44564f61e9cc3c85250e2e6d1e5ff47ed95dcd4d 100644 (file)
@@ -1000,7 +1000,7 @@ int hid_open_report(struct hid_device *device)
        parser = vzalloc(sizeof(struct hid_parser));
        if (!parser) {
                ret = -ENOMEM;
-               goto err;
+               goto alloc_err;
        }
 
        parser->device = device;
@@ -1039,6 +1039,7 @@ int hid_open_report(struct hid_device *device)
                                hid_err(device, "unbalanced delimiter at end of report description\n");
                                goto err;
                        }
+                       kfree(parser->collection_stack);
                        vfree(parser);
                        device->status |= HID_STAT_PARSED;
                        return 0;
@@ -1047,6 +1048,8 @@ int hid_open_report(struct hid_device *device)
 
        hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
 err:
+       kfree(parser->collection_stack);
+alloc_err:
        vfree(parser);
        hid_close_report(device);
        return ret;
index 79bdf0c7e3516bc0d5055309cac268145507f9d2..5146ee029db4bd6c35bb3a15cdd25b6caf54c64e 100644 (file)
@@ -88,6 +88,7 @@
 #define USB_DEVICE_ID_ANTON_TOUCH_PAD  0x3101
 
 #define USB_VENDOR_ID_APPLE            0x05ac
+#define BT_VENDOR_ID_APPLE             0x004c
 #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE        0x0304
 #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
 #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD      0x030e
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO   0x0256
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS   0x0257
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI   0x0267
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI   0x026c
 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI   0x0290
 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO    0x0291
 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS    0x0292
 #define I2C_VENDOR_ID_HANTICK          0x0911
 #define I2C_PRODUCT_ID_HANTICK_5288    0x5288
 
-#define I2C_VENDOR_ID_RAYD             0x2386
-#define I2C_PRODUCT_ID_RAYD_3118       0x3118
-
 #define USB_VENDOR_ID_HANWANG          0x0b57
 #define USB_DEVICE_ID_HANWANG_TABLET_FIRST     0x5000
 #define USB_DEVICE_ID_HANWANG_TABLET_LAST      0x8fff
 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
 #define USB_DEVICE_ID_SAITEK_PS1000    0x0621
 #define USB_DEVICE_ID_SAITEK_RAT7_OLD  0x0ccb
+#define USB_DEVICE_ID_SAITEK_RAT7_CONTAGION    0x0ccd
 #define USB_DEVICE_ID_SAITEK_RAT7      0x0cd7
 #define USB_DEVICE_ID_SAITEK_RAT9      0x0cfa
 #define USB_DEVICE_ID_SAITEK_MMO7      0x0cd0
index 4e94ea3e280a3c66a00cdf0709569a131bf4ee49..a481eaf39e887bad41d89bf251c0dc4a8f2a2096 100644 (file)
@@ -1582,6 +1582,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
        input_dev->dev.parent = &hid->dev;
 
        hidinput->input = input_dev;
+       hidinput->application = application;
        list_add_tail(&hidinput->list, &hid->inputs);
 
        INIT_LIST_HEAD(&hidinput->reports);
@@ -1677,8 +1678,7 @@ static struct hid_input *hidinput_match_application(struct hid_report *report)
        struct hid_input *hidinput;
 
        list_for_each_entry(hidinput, &hid->inputs, list) {
-               if (hidinput->report &&
-                   hidinput->report->application == report->application)
+               if (hidinput->application == report->application)
                        return hidinput;
        }
 
@@ -1815,6 +1815,7 @@ void hidinput_disconnect(struct hid_device *hid)
                        input_unregister_device(hidinput->input);
                else
                        input_free_device(hidinput->input);
+               kfree(hidinput->name);
                kfree(hidinput);
        }
 
index 40fbb7c52723378eaf32d351f9541dd7ef0d61e3..da954f3f4da7fcf5071522eec3a6b5b62dd46eed 100644 (file)
@@ -1375,7 +1375,8 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
                                     struct hid_usage *usage,
                                     enum latency_mode latency,
                                     bool surface_switch,
-                                    bool button_switch)
+                                    bool button_switch,
+                                    bool *inputmode_found)
 {
        struct mt_device *td = hid_get_drvdata(hdev);
        struct mt_class *cls = &td->mtclass;
@@ -1387,6 +1388,14 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
 
        switch (usage->hid) {
        case HID_DG_INPUTMODE:
+               /*
+                * Some elan panels wrongly declare 2 input mode features,
+                * and silently ignore when we set the value in the second
+                * field. Skip the second feature and hope for the best.
+                */
+               if (*inputmode_found)
+                       return false;
+
                if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
                        report_len = hid_report_len(report);
                        buf = hid_alloc_report_buf(report, GFP_KERNEL);
@@ -1402,6 +1411,7 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
                }
 
                field->value[index] = td->inputmode_value;
+               *inputmode_found = true;
                return true;
 
        case HID_DG_CONTACTMAX:
@@ -1439,6 +1449,7 @@ static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
        struct hid_usage *usage;
        int i, j;
        bool update_report;
+       bool inputmode_found = false;
 
        rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
        list_for_each_entry(rep, &rep_enum->report_list, list) {
@@ -1457,7 +1468,8 @@ static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
                                                             usage,
                                                             latency,
                                                             surface_switch,
-                                                            button_switch))
+                                                            button_switch,
+                                                            &inputmode_found))
                                        update_report = true;
                        }
                }
@@ -1685,6 +1697,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
         */
        hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
 
+       if (id->group != HID_GROUP_MULTITOUCH_WIN_8)
+               hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+
        timer_setup(&td->release_timer, mt_expired_timeout, 0);
 
        ret = hid_parse(hdev);
index 39e642686ff0466322cdacf7ea410fd6306932e5..683861f324e3cd6842f30016f4911b4b088d8a2a 100644 (file)
@@ -183,6 +183,8 @@ static const struct hid_device_id saitek_devices[] = {
                .driver_data = SAITEK_RELEASE_MODE_RAT7 },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7),
                .driver_data = SAITEK_RELEASE_MODE_RAT7 },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_CONTAGION),
+               .driver_data = SAITEK_RELEASE_MODE_RAT7 },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT9),
                .driver_data = SAITEK_RELEASE_MODE_RAT7 },
        { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9),
index 50af72baa5ca9a6dbf37505cda39fbd4290668c4..2b63487057c25b7fb931b8823db31d15f69667be 100644 (file)
@@ -579,6 +579,28 @@ void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
 }
 EXPORT_SYMBOL_GPL(sensor_hub_device_close);
 
+static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+               unsigned int *rsize)
+{
+       /*
+        * Checks if the report descriptor of Thinkpad Helix 2 has a logical
+        * minimum for magnetic flux axis greater than the maximum.
+        */
+       if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&
+               *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&
+               rdesc[915] == 0x81 && rdesc[916] == 0x08 &&
+               rdesc[917] == 0x00 && rdesc[918] == 0x27 &&
+               rdesc[921] == 0x07 && rdesc[922] == 0x00) {
+               /* Sets negative logical minimum for mag x, y and z */
+               rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;
+               rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;
+               rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;
+               rdesc[917] = rdesc[938] = rdesc[959] = 0xff;
+       }
+
+       return rdesc;
+}
+
 static int sensor_hub_probe(struct hid_device *hdev,
                                const struct hid_device_id *id)
 {
@@ -743,6 +765,7 @@ static struct hid_driver sensor_hub_driver = {
        .probe = sensor_hub_probe,
        .remove = sensor_hub_remove,
        .raw_event = sensor_hub_raw_event,
+       .report_fixup = sensor_hub_report_fixup,
 #ifdef CONFIG_PM
        .suspend = sensor_hub_suspend,
        .resume = sensor_hub_resume,
index 2ce194a84868e0fe5e133e241a0de368dfe3becf..f3076659361abcb0567804c298af25e278de8fa9 100644 (file)
@@ -170,8 +170,6 @@ static const struct i2c_hid_quirks {
                I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
        { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
                I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
-       { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
-               I2C_HID_QUIRK_RESEND_REPORT_DESCR },
        { USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS10FB_TOUCH,
                I2C_HID_QUIRK_RESEND_REPORT_DESCR },
        { 0, 0 }
@@ -1235,11 +1233,16 @@ static int i2c_hid_resume(struct device *dev)
        pm_runtime_enable(dev);
 
        enable_irq(client->irq);
-       ret = i2c_hid_hwreset(client);
+
+       /* Instead of resetting device, simply powers the device on. This
+        * solves "incomplete reports" on Raydium devices 2386:3118 and
+        * 2386:4B33
+        */
+       ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
        if (ret)
                return ret;
 
-       /* RAYDIUM device (2386:3118) need to re-send report descr cmd
+       /* Some devices need to re-send report descr cmd
         * after resume, after this it will be back normal.
         * otherwise it issues too many incomplete reports.
         */
index 97869b7410ebb83ec78c31f2c9a1b65b6597a613..da133716bed05b63dadef22e072f05b4e7b0f5da 100644 (file)
@@ -29,6 +29,7 @@
 #define CNL_Ax_DEVICE_ID       0x9DFC
 #define GLK_Ax_DEVICE_ID       0x31A2
 #define CNL_H_DEVICE_ID                0xA37C
+#define SPT_H_DEVICE_ID                0xA135
 
 #define        REVISION_ID_CHT_A0      0x6
 #define        REVISION_ID_CHT_Ax_SI   0x0
index 050f9872f5c0dc7d465c71f505dcb995b53c4321..a1125a5c7965a255f8b5480f47cc8a53b534b76f 100644 (file)
@@ -38,6 +38,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_Ax_DEVICE_ID)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, GLK_Ax_DEVICE_ID)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_H_DEVICE_ID)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)},
        {0, }
 };
 MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
index b1b548a21f919b31f8e5d7f670352ee6f7d25f56..c71cc857b649ddc23f3289e23ec43e898901fa1a 100644 (file)
@@ -1291,6 +1291,9 @@ static ssize_t vmbus_chan_attr_show(struct kobject *kobj,
        if (!attribute->show)
                return -EIO;
 
+       if (chan->state != CHANNEL_OPENED_STATE)
+               return -EINVAL;
+
        return attribute->show(chan, buf);
 }
 
index 944f5b63aecd706228ebcd3a128e3ec488bf63ba..78603b78cf410de903aa22d55147e6b600ab0398 100644 (file)
@@ -207,8 +207,6 @@ superio_exit(int ioreg)
 
 #define NUM_FAN                7
 
-#define TEMP_SOURCE_VIRTUAL    0x1f
-
 /* Common and NCT6775 specific data */
 
 /* Voltage min/max registers for nr=7..14 are in bank 5 */
@@ -299,8 +297,9 @@ static const u16 NCT6775_REG_PWM_READ[] = {
 
 static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
 static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
-static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
-static const u16 NCT6775_FAN_PULSE_SHIFT[] = { 0, 0, 0, 0, 0, 0 };
+static const u16 NCT6775_REG_FAN_PULSES[NUM_FAN] = {
+       0x641, 0x642, 0x643, 0x644 };
+static const u16 NCT6775_FAN_PULSE_SHIFT[NUM_FAN] = { };
 
 static const u16 NCT6775_REG_TEMP[] = {
        0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
@@ -373,6 +372,7 @@ static const char *const nct6775_temp_label[] = {
 };
 
 #define NCT6775_TEMP_MASK      0x001ffffe
+#define NCT6775_VIRT_TEMP_MASK 0x00000000
 
 static const u16 NCT6775_REG_TEMP_ALTERNATE[32] = {
        [13] = 0x661,
@@ -425,8 +425,8 @@ static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 };
 
 static const u16 NCT6776_REG_FAN_MIN[] = {
        0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c };
-static const u16 NCT6776_REG_FAN_PULSES[] = {
-       0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 };
+static const u16 NCT6776_REG_FAN_PULSES[NUM_FAN] = {
+       0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
 
 static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
        0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e };
@@ -461,6 +461,7 @@ static const char *const nct6776_temp_label[] = {
 };
 
 #define NCT6776_TEMP_MASK      0x007ffffe
+#define NCT6776_VIRT_TEMP_MASK 0x00000000
 
 static const u16 NCT6776_REG_TEMP_ALTERNATE[32] = {
        [14] = 0x401,
@@ -501,9 +502,9 @@ static const s8 NCT6779_BEEP_BITS[] = {
        30, 31 };                       /* intrusion0, intrusion1 */
 
 static const u16 NCT6779_REG_FAN[] = {
-       0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x660 };
-static const u16 NCT6779_REG_FAN_PULSES[] = {
-       0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 };
+       0x4c0, 0x4c2, 0x4c4, 0x4c6, 0x4c8, 0x4ca, 0x4ce };
+static const u16 NCT6779_REG_FAN_PULSES[NUM_FAN] = {
+       0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
 
 static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
        0x136, 0x236, 0x336, 0x836, 0x936, 0xa36, 0xb36 };
@@ -559,7 +560,9 @@ static const char *const nct6779_temp_label[] = {
 };
 
 #define NCT6779_TEMP_MASK      0x07ffff7e
+#define NCT6779_VIRT_TEMP_MASK 0x00000000
 #define NCT6791_TEMP_MASK      0x87ffff7e
+#define NCT6791_VIRT_TEMP_MASK 0x80000000
 
 static const u16 NCT6779_REG_TEMP_ALTERNATE[32]
        = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
@@ -638,6 +641,7 @@ static const char *const nct6792_temp_label[] = {
 };
 
 #define NCT6792_TEMP_MASK      0x9fffff7e
+#define NCT6792_VIRT_TEMP_MASK 0x80000000
 
 static const char *const nct6793_temp_label[] = {
        "",
@@ -675,6 +679,7 @@ static const char *const nct6793_temp_label[] = {
 };
 
 #define NCT6793_TEMP_MASK      0xbfff037e
+#define NCT6793_VIRT_TEMP_MASK 0x80000000
 
 static const char *const nct6795_temp_label[] = {
        "",
@@ -712,6 +717,7 @@ static const char *const nct6795_temp_label[] = {
 };
 
 #define NCT6795_TEMP_MASK      0xbfffff7e
+#define NCT6795_VIRT_TEMP_MASK 0x80000000
 
 static const char *const nct6796_temp_label[] = {
        "",
@@ -724,8 +730,8 @@ static const char *const nct6796_temp_label[] = {
        "AUXTIN4",
        "SMBUSMASTER 0",
        "SMBUSMASTER 1",
-       "",
-       "",
+       "Virtual_TEMP",
+       "Virtual_TEMP",
        "",
        "",
        "",
@@ -748,7 +754,8 @@ static const char *const nct6796_temp_label[] = {
        "Virtual_TEMP"
 };
 
-#define NCT6796_TEMP_MASK      0xbfff03fe
+#define NCT6796_TEMP_MASK      0xbfff0ffe
+#define NCT6796_VIRT_TEMP_MASK 0x80000c00
 
 /* NCT6102D/NCT6106D specific data */
 
@@ -779,8 +786,8 @@ static const u16 NCT6106_REG_TEMP_CONFIG[] = {
 
 static const u16 NCT6106_REG_FAN[] = { 0x20, 0x22, 0x24 };
 static const u16 NCT6106_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4 };
-static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0, 0 };
-static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4, 0, 0 };
+static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6 };
+static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 };
 
 static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
 static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
@@ -917,6 +924,11 @@ static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
        return 1350000U / (reg << divreg);
 }
 
+static unsigned int fan_from_reg_rpm(u16 reg, unsigned int divreg)
+{
+       return reg;
+}
+
 static u16 fan_to_reg(u32 fan, unsigned int divreg)
 {
        if (!fan)
@@ -969,6 +981,7 @@ struct nct6775_data {
        u16 reg_temp_config[NUM_TEMP];
        const char * const *temp_label;
        u32 temp_mask;
+       u32 virt_temp_mask;
 
        u16 REG_CONFIG;
        u16 REG_VBAT;
@@ -1276,11 +1289,11 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
        case nct6795:
        case nct6796:
                return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
-                 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
+                 (reg & 0xfff0) == 0x4c0 ||
                  reg == 0x402 ||
                  reg == 0x63a || reg == 0x63c || reg == 0x63e ||
                  reg == 0x640 || reg == 0x642 || reg == 0x64a ||
-                 reg == 0x64c || reg == 0x660 ||
+                 reg == 0x64c ||
                  reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
                  reg == 0x7b || reg == 0x7d;
        }
@@ -1558,7 +1571,7 @@ static void nct6775_update_pwm(struct device *dev)
                reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
                data->pwm_weight_temp_sel[i] = reg & 0x1f;
                /* If weight is disabled, report weight source as 0 */
-               if (j == 1 && !(reg & 0x80))
+               if (!(reg & 0x80))
                        data->pwm_weight_temp_sel[i] = 0;
 
                /* Weight temp data */
@@ -1682,9 +1695,13 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
                        if (data->has_fan_min & BIT(i))
                                data->fan_min[i] = nct6775_read_value(data,
                                           data->REG_FAN_MIN[i]);
-                       data->fan_pulses[i] =
-                         (nct6775_read_value(data, data->REG_FAN_PULSES[i])
-                               >> data->FAN_PULSE_SHIFT[i]) & 0x03;
+
+                       if (data->REG_FAN_PULSES[i]) {
+                               data->fan_pulses[i] =
+                                 (nct6775_read_value(data,
+                                                     data->REG_FAN_PULSES[i])
+                                  >> data->FAN_PULSE_SHIFT[i]) & 0x03;
+                       }
 
                        nct6775_select_fan_div(dev, data, i, reg);
                }
@@ -3639,6 +3656,7 @@ static int nct6775_probe(struct platform_device *pdev)
 
                data->temp_label = nct6776_temp_label;
                data->temp_mask = NCT6776_TEMP_MASK;
+               data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
 
                data->REG_VBAT = NCT6106_REG_VBAT;
                data->REG_DIODE = NCT6106_REG_DIODE;
@@ -3717,6 +3735,7 @@ static int nct6775_probe(struct platform_device *pdev)
 
                data->temp_label = nct6775_temp_label;
                data->temp_mask = NCT6775_TEMP_MASK;
+               data->virt_temp_mask = NCT6775_VIRT_TEMP_MASK;
 
                data->REG_CONFIG = NCT6775_REG_CONFIG;
                data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3789,6 +3808,7 @@ static int nct6775_probe(struct platform_device *pdev)
 
                data->temp_label = nct6776_temp_label;
                data->temp_mask = NCT6776_TEMP_MASK;
+               data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
 
                data->REG_CONFIG = NCT6775_REG_CONFIG;
                data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3853,7 +3873,7 @@ static int nct6775_probe(struct platform_device *pdev)
                data->ALARM_BITS = NCT6779_ALARM_BITS;
                data->BEEP_BITS = NCT6779_BEEP_BITS;
 
-               data->fan_from_reg = fan_from_reg13;
+               data->fan_from_reg = fan_from_reg_rpm;
                data->fan_from_reg_min = fan_from_reg13;
                data->target_temp_mask = 0xff;
                data->tolerance_mask = 0x07;
@@ -3861,6 +3881,7 @@ static int nct6775_probe(struct platform_device *pdev)
 
                data->temp_label = nct6779_temp_label;
                data->temp_mask = NCT6779_TEMP_MASK;
+               data->virt_temp_mask = NCT6779_VIRT_TEMP_MASK;
 
                data->REG_CONFIG = NCT6775_REG_CONFIG;
                data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3933,7 +3954,7 @@ static int nct6775_probe(struct platform_device *pdev)
                data->ALARM_BITS = NCT6791_ALARM_BITS;
                data->BEEP_BITS = NCT6779_BEEP_BITS;
 
-               data->fan_from_reg = fan_from_reg13;
+               data->fan_from_reg = fan_from_reg_rpm;
                data->fan_from_reg_min = fan_from_reg13;
                data->target_temp_mask = 0xff;
                data->tolerance_mask = 0x07;
@@ -3944,22 +3965,27 @@ static int nct6775_probe(struct platform_device *pdev)
                case nct6791:
                        data->temp_label = nct6779_temp_label;
                        data->temp_mask = NCT6791_TEMP_MASK;
+                       data->virt_temp_mask = NCT6791_VIRT_TEMP_MASK;
                        break;
                case nct6792:
                        data->temp_label = nct6792_temp_label;
                        data->temp_mask = NCT6792_TEMP_MASK;
+                       data->virt_temp_mask = NCT6792_VIRT_TEMP_MASK;
                        break;
                case nct6793:
                        data->temp_label = nct6793_temp_label;
                        data->temp_mask = NCT6793_TEMP_MASK;
+                       data->virt_temp_mask = NCT6793_VIRT_TEMP_MASK;
                        break;
                case nct6795:
                        data->temp_label = nct6795_temp_label;
                        data->temp_mask = NCT6795_TEMP_MASK;
+                       data->virt_temp_mask = NCT6795_VIRT_TEMP_MASK;
                        break;
                case nct6796:
                        data->temp_label = nct6796_temp_label;
                        data->temp_mask = NCT6796_TEMP_MASK;
+                       data->virt_temp_mask = NCT6796_VIRT_TEMP_MASK;
                        break;
                }
 
@@ -4143,7 +4169,7 @@ static int nct6775_probe(struct platform_device *pdev)
                 * for each fan reflects a different temperature, and there
                 * are no duplicates.
                 */
-               if (src != TEMP_SOURCE_VIRTUAL) {
+               if (!(data->virt_temp_mask & BIT(src))) {
                        if (mask & BIT(src))
                                continue;
                        mask |= BIT(src);
index da962aa2cef5297ba7a5f78c4f499c12ac5a464a..fc6b7f8b62fb888238b83178212a16f9478564c8 100644 (file)
@@ -139,7 +139,8 @@ static int intel_th_remove(struct device *dev)
                        th->thdev[i] = NULL;
                }
 
-               th->num_thdevs = lowest;
+               if (lowest >= 0)
+                       th->num_thdevs = lowest;
        }
 
        if (thdrv->attr_group)
@@ -487,7 +488,7 @@ static const struct intel_th_subdevice {
                                .flags  = IORESOURCE_MEM,
                        },
                        {
-                               .start  = TH_MMIO_SW,
+                               .start  = 1, /* use resource[1] */
                                .end    = 0,
                                .flags  = IORESOURCE_MEM,
                        },
@@ -580,6 +581,7 @@ intel_th_subdevice_alloc(struct intel_th *th,
        struct intel_th_device *thdev;
        struct resource res[3];
        unsigned int req = 0;
+       bool is64bit = false;
        int r, err;
 
        thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
@@ -589,12 +591,18 @@ intel_th_subdevice_alloc(struct intel_th *th,
 
        thdev->drvdata = th->drvdata;
 
+       for (r = 0; r < th->num_resources; r++)
+               if (th->resource[r].flags & IORESOURCE_MEM_64) {
+                       is64bit = true;
+                       break;
+               }
+
        memcpy(res, subdev->res,
               sizeof(struct resource) * subdev->nres);
 
        for (r = 0; r < subdev->nres; r++) {
                struct resource *devres = th->resource;
-               int bar = TH_MMIO_CONFIG;
+               int bar = 0; /* cut subdevices' MMIO from resource[0] */
 
                /*
                 * Take .end == 0 to mean 'take the whole bar',
@@ -603,6 +611,8 @@ intel_th_subdevice_alloc(struct intel_th *th,
                 */
                if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
                        bar = res[r].start;
+                       if (is64bit)
+                               bar *= 2;
                        res[r].start = 0;
                        res[r].end = resource_size(&devres[bar]) - 1;
                }
index c2e55e5d97f654cf3a392fdf1449ca9ddd47250d..1cf6290d643555d1cd9edfd114f2756b66d1b4bb 100644 (file)
@@ -160,6 +160,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Ice Lake PCH */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        { 0 },
 };
 
index 7589f2ad1dae7de9fe04b5448b233fdda786db70..631360b14ca71c398e67a9425dff363de1eb255a 100644 (file)
@@ -187,12 +187,15 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
 
 int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
 {
-       u16 fifo_watermark = ~0, cur_watermark, sip = 0, fifo_th_mask;
+       u16 fifo_watermark = ~0, cur_watermark, fifo_th_mask;
        struct st_lsm6dsx_hw *hw = sensor->hw;
        struct st_lsm6dsx_sensor *cur_sensor;
        int i, err, data;
        __le16 wdata;
 
+       if (!hw->sip)
+               return 0;
+
        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
                cur_sensor = iio_priv(hw->iio_devs[i]);
 
@@ -203,14 +206,10 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
                                                       : cur_sensor->watermark;
 
                fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
-               sip += cur_sensor->sip;
        }
 
-       if (!sip)
-               return 0;
-
-       fifo_watermark = max_t(u16, fifo_watermark, sip);
-       fifo_watermark = (fifo_watermark / sip) * sip;
+       fifo_watermark = max_t(u16, fifo_watermark, hw->sip);
+       fifo_watermark = (fifo_watermark / hw->sip) * hw->sip;
        fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl;
 
        err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1,
index 54e383231d1edef07abf150793656fa0cb9e92e5..c31b9633f32d9b8bcac8d05d3822230d7725f5dc 100644 (file)
@@ -258,7 +258,6 @@ static int maxim_thermocouple_remove(struct spi_device *spi)
 static const struct spi_device_id maxim_thermocouple_id[] = {
        {"max6675", MAX6675},
        {"max31855", MAX31855},
-       {"max31856", MAX31855},
        {},
 };
 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
index 0bee1f4b914e751d9893875665d0b588d7e3258d..3208ad6ad54014776cd333f4ac068c56cc737484 100644 (file)
@@ -337,6 +337,39 @@ static int add_roce_gid(struct ib_gid_table_entry *entry)
        return 0;
 }
 
+/**
+ * del_gid - Delete GID table entry
+ *
+ * @ib_dev:    IB device whose GID entry to be deleted
+ * @port:      Port number of the IB device
+ * @table:     GID table of the IB device for a port
+ * @ix:                GID entry index to delete
+ *
+ */
+static void del_gid(struct ib_device *ib_dev, u8 port,
+                   struct ib_gid_table *table, int ix)
+{
+       struct ib_gid_table_entry *entry;
+
+       lockdep_assert_held(&table->lock);
+
+       pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
+                ib_dev->name, port, ix,
+                table->data_vec[ix]->attr.gid.raw);
+
+       write_lock_irq(&table->rwlock);
+       entry = table->data_vec[ix];
+       entry->state = GID_TABLE_ENTRY_PENDING_DEL;
+       /*
+        * For non RoCE protocol, GID entry slot is ready to use.
+        */
+       if (!rdma_protocol_roce(ib_dev, port))
+               table->data_vec[ix] = NULL;
+       write_unlock_irq(&table->rwlock);
+
+       put_gid_entry_locked(entry);
+}
+
 /**
  * add_modify_gid - Add or modify GID table entry
  *
@@ -358,7 +391,7 @@ static int add_modify_gid(struct ib_gid_table *table,
         * this index.
         */
        if (is_gid_entry_valid(table->data_vec[attr->index]))
-               put_gid_entry(table->data_vec[attr->index]);
+               del_gid(attr->device, attr->port_num, table, attr->index);
 
        /*
         * Some HCA's report multiple GID entries with only one valid GID, and
@@ -386,39 +419,6 @@ static int add_modify_gid(struct ib_gid_table *table,
        return ret;
 }
 
-/**
- * del_gid - Delete GID table entry
- *
- * @ib_dev:    IB device whose GID entry to be deleted
- * @port:      Port number of the IB device
- * @table:     GID table of the IB device for a port
- * @ix:                GID entry index to delete
- *
- */
-static void del_gid(struct ib_device *ib_dev, u8 port,
-                   struct ib_gid_table *table, int ix)
-{
-       struct ib_gid_table_entry *entry;
-
-       lockdep_assert_held(&table->lock);
-
-       pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
-                ib_dev->name, port, ix,
-                table->data_vec[ix]->attr.gid.raw);
-
-       write_lock_irq(&table->rwlock);
-       entry = table->data_vec[ix];
-       entry->state = GID_TABLE_ENTRY_PENDING_DEL;
-       /*
-        * For non RoCE protocol, GID entry slot is ready to use.
-        */
-       if (!rdma_protocol_roce(ib_dev, port))
-               table->data_vec[ix] = NULL;
-       write_unlock_irq(&table->rwlock);
-
-       put_gid_entry_locked(entry);
-}
-
 /* rwlock should be read locked, or lock should be held */
 static int find_gid(struct ib_gid_table *table, const union ib_gid *gid,
                    const struct ib_gid_attr *val, bool default_gid,
index f72677291b692511ce7abcf1e9e8da9bf8f06326..a36c94930c31de8a03652cbf07844c10bcc09877 100644 (file)
@@ -724,6 +724,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
        dgid = (union ib_gid *) &addr->sib_addr;
        pkey = ntohs(addr->sib_pkey);
 
+       mutex_lock(&lock);
        list_for_each_entry(cur_dev, &dev_list, list) {
                for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
                        if (!rdma_cap_af_ib(cur_dev->device, p))
@@ -750,18 +751,19 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
                                        cma_dev = cur_dev;
                                        sgid = gid;
                                        id_priv->id.port_num = p;
+                                       goto found;
                                }
                        }
                }
        }
-
-       if (!cma_dev)
-               return -ENODEV;
+       mutex_unlock(&lock);
+       return -ENODEV;
 
 found:
        cma_attach_to_dev(id_priv, cma_dev);
-       addr = (struct sockaddr_ib *) cma_src_addr(id_priv);
-       memcpy(&addr->sib_addr, &sgid, sizeof sgid);
+       mutex_unlock(&lock);
+       addr = (struct sockaddr_ib *)cma_src_addr(id_priv);
+       memcpy(&addr->sib_addr, &sgid, sizeof(sgid));
        cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr);
        return 0;
 }
index 6eb64c6f08028b6c4a92407435bb2339128fe48b..c4118bcd5103565e3b20b6a970e67322061d195f 100644 (file)
@@ -882,6 +882,8 @@ static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,
                WARN_ON(uverbs_try_lock_object(obj, UVERBS_LOOKUP_WRITE));
                if (!uverbs_destroy_uobject(obj, reason))
                        ret = 0;
+               else
+                       atomic_set(&obj->usecnt, 0);
        }
        return ret;
 }
index ec8fb289621fb7590dd3e3f4000967fa2b6c9aae..21863ddde63e3040b285d9decd8a2ee1c47534b8 100644 (file)
@@ -124,6 +124,8 @@ static DEFINE_MUTEX(mut);
 static DEFINE_IDR(ctx_idr);
 static DEFINE_IDR(multicast_idr);
 
+static const struct file_operations ucma_fops;
+
 static inline struct ucma_context *_ucma_find_context(int id,
                                                      struct ucma_file *file)
 {
@@ -1581,6 +1583,10 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
        f = fdget(cmd.fd);
        if (!f.file)
                return -ENOENT;
+       if (f.file->f_op != &ucma_fops) {
+               ret = -EINVAL;
+               goto file_put;
+       }
 
        /* Validate current fd and prevent destruction of id. */
        ctx = ucma_get_ctx(f.file->private_data, cmd.id);
@@ -1753,6 +1759,8 @@ static int ucma_close(struct inode *inode, struct file *filp)
                mutex_lock(&mut);
                if (!ctx->closing) {
                        mutex_unlock(&mut);
+                       ucma_put_ctx(ctx);
+                       wait_for_completion(&ctx->comp);
                        /* rdma_destroy_id ensures that no event handlers are
                         * inflight for that id before releasing it.
                         */
index a21d5214afc367b260fd445642c55e6040d02dfb..e012ca80f9d196ddbb8723691ec4087a55c0d863 100644 (file)
@@ -2027,33 +2027,55 @@ static int modify_qp(struct ib_uverbs_file *file,
 
        if ((cmd->base.attr_mask & IB_QP_CUR_STATE &&
            cmd->base.cur_qp_state > IB_QPS_ERR) ||
-           cmd->base.qp_state > IB_QPS_ERR) {
+           (cmd->base.attr_mask & IB_QP_STATE &&
+           cmd->base.qp_state > IB_QPS_ERR)) {
                ret = -EINVAL;
                goto release_qp;
        }
 
-       attr->qp_state            = cmd->base.qp_state;
-       attr->cur_qp_state        = cmd->base.cur_qp_state;
-       attr->path_mtu            = cmd->base.path_mtu;
-       attr->path_mig_state      = cmd->base.path_mig_state;
-       attr->qkey                = cmd->base.qkey;
-       attr->rq_psn              = cmd->base.rq_psn;
-       attr->sq_psn              = cmd->base.sq_psn;
-       attr->dest_qp_num         = cmd->base.dest_qp_num;
-       attr->qp_access_flags     = cmd->base.qp_access_flags;
-       attr->pkey_index          = cmd->base.pkey_index;
-       attr->alt_pkey_index      = cmd->base.alt_pkey_index;
-       attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify;
-       attr->max_rd_atomic       = cmd->base.max_rd_atomic;
-       attr->max_dest_rd_atomic  = cmd->base.max_dest_rd_atomic;
-       attr->min_rnr_timer       = cmd->base.min_rnr_timer;
-       attr->port_num            = cmd->base.port_num;
-       attr->timeout             = cmd->base.timeout;
-       attr->retry_cnt           = cmd->base.retry_cnt;
-       attr->rnr_retry           = cmd->base.rnr_retry;
-       attr->alt_port_num        = cmd->base.alt_port_num;
-       attr->alt_timeout         = cmd->base.alt_timeout;
-       attr->rate_limit          = cmd->rate_limit;
+       if (cmd->base.attr_mask & IB_QP_STATE)
+               attr->qp_state = cmd->base.qp_state;
+       if (cmd->base.attr_mask & IB_QP_CUR_STATE)
+               attr->cur_qp_state = cmd->base.cur_qp_state;
+       if (cmd->base.attr_mask & IB_QP_PATH_MTU)
+               attr->path_mtu = cmd->base.path_mtu;
+       if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
+               attr->path_mig_state = cmd->base.path_mig_state;
+       if (cmd->base.attr_mask & IB_QP_QKEY)
+               attr->qkey = cmd->base.qkey;
+       if (cmd->base.attr_mask & IB_QP_RQ_PSN)
+               attr->rq_psn = cmd->base.rq_psn;
+       if (cmd->base.attr_mask & IB_QP_SQ_PSN)
+               attr->sq_psn = cmd->base.sq_psn;
+       if (cmd->base.attr_mask & IB_QP_DEST_QPN)
+               attr->dest_qp_num = cmd->base.dest_qp_num;
+       if (cmd->base.attr_mask & IB_QP_ACCESS_FLAGS)
+               attr->qp_access_flags = cmd->base.qp_access_flags;
+       if (cmd->base.attr_mask & IB_QP_PKEY_INDEX)
+               attr->pkey_index = cmd->base.pkey_index;
+       if (cmd->base.attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY)
+               attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify;
+       if (cmd->base.attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
+               attr->max_rd_atomic = cmd->base.max_rd_atomic;
+       if (cmd->base.attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
+               attr->max_dest_rd_atomic = cmd->base.max_dest_rd_atomic;
+       if (cmd->base.attr_mask & IB_QP_MIN_RNR_TIMER)
+               attr->min_rnr_timer = cmd->base.min_rnr_timer;
+       if (cmd->base.attr_mask & IB_QP_PORT)
+               attr->port_num = cmd->base.port_num;
+       if (cmd->base.attr_mask & IB_QP_TIMEOUT)
+               attr->timeout = cmd->base.timeout;
+       if (cmd->base.attr_mask & IB_QP_RETRY_CNT)
+               attr->retry_cnt = cmd->base.retry_cnt;
+       if (cmd->base.attr_mask & IB_QP_RNR_RETRY)
+               attr->rnr_retry = cmd->base.rnr_retry;
+       if (cmd->base.attr_mask & IB_QP_ALT_PATH) {
+               attr->alt_port_num = cmd->base.alt_port_num;
+               attr->alt_timeout = cmd->base.alt_timeout;
+               attr->alt_pkey_index = cmd->base.alt_pkey_index;
+       }
+       if (cmd->base.attr_mask & IB_QP_RATE_LIMIT)
+               attr->rate_limit = cmd->rate_limit;
 
        if (cmd->base.attr_mask & IB_QP_AV)
                copy_ah_attr_from_uverbs(qp->device, &attr->ah_attr,
index 823beca448e10937d290b9ebaf0bf3aed444f05b..50152c1b100452f7a4c8a9f733739ac25cbe777d 100644 (file)
@@ -440,6 +440,7 @@ static int ib_uverbs_comp_event_close(struct inode *inode, struct file *filp)
                        list_del(&entry->obj_list);
                kfree(entry);
        }
+       file->ev_queue.is_closed = 1;
        spin_unlock_irq(&file->ev_queue.lock);
 
        uverbs_close_fd(filp);
@@ -1050,7 +1051,7 @@ static void ib_uverbs_add_one(struct ib_device *device)
        uverbs_dev->num_comp_vectors = device->num_comp_vectors;
 
        if (ib_uverbs_create_uapi(device, uverbs_dev))
-               goto err;
+               goto err_uapi;
 
        cdev_init(&uverbs_dev->cdev, NULL);
        uverbs_dev->cdev.owner = THIS_MODULE;
@@ -1077,11 +1078,10 @@ static void ib_uverbs_add_one(struct ib_device *device)
 
 err_class:
        device_destroy(uverbs_class, uverbs_dev->cdev.dev);
-
 err_cdev:
        cdev_del(&uverbs_dev->cdev);
+err_uapi:
        clear_bit(devnum, dev_map);
-
 err:
        if (atomic_dec_and_test(&uverbs_dev->refcount))
                ib_uverbs_comp_dev(uverbs_dev);
index 73ea6f0db88fb5c2b2bbd698be684baf34dc5331..be854628a7c63149c05ed74f9f001a39fb1bc59d 100644 (file)
@@ -248,6 +248,7 @@ void uverbs_destroy_api(struct uverbs_api *uapi)
                kfree(rcu_dereference_protected(*slot, true));
                radix_tree_iter_delete(&uapi->radix, &iter, slot);
        }
+       kfree(uapi);
 }
 
 struct uverbs_api *uverbs_alloc_api(
index bbfb86eb2d24204565c78187faa6eb23984f24bf..bc2b9e03843903750aba02c0994430cd024cf4e3 100644 (file)
@@ -833,6 +833,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
                                "Failed to destroy Shadow QP");
                        return rc;
                }
+               bnxt_qplib_free_qp_res(&rdev->qplib_res,
+                                      &rdev->qp1_sqp->qplib_qp);
                mutex_lock(&rdev->qp_lock);
                list_del(&rdev->qp1_sqp->list);
                atomic_dec(&rdev->qp_count);
index 20b9f31052bf974fe43d335730daa4268ad614de..85cd1a3593d610132ded3796b5b90384bdb0342c 100644 (file)
@@ -78,7 +78,7 @@ static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list);
 /* Mutex to protect the list of bnxt_re devices added */
 static DEFINE_MUTEX(bnxt_re_dev_lock);
 static struct workqueue_struct *bnxt_re_wq;
-static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait);
+static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev);
 
 /* SR-IOV helper functions */
 
@@ -182,7 +182,7 @@ static void bnxt_re_shutdown(void *p)
        if (!rdev)
                return;
 
-       bnxt_re_ib_unreg(rdev, false);
+       bnxt_re_ib_unreg(rdev);
 }
 
 static void bnxt_re_stop_irq(void *handle)
@@ -251,7 +251,7 @@ static struct bnxt_ulp_ops bnxt_re_ulp_ops = {
 /* Driver registration routines used to let the networking driver (bnxt_en)
  * to know that the RoCE driver is now installed
  */
-static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev, bool lock_wait)
+static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev)
 {
        struct bnxt_en_dev *en_dev;
        int rc;
@@ -260,14 +260,9 @@ static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev, bool lock_wait)
                return -EINVAL;
 
        en_dev = rdev->en_dev;
-       /* Acquire rtnl lock if it is not invokded from netdev event */
-       if (lock_wait)
-               rtnl_lock();
 
        rc = en_dev->en_ops->bnxt_unregister_device(rdev->en_dev,
                                                    BNXT_ROCE_ULP);
-       if (lock_wait)
-               rtnl_unlock();
        return rc;
 }
 
@@ -281,14 +276,12 @@ static int bnxt_re_register_netdev(struct bnxt_re_dev *rdev)
 
        en_dev = rdev->en_dev;
 
-       rtnl_lock();
        rc = en_dev->en_ops->bnxt_register_device(en_dev, BNXT_ROCE_ULP,
                                                  &bnxt_re_ulp_ops, rdev);
-       rtnl_unlock();
        return rc;
 }
 
-static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
+static int bnxt_re_free_msix(struct bnxt_re_dev *rdev)
 {
        struct bnxt_en_dev *en_dev;
        int rc;
@@ -298,13 +291,9 @@ static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
 
        en_dev = rdev->en_dev;
 
-       if (lock_wait)
-               rtnl_lock();
 
        rc = en_dev->en_ops->bnxt_free_msix(rdev->en_dev, BNXT_ROCE_ULP);
 
-       if (lock_wait)
-               rtnl_unlock();
        return rc;
 }
 
@@ -320,7 +309,6 @@ static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
 
        num_msix_want = min_t(u32, BNXT_RE_MAX_MSIX, num_online_cpus());
 
-       rtnl_lock();
        num_msix_got = en_dev->en_ops->bnxt_request_msix(en_dev, BNXT_ROCE_ULP,
                                                         rdev->msix_entries,
                                                         num_msix_want);
@@ -335,7 +323,6 @@ static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
        }
        rdev->num_msix = num_msix_got;
 done:
-       rtnl_unlock();
        return rc;
 }
 
@@ -358,24 +345,18 @@ static void bnxt_re_fill_fw_msg(struct bnxt_fw_msg *fw_msg, void *msg,
        fw_msg->timeout = timeout;
 }
 
-static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id,
-                                bool lock_wait)
+static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id)
 {
        struct bnxt_en_dev *en_dev = rdev->en_dev;
        struct hwrm_ring_free_input req = {0};
        struct hwrm_ring_free_output resp;
        struct bnxt_fw_msg fw_msg;
-       bool do_unlock = false;
        int rc = -EINVAL;
 
        if (!en_dev)
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       if (lock_wait) {
-               rtnl_lock();
-               do_unlock = true;
-       }
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_FREE, -1, -1);
        req.ring_type = RING_ALLOC_REQ_RING_TYPE_L2_CMPL;
@@ -386,8 +367,6 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id,
        if (rc)
                dev_err(rdev_to_dev(rdev),
                        "Failed to free HW ring:%d :%#x", req.ring_id, rc);
-       if (do_unlock)
-               rtnl_unlock();
        return rc;
 }
 
@@ -405,7 +384,6 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       rtnl_lock();
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
        req.enables = 0;
        req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
@@ -426,27 +404,21 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
        if (!rc)
                *fw_ring_id = le16_to_cpu(resp.ring_id);
 
-       rtnl_unlock();
        return rc;
 }
 
 static int bnxt_re_net_stats_ctx_free(struct bnxt_re_dev *rdev,
-                                     u32 fw_stats_ctx_id, bool lock_wait)
+                                     u32 fw_stats_ctx_id)
 {
        struct bnxt_en_dev *en_dev = rdev->en_dev;
        struct hwrm_stat_ctx_free_input req = {0};
        struct bnxt_fw_msg fw_msg;
-       bool do_unlock = false;
        int rc = -EINVAL;
 
        if (!en_dev)
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       if (lock_wait) {
-               rtnl_lock();
-               do_unlock = true;
-       }
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_FREE, -1, -1);
        req.stat_ctx_id = cpu_to_le32(fw_stats_ctx_id);
@@ -457,8 +429,6 @@ static int bnxt_re_net_stats_ctx_free(struct bnxt_re_dev *rdev,
                dev_err(rdev_to_dev(rdev),
                        "Failed to free HW stats context %#x", rc);
 
-       if (do_unlock)
-               rtnl_unlock();
        return rc;
 }
 
@@ -478,7 +448,6 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev,
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       rtnl_lock();
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1);
        req.update_period_ms = cpu_to_le32(1000);
@@ -490,7 +459,6 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev,
        if (!rc)
                *fw_stats_ctx_id = le32_to_cpu(resp.stat_ctx_id);
 
-       rtnl_unlock();
        return rc;
 }
 
@@ -929,19 +897,19 @@ static int bnxt_re_init_res(struct bnxt_re_dev *rdev)
        return rc;
 }
 
-static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev, bool lock_wait)
+static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev)
 {
        int i;
 
        for (i = 0; i < rdev->num_msix - 1; i++) {
-               bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, lock_wait);
+               bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id);
                bnxt_qplib_free_nq(&rdev->nq[i]);
        }
 }
 
-static void bnxt_re_free_res(struct bnxt_re_dev *rdev, bool lock_wait)
+static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
 {
-       bnxt_re_free_nq_res(rdev, lock_wait);
+       bnxt_re_free_nq_res(rdev);
 
        if (rdev->qplib_res.dpi_tbl.max) {
                bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
@@ -1219,7 +1187,7 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
        return 0;
 }
 
-static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
+static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev)
 {
        int i, rc;
 
@@ -1234,28 +1202,27 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
                cancel_delayed_work(&rdev->worker);
 
        bnxt_re_cleanup_res(rdev);
-       bnxt_re_free_res(rdev, lock_wait);
+       bnxt_re_free_res(rdev);
 
        if (test_and_clear_bit(BNXT_RE_FLAG_RCFW_CHANNEL_EN, &rdev->flags)) {
                rc = bnxt_qplib_deinit_rcfw(&rdev->rcfw);
                if (rc)
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to deinitialize RCFW: %#x", rc);
-               bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id,
-                                          lock_wait);
+               bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
                bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
                bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
-               bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, lock_wait);
+               bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id);
                bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
        }
        if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) {
-               rc = bnxt_re_free_msix(rdev, lock_wait);
+               rc = bnxt_re_free_msix(rdev);
                if (rc)
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to free MSI-X vectors: %#x", rc);
        }
        if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) {
-               rc = bnxt_re_unregister_netdev(rdev, lock_wait);
+               rc = bnxt_re_unregister_netdev(rdev);
                if (rc)
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to unregister with netdev: %#x", rc);
@@ -1276,6 +1243,12 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 {
        int i, j, rc;
 
+       bool locked;
+
+       /* Acquire rtnl lock through out this function */
+       rtnl_lock();
+       locked = true;
+
        /* Registered a new RoCE device instance to netdev */
        rc = bnxt_re_register_netdev(rdev);
        if (rc) {
@@ -1374,12 +1347,16 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
                schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000));
        }
 
+       rtnl_unlock();
+       locked = false;
+
        /* Register ib dev */
        rc = bnxt_re_register_ib(rdev);
        if (rc) {
                pr_err("Failed to register with IB: %#x\n", rc);
                goto fail;
        }
+       set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags);
        dev_info(rdev_to_dev(rdev), "Device registered successfully");
        for (i = 0; i < ARRAY_SIZE(bnxt_re_attributes); i++) {
                rc = device_create_file(&rdev->ibdev.dev,
@@ -1395,7 +1372,6 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
                        goto fail;
                }
        }
-       set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags);
        ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
                         &rdev->active_width);
        set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
@@ -1404,17 +1380,21 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 
        return 0;
 free_sctx:
-       bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id, true);
+       bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
 free_ctx:
        bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
 disable_rcfw:
        bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 free_ring:
-       bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, true);
+       bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id);
 free_rcfw:
        bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
 fail:
-       bnxt_re_ib_unreg(rdev, true);
+       if (!locked)
+               rtnl_lock();
+       bnxt_re_ib_unreg(rdev);
+       rtnl_unlock();
+
        return rc;
 }
 
@@ -1567,7 +1547,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier,
                 */
                if (atomic_read(&rdev->sched_count) > 0)
                        goto exit;
-               bnxt_re_ib_unreg(rdev, false);
+               bnxt_re_ib_unreg(rdev);
                bnxt_re_remove_one(rdev);
                bnxt_re_dev_unreg(rdev);
                break;
@@ -1646,7 +1626,10 @@ static void __exit bnxt_re_mod_exit(void)
                 */
                flush_workqueue(bnxt_re_wq);
                bnxt_re_dev_stop(rdev);
-               bnxt_re_ib_unreg(rdev, true);
+               /* Acquire the rtnl_lock as the L2 resources are freed here */
+               rtnl_lock();
+               bnxt_re_ib_unreg(rdev);
+               rtnl_unlock();
                bnxt_re_remove_one(rdev);
                bnxt_re_dev_unreg(rdev);
        }
index e426b990c1dd5bf3fa08966f41ccd08e3f3c4e44..6ad0d46ab879a6a1bf6d231e22b6e766b796efd2 100644 (file)
@@ -196,7 +196,7 @@ static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res,
                                       struct bnxt_qplib_qp *qp)
 {
        struct bnxt_qplib_q *rq = &qp->rq;
-       struct bnxt_qplib_q *sq = &qp->rq;
+       struct bnxt_qplib_q *sq = &qp->sq;
        int rc = 0;
 
        if (qp->sq_hdr_buf_size && sq->hwq.max_elements) {
index b3203afa3b1de705c74da5aaec9ca55a3172b0d2..347fe18b1a41c0990c753aa29f2efaaea0cd119b 100644 (file)
@@ -1685,6 +1685,12 @@ static void flush_qp(struct c4iw_qp *qhp)
        schp = to_c4iw_cq(qhp->ibqp.send_cq);
 
        if (qhp->ibqp.uobject) {
+
+               /* for user qps, qhp->wq.flushed is protected by qhp->mutex */
+               if (qhp->wq.flushed)
+                       return;
+
+               qhp->wq.flushed = 1;
                t4_set_wq_in_error(&qhp->wq, 0);
                t4_set_cq_in_error(&rchp->cq);
                spin_lock_irqsave(&rchp->comp_handler_lock, flag);
index 2c19bf772451bfef693eaad1fa5a678e5cc9e067..e1668bcc2d13d71aba2f35021ec25cd693e79682 100644 (file)
@@ -6733,6 +6733,7 @@ void start_freeze_handling(struct hfi1_pportdata *ppd, int flags)
        struct hfi1_devdata *dd = ppd->dd;
        struct send_context *sc;
        int i;
+       int sc_flags;
 
        if (flags & FREEZE_SELF)
                write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_FREEZE_SMASK);
@@ -6743,11 +6744,13 @@ void start_freeze_handling(struct hfi1_pportdata *ppd, int flags)
        /* notify all SDMA engines that they are going into a freeze */
        sdma_freeze_notify(dd, !!(flags & FREEZE_LINK_DOWN));
 
+       sc_flags = SCF_FROZEN | SCF_HALTED | (flags & FREEZE_LINK_DOWN ?
+                                             SCF_LINK_DOWN : 0);
        /* do halt pre-handling on all enabled send contexts */
        for (i = 0; i < dd->num_send_contexts; i++) {
                sc = dd->send_contexts[i].sc;
                if (sc && (sc->flags & SCF_ENABLED))
-                       sc_stop(sc, SCF_FROZEN | SCF_HALTED);
+                       sc_stop(sc, sc_flags);
        }
 
        /* Send context are frozen. Notify user space */
@@ -10674,6 +10677,7 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
                add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
 
                handle_linkup_change(dd, 1);
+               pio_kernel_linkup(dd);
 
                /*
                 * After link up, a new link width will have been set.
index eec83757d55f94331936518804672a72b8e29898..6c967dde58e702c228835a84c3b1ea19abc1ea64 100644 (file)
@@ -893,14 +893,11 @@ static int trigger_sbr(struct hfi1_devdata *dd)
                }
 
        /*
-        * A secondary bus reset (SBR) issues a hot reset to our device.
-        * The following routine does a 1s wait after the reset is dropped
-        * per PCI Trhfa (recovery time).  PCIe 3.0 section 6.6.1 -
-        * Conventional Reset, paragraph 3, line 35 also says that a 1s
-        * delay after a reset is required.  Per spec requirements,
-        * the link is either working or not after that point.
+        * This is an end around to do an SBR during probe time. A new API needs
+        * to be implemented to have cleaner interface but this fixes the
+        * current brokenness
         */
-       return pci_reset_bus(dev);
+       return pci_bridge_secondary_bus_reset(dev->bus->self);
 }
 
 /*
index c2c1cba5b23be440bc292a205ca523d6962c4233..752057647f091734368f998c0173234d8a1f2dd0 100644 (file)
@@ -86,6 +86,7 @@ void pio_send_control(struct hfi1_devdata *dd, int op)
        unsigned long flags;
        int write = 1;  /* write sendctrl back */
        int flush = 0;  /* re-read sendctrl to make sure it is flushed */
+       int i;
 
        spin_lock_irqsave(&dd->sendctrl_lock, flags);
 
@@ -95,9 +96,13 @@ void pio_send_control(struct hfi1_devdata *dd, int op)
                reg |= SEND_CTRL_SEND_ENABLE_SMASK;
        /* Fall through */
        case PSC_DATA_VL_ENABLE:
+               mask = 0;
+               for (i = 0; i < ARRAY_SIZE(dd->vld); i++)
+                       if (!dd->vld[i].mtu)
+                               mask |= BIT_ULL(i);
                /* Disallow sending on VLs not enabled */
-               mask = (((~0ull) << num_vls) & SEND_CTRL_UNSUPPORTED_VL_MASK) <<
-                               SEND_CTRL_UNSUPPORTED_VL_SHIFT;
+               mask = (mask & SEND_CTRL_UNSUPPORTED_VL_MASK) <<
+                       SEND_CTRL_UNSUPPORTED_VL_SHIFT;
                reg = (reg & ~SEND_CTRL_UNSUPPORTED_VL_SMASK) | mask;
                break;
        case PSC_GLOBAL_DISABLE:
@@ -921,20 +926,18 @@ void sc_free(struct send_context *sc)
 void sc_disable(struct send_context *sc)
 {
        u64 reg;
-       unsigned long flags;
        struct pio_buf *pbuf;
 
        if (!sc)
                return;
 
        /* do all steps, even if already disabled */
-       spin_lock_irqsave(&sc->alloc_lock, flags);
+       spin_lock_irq(&sc->alloc_lock);
        reg = read_kctxt_csr(sc->dd, sc->hw_context, SC(CTRL));
        reg &= ~SC(CTRL_CTXT_ENABLE_SMASK);
        sc->flags &= ~SCF_ENABLED;
        sc_wait_for_packet_egress(sc, 1);
        write_kctxt_csr(sc->dd, sc->hw_context, SC(CTRL), reg);
-       spin_unlock_irqrestore(&sc->alloc_lock, flags);
 
        /*
         * Flush any waiters.  Once the context is disabled,
@@ -944,7 +947,7 @@ void sc_disable(struct send_context *sc)
         * proceed with the flush.
         */
        udelay(1);
-       spin_lock_irqsave(&sc->release_lock, flags);
+       spin_lock(&sc->release_lock);
        if (sc->sr) {   /* this context has a shadow ring */
                while (sc->sr_tail != sc->sr_head) {
                        pbuf = &sc->sr[sc->sr_tail].pbuf;
@@ -955,7 +958,8 @@ void sc_disable(struct send_context *sc)
                                sc->sr_tail = 0;
                }
        }
-       spin_unlock_irqrestore(&sc->release_lock, flags);
+       spin_unlock(&sc->release_lock);
+       spin_unlock_irq(&sc->alloc_lock);
 }
 
 /* return SendEgressCtxtStatus.PacketOccupancy */
@@ -1178,11 +1182,39 @@ void pio_kernel_unfreeze(struct hfi1_devdata *dd)
                sc = dd->send_contexts[i].sc;
                if (!sc || !(sc->flags & SCF_FROZEN) || sc->type == SC_USER)
                        continue;
+               if (sc->flags & SCF_LINK_DOWN)
+                       continue;
 
                sc_enable(sc);  /* will clear the sc frozen flag */
        }
 }
 
+/**
+ * pio_kernel_linkup() - Re-enable send contexts after linkup event
+ * @dd: valid devive data
+ *
+ * When the link goes down, the freeze path is taken.  However, a link down
+ * event is different from a freeze because if the send context is re-enabled
+ * whowever is sending data will start sending data again, which will hang
+ * any QP that is sending data.
+ *
+ * The freeze path now looks at the type of event that occurs and takes this
+ * path for link down event.
+ */
+void pio_kernel_linkup(struct hfi1_devdata *dd)
+{
+       struct send_context *sc;
+       int i;
+
+       for (i = 0; i < dd->num_send_contexts; i++) {
+               sc = dd->send_contexts[i].sc;
+               if (!sc || !(sc->flags & SCF_LINK_DOWN) || sc->type == SC_USER)
+                       continue;
+
+               sc_enable(sc);  /* will clear the sc link down flag */
+       }
+}
+
 /*
  * Wait for the SendPioInitCtxt.PioInitInProgress bit to clear.
  * Returns:
@@ -1382,11 +1414,10 @@ void sc_stop(struct send_context *sc, int flag)
 {
        unsigned long flags;
 
-       /* mark the context */
-       sc->flags |= flag;
-
        /* stop buffer allocations */
        spin_lock_irqsave(&sc->alloc_lock, flags);
+       /* mark the context */
+       sc->flags |= flag;
        sc->flags &= ~SCF_ENABLED;
        spin_unlock_irqrestore(&sc->alloc_lock, flags);
        wake_up(&sc->halt_wait);
index 058b08f459ab7947e53aa5ad676febc9999f7ade..aaf372c3e5d6a3cc0de82aaf9819c02b97bd195f 100644 (file)
@@ -139,6 +139,7 @@ struct send_context {
 #define SCF_IN_FREE 0x02
 #define SCF_HALTED  0x04
 #define SCF_FROZEN  0x08
+#define SCF_LINK_DOWN 0x10
 
 struct send_context_info {
        struct send_context *sc;        /* allocated working context */
@@ -306,6 +307,7 @@ void set_pio_integrity(struct send_context *sc);
 void pio_reset_all(struct hfi1_devdata *dd);
 void pio_freeze(struct hfi1_devdata *dd);
 void pio_kernel_unfreeze(struct hfi1_devdata *dd);
+void pio_kernel_linkup(struct hfi1_devdata *dd);
 
 /* global PIO send control operations */
 #define PSC_GLOBAL_ENABLE 0
index a3a7b33196d64158cd069cdf5d32c429f79f7b5d..5c88706121c1cb0faf2da79dae014113f7d0a0d9 100644 (file)
@@ -828,7 +828,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
                        if (READ_ONCE(iovec->offset) == iovec->iov.iov_len) {
                                if (++req->iov_idx == req->data_iovs) {
                                        ret = -EFAULT;
-                                       goto free_txreq;
+                                       goto free_tx;
                                }
                                iovec = &req->iovs[req->iov_idx];
                                WARN_ON(iovec->offset);
index 13374c727b142d61dc3f6bdb0603f958c6a1a0ca..a7c586a5589d642524f7e659c6a4dfa512eed4e2 100644 (file)
@@ -1582,6 +1582,7 @@ static int hfi1_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)
        struct hfi1_pportdata *ppd;
        struct hfi1_devdata *dd;
        u8 sc5;
+       u8 sl;
 
        if (hfi1_check_mcast(rdma_ah_get_dlid(ah_attr)) &&
            !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
@@ -1590,8 +1591,13 @@ static int hfi1_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)
        /* test the mapping for validity */
        ibp = to_iport(ibdev, rdma_ah_get_port_num(ah_attr));
        ppd = ppd_from_ibp(ibp);
-       sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)];
        dd = dd_from_ppd(ppd);
+
+       sl = rdma_ah_get_sl(ah_attr);
+       if (sl >= ARRAY_SIZE(ibp->sl_to_sc))
+               return -EINVAL;
+
+       sc5 = ibp->sl_to_sc[sl];
        if (sc_to_vlt(dd, sc5) > num_vls && sc_to_vlt(dd, sc5) != 0xf)
                return -EINVAL;
        return 0;
index ca0f1ee26091b38200b2447ccfe92324a3c0bd32..0bbeaaae47e07d2e99529925bb6236ab98be377b 100644 (file)
@@ -517,9 +517,11 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
        props->page_size_cap       = dev->dev->caps.page_size_cap;
        props->max_qp              = dev->dev->quotas.qp;
        props->max_qp_wr           = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
-       props->max_send_sge        = dev->dev->caps.max_sq_sg;
-       props->max_recv_sge        = dev->dev->caps.max_rq_sg;
-       props->max_sge_rd          = MLX4_MAX_SGE_RD;
+       props->max_send_sge =
+               min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg);
+       props->max_recv_sge =
+               min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg);
+       props->max_sge_rd = MLX4_MAX_SGE_RD;
        props->max_cq              = dev->dev->quotas.cq;
        props->max_cqe             = dev->dev->caps.max_cqes;
        props->max_mr              = dev->dev->quotas.mpt;
index ac116d63e4661adf03662bdfb2cd598cc179ce3c..f2f11e652dcd2a751d10397c8c65d6be8a53b53e 100644 (file)
@@ -723,6 +723,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
                attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE);
        struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
        struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
+       u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
        struct devx_obj *obj;
        int err;
 
@@ -754,10 +755,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
 
        err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
        if (err)
-               goto obj_free;
+               goto obj_destroy;
 
        return 0;
 
+obj_destroy:
+       mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
 obj_free:
        kfree(obj);
        return err;
index ea01b8dd2be606206193408ca7bf9c42e4ea4e39..3d5424f335cb06e1dcaad16a4f4c3c7910d3295e 100644 (file)
@@ -1027,12 +1027,14 @@ static int ipoib_cm_rep_handler(struct ib_cm_id *cm_id,
 
        skb_queue_head_init(&skqueue);
 
+       netif_tx_lock_bh(p->dev);
        spin_lock_irq(&priv->lock);
        set_bit(IPOIB_FLAG_OPER_UP, &p->flags);
        if (p->neigh)
                while ((skb = __skb_dequeue(&p->neigh->queue)))
                        __skb_queue_tail(&skqueue, skb);
        spin_unlock_irq(&priv->lock);
+       netif_tx_unlock_bh(p->dev);
 
        while ((skb = __skb_dequeue(&skqueue))) {
                skb->dev = p->dev;
index 444d16520506a1773f01dc0b89087091d867e939..0b34e909505f5fa4c6a1404227a137ae94e54aa9 100644 (file)
@@ -2951,7 +2951,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 {
        struct srp_target_port *target = host_to_target(scmnd->device->host);
        struct srp_rdma_ch *ch;
-       int i;
+       int i, j;
        u8 status;
 
        shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
@@ -2965,8 +2965,8 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 
        for (i = 0; i < target->ch_count; i++) {
                ch = &target->ch[i];
-               for (i = 0; i < target->req_ring_size; ++i) {
-                       struct srp_request *req = &ch->req_ring[i];
+               for (j = 0; j < target->req_ring_size; ++j) {
+                       struct srp_request *req = &ch->req_ring[j];
 
                        srp_finish_req(ch, req, scmnd->device, DID_RESET << 16);
                }
index 6f62da2909ec0f07eb7cd7d1a76122bc11ed13a7..6caee807cafabf6955053ee817c30f70571d3ef5 100644 (file)
@@ -75,8 +75,7 @@ MODULE_LICENSE("GPL");
  */
 
 
-static unsigned char atakbd_keycode[0x72] = {  /* American layout */
-       [0]      = KEY_GRAVE,
+static unsigned char atakbd_keycode[0x73] = {  /* American layout */
        [1]      = KEY_ESC,
        [2]      = KEY_1,
        [3]      = KEY_2,
@@ -117,9 +116,9 @@ static unsigned char atakbd_keycode[0x72] = {       /* American layout */
        [38]     = KEY_L,
        [39]     = KEY_SEMICOLON,
        [40]     = KEY_APOSTROPHE,
-       [41]     = KEY_BACKSLASH,       /* FIXME, '#' */
+       [41]     = KEY_GRAVE,
        [42]     = KEY_LEFTSHIFT,
-       [43]     = KEY_GRAVE,           /* FIXME: '~' */
+       [43]     = KEY_BACKSLASH,
        [44]     = KEY_Z,
        [45]     = KEY_X,
        [46]     = KEY_C,
@@ -145,45 +144,34 @@ static unsigned char atakbd_keycode[0x72] = {     /* American layout */
        [66]     = KEY_F8,
        [67]     = KEY_F9,
        [68]     = KEY_F10,
-       [69]     = KEY_ESC,
-       [70]     = KEY_DELETE,
-       [71]     = KEY_KP7,
-       [72]     = KEY_KP8,
-       [73]     = KEY_KP9,
+       [71]     = KEY_HOME,
+       [72]     = KEY_UP,
        [74]     = KEY_KPMINUS,
-       [75]     = KEY_KP4,
-       [76]     = KEY_KP5,
-       [77]     = KEY_KP6,
+       [75]     = KEY_LEFT,
+       [77]     = KEY_RIGHT,
        [78]     = KEY_KPPLUS,
-       [79]     = KEY_KP1,
-       [80]     = KEY_KP2,
-       [81]     = KEY_KP3,
-       [82]     = KEY_KP0,
-       [83]     = KEY_KPDOT,
-       [90]     = KEY_KPLEFTPAREN,
-       [91]     = KEY_KPRIGHTPAREN,
-       [92]     = KEY_KPASTERISK,      /* FIXME */
-       [93]     = KEY_KPASTERISK,
-       [94]     = KEY_KPPLUS,
-       [95]     = KEY_HELP,
+       [80]     = KEY_DOWN,
+       [82]     = KEY_INSERT,
+       [83]     = KEY_DELETE,
        [96]     = KEY_102ND,
-       [97]     = KEY_KPASTERISK,      /* FIXME */
-       [98]     = KEY_KPSLASH,
+       [97]     = KEY_UNDO,
+       [98]     = KEY_HELP,
        [99]     = KEY_KPLEFTPAREN,
        [100]    = KEY_KPRIGHTPAREN,
        [101]    = KEY_KPSLASH,
        [102]    = KEY_KPASTERISK,
-       [103]    = KEY_UP,
-       [104]    = KEY_KPASTERISK,      /* FIXME */
-       [105]    = KEY_LEFT,
-       [106]    = KEY_RIGHT,
-       [107]    = KEY_KPASTERISK,      /* FIXME */
-       [108]    = KEY_DOWN,
-       [109]    = KEY_KPASTERISK,      /* FIXME */
-       [110]    = KEY_KPASTERISK,      /* FIXME */
-       [111]    = KEY_KPASTERISK,      /* FIXME */
-       [112]    = KEY_KPASTERISK,      /* FIXME */
-       [113]    = KEY_KPASTERISK       /* FIXME */
+       [103]    = KEY_KP7,
+       [104]    = KEY_KP8,
+       [105]    = KEY_KP9,
+       [106]    = KEY_KP4,
+       [107]    = KEY_KP5,
+       [108]    = KEY_KP6,
+       [109]    = KEY_KP1,
+       [110]    = KEY_KP2,
+       [111]    = KEY_KP3,
+       [112]    = KEY_KP0,
+       [113]    = KEY_KPDOT,
+       [114]    = KEY_KPENTER,
 };
 
 static struct input_dev *atakbd_dev;
@@ -191,21 +179,15 @@ static struct input_dev *atakbd_dev;
 static void atakbd_interrupt(unsigned char scancode, char down)
 {
 
-       if (scancode < 0x72) {          /* scancodes < 0xf2 are keys */
+       if (scancode < 0x73) {          /* scancodes < 0xf3 are keys */
 
                // report raw events here?
 
                scancode = atakbd_keycode[scancode];
 
-               if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */
-                       input_report_key(atakbd_dev, scancode, 1);
-                       input_report_key(atakbd_dev, scancode, 0);
-                       input_sync(atakbd_dev);
-               } else {
-                       input_report_key(atakbd_dev, scancode, down);
-                       input_sync(atakbd_dev);
-               }
-       } else                          /* scancodes >= 0xf2 are mouse data, most likely */
+               input_report_key(atakbd_dev, scancode, down);
+               input_sync(atakbd_dev);
+       } else                          /* scancodes >= 0xf3 are mouse data, most likely */
                printk(KERN_INFO "atakbd: unhandled scancode %x\n", scancode);
 
        return;
index 96a887f336982f7efc0d971e145ded52829b2dc8..eb14ddf693467b4619a9501aa5e712a9b45dfcdf 100644 (file)
@@ -410,7 +410,7 @@ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code,
        min = abs->minimum;
        max = abs->maximum;
 
-       if ((min != 0 || max != 0) && max <= min) {
+       if ((min != 0 || max != 0) && max < min) {
                printk(KERN_DEBUG
                       "%s: invalid abs[%02x] min:%d max:%d\n",
                       UINPUT_NAME, code, min, max);
index 44f57cf6675bbf10ed6fd5bc8b9900936e76a086..2d95e8d93cc761aefb102217473d940faf1e4d02 100644 (file)
@@ -1178,6 +1178,8 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
 static const char * const middle_button_pnp_ids[] = {
        "LEN2131", /* ThinkPad P52 w/ NFC */
        "LEN2132", /* ThinkPad P52 */
+       "LEN2133", /* ThinkPad P72 w/ NFC */
+       "LEN2134", /* ThinkPad P72 */
        NULL
 };
 
index 80e69bb8283e4b417c677637889654e0b1cadf30..83ac8c128192846f21a9aeb40d80b39869a1c245 100644 (file)
@@ -241,6 +241,9 @@ static int __maybe_unused egalax_ts_suspend(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        int ret;
 
+       if (device_may_wakeup(dev))
+               return enable_irq_wake(client->irq);
+
        ret = i2c_master_send(client, suspend_cmd, MAX_I2C_DATA_LEN);
        return ret > 0 ? 0 : ret;
 }
@@ -249,6 +252,9 @@ static int __maybe_unused egalax_ts_resume(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
 
+       if (device_may_wakeup(dev))
+               return disable_irq_wake(client->irq);
+
        return egalax_wake_up_device(client);
 }
 
index 4e04fff23977348877cce7a00d4ae394fadf91ef..73e47d93e7a05a5f7b9ebc79096081c573656746 100644 (file)
@@ -246,7 +246,13 @@ static u16 get_alias(struct device *dev)
 
        /* The callers make sure that get_device_id() does not fail here */
        devid = get_device_id(dev);
+
+       /* For ACPI HID devices, we simply return the devid as such */
+       if (!dev_is_pci(dev))
+               return devid;
+
        ivrs_alias = amd_iommu_alias_table[devid];
+
        pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
 
        if (ivrs_alias == pci_alias)
index 5f3f10cf9d9d0fecb1fc5747c60cbe9d4f9034b1..bedc801b06a0bf2c6745511acbab08e769a54eb2 100644 (file)
@@ -2540,9 +2540,9 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
        if (dev && dev_is_pci(dev) && info->pasid_supported) {
                ret = intel_pasid_alloc_table(dev);
                if (ret) {
-                       __dmar_remove_one_dev_info(info);
-                       spin_unlock_irqrestore(&device_domain_lock, flags);
-                       return NULL;
+                       pr_warn("No pasid table for %s, pasid disabled\n",
+                               dev_name(dev));
+                       info->pasid_supported = 0;
                }
        }
        spin_unlock_irqrestore(&device_domain_lock, flags);
index 1c05ed6fc5a596383c7ed94d7bac69de38d4554d..1fb5e12b029ac717379ec74544c83254ea0c0259 100644 (file)
@@ -11,7 +11,7 @@
 #define __INTEL_PASID_H
 
 #define PASID_MIN                      0x1
-#define PASID_MAX                      0x100000
+#define PASID_MAX                      0x20000
 
 struct pasid_entry {
        u64 val;
index 258115b10fa9e448129d84a0663ab99d51c64ee5..ad3e2b97469ed6de44f3524cafd677825d7afca5 100644 (file)
@@ -1241,6 +1241,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
 
 static void rk_iommu_shutdown(struct platform_device *pdev)
 {
+       struct rk_iommu *iommu = platform_get_drvdata(pdev);
+       int i = 0, irq;
+
+       while ((irq = platform_get_irq(pdev, i++)) != -ENXIO)
+               devm_free_irq(iommu->dev, irq, iommu);
+
        pm_runtime_force_suspend(&pdev->dev);
 }
 
index 83504dd8100ab2a80d7f0e737e50266de41add32..954dad29e6e8fca910b0ebd24171591f2acd0831 100644 (file)
@@ -965,6 +965,7 @@ void bch_prio_write(struct cache *ca);
 void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent);
 
 extern struct workqueue_struct *bcache_wq;
+extern struct workqueue_struct *bch_journal_wq;
 extern struct mutex bch_register_lock;
 extern struct list_head bch_cache_sets;
 
index 6116bbf870d8ef9004717bf5d04803895d085bab..522c7426f3a05cee10df0e984521472849b9b707 100644 (file)
@@ -485,7 +485,7 @@ static void do_journal_discard(struct cache *ca)
 
                closure_get(&ca->set->cl);
                INIT_WORK(&ja->discard_work, journal_discard_work);
-               schedule_work(&ja->discard_work);
+               queue_work(bch_journal_wq, &ja->discard_work);
        }
 }
 
@@ -592,7 +592,7 @@ static void journal_write_done(struct closure *cl)
                : &j->w[0];
 
        __closure_wake_up(&w->wait);
-       continue_at_nobarrier(cl, journal_write, system_wq);
+       continue_at_nobarrier(cl, journal_write, bch_journal_wq);
 }
 
 static void journal_write_unlock(struct closure *cl)
@@ -627,7 +627,7 @@ static void journal_write_unlocked(struct closure *cl)
                spin_unlock(&c->journal.lock);
 
                btree_flush_write(c);
-               continue_at(cl, journal_write, system_wq);
+               continue_at(cl, journal_write, bch_journal_wq);
                return;
        }
 
index 94c756c66bd7216a6d83b67eaef891269f965467..30ba9aeb5ee8345ac192e34e51e67beae2127950 100644 (file)
@@ -47,6 +47,7 @@ static int bcache_major;
 static DEFINE_IDA(bcache_device_idx);
 static wait_queue_head_t unregister_wait;
 struct workqueue_struct *bcache_wq;
+struct workqueue_struct *bch_journal_wq;
 
 #define BTREE_MAX_PAGES                (256 * 1024 / PAGE_SIZE)
 /* limitation of partitions number on single bcache device */
@@ -2341,6 +2342,9 @@ static void bcache_exit(void)
                kobject_put(bcache_kobj);
        if (bcache_wq)
                destroy_workqueue(bcache_wq);
+       if (bch_journal_wq)
+               destroy_workqueue(bch_journal_wq);
+
        if (bcache_major)
                unregister_blkdev(bcache_major, "bcache");
        unregister_reboot_notifier(&reboot);
@@ -2370,6 +2374,10 @@ static int __init bcache_init(void)
        if (!bcache_wq)
                goto err;
 
+       bch_journal_wq = alloc_workqueue("bch_journal", WQ_MEM_RECLAIM, 0);
+       if (!bch_journal_wq)
+               goto err;
+
        bcache_kobj = kobject_create_and_add("bcache", fs_kobj);
        if (!bcache_kobj)
                goto err;
index f266c81f396fe7a82032827c92c95896f168deba..0481223b1deb826af43fa8f0da0b81e5b6654009 100644 (file)
@@ -332,7 +332,7 @@ static int crypt_iv_essiv_init(struct crypt_config *cc)
        int err;
 
        desc->tfm = essiv->hash_tfm;
-       desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+       desc->flags = 0;
 
        err = crypto_shash_digest(desc, cc->key, cc->key_size, essiv->salt);
        shash_desc_zero(desc);
@@ -606,7 +606,7 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,
        int i, r;
 
        desc->tfm = lmk->hash_tfm;
-       desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+       desc->flags = 0;
 
        r = crypto_shash_init(desc);
        if (r)
@@ -768,7 +768,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,
 
        /* calculate crc32 for every 32bit part and xor it */
        desc->tfm = tcw->crc32_tfm;
-       desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+       desc->flags = 0;
        for (i = 0; i < 4; i++) {
                r = crypto_shash_init(desc);
                if (r)
@@ -1251,7 +1251,7 @@ static void crypt_alloc_req_skcipher(struct crypt_config *cc,
         * requests if driver request queue is full.
         */
        skcipher_request_set_callback(ctx->r.req,
-           CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
+           CRYPTO_TFM_REQ_MAY_BACKLOG,
            kcryptd_async_done, dmreq_of_req(cc, ctx->r.req));
 }
 
@@ -1268,7 +1268,7 @@ static void crypt_alloc_req_aead(struct crypt_config *cc,
         * requests if driver request queue is full.
         */
        aead_request_set_callback(ctx->r.req_aead,
-           CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
+           CRYPTO_TFM_REQ_MAY_BACKLOG,
            kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead));
 }
 
index 37887859946631cb40c42256f0ba3d4d5a471132..89ccb64342de7a4fa8e03d528f66ab9b726e0539 100644 (file)
@@ -532,7 +532,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result
        unsigned j, size;
 
        desc->tfm = ic->journal_mac;
-       desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+       desc->flags = 0;
 
        r = crypto_shash_init(desc);
        if (unlikely(r)) {
@@ -676,7 +676,7 @@ static void complete_journal_encrypt(struct crypto_async_request *req, int err)
 static bool do_crypt(bool encrypt, struct skcipher_request *req, struct journal_completion *comp)
 {
        int r;
-       skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
+       skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                      complete_journal_encrypt, comp);
        if (likely(encrypt))
                r = crypto_skcipher_encrypt(req);
index cae689de75fd5a719c406f1093db076c201fcdef..5ba067fa0c729bc89b7789bd35648b1189003b27 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010-2011 Neil Brown
- * Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
@@ -29,9 +29,6 @@
  */
 #define        MIN_RAID456_JOURNAL_SPACE (4*2048)
 
-/* Global list of all raid sets */
-static LIST_HEAD(raid_sets);
-
 static bool devices_handle_discard_safely = false;
 
 /*
@@ -227,7 +224,6 @@ struct rs_layout {
 
 struct raid_set {
        struct dm_target *ti;
-       struct list_head list;
 
        uint32_t stripe_cache_entries;
        unsigned long ctr_flags;
@@ -273,19 +269,6 @@ static void rs_config_restore(struct raid_set *rs, struct rs_layout *l)
        mddev->new_chunk_sectors = l->new_chunk_sectors;
 }
 
-/* Find any raid_set in active slot for @rs on global list */
-static struct raid_set *rs_find_active(struct raid_set *rs)
-{
-       struct raid_set *r;
-       struct mapped_device *md = dm_table_get_md(rs->ti->table);
-
-       list_for_each_entry(r, &raid_sets, list)
-               if (r != rs && dm_table_get_md(r->ti->table) == md)
-                       return r;
-
-       return NULL;
-}
-
 /* raid10 algorithms (i.e. formats) */
 #define        ALGORITHM_RAID10_DEFAULT        0
 #define        ALGORITHM_RAID10_NEAR           1
@@ -764,7 +747,6 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
 
        mddev_init(&rs->md);
 
-       INIT_LIST_HEAD(&rs->list);
        rs->raid_disks = raid_devs;
        rs->delta_disks = 0;
 
@@ -782,9 +764,6 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
        for (i = 0; i < raid_devs; i++)
                md_rdev_init(&rs->dev[i].rdev);
 
-       /* Add @rs to global list. */
-       list_add(&rs->list, &raid_sets);
-
        /*
         * Remaining items to be initialized by further RAID params:
         *  rs->md.persistent
@@ -797,7 +776,7 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
        return rs;
 }
 
-/* Free all @rs allocations and remove it from global list. */
+/* Free all @rs allocations */
 static void raid_set_free(struct raid_set *rs)
 {
        int i;
@@ -815,8 +794,6 @@ static void raid_set_free(struct raid_set *rs)
                        dm_put_device(rs->ti, rs->dev[i].data_dev);
        }
 
-       list_del(&rs->list);
-
        kfree(rs);
 }
 
@@ -2649,7 +2626,7 @@ static int rs_adjust_data_offsets(struct raid_set *rs)
                return 0;
        }
 
-       /* HM FIXME: get InSync raid_dev? */
+       /* HM FIXME: get In_Sync raid_dev? */
        rdev = &rs->dev[0].rdev;
 
        if (rs->delta_disks < 0) {
@@ -3149,6 +3126,11 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
                rs_set_new(rs);
        } else if (rs_is_recovering(rs)) {
+               /* Rebuild particular devices */
+               if (test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags)) {
+                       set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
+                       rs_setup_recovery(rs, MaxSector);
+               }
                /* A recovering raid set may be resized */
                ; /* skip setup rs */
        } else if (rs_is_reshaping(rs)) {
@@ -3242,6 +3224,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        /* Start raid set read-only and assumed clean to change in raid_resume() */
        rs->md.ro = 1;
        rs->md.in_sync = 1;
+
+       /* Keep array frozen */
        set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
 
        /* Has to be held on running the array */
@@ -3265,7 +3249,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        rs->callbacks.congested_fn = raid_is_congested;
        dm_table_add_target_callbacks(ti->table, &rs->callbacks);
 
-       /* If raid4/5/6 journal mode explictely requested (only possible with journal dev) -> set it */
+       /* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
        if (test_bit(__CTR_FLAG_JOURNAL_MODE, &rs->ctr_flags)) {
                r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode);
                if (r) {
@@ -3350,32 +3334,53 @@ static int raid_map(struct dm_target *ti, struct bio *bio)
        return DM_MAPIO_SUBMITTED;
 }
 
-/* Return string describing the current sync action of @mddev */
-static const char *decipher_sync_action(struct mddev *mddev, unsigned long recovery)
+/* Return sync state string for @state */
+enum sync_state { st_frozen, st_reshape, st_resync, st_check, st_repair, st_recover, st_idle };
+static const char *sync_str(enum sync_state state)
+{
+       /* Has to be in above sync_state order! */
+       static const char *sync_strs[] = {
+               "frozen",
+               "reshape",
+               "resync",
+               "check",
+               "repair",
+               "recover",
+               "idle"
+       };
+
+       return __within_range(state, 0, ARRAY_SIZE(sync_strs) - 1) ? sync_strs[state] : "undef";
+};
+
+/* Return enum sync_state for @mddev derived from @recovery flags */
+static const enum sync_state decipher_sync_action(struct mddev *mddev, unsigned long recovery)
 {
        if (test_bit(MD_RECOVERY_FROZEN, &recovery))
-               return "frozen";
+               return st_frozen;
 
-       /* The MD sync thread can be done with io but still be running */
+       /* The MD sync thread can be done with io or be interrupted but still be running */
        if (!test_bit(MD_RECOVERY_DONE, &recovery) &&
            (test_bit(MD_RECOVERY_RUNNING, &recovery) ||
             (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &recovery)))) {
                if (test_bit(MD_RECOVERY_RESHAPE, &recovery))
-                       return "reshape";
+                       return st_reshape;
 
                if (test_bit(MD_RECOVERY_SYNC, &recovery)) {
                        if (!test_bit(MD_RECOVERY_REQUESTED, &recovery))
-                               return "resync";
-                       else if (test_bit(MD_RECOVERY_CHECK, &recovery))
-                               return "check";
-                       return "repair";
+                               return st_resync;
+                       if (test_bit(MD_RECOVERY_CHECK, &recovery))
+                               return st_check;
+                       return st_repair;
                }
 
                if (test_bit(MD_RECOVERY_RECOVER, &recovery))
-                       return "recover";
+                       return st_recover;
+
+               if (mddev->reshape_position != MaxSector)
+                       return st_reshape;
        }
 
-       return "idle";
+       return st_idle;
 }
 
 /*
@@ -3409,6 +3414,7 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
                                sector_t resync_max_sectors)
 {
        sector_t r;
+       enum sync_state state;
        struct mddev *mddev = &rs->md;
 
        clear_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
@@ -3419,20 +3425,14 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
                set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
 
        } else {
-               if (!test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags) &&
-                   !test_bit(MD_RECOVERY_INTR, &recovery) &&
-                   (test_bit(MD_RECOVERY_NEEDED, &recovery) ||
-                    test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
-                    test_bit(MD_RECOVERY_RUNNING, &recovery)))
-                       r = mddev->curr_resync_completed;
-               else
+               state = decipher_sync_action(mddev, recovery);
+
+               if (state == st_idle && !test_bit(MD_RECOVERY_INTR, &recovery))
                        r = mddev->recovery_cp;
+               else
+                       r = mddev->curr_resync_completed;
 
-               if (r >= resync_max_sectors &&
-                   (!test_bit(MD_RECOVERY_REQUESTED, &recovery) ||
-                    (!test_bit(MD_RECOVERY_FROZEN, &recovery) &&
-                     !test_bit(MD_RECOVERY_NEEDED, &recovery) &&
-                     !test_bit(MD_RECOVERY_RUNNING, &recovery)))) {
+               if (state == st_idle && r >= resync_max_sectors) {
                        /*
                         * Sync complete.
                         */
@@ -3440,24 +3440,20 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
                        if (test_bit(MD_RECOVERY_RECOVER, &recovery))
                                set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
 
-               } else if (test_bit(MD_RECOVERY_RECOVER, &recovery)) {
+               } else if (state == st_recover)
                        /*
                         * In case we are recovering, the array is not in sync
                         * and health chars should show the recovering legs.
                         */
                        ;
-
-               } else if (test_bit(MD_RECOVERY_SYNC, &recovery) &&
-                          !test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
+               else if (state == st_resync)
                        /*
                         * If "resync" is occurring, the raid set
                         * is or may be out of sync hence the health
                         * characters shall be 'a'.
                         */
                        set_bit(RT_FLAG_RS_RESYNCING, &rs->runtime_flags);
-
-               } else if (test_bit(MD_RECOVERY_RESHAPE, &recovery) &&
-                          !test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
+               else if (state == st_reshape)
                        /*
                         * If "reshape" is occurring, the raid set
                         * is or may be out of sync hence the health
@@ -3465,7 +3461,7 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
                         */
                        set_bit(RT_FLAG_RS_RESYNCING, &rs->runtime_flags);
 
-               } else if (test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
+               else if (state == st_check || state == st_repair)
                        /*
                         * If "check" or "repair" is occurring, the raid set has
                         * undergone an initial sync and the health characters
@@ -3473,12 +3469,12 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
                         */
                        set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
 
-               else {
+               else {
                        struct md_rdev *rdev;
 
                        /*
                         * We are idle and recovery is needed, prevent 'A' chars race
-                        * caused by components still set to in-sync by constrcuctor.
+                        * caused by components still set to in-sync by constructor.
                         */
                        if (test_bit(MD_RECOVERY_NEEDED, &recovery))
                                set_bit(RT_FLAG_RS_RESYNCING, &rs->runtime_flags);
@@ -3542,7 +3538,7 @@ static void raid_status(struct dm_target *ti, status_type_t type,
                progress = rs_get_progress(rs, recovery, resync_max_sectors);
                resync_mismatches = (mddev->last_sync_action && !strcasecmp(mddev->last_sync_action, "check")) ?
                                    atomic64_read(&mddev->resync_mismatches) : 0;
-               sync_action = decipher_sync_action(&rs->md, recovery);
+               sync_action = sync_str(decipher_sync_action(&rs->md, recovery));
 
                /* HM FIXME: do we want another state char for raid0? It shows 'D'/'A'/'-' now */
                for (i = 0; i < rs->raid_disks; i++)
@@ -3892,14 +3888,13 @@ static int rs_start_reshape(struct raid_set *rs)
        struct mddev *mddev = &rs->md;
        struct md_personality *pers = mddev->pers;
 
+       /* Don't allow the sync thread to work until the table gets reloaded. */
+       set_bit(MD_RECOVERY_WAIT, &mddev->recovery);
+
        r = rs_setup_reshape(rs);
        if (r)
                return r;
 
-       /* Need to be resumed to be able to start reshape, recovery is frozen until raid_resume() though */
-       if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
-               mddev_resume(mddev);
-
        /*
         * Check any reshape constraints enforced by the personalility
         *
@@ -3923,10 +3918,6 @@ static int rs_start_reshape(struct raid_set *rs)
                }
        }
 
-       /* Suspend because a resume will happen in raid_resume() */
-       set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags);
-       mddev_suspend(mddev);
-
        /*
         * Now reshape got set up, update superblocks to
         * reflect the fact so that a table reload will
@@ -3947,29 +3938,6 @@ static int raid_preresume(struct dm_target *ti)
        if (test_and_set_bit(RT_FLAG_RS_PRERESUMED, &rs->runtime_flags))
                return 0;
 
-       if (!test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags)) {
-               struct raid_set *rs_active = rs_find_active(rs);
-
-               if (rs_active) {
-                       /*
-                        * In case no rebuilds have been requested
-                        * and an active table slot exists, copy
-                        * current resynchonization completed and
-                        * reshape position pointers across from
-                        * suspended raid set in the active slot.
-                        *
-                        * This resumes the new mapping at current
-                        * offsets to continue recover/reshape without
-                        * necessarily redoing a raid set partially or
-                        * causing data corruption in case of a reshape.
-                        */
-                       if (rs_active->md.curr_resync_completed != MaxSector)
-                               mddev->curr_resync_completed = rs_active->md.curr_resync_completed;
-                       if (rs_active->md.reshape_position != MaxSector)
-                               mddev->reshape_position = rs_active->md.reshape_position;
-               }
-       }
-
        /*
         * The superblocks need to be updated on disk if the
         * array is new or new devices got added (thus zeroed
@@ -4046,7 +4014,7 @@ static void raid_resume(struct dm_target *ti)
 
 static struct target_type raid_target = {
        .name = "raid",
-       .version = {1, 13, 2},
+       .version = {1, 14, 0},
        .module = THIS_MODULE,
        .ctr = raid_ctr,
        .dtr = raid_dtr,
index 72142021b5c9a0410cfb6ccb04a93d613376fb53..74f6770c70b12404e965345ec561318bf2225fcb 100644 (file)
@@ -188,6 +188,12 @@ struct dm_pool_metadata {
        unsigned long flags;
        sector_t data_block_size;
 
+       /*
+        * We reserve a section of the metadata for commit overhead.
+        * All reported space does *not* include this.
+        */
+       dm_block_t metadata_reserve;
+
        /*
         * Set if a transaction has to be aborted but the attempt to roll back
         * to the previous (good) transaction failed.  The only pool metadata
@@ -816,6 +822,22 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
        return dm_tm_commit(pmd->tm, sblock);
 }
 
+static void __set_metadata_reserve(struct dm_pool_metadata *pmd)
+{
+       int r;
+       dm_block_t total;
+       dm_block_t max_blocks = 4096; /* 16M */
+
+       r = dm_sm_get_nr_blocks(pmd->metadata_sm, &total);
+       if (r) {
+               DMERR("could not get size of metadata device");
+               pmd->metadata_reserve = max_blocks;
+       } else {
+               sector_div(total, 10);
+               pmd->metadata_reserve = min(max_blocks, total);
+       }
+}
+
 struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
                                               sector_t data_block_size,
                                               bool format_device)
@@ -849,6 +871,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
                return ERR_PTR(r);
        }
 
+       __set_metadata_reserve(pmd);
+
        return pmd;
 }
 
@@ -1820,6 +1844,13 @@ int dm_pool_get_free_metadata_block_count(struct dm_pool_metadata *pmd,
        down_read(&pmd->root_lock);
        if (!pmd->fail_io)
                r = dm_sm_get_nr_free(pmd->metadata_sm, result);
+
+       if (!r) {
+               if (*result < pmd->metadata_reserve)
+                       *result = 0;
+               else
+                       *result -= pmd->metadata_reserve;
+       }
        up_read(&pmd->root_lock);
 
        return r;
@@ -1932,8 +1963,11 @@ int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_cou
        int r = -EINVAL;
 
        down_write(&pmd->root_lock);
-       if (!pmd->fail_io)
+       if (!pmd->fail_io) {
                r = __resize_space_map(pmd->metadata_sm, new_count);
+               if (!r)
+                       __set_metadata_reserve(pmd);
+       }
        up_write(&pmd->root_lock);
 
        return r;
index 7bd60a150f8faec85071cf1d984bd35d27b08391..aaf1ad481ee88e59b90273133b7a7bd90c69d3fb 100644 (file)
@@ -200,7 +200,13 @@ struct dm_thin_new_mapping;
 enum pool_mode {
        PM_WRITE,               /* metadata may be changed */
        PM_OUT_OF_DATA_SPACE,   /* metadata may be changed, though data may not be allocated */
+
+       /*
+        * Like READ_ONLY, except may switch back to WRITE on metadata resize. Reported as READ_ONLY.
+        */
+       PM_OUT_OF_METADATA_SPACE,
        PM_READ_ONLY,           /* metadata may not be changed */
+
        PM_FAIL,                /* all I/O fails */
 };
 
@@ -1371,7 +1377,35 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);
 
 static void requeue_bios(struct pool *pool);
 
-static void check_for_space(struct pool *pool)
+static bool is_read_only_pool_mode(enum pool_mode mode)
+{
+       return (mode == PM_OUT_OF_METADATA_SPACE || mode == PM_READ_ONLY);
+}
+
+static bool is_read_only(struct pool *pool)
+{
+       return is_read_only_pool_mode(get_pool_mode(pool));
+}
+
+static void check_for_metadata_space(struct pool *pool)
+{
+       int r;
+       const char *ooms_reason = NULL;
+       dm_block_t nr_free;
+
+       r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free);
+       if (r)
+               ooms_reason = "Could not get free metadata blocks";
+       else if (!nr_free)
+               ooms_reason = "No free metadata blocks";
+
+       if (ooms_reason && !is_read_only(pool)) {
+               DMERR("%s", ooms_reason);
+               set_pool_mode(pool, PM_OUT_OF_METADATA_SPACE);
+       }
+}
+
+static void check_for_data_space(struct pool *pool)
 {
        int r;
        dm_block_t nr_free;
@@ -1397,14 +1431,16 @@ static int commit(struct pool *pool)
 {
        int r;
 
-       if (get_pool_mode(pool) >= PM_READ_ONLY)
+       if (get_pool_mode(pool) >= PM_OUT_OF_METADATA_SPACE)
                return -EINVAL;
 
        r = dm_pool_commit_metadata(pool->pmd);
        if (r)
                metadata_operation_failed(pool, "dm_pool_commit_metadata", r);
-       else
-               check_for_space(pool);
+       else {
+               check_for_metadata_space(pool);
+               check_for_data_space(pool);
+       }
 
        return r;
 }
@@ -1470,6 +1506,19 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
                return r;
        }
 
+       r = dm_pool_get_free_metadata_block_count(pool->pmd, &free_blocks);
+       if (r) {
+               metadata_operation_failed(pool, "dm_pool_get_free_metadata_block_count", r);
+               return r;
+       }
+
+       if (!free_blocks) {
+               /* Let's commit before we use up the metadata reserve. */
+               r = commit(pool);
+               if (r)
+                       return r;
+       }
+
        return 0;
 }
 
@@ -1501,6 +1550,7 @@ static blk_status_t should_error_unserviceable_bio(struct pool *pool)
        case PM_OUT_OF_DATA_SPACE:
                return pool->pf.error_if_no_space ? BLK_STS_NOSPC : 0;
 
+       case PM_OUT_OF_METADATA_SPACE:
        case PM_READ_ONLY:
        case PM_FAIL:
                return BLK_STS_IOERR;
@@ -2464,8 +2514,9 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
                error_retry_list(pool);
                break;
 
+       case PM_OUT_OF_METADATA_SPACE:
        case PM_READ_ONLY:
-               if (old_mode != new_mode)
+               if (!is_read_only_pool_mode(old_mode))
                        notify_of_pool_mode_change(pool, "read-only");
                dm_pool_metadata_read_only(pool->pmd);
                pool->process_bio = process_bio_read_only;
@@ -3403,6 +3454,10 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit)
                DMINFO("%s: growing the metadata device from %llu to %llu blocks",
                       dm_device_name(pool->pool_md),
                       sb_metadata_dev_size, metadata_dev_size);
+
+               if (get_pool_mode(pool) == PM_OUT_OF_METADATA_SPACE)
+                       set_pool_mode(pool, PM_WRITE);
+
                r = dm_pool_resize_metadata_dev(pool->pmd, metadata_dev_size);
                if (r) {
                        metadata_operation_failed(pool, "dm_pool_resize_metadata_dev", r);
@@ -3707,7 +3762,7 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv,
        struct pool_c *pt = ti->private;
        struct pool *pool = pt->pool;
 
-       if (get_pool_mode(pool) >= PM_READ_ONLY) {
+       if (get_pool_mode(pool) >= PM_OUT_OF_METADATA_SPACE) {
                DMERR("%s: unable to service pool target messages in READ_ONLY or FAIL mode",
                      dm_device_name(pool->pool_md));
                return -EOPNOTSUPP;
@@ -3781,6 +3836,7 @@ static void pool_status(struct dm_target *ti, status_type_t type,
        dm_block_t nr_blocks_data;
        dm_block_t nr_blocks_metadata;
        dm_block_t held_root;
+       enum pool_mode mode;
        char buf[BDEVNAME_SIZE];
        char buf2[BDEVNAME_SIZE];
        struct pool_c *pt = ti->private;
@@ -3851,9 +3907,10 @@ static void pool_status(struct dm_target *ti, status_type_t type,
                else
                        DMEMIT("- ");
 
-               if (pool->pf.mode == PM_OUT_OF_DATA_SPACE)
+               mode = get_pool_mode(pool);
+               if (mode == PM_OUT_OF_DATA_SPACE)
                        DMEMIT("out_of_data_space ");
-               else if (pool->pf.mode == PM_READ_ONLY)
+               else if (is_read_only_pool_mode(mode))
                        DMEMIT("ro ");
                else
                        DMEMIT("rw ");
index 12decdbd722d866ed48a0a6a8d8b8f2e0a6aefbc..fc65f0dedf7f702b31d6adf21b8a2b26238c8b43 100644 (file)
@@ -99,10 +99,26 @@ static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
 {
        struct scatterlist sg;
 
-       sg_init_one(&sg, data, len);
-       ahash_request_set_crypt(req, &sg, NULL, len);
-
-       return crypto_wait_req(crypto_ahash_update(req), wait);
+       if (likely(!is_vmalloc_addr(data))) {
+               sg_init_one(&sg, data, len);
+               ahash_request_set_crypt(req, &sg, NULL, len);
+               return crypto_wait_req(crypto_ahash_update(req), wait);
+       } else {
+               do {
+                       int r;
+                       size_t this_step = min_t(size_t, len, PAGE_SIZE - offset_in_page(data));
+                       flush_kernel_vmap_range((void *)data, this_step);
+                       sg_init_table(&sg, 1);
+                       sg_set_page(&sg, vmalloc_to_page(data), this_step, offset_in_page(data));
+                       ahash_request_set_crypt(req, &sg, NULL, this_step);
+                       r = crypto_wait_req(crypto_ahash_update(req), wait);
+                       if (unlikely(r))
+                               return r;
+                       data += this_step;
+                       len -= this_step;
+               } while (len);
+               return 0;
+       }
 }
 
 /*
index b5410aeb5fe26ea9975716dc4161ba2b06d03dac..bb41bea950ac3f6ccfb325fb3cbdebf51d58e408 100644 (file)
@@ -1159,41 +1159,21 @@ static int mt9v111_probe(struct i2c_client *client)
                                              V4L2_CID_AUTO_WHITE_BALANCE,
                                              0, 1, 1,
                                              V4L2_WHITE_BALANCE_AUTO);
-       if (IS_ERR_OR_NULL(mt9v111->auto_awb)) {
-               ret = PTR_ERR(mt9v111->auto_awb);
-               goto error_free_ctrls;
-       }
-
        mt9v111->auto_exp = v4l2_ctrl_new_std_menu(&mt9v111->ctrls,
                                                   &mt9v111_ctrl_ops,
                                                   V4L2_CID_EXPOSURE_AUTO,
                                                   V4L2_EXPOSURE_MANUAL,
                                                   0, V4L2_EXPOSURE_AUTO);
-       if (IS_ERR_OR_NULL(mt9v111->auto_exp)) {
-               ret = PTR_ERR(mt9v111->auto_exp);
-               goto error_free_ctrls;
-       }
-
-       /* Initialize timings */
        mt9v111->hblank = v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops,
                                            V4L2_CID_HBLANK,
                                            MT9V111_CORE_R05_MIN_HBLANK,
                                            MT9V111_CORE_R05_MAX_HBLANK, 1,
                                            MT9V111_CORE_R05_DEF_HBLANK);
-       if (IS_ERR_OR_NULL(mt9v111->hblank)) {
-               ret = PTR_ERR(mt9v111->hblank);
-               goto error_free_ctrls;
-       }
-
        mt9v111->vblank = v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops,
                                            V4L2_CID_VBLANK,
                                            MT9V111_CORE_R06_MIN_VBLANK,
                                            MT9V111_CORE_R06_MAX_VBLANK, 1,
                                            MT9V111_CORE_R06_DEF_VBLANK);
-       if (IS_ERR_OR_NULL(mt9v111->vblank)) {
-               ret = PTR_ERR(mt9v111->vblank);
-               goto error_free_ctrls;
-       }
 
        /* PIXEL_RATE is fixed: just expose it to user space. */
        v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops,
@@ -1201,6 +1181,10 @@ static int mt9v111_probe(struct i2c_client *client)
                          DIV_ROUND_CLOSEST(mt9v111->sysclk, 2), 1,
                          DIV_ROUND_CLOSEST(mt9v111->sysclk, 2));
 
+       if (mt9v111->ctrls.error) {
+               ret = mt9v111->ctrls.error;
+               goto error_free_ctrls;
+       }
        mt9v111->sd.ctrl_handler = &mt9v111->ctrls;
 
        /* Start with default configuration: 640x480 UYVY. */
@@ -1226,26 +1210,27 @@ static int mt9v111_probe(struct i2c_client *client)
        mt9v111->pad.flags      = MEDIA_PAD_FL_SOURCE;
        ret = media_entity_pads_init(&mt9v111->sd.entity, 1, &mt9v111->pad);
        if (ret)
-               goto error_free_ctrls;
+               goto error_free_entity;
 #endif
 
        ret = mt9v111_chip_probe(mt9v111);
        if (ret)
-               goto error_free_ctrls;
+               goto error_free_entity;
 
        ret = v4l2_async_register_subdev(&mt9v111->sd);
        if (ret)
-               goto error_free_ctrls;
+               goto error_free_entity;
 
        return 0;
 
-error_free_ctrls:
-       v4l2_ctrl_handler_free(&mt9v111->ctrls);
-
+error_free_entity:
 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
        media_entity_cleanup(&mt9v111->sd.entity);
 #endif
 
+error_free_ctrls:
+       v4l2_ctrl_handler_free(&mt9v111->ctrls);
+
        mutex_destroy(&mt9v111->pwr_mutex);
        mutex_destroy(&mt9v111->stream_mutex);
 
@@ -1259,12 +1244,12 @@ static int mt9v111_remove(struct i2c_client *client)
 
        v4l2_async_unregister_subdev(sd);
 
-       v4l2_ctrl_handler_free(&mt9v111->ctrls);
-
 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
        media_entity_cleanup(&sd->entity);
 #endif
 
+       v4l2_ctrl_handler_free(&mt9v111->ctrls);
+
        mutex_destroy(&mt9v111->pwr_mutex);
        mutex_destroy(&mt9v111->stream_mutex);
 
index 94c1fe0e978794124568ecdecbcc211aef829929..54fe90acb5b2962432140949a17e1630361e08ca 100644 (file)
@@ -541,6 +541,8 @@ config VIDEO_CROS_EC_CEC
        depends on MFD_CROS_EC
        select CEC_CORE
        select CEC_NOTIFIER
+       select CHROME_PLATFORMS
+       select CROS_EC_PROTO
        ---help---
          If you say yes here you will get support for the
          ChromeOS Embedded Controller's CEC.
index 729b31891466db3431c0ac295b0aa4df64e16c1b..a5ae85674ffbb01c7bd93322a26821406e87f6fe 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
index c832539397d7a852a93093a55fb1e3385f85bfdc..12bce391d71fd0393d63413f52b114bb516fa1dd 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #define CAMSS_CSI_PHY_LNn_CFG2(n)              (0x004 + 0x40 * (n))
 #define CAMSS_CSI_PHY_LNn_CFG3(n)              (0x008 + 0x40 * (n))
index bcd0dfd3361865a18873ccebd5fd7879c6937b02..2e65caf1ecae7046bdfea5bd9f272ddbbc0556d5 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #define CSIPHY_3PH_LNn_CFG1(n)                 (0x000 + 0x100 * (n))
 #define CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG    (BIT(7) | BIT(6))
index 4559f3b1b38cb823352dae35271057af87aab72a..008afb85023bec24eefefaf5042c32269eb257c0 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
index 7f269021d08c0d8c13995328c9ba85e99de836e4..1f33b4eb198cc0c3085239afbd52aee428bf63a4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
@@ -1076,8 +1077,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
        else
                return -EINVAL;
 
-       ispif->line = kcalloc(ispif->line_num, sizeof(*ispif->line),
-                             GFP_KERNEL);
+       ispif->line = devm_kcalloc(dev, ispif->line_num, sizeof(*ispif->line),
+                                  GFP_KERNEL);
        if (!ispif->line)
                return -ENOMEM;
 
index da3a9fed9f2ddcb1a7ae39a541f6c9aad2be2ae8..174a36be6f5d86630947a8203e524414b4043ccd 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/iopoll.h>
 
 #include "camss-vfe.h"
index 4c584bffd179e1a25d8ddf95ea0403f8cb132d45..0dca8bf9281e7749c32dbc113dcd0a7d277c22e1 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/iopoll.h>
 
 #include "camss-vfe.h"
index dcc0c30ef1b109a91bf6185b434feba5fed94794..669615fff6a0819dfa792a9be7253f92b39f79c5 100644 (file)
@@ -848,17 +848,18 @@ static int camss_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       camss->csiphy = kcalloc(camss->csiphy_num, sizeof(*camss->csiphy),
-                               GFP_KERNEL);
+       camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
+                                    sizeof(*camss->csiphy), GFP_KERNEL);
        if (!camss->csiphy)
                return -ENOMEM;
 
-       camss->csid = kcalloc(camss->csid_num, sizeof(*camss->csid),
-                             GFP_KERNEL);
+       camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
+                                  GFP_KERNEL);
        if (!camss->csid)
                return -ENOMEM;
 
-       camss->vfe = kcalloc(camss->vfe_num, sizeof(*camss->vfe), GFP_KERNEL);
+       camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
+                                 GFP_KERNEL);
        if (!camss->vfe)
                return -ENOMEM;
 
@@ -993,12 +994,12 @@ static const struct of_device_id camss_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, camss_dt_match);
 
-static int camss_runtime_suspend(struct device *dev)
+static int __maybe_unused camss_runtime_suspend(struct device *dev)
 {
        return 0;
 }
 
-static int camss_runtime_resume(struct device *dev)
+static int __maybe_unused camss_runtime_resume(struct device *dev)
 {
        return 0;
 }
index 666d319d3d1ab21db3b50f35a725536bb486cd38..1f6c1eefe38920c9f1e08d1f99158db7e715c838 100644 (file)
@@ -402,8 +402,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                        if (msg[0].addr == state->af9033_i2c_addr[1])
                                reg |= 0x100000;
 
-                       ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
-                                       msg[0].len - 3);
+                       ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg,
+                                                                &msg[0].buf[3],
+                                                                msg[0].len - 3)
+                                               : -EOPNOTSUPP;
                } else {
                        /* I2C write */
                        u8 buf[MAX_XFER_SIZE];
index e11ab12fbdf27228f7d003a542a61321ba3ca30b..800986a797041c3b8ded3cc81cb8d43b4d350183 100644 (file)
@@ -528,8 +528,8 @@ static int usbhs_omap_get_dt_pdata(struct device *dev,
 }
 
 static const struct of_device_id usbhs_child_match_table[] = {
-       { .compatible = "ti,omap-ehci", },
-       { .compatible = "ti,omap-ohci", },
+       { .compatible = "ti,ehci-omap", },
+       { .compatible = "ti,ohci-omap3", },
        { }
 };
 
@@ -855,6 +855,7 @@ static struct platform_driver usbhs_omap_driver = {
                .pm             = &usbhsomap_dev_pm_ops,
                .of_match_table = usbhs_omap_dt_ids,
        },
+       .probe          = usbhs_omap_probe,
        .remove         = usbhs_omap_remove,
 };
 
@@ -864,9 +865,9 @@ MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
 
-static int __init omap_usbhs_drvinit(void)
+static int omap_usbhs_drvinit(void)
 {
-       return platform_driver_probe(&usbhs_omap_driver, usbhs_omap_probe);
+       return platform_driver_register(&usbhs_omap_driver);
 }
 
 /*
@@ -878,7 +879,7 @@ static int __init omap_usbhs_drvinit(void)
  */
 fs_initcall_sync(omap_usbhs_drvinit);
 
-static void __exit omap_usbhs_drvexit(void)
+static void omap_usbhs_drvexit(void)
 {
        platform_driver_unregister(&usbhs_omap_driver);
 }
index eeb7eef62174c4dfb5c8854efbef2d798f161f1e..38f90e17992717d7cd0f12ad904490abbaa2d1a5 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/sysfs.h>
+#include <linux/nospec.h>
 
 static DEFINE_MUTEX(compass_mutex);
 
@@ -50,6 +51,7 @@ static int compass_store(struct device *dev, const char *buf, size_t count,
                return ret;
        if (val >= strlen(map))
                return -EINVAL;
+       val = array_index_nospec(val, strlen(map));
        mutex_lock(&compass_mutex);
        ret = compass_command(c, map[val]);
        mutex_unlock(&compass_mutex);
index 8f82bb9d11e2e3bfb6fbbf3764180a1b7fb0d0a2..b8aaa684c397b0b8be8fe0c5ae00a37b087b6997 100644 (file)
@@ -2131,7 +2131,7 @@ static int ibmvmc_init_crq_queue(struct crq_server_adapter *adapter)
        retrc = plpar_hcall_norets(H_REG_CRQ,
                                   vdev->unit_address,
                                   queue->msg_token, PAGE_SIZE);
-       retrc = rc;
+       rc = retrc;
 
        if (rc == H_RESOURCE)
                rc = ibmvmc_reset_crq_queue(adapter);
index 7bba62a72921ebe405f36306e9233afc910351b4..fc3872fe7b2510e1fa862ea508be53ad377a4bfd 100644 (file)
@@ -521,17 +521,15 @@ int mei_cldev_enable(struct mei_cl_device *cldev)
 
        cl = cldev->cl;
 
+       mutex_lock(&bus->device_lock);
        if (cl->state == MEI_FILE_UNINITIALIZED) {
-               mutex_lock(&bus->device_lock);
                ret = mei_cl_link(cl);
-               mutex_unlock(&bus->device_lock);
                if (ret)
-                       return ret;
+                       goto out;
                /* update pointers */
                cl->cldev = cldev;
        }
 
-       mutex_lock(&bus->device_lock);
        if (mei_cl_is_connected(cl)) {
                ret = 0;
                goto out;
@@ -616,9 +614,8 @@ int mei_cldev_disable(struct mei_cl_device *cldev)
        if (err < 0)
                dev_err(bus->dev, "Could not disconnect from the ME client\n");
 
-out:
        mei_cl_bus_module_put(cldev);
-
+out:
        /* Flush queues and remove any pending read */
        mei_cl_flush_queues(cl, NULL);
        mei_cl_unlink(cl);
@@ -876,12 +873,13 @@ static void mei_cl_bus_dev_release(struct device *dev)
 
        mei_me_cl_put(cldev->me_cl);
        mei_dev_bus_put(cldev->bus);
+       mei_cl_unlink(cldev->cl);
        kfree(cldev->cl);
        kfree(cldev);
 }
 
 static const struct device_type mei_cl_device_type = {
-       .release        = mei_cl_bus_dev_release,
+       .release = mei_cl_bus_dev_release,
 };
 
 /**
index 4ab6251d418ecf4fac7ec93a4b8101db313f5249..ebdcf0b450e25bb00be1db564fd09f806e87edad 100644 (file)
@@ -1767,7 +1767,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb)
                }
        }
 
-       rets = buf->size;
+       rets = len;
 err:
        cl_dbg(dev, cl, "rpm: autosuspend\n");
        pm_runtime_mark_last_busy(dev->dev);
index 09e233d4c0de386eab9ea2f2ce178dedf4ebb480..e56f3e72d57a06cc4a9c2e8358bd3359113524c8 100644 (file)
@@ -1161,15 +1161,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                props_res = (struct hbm_props_response *)mei_msg;
 
-               if (props_res->status) {
+               if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) {
+                       dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n",
+                               props_res->me_addr);
+               } else if (props_res->status) {
                        dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n",
                                props_res->status,
                                mei_hbm_status_str(props_res->status));
                        return -EPROTO;
+               } else {
+                       mei_hbm_me_cl_add(dev, props_res);
                }
 
-               mei_hbm_me_cl_add(dev, props_res);
-
                /* request property for the next client */
                if (mei_hbm_prop_req(dev, props_res->me_addr + 1))
                        return -EIO;
index 09cb89645d06ebc97c77b886ff3c6a1be9b62c5c..2cfec33178c1fa20532270c04a1f634414a4ec19 100644 (file)
@@ -517,19 +517,23 @@ static struct mmc_host_ops meson_mx_mmc_ops = {
 static struct platform_device *meson_mx_mmc_slot_pdev(struct device *parent)
 {
        struct device_node *slot_node;
+       struct platform_device *pdev;
 
        /*
         * TODO: the MMC core framework currently does not support
         * controllers with multiple slots properly. So we only register
         * the first slot for now
         */
-       slot_node = of_find_compatible_node(parent->of_node, NULL, "mmc-slot");
+       slot_node = of_get_compatible_child(parent->of_node, "mmc-slot");
        if (!slot_node) {
                dev_warn(parent, "no 'mmc-slot' sub-node found\n");
                return ERR_PTR(-ENOENT);
        }
 
-       return of_platform_device_create(slot_node, NULL, parent);
+       pdev = of_platform_device_create(slot_node, NULL, parent);
+       of_node_put(slot_node);
+
+       return pdev;
 }
 
 static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host)
index 071693ebfe18914fe799b7da1d91df1e6f8b99b9..68760d4a5d3da1a53c655d1b33f1c2237273d136 100644 (file)
@@ -2177,6 +2177,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
        dma_release_channel(host->tx_chan);
        dma_release_channel(host->rx_chan);
 
+       dev_pm_clear_wake_irq(host->dev);
        pm_runtime_dont_use_autosuspend(host->dev);
        pm_runtime_put_sync(host->dev);
        pm_runtime_disable(host->dev);
index cbfafc453274aa2bef7aee285c5109601516d5e7..270d3c9580c51195ccb6b05e3719e98fb1836031 100644 (file)
@@ -39,13 +39,23 @@ static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
        struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1),
                                          SPI_MEM_OP_NO_ADDR,
                                          SPI_MEM_OP_NO_DUMMY,
-                                         SPI_MEM_OP_DATA_IN(len, val, 1));
+                                         SPI_MEM_OP_DATA_IN(len, NULL, 1));
+       void *scratchbuf;
        int ret;
 
+       scratchbuf = kmalloc(len, GFP_KERNEL);
+       if (!scratchbuf)
+               return -ENOMEM;
+
+       op.data.buf.in = scratchbuf;
        ret = spi_mem_exec_op(flash->spimem, &op);
        if (ret < 0)
                dev_err(&flash->spimem->spi->dev, "error %d reading %x\n", ret,
                        code);
+       else
+               memcpy(val, scratchbuf, len);
+
+       kfree(scratchbuf);
 
        return ret;
 }
@@ -56,9 +66,19 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
        struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1),
                                          SPI_MEM_OP_NO_ADDR,
                                          SPI_MEM_OP_NO_DUMMY,
-                                         SPI_MEM_OP_DATA_OUT(len, buf, 1));
+                                         SPI_MEM_OP_DATA_OUT(len, NULL, 1));
+       void *scratchbuf;
+       int ret;
 
-       return spi_mem_exec_op(flash->spimem, &op);
+       scratchbuf = kmemdup(buf, len, GFP_KERNEL);
+       if (!scratchbuf)
+               return -ENOMEM;
+
+       op.data.buf.out = scratchbuf;
+       ret = spi_mem_exec_op(flash->spimem, &op);
+       kfree(scratchbuf);
+
+       return ret;
 }
 
 static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
index 52e2cb35fc7902b1fce895d46e9944a6d908946d..99c460facd5e97702896aae893d4df258320c0f2 100644 (file)
@@ -873,8 +873,11 @@ static int mtd_part_of_parse(struct mtd_info *master,
        int ret, err = 0;
 
        np = mtd_get_of_node(master);
-       if (!mtd_is_partition(master))
+       if (mtd_is_partition(master))
+               of_node_get(np);
+       else
                np = of_get_child_by_name(np, "partitions");
+
        of_property_for_each_string(np, "compatible", prop, compat) {
                parser = mtd_part_get_compatible_parser(compat);
                if (!parser)
index 67b2065e7a19cace554463a74871ab676c221906..b864b93dd289ed6eda8b2591006a6ab57922c1b7 100644 (file)
@@ -596,6 +596,12 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
        }
 
        iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
+       /*
+        * The ->setup_dma() hook kicks DMA by using the data/command
+        * interface, which belongs to a different AXI port from the
+        * register interface.  Read back the register to avoid a race.
+        */
+       ioread32(denali->reg + DMA_ENABLE);
 
        denali_reset_irq(denali);
        denali->setup_dma(denali, dma_addr, page, write);
index 7af4d6213ee56e23d2aaeb63decbfd5cd42a00ae..bc2ef52097834f7c43194835a5177d102e6e2c88 100644 (file)
@@ -1547,7 +1547,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip,
        for (op_id = 0; op_id < subop->ninstrs; op_id++) {
                unsigned int offset, naddrs;
                const u8 *addrs;
-               int len = nand_subop_get_data_len(subop, op_id);
+               int len;
 
                instr = &subop->instrs[op_id];
 
@@ -1593,6 +1593,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip,
                                nfc_op->ndcb[0] |=
                                        NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) |
                                        NDCB0_LEN_OVRD;
+                               len = nand_subop_get_data_len(subop, op_id);
                                nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH);
                        }
                        nfc_op->data_delay_ns = instr->delay_ns;
@@ -1606,6 +1607,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip,
                                nfc_op->ndcb[0] |=
                                        NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) |
                                        NDCB0_LEN_OVRD;
+                               len = nand_subop_get_data_len(subop, op_id);
                                nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH);
                        }
                        nfc_op->data_delay_ns = instr->delay_ns;
index 9375cef2242053c1f1ade3323d04d7dd4bea77af..3d27616d9c85540304a8d78c4a2f050c0866b9a2 100644 (file)
@@ -283,8 +283,12 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                 case SIOCFINDIPDDPRT:
                        spin_lock_bh(&ipddp_route_lock);
                        rp = __ipddp_find_route(&rcp);
-                       if (rp)
-                               memcpy(&rcp2, rp, sizeof(rcp2));
+                       if (rp) {
+                               memset(&rcp2, 0, sizeof(rcp2));
+                               rcp2.ip    = rp->ip;
+                               rcp2.at    = rp->at;
+                               rcp2.flags = rp->flags;
+                       }
                        spin_unlock_bh(&ipddp_route_lock);
 
                        if (rp) {
index a764a83f99dabe54585dbad7dba40b6601177c03..0d87e11e7f1d84537fe43d95249b1bd3a2ce291d 100644 (file)
@@ -971,16 +971,13 @@ static void bond_poll_controller(struct net_device *bond_dev)
        struct slave *slave = NULL;
        struct list_head *iter;
        struct ad_info ad_info;
-       struct netpoll_info *ni;
-       const struct net_device_ops *ops;
 
        if (BOND_MODE(bond) == BOND_MODE_8023AD)
                if (bond_3ad_get_active_agg_info(bond, &ad_info))
                        return;
 
        bond_for_each_slave_rcu(bond, slave, iter) {
-               ops = slave->dev->netdev_ops;
-               if (!bond_slave_is_up(slave) || !ops->ndo_poll_controller)
+               if (!bond_slave_is_up(slave))
                        continue;
 
                if (BOND_MODE(bond) == BOND_MODE_8023AD) {
@@ -992,11 +989,7 @@ static void bond_poll_controller(struct net_device *bond_dev)
                                continue;
                }
 
-               ni = rcu_dereference_bh(slave->dev->npinfo);
-               if (down_trylock(&ni->dev_lock))
-                       continue;
-               ops->ndo_poll_controller(slave->dev);
-               up(&ni->dev_lock);
+               netpoll_poll_dev(slave->dev);
        }
 }
 
index 7c791c1da4b98af8cdd2885f91ce18ae119ae1d2..bef01331266f40776db98937c13d4e468158fa72 100644 (file)
 #define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION          0x7000
 #define MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION          BIT(7)
 #define MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION           BIT(6)
-#define MV88E6XXX_G1_ATU_OP_MISS_VIOLTATION            BIT(5)
+#define MV88E6XXX_G1_ATU_OP_MISS_VIOLATION             BIT(5)
 #define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION             BIT(4)
 
 /* Offset 0x0C: ATU Data Register */
index 307410898fc98e69575879489a259943ce090b50..5200e4bdce93d19f3a3938f3fabbe74743b1352d 100644 (file)
@@ -349,7 +349,7 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
                chip->ports[entry.portvec].atu_member_violation++;
        }
 
-       if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
+       if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
                dev_err_ratelimited(chip->dev,
                                    "ATU miss violation for %pM portvec %x\n",
                                    entry.mac, entry.portvec);
index 17f12c18d225a50a21bba97eabf0670ac9f135e5..7635c38e77dd0ce43a960ffef0fdbaabc4f1422d 100644 (file)
@@ -459,12 +459,12 @@ static void ena_com_handle_admin_completion(struct ena_com_admin_queue *admin_qu
        cqe = &admin_queue->cq.entries[head_masked];
 
        /* Go over all the completions */
-       while ((cqe->acq_common_descriptor.flags &
+       while ((READ_ONCE(cqe->acq_common_descriptor.flags) &
                        ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) {
                /* Do not read the rest of the completion entry before the
                 * phase bit was validated
                 */
-               rmb();
+               dma_rmb();
                ena_com_handle_single_admin_completion(admin_queue, cqe);
 
                head_masked++;
@@ -627,17 +627,10 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
        mmio_read_reg |= mmio_read->seq_num &
                        ENA_REGS_MMIO_REG_READ_REQ_ID_MASK;
 
-       /* make sure read_resp->req_id get updated before the hw can write
-        * there
-        */
-       wmb();
-
-       writel_relaxed(mmio_read_reg,
-                      ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
+       writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
-       mmiowb();
        for (i = 0; i < timeout; i++) {
-               if (read_resp->req_id == mmio_read->seq_num)
+               if (READ_ONCE(read_resp->req_id) == mmio_read->seq_num)
                        break;
 
                udelay(1);
@@ -1796,8 +1789,13 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
        aenq_common = &aenq_e->aenq_common_desc;
 
        /* Go over all the events */
-       while ((aenq_common->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) ==
-              phase) {
+       while ((READ_ONCE(aenq_common->flags) &
+               ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == phase) {
+               /* Make sure the phase bit (ownership) is as expected before
+                * reading the rest of the descriptor.
+                */
+               dma_rmb();
+
                pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n",
                         aenq_common->group, aenq_common->syndrom,
                         (u64)aenq_common->timestamp_low +
index ea149c134e1538d6c888db712d9b6cdc2b01412f..1c682b76190f9eb9ecbe6e428735ae21c4ed8b71 100644 (file)
@@ -51,6 +51,11 @@ static inline struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc(
        if (desc_phase != expected_phase)
                return NULL;
 
+       /* Make sure we read the rest of the descriptor after the phase bit
+        * has been read
+        */
+       dma_rmb();
+
        return cdesc;
 }
 
@@ -493,6 +498,7 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id)
        if (cdesc_phase != expected_phase)
                return -EAGAIN;
 
+       dma_rmb();
        if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
                pr_err("Invalid req id %d\n", cdesc->req_id);
                return -EINVAL;
index 6fdc753d948382e7a56aaeac801cf16ab3b8f833..2f7657227cfe9c60d77482c98df22fdb2f89e3c9 100644 (file)
@@ -107,8 +107,7 @@ static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq)
        return io_sq->q_depth - 1 - cnt;
 }
 
-static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq,
-                                           bool relaxed)
+static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
 {
        u16 tail;
 
@@ -117,10 +116,7 @@ static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq,
        pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
                 io_sq->qid, tail);
 
-       if (relaxed)
-               writel_relaxed(tail, io_sq->db_addr);
-       else
-               writel(tail, io_sq->db_addr);
+       writel(tail, io_sq->db_addr);
 
        return 0;
 }
index c673ac2df65bdf3f9b4d03403be705b581505657..29b5774dd32d47e5ad2c43e78b599493f011d129 100644 (file)
@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
 
 static int ena_rss_init_default(struct ena_adapter *adapter);
 static void check_for_admin_com_state(struct ena_adapter *adapter);
-static void ena_destroy_device(struct ena_adapter *adapter);
+static void ena_destroy_device(struct ena_adapter *adapter, bool graceful);
 static int ena_restore_device(struct ena_adapter *adapter);
 
 static void ena_tx_timeout(struct net_device *dev)
@@ -461,7 +461,7 @@ static inline int ena_alloc_rx_page(struct ena_ring *rx_ring,
                return -ENOMEM;
        }
 
-       dma = dma_map_page(rx_ring->dev, page, 0, PAGE_SIZE,
+       dma = dma_map_page(rx_ring->dev, page, 0, ENA_PAGE_SIZE,
                           DMA_FROM_DEVICE);
        if (unlikely(dma_mapping_error(rx_ring->dev, dma))) {
                u64_stats_update_begin(&rx_ring->syncp);
@@ -478,7 +478,7 @@ static inline int ena_alloc_rx_page(struct ena_ring *rx_ring,
        rx_info->page_offset = 0;
        ena_buf = &rx_info->ena_buf;
        ena_buf->paddr = dma;
-       ena_buf->len = PAGE_SIZE;
+       ena_buf->len = ENA_PAGE_SIZE;
 
        return 0;
 }
@@ -495,7 +495,7 @@ static void ena_free_rx_page(struct ena_ring *rx_ring,
                return;
        }
 
-       dma_unmap_page(rx_ring->dev, ena_buf->paddr, PAGE_SIZE,
+       dma_unmap_page(rx_ring->dev, ena_buf->paddr, ENA_PAGE_SIZE,
                       DMA_FROM_DEVICE);
 
        __free_page(page);
@@ -551,14 +551,9 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
                            rx_ring->qid, i, num);
        }
 
-       if (likely(i)) {
-               /* Add memory barrier to make sure the desc were written before
-                * issue a doorbell
-                */
-               wmb();
-               ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq, true);
-               mmiowb();
-       }
+       /* ena_com_write_sq_doorbell issues a wmb() */
+       if (likely(i))
+               ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
 
        rx_ring->next_to_use = next_to_use;
 
@@ -916,10 +911,10 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
        do {
                dma_unmap_page(rx_ring->dev,
                               dma_unmap_addr(&rx_info->ena_buf, paddr),
-                              PAGE_SIZE, DMA_FROM_DEVICE);
+                              ENA_PAGE_SIZE, DMA_FROM_DEVICE);
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
-                               rx_info->page_offset, len, PAGE_SIZE);
+                               rx_info->page_offset, len, ENA_PAGE_SIZE);
 
                netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
                          "rx skb updated. len %d. data_len %d\n",
@@ -1900,7 +1895,7 @@ static int ena_close(struct net_device *netdev)
                          "Destroy failure, restarting device\n");
                ena_dump_stats_to_dmesg(adapter);
                /* rtnl lock already obtained in dev_ioctl() layer */
-               ena_destroy_device(adapter);
+               ena_destroy_device(adapter, false);
                ena_restore_device(adapter);
        }
 
@@ -2112,12 +2107,6 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
        tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
                tx_ring->ring_size);
 
-       /* This WMB is aimed to:
-        * 1 - perform smp barrier before reading next_to_completion
-        * 2 - make sure the desc were written before trigger DB
-        */
-       wmb();
-
        /* stop the queue when no more space available, the packet can have up
         * to sgl_size + 2. one for the meta descriptor and one for header
         * (if the header is larger than tx_max_header_size).
@@ -2136,10 +2125,11 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
                 * stop the queue but meanwhile clean_tx_irq updates
                 * next_to_completion and terminates.
                 * The queue will remain stopped forever.
-                * To solve this issue this function perform rmb, check
-                * the wakeup condition and wake up the queue if needed.
+                * To solve this issue add a mb() to make sure that
+                * netif_tx_stop_queue() write is vissible before checking if
+                * there is additional space in the queue.
                 */
-               smp_rmb();
+               smp_mb();
 
                if (ena_com_sq_empty_space(tx_ring->ena_com_io_sq)
                                > ENA_TX_WAKEUP_THRESH) {
@@ -2151,8 +2141,10 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        if (netif_xmit_stopped(txq) || !skb->xmit_more) {
-               /* trigger the dma engine */
-               ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq, false);
+               /* trigger the dma engine. ena_com_write_sq_doorbell()
+                * has a mb
+                */
+               ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
                u64_stats_update_begin(&tx_ring->syncp);
                tx_ring->tx_stats.doorbells++;
                u64_stats_update_end(&tx_ring->syncp);
@@ -2550,12 +2542,15 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
        return rc;
 }
 
-static void ena_destroy_device(struct ena_adapter *adapter)
+static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
 {
        struct net_device *netdev = adapter->netdev;
        struct ena_com_dev *ena_dev = adapter->ena_dev;
        bool dev_up;
 
+       if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
+               return;
+
        netif_carrier_off(netdev);
 
        del_timer_sync(&adapter->timer_service);
@@ -2563,7 +2558,8 @@ static void ena_destroy_device(struct ena_adapter *adapter)
        dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
        adapter->dev_up_before_reset = dev_up;
 
-       ena_com_set_admin_running_state(ena_dev, false);
+       if (!graceful)
+               ena_com_set_admin_running_state(ena_dev, false);
 
        if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
                ena_down(adapter);
@@ -2591,6 +2587,7 @@ static void ena_destroy_device(struct ena_adapter *adapter)
        adapter->reset_reason = ENA_REGS_RESET_NORMAL;
 
        clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+       clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
 }
 
 static int ena_restore_device(struct ena_adapter *adapter)
@@ -2635,6 +2632,7 @@ static int ena_restore_device(struct ena_adapter *adapter)
                }
        }
 
+       set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
        mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
        dev_err(&pdev->dev, "Device reset completed successfully\n");
 
@@ -2665,7 +2663,7 @@ static void ena_fw_reset_device(struct work_struct *work)
                return;
        }
        rtnl_lock();
-       ena_destroy_device(adapter);
+       ena_destroy_device(adapter, false);
        ena_restore_device(adapter);
        rtnl_unlock();
 }
@@ -3409,30 +3407,24 @@ static void ena_remove(struct pci_dev *pdev)
                netdev->rx_cpu_rmap = NULL;
        }
 #endif /* CONFIG_RFS_ACCEL */
-
-       unregister_netdev(netdev);
        del_timer_sync(&adapter->timer_service);
 
        cancel_work_sync(&adapter->reset_task);
 
-       /* Reset the device only if the device is running. */
-       if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
-               ena_com_dev_reset(ena_dev, adapter->reset_reason);
+       unregister_netdev(netdev);
 
-       ena_free_mgmnt_irq(adapter);
+       /* If the device is running then we want to make sure the device will be
+        * reset to make sure no more events will be issued by the device.
+        */
+       if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
+               set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
 
-       ena_disable_msix(adapter);
+       rtnl_lock();
+       ena_destroy_device(adapter, true);
+       rtnl_unlock();
 
        free_netdev(netdev);
 
-       ena_com_mmio_reg_read_request_destroy(ena_dev);
-
-       ena_com_abort_admin_commands(ena_dev);
-
-       ena_com_wait_for_abort_completion(ena_dev);
-
-       ena_com_admin_destroy(ena_dev);
-
        ena_com_rss_destroy(ena_dev);
 
        ena_com_delete_debug_area(ena_dev);
@@ -3467,7 +3459,7 @@ static int ena_suspend(struct pci_dev *pdev,  pm_message_t state)
                        "ignoring device reset request as the device is being suspended\n");
                clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
        }
-       ena_destroy_device(adapter);
+       ena_destroy_device(adapter, true);
        rtnl_unlock();
        return 0;
 }
index f1972b5ab650332f9fd7c6aedbb949756785c644..7c7ae56c52cfddb11a8e1b096738dfc499ea57dc 100644 (file)
@@ -355,4 +355,15 @@ void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf);
 
 int ena_get_sset_count(struct net_device *netdev, int sset);
 
+/* The ENA buffer length fields is 16 bit long. So when PAGE_SIZE == 64kB the
+ * driver passas 0.
+ * Since the max packet size the ENA handles is ~9kB limit the buffer length to
+ * 16kB.
+ */
+#if PAGE_SIZE > SZ_16K
+#define ENA_PAGE_SIZE SZ_16K
+#else
+#define ENA_PAGE_SIZE PAGE_SIZE
+#endif
+
 #endif /* !(ENA_H) */
index 024998d6d8c6ed959c555c82b66f687cb0a85c2c..6a8e2567f2bdef5e4a7fa3685de97354c67ed280 100644 (file)
@@ -154,7 +154,7 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id);
 static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id);
 static void bmac_set_timeout(struct net_device *dev);
 static void bmac_tx_timeout(struct timer_list *t);
-static int bmac_output(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t bmac_output(struct sk_buff *skb, struct net_device *dev);
 static void bmac_start(struct net_device *dev);
 
 #define        DBDMA_SET(x)    ( ((x) | (x) << 16) )
@@ -1456,7 +1456,7 @@ bmac_start(struct net_device *dev)
        spin_unlock_irqrestore(&bp->lock, flags);
 }
 
-static int
+static netdev_tx_t
 bmac_output(struct sk_buff *skb, struct net_device *dev)
 {
        struct bmac_data *bp = netdev_priv(dev);
index 0b5429d76bcf230f7c32fd52c690d1fc385535c5..68b9ee4894892f96f82453cd657d7aa4875b467b 100644 (file)
@@ -78,7 +78,7 @@ struct mace_data {
 
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static void mace_reset(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
@@ -525,7 +525,7 @@ static inline void mace_set_timeout(struct net_device *dev)
     mp->timeout_active = 1;
 }
 
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
     struct mace_data *mp = netdev_priv(dev);
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
index 137cbb470af2301b83864901332d794dcaa6f9b5..376f2c2613e7fbe27a1cbc18d15e77527fe3622a 100644 (file)
@@ -89,7 +89,7 @@ struct mace_frame {
 
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
 static void mace_reset(struct net_device *dev);
@@ -444,7 +444,7 @@ static int mace_close(struct net_device *dev)
  * Transmit a frame
  */
 
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
        struct mace_data *mp = netdev_priv(dev);
        unsigned long flags;
index b5f1f62e8e253785436fa7cd9119a8467edf4fd4..d1e1a0ba86150208e73ffdbce006e8d1a822302c 100644 (file)
@@ -225,9 +225,10 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
                }
 
                /* for single fragment packets use build_skb() */
-               if (buff->is_eop) {
+               if (buff->is_eop &&
+                   buff->len <= AQ_CFG_RX_FRAME_MAX - AQ_SKB_ALIGN) {
                        skb = build_skb(page_address(buff->page),
-                                       buff->len + AQ_SKB_ALIGN);
+                                       AQ_CFG_RX_FRAME_MAX);
                        if (unlikely(!skb)) {
                                err = -ENOMEM;
                                goto err_exit;
@@ -247,18 +248,21 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
                                        buff->len - ETH_HLEN,
                                        SKB_TRUESIZE(buff->len - ETH_HLEN));
 
-                       for (i = 1U, next_ = buff->next,
-                            buff_ = &self->buff_ring[next_]; true;
-                            next_ = buff_->next,
-                            buff_ = &self->buff_ring[next_], ++i) {
-                               skb_add_rx_frag(skb, i, buff_->page, 0,
-                                               buff_->len,
-                                               SKB_TRUESIZE(buff->len -
-                                               ETH_HLEN));
-                               buff_->is_cleaned = 1;
-
-                               if (buff_->is_eop)
-                                       break;
+                       if (!buff->is_eop) {
+                               for (i = 1U, next_ = buff->next,
+                                    buff_ = &self->buff_ring[next_];
+                                    true; next_ = buff_->next,
+                                    buff_ = &self->buff_ring[next_], ++i) {
+                                       skb_add_rx_frag(skb, i,
+                                                       buff_->page, 0,
+                                                       buff_->len,
+                                                       SKB_TRUESIZE(buff->len -
+                                                       ETH_HLEN));
+                                       buff_->is_cleaned = 1;
+
+                                       if (buff_->is_eop)
+                                               break;
+                               }
                        }
                }
 
index 71362b7f60402545c3b4aa2bc391a1e2d3cd7f7f..fcc2328bb0d953e797c49699b11e5e5956a0d583 100644 (file)
@@ -12894,19 +12894,6 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        }
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void poll_bnx2x(struct net_device *dev)
-{
-       struct bnx2x *bp = netdev_priv(dev);
-       int i;
-
-       for_each_eth_queue(bp, i) {
-               struct bnx2x_fastpath *fp = &bp->fp[i];
-               napi_schedule(&bnx2x_fp(bp, fp->index, napi));
-       }
-}
-#endif
-
 static int bnx2x_validate_addr(struct net_device *dev)
 {
        struct bnx2x *bp = netdev_priv(dev);
@@ -13113,9 +13100,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
        .ndo_tx_timeout         = bnx2x_tx_timeout,
        .ndo_vlan_rx_add_vid    = bnx2x_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = bnx2x_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = poll_bnx2x,
-#endif
        .ndo_setup_tc           = __bnx2x_setup_tc,
 #ifdef CONFIG_BNX2X_SRIOV
        .ndo_set_vf_mac         = bnx2x_set_vf_mac,
index cecbb1d1f587f936b0d2960739c911fc28f05d51..61957b0bbd8c9f46773ff26ac9d14759b96c3960 100644 (file)
@@ -7672,21 +7672,6 @@ static void bnxt_tx_timeout(struct net_device *dev)
        bnxt_queue_sp_work(bp);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void bnxt_poll_controller(struct net_device *dev)
-{
-       struct bnxt *bp = netdev_priv(dev);
-       int i;
-
-       /* Only process tx rings/combined rings in netpoll mode. */
-       for (i = 0; i < bp->tx_nr_rings; i++) {
-               struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
-
-               napi_schedule(&txr->bnapi->napi);
-       }
-}
-#endif
-
 static void bnxt_timer(struct timer_list *t)
 {
        struct bnxt *bp = from_timer(bp, t, timer);
@@ -8027,7 +8012,7 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p)
        if (ether_addr_equal(addr->sa_data, dev->dev_addr))
                return 0;
 
-       rc = bnxt_approve_mac(bp, addr->sa_data);
+       rc = bnxt_approve_mac(bp, addr->sa_data, true);
        if (rc)
                return rc;
 
@@ -8519,9 +8504,6 @@ static const struct net_device_ops bnxt_netdev_ops = {
        .ndo_set_vf_link_state  = bnxt_set_vf_link_state,
        .ndo_set_vf_spoofchk    = bnxt_set_vf_spoofchk,
        .ndo_set_vf_trust       = bnxt_set_vf_trust,
-#endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = bnxt_poll_controller,
 #endif
        .ndo_setup_tc           = bnxt_setup_tc,
 #ifdef CONFIG_RFS_ACCEL
@@ -8827,14 +8809,19 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
        } else {
 #ifdef CONFIG_BNXT_SRIOV
                struct bnxt_vf_info *vf = &bp->vf;
+               bool strict_approval = true;
 
                if (is_valid_ether_addr(vf->mac_addr)) {
                        /* overwrite netdev dev_addr with admin VF MAC */
                        memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
+                       /* Older PF driver or firmware may not approve this
+                        * correctly.
+                        */
+                       strict_approval = false;
                } else {
                        eth_hw_addr_random(bp->dev);
                }
-               rc = bnxt_approve_mac(bp, bp->dev->dev_addr);
+               rc = bnxt_approve_mac(bp, bp->dev->dev_addr, strict_approval);
 #endif
        }
        return rc;
index f3b9fbcc705bc62304a5a09cbe54eae3d2e0b95d..790c684f08abcab21980cd9a8479f27cf516d464 100644 (file)
@@ -46,6 +46,9 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
                }
        }
 
+       if (i == ARRAY_SIZE(nvm_params))
+               return -EOPNOTSUPP;
+
        if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
                idx = bp->pf.port_id;
        else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
index fcd085a9853a96e694bcbb3847d554d41f1a014c..3962f6fd543c96f6322ca531c9ebdb3eb1cd2a23 100644 (file)
@@ -1104,7 +1104,7 @@ void bnxt_update_vf_mac(struct bnxt *bp)
        mutex_unlock(&bp->hwrm_cmd_lock);
 }
 
-int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
+int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict)
 {
        struct hwrm_func_vf_cfg_input req = {0};
        int rc = 0;
@@ -1122,12 +1122,13 @@ int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
        memcpy(req.dflt_mac_addr, mac, ETH_ALEN);
        rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
 mac_done:
-       if (rc) {
+       if (rc && strict) {
                rc = -EADDRNOTAVAIL;
                netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n",
                            mac);
+               return rc;
        }
-       return rc;
+       return 0;
 }
 #else
 
@@ -1144,7 +1145,7 @@ void bnxt_update_vf_mac(struct bnxt *bp)
 {
 }
 
-int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
+int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict)
 {
        return 0;
 }
index e9b20cd1988194c265e311ac61ca5ea7b738c118..2eed9eda1195c0abc21b1bc2374a91e99141d6f8 100644 (file)
@@ -39,5 +39,5 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs);
 void bnxt_sriov_disable(struct bnxt *);
 void bnxt_hwrm_exec_fwd_req(struct bnxt *);
 void bnxt_update_vf_mac(struct bnxt *);
-int bnxt_approve_mac(struct bnxt *, u8 *);
+int bnxt_approve_mac(struct bnxt *, u8 *, bool);
 #endif
index 092c817f8f11cdda48fe8233fb04b7de2a76586a..e1594c9df4c6cda15c61a3b77afa4e2564363b57 100644 (file)
@@ -75,17 +75,23 @@ static int bnxt_tc_parse_redir(struct bnxt *bp,
        return 0;
 }
 
-static void bnxt_tc_parse_vlan(struct bnxt *bp,
-                              struct bnxt_tc_actions *actions,
-                              const struct tc_action *tc_act)
+static int bnxt_tc_parse_vlan(struct bnxt *bp,
+                             struct bnxt_tc_actions *actions,
+                             const struct tc_action *tc_act)
 {
-       if (tcf_vlan_action(tc_act) == TCA_VLAN_ACT_POP) {
+       switch (tcf_vlan_action(tc_act)) {
+       case TCA_VLAN_ACT_POP:
                actions->flags |= BNXT_TC_ACTION_FLAG_POP_VLAN;
-       } else if (tcf_vlan_action(tc_act) == TCA_VLAN_ACT_PUSH) {
+               break;
+       case TCA_VLAN_ACT_PUSH:
                actions->flags |= BNXT_TC_ACTION_FLAG_PUSH_VLAN;
                actions->push_vlan_tci = htons(tcf_vlan_push_vid(tc_act));
                actions->push_vlan_tpid = tcf_vlan_push_proto(tc_act);
+               break;
+       default:
+               return -EOPNOTSUPP;
        }
+       return 0;
 }
 
 static int bnxt_tc_parse_tunnel_set(struct bnxt *bp,
@@ -134,7 +140,9 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
 
                /* Push/pop VLAN */
                if (is_tcf_vlan(tc_act)) {
-                       bnxt_tc_parse_vlan(bp, actions, tc_act);
+                       rc = bnxt_tc_parse_vlan(bp, actions, tc_act);
+                       if (rc)
+                               return rc;
                        continue;
                }
 
index 16e4ef7d71855c7ed10905c3fdcf8d3a255f20c4..f1a86b42261796865fc659bc042c6763a2393a6f 100644 (file)
@@ -3837,6 +3837,13 @@ static const struct macb_config at91sam9260_config = {
        .init = macb_init,
 };
 
+static const struct macb_config sama5d3macb_config = {
+       .caps = MACB_CAPS_SG_DISABLED
+             | MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+       .clk_init = macb_clk_init,
+       .init = macb_init,
+};
+
 static const struct macb_config pc302gem_config = {
        .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
        .dma_burst_length = 16,
@@ -3904,6 +3911,7 @@ static const struct of_device_id macb_dt_ids[] = {
        { .compatible = "cdns,gem", .data = &pc302gem_config },
        { .compatible = "atmel,sama5d2-gem", .data = &sama5d2_config },
        { .compatible = "atmel,sama5d3-gem", .data = &sama5d3_config },
+       { .compatible = "atmel,sama5d3-macb", .data = &sama5d3macb_config },
        { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config },
        { .compatible = "cdns,at91rm9200-emac", .data = &emac_config },
        { .compatible = "cdns,emac", .data = &emac_config },
index b8f75a22fb6c97183d89c97f7ce2a9f0cd5ead5d..f152da1ce0464c5c065010813213e5f60eb111af 100644 (file)
@@ -753,7 +753,6 @@ struct cpl_abort_req_rss {
 };
 
 struct cpl_abort_req_rss6 {
-       WR_HDR;
        union opcode_tid ot;
        __be32 srqidx_status;
 };
index e2a702996db41f073879b91475c24c249292955a..13dfdfca49fc7816b8fb64c55d372b19370e4a7f 100644 (file)
@@ -332,7 +332,7 @@ static int ep93xx_poll(struct napi_struct *napi, int budget)
        return rx;
 }
 
-static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ep93xx_priv *ep = netdev_priv(dev);
        struct ep93xx_tdesc *txd;
index 3f8fe8fd79cc65beb17e334a0403b01006f0bd08..6324e80960c3e1126eb4ad1fe19aac30b74a0b6d 100644 (file)
@@ -113,7 +113,7 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id);
 static void set_multicast_list(struct net_device *dev);
 static void net_rx(struct net_device *dev);
@@ -324,7 +324,7 @@ net_open(struct net_device *dev)
        return 0;
 }
 
-static int
+static netdev_tx_t
 net_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_local *lp = netdev_priv(dev);
index ff92ab1daeb80cec7779e1f00faa5f0174fcf727..1e9d882c04ef1a8d989c56f14f0db271d6c4027d 100644 (file)
@@ -4500,7 +4500,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
                                port_res->max_vfs += le16_to_cpu(pcie->num_vfs);
                        }
                }
-               return status;
+               goto err;
        }
 
        pcie = be_get_pcie_desc(resp->func_param, desc_count,
index c8c7ad2eff77ecb5f2bd4ee5012a41b3ac1afcc8..9b5a68b6543287a93107ae2a923ee3bf99a38a82 100644 (file)
@@ -2634,7 +2634,7 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
                /* Wait for link to drop */
                time = jiffies + (HZ / 10);
                do {
-                       if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
+                       if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
                                break;
                        if (!in_interrupt())
                                schedule_timeout_interruptible(1);
index dc983450354bbf3eae79dda14d7c44815cee126d..35f6291a3672331584539831a46025994749a69e 100644 (file)
@@ -64,7 +64,8 @@ static unsigned int net_debug = NET_DEBUG;
 #define RX_AREA_END    0x0fc00
 
 static int ether1_open(struct net_device *dev);
-static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ether1_sendpacket(struct sk_buff *skb,
+                                    struct net_device *dev);
 static irqreturn_t ether1_interrupt(int irq, void *dev_id);
 static int ether1_close(struct net_device *dev);
 static void ether1_setmulticastlist(struct net_device *dev);
@@ -667,7 +668,7 @@ ether1_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 }
 
-static int
+static netdev_tx_t
 ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
 {
        int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
index f00a1dc2128cbcfcf590cb22bf88aa3796b6ab45..2f7ae118217fe881a53614fb436ed119bf56919f 100644 (file)
@@ -347,7 +347,7 @@ static const char init_setup[] =
        0x7f /*  *multi IA */ };
 
 static int i596_open(struct net_device *dev);
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -966,7 +966,7 @@ static void i596_tx_timeout (struct net_device *dev)
 }
 
 
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct i596_private *lp = netdev_priv(dev);
        struct tx_cmd *tx_cmd;
index 8bb15a8c2a4026939f37161629d424963dc0a082..1a86184d44c0ae8cc2f96b0d942c70711630c4df 100644 (file)
@@ -121,7 +121,8 @@ static int     sun3_82586_probe1(struct net_device *dev,int ioaddr);
 static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id);
 static int     sun3_82586_open(struct net_device *dev);
 static int     sun3_82586_close(struct net_device *dev);
-static int     sun3_82586_send_packet(struct sk_buff *,struct net_device *);
+static netdev_tx_t     sun3_82586_send_packet(struct sk_buff *,
+                                             struct net_device *);
 static struct  net_device_stats *sun3_82586_get_stats(struct net_device *dev);
 static void    set_multicast_list(struct net_device *dev);
 static void    sun3_82586_timeout(struct net_device *dev);
@@ -1002,7 +1003,8 @@ static void sun3_82586_timeout(struct net_device *dev)
  * send frame
  */
 
-static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        int len,i;
 #ifndef NO_NOPCOMMANDS
index 3726646863095dc145e8df1ccc5d082f9fd802bd..129f4e9f38dac01f424ea7337002add11a2751e5 100644 (file)
@@ -2677,12 +2677,17 @@ static int emac_init_phy(struct emac_instance *dev)
                if (of_phy_is_fixed_link(np)) {
                        int res = emac_dt_mdio_probe(dev);
 
-                       if (!res) {
-                               res = of_phy_register_fixed_link(np);
-                               if (res)
-                                       mdiobus_unregister(dev->mii_bus);
+                       if (res)
+                               return res;
+
+                       res = of_phy_register_fixed_link(np);
+                       dev->phy_dev = of_phy_find_device(np);
+                       if (res || !dev->phy_dev) {
+                               mdiobus_unregister(dev->mii_bus);
+                               return res ? res : -EINVAL;
                        }
-                       return res;
+                       emac_adjust_link(dev->ndev);
+                       put_device(&dev->phy_dev->mdio.dev);
                }
                return 0;
        }
index a903a0ba45e180c39e99c6b6a0726291203b1f91..7d42582ed48dc36f3da8b6b670d1c4f8847ffa9b 100644 (file)
@@ -504,9 +504,6 @@ void fm10k_update_stats(struct fm10k_intfc *interface);
 void fm10k_service_event_schedule(struct fm10k_intfc *interface);
 void fm10k_macvlan_schedule(struct fm10k_intfc *interface);
 void fm10k_update_rx_drop_en(struct fm10k_intfc *interface);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-void fm10k_netpoll(struct net_device *netdev);
-#endif
 
 /* Netdev */
 struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info);
index 929f538d28bc03a391340ebf6cc531b03f92b7a3..538a8467f43413f97bbf477053ba8e93560e2bcf 100644 (file)
@@ -1648,9 +1648,6 @@ static const struct net_device_ops fm10k_netdev_ops = {
        .ndo_udp_tunnel_del     = fm10k_udp_tunnel_del,
        .ndo_dfwd_add_station   = fm10k_dfwd_add_station,
        .ndo_dfwd_del_station   = fm10k_dfwd_del_station,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = fm10k_netpoll,
-#endif
        .ndo_features_check     = fm10k_features_check,
 };
 
index 15071e4adb98c9924ab2e9a17c7f616f23104bd0..c859ababeed50e030baf7cb7041fbd20916c2265 100644 (file)
@@ -1210,28 +1210,6 @@ static irqreturn_t fm10k_msix_mbx_vf(int __always_unused irq, void *data)
        return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- *  fm10k_netpoll - A Polling 'interrupt' handler
- *  @netdev: network interface device structure
- *
- *  This is used by netconsole to send skbs without having to re-enable
- *  interrupts. It's not called while the normal interrupt routine is executing.
- **/
-void fm10k_netpoll(struct net_device *netdev)
-{
-       struct fm10k_intfc *interface = netdev_priv(netdev);
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__FM10K_DOWN, interface->state))
-               return;
-
-       for (i = 0; i < interface->num_q_vectors; i++)
-               fm10k_msix_clean_rings(0, interface->q_vector[i]);
-}
-
-#endif
 #define FM10K_ERR_MSG(type) case (type): error = #type; break
 static void fm10k_handle_fault(struct fm10k_intfc *interface, int type,
                               struct fm10k_fault *fault)
index 5906c1c1d19d82d7e37b0a891e457fea792b4153..fef6d892ed4cfe5ae293aa2fe01ef38a257c47bf 100644 (file)
@@ -396,29 +396,6 @@ static void i40evf_map_rings_to_vectors(struct i40evf_adapter *adapter)
        adapter->aq_required |= I40EVF_FLAG_AQ_MAP_VECTORS;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * i40evf_netpoll - A Polling 'interrupt' handler
- * @netdev: network interface device structure
- *
- * This is used by netconsole to send skbs without having to re-enable
- * interrupts.  It's not called while the normal interrupt routine is executing.
- **/
-static void i40evf_netpoll(struct net_device *netdev)
-{
-       struct i40evf_adapter *adapter = netdev_priv(netdev);
-       int q_vectors = adapter->num_msix_vectors - NONQ_VECS;
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__I40E_VSI_DOWN, adapter->vsi.state))
-               return;
-
-       for (i = 0; i < q_vectors; i++)
-               i40evf_msix_clean_rings(0, &adapter->q_vectors[i]);
-}
-
-#endif
 /**
  * i40evf_irq_affinity_notify - Callback for affinity changes
  * @notify: context as to what irq was changed
@@ -3229,9 +3206,6 @@ static const struct net_device_ops i40evf_netdev_ops = {
        .ndo_features_check     = i40evf_features_check,
        .ndo_fix_features       = i40evf_fix_features,
        .ndo_set_features       = i40evf_set_features,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = i40evf_netpoll,
-#endif
        .ndo_setup_tc           = i40evf_setup_tc,
 };
 
index f1e80eed2fd6d9f94eab163acb4d178d83ba4af2..3f047bb43348881c592adf3b236518ee21bc2fdd 100644 (file)
@@ -4806,30 +4806,6 @@ void ice_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
        stats->rx_length_errors = vsi_stats->rx_length_errors;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * ice_netpoll - polling "interrupt" handler
- * @netdev: network interface device structure
- *
- * Used by netconsole to send skbs without having to re-enable interrupts.
- * This is not called in the normal interrupt path.
- */
-static void ice_netpoll(struct net_device *netdev)
-{
-       struct ice_netdev_priv *np = netdev_priv(netdev);
-       struct ice_vsi *vsi = np->vsi;
-       struct ice_pf *pf = vsi->back;
-       int i;
-
-       if (test_bit(__ICE_DOWN, vsi->state) ||
-           !test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
-               return;
-
-       for (i = 0; i < vsi->num_q_vectors; i++)
-               ice_msix_clean_rings(0, vsi->q_vectors[i]);
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
 /**
  * ice_napi_disable_all - Disable NAPI for all q_vectors in the VSI
  * @vsi: VSI having NAPI disabled
@@ -5497,9 +5473,6 @@ static const struct net_device_ops ice_netdev_ops = {
        .ndo_validate_addr = eth_validate_addr,
        .ndo_change_mtu = ice_change_mtu,
        .ndo_get_stats64 = ice_get_stats64,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller = ice_netpoll,
-#endif /* CONFIG_NET_POLL_CONTROLLER */
        .ndo_vlan_rx_add_vid = ice_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid = ice_vlan_rx_kill_vid,
        .ndo_set_features = ice_set_features,
index a32c576c1e656c0102989413cad114d1d8f03771..0796cef96fa335ee1907d9aa5d4d56f4fd366ca3 100644 (file)
@@ -205,10 +205,6 @@ static struct notifier_block dca_notifier = {
        .priority       = 0
 };
 #endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* for netdump / net console */
-static void igb_netpoll(struct net_device *);
-#endif
 #ifdef CONFIG_PCI_IOV
 static unsigned int max_vfs;
 module_param(max_vfs, uint, 0);
@@ -2881,9 +2877,6 @@ static const struct net_device_ops igb_netdev_ops = {
        .ndo_set_vf_spoofchk    = igb_ndo_set_vf_spoofchk,
        .ndo_set_vf_trust       = igb_ndo_set_vf_trust,
        .ndo_get_vf_config      = igb_ndo_get_vf_config,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = igb_netpoll,
-#endif
        .ndo_fix_features       = igb_fix_features,
        .ndo_set_features       = igb_set_features,
        .ndo_fdb_add            = igb_ndo_fdb_add,
@@ -9053,29 +9046,6 @@ static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
        return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void igb_netpoll(struct net_device *netdev)
-{
-       struct igb_adapter *adapter = netdev_priv(netdev);
-       struct e1000_hw *hw = &adapter->hw;
-       struct igb_q_vector *q_vector;
-       int i;
-
-       for (i = 0; i < adapter->num_q_vectors; i++) {
-               q_vector = adapter->q_vector[i];
-               if (adapter->flags & IGB_FLAG_HAS_MSIX)
-                       wr32(E1000_EIMC, q_vector->eims_value);
-               else
-                       igb_irq_disable(adapter);
-               napi_schedule(&q_vector->napi);
-       }
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
 /**
  *  igb_io_error_detected - called when PCI error is detected
  *  @pdev: Pointer to PCI device
index d3e72d0f66ef428b08e4bd88508e05b734bc43a4..7722153c4ac2fdff29c0afa0627ec26228557d69 100644 (file)
@@ -81,11 +81,6 @@ static int ixgb_vlan_rx_kill_vid(struct net_device *netdev,
                                 __be16 proto, u16 vid);
 static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* for netdump / net console */
-static void ixgb_netpoll(struct net_device *dev);
-#endif
-
 static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
                              enum pci_channel_state state);
 static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev);
@@ -348,9 +343,6 @@ static const struct net_device_ops ixgb_netdev_ops = {
        .ndo_tx_timeout         = ixgb_tx_timeout,
        .ndo_vlan_rx_add_vid    = ixgb_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ixgb_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ixgb_netpoll,
-#endif
        .ndo_fix_features       = ixgb_fix_features,
        .ndo_set_features       = ixgb_set_features,
 };
@@ -2195,23 +2187,6 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
                ixgb_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-
-static void ixgb_netpoll(struct net_device *dev)
-{
-       struct ixgb_adapter *adapter = netdev_priv(dev);
-
-       disable_irq(adapter->pdev->irq);
-       ixgb_intr(adapter->pdev->irq, dev);
-       enable_irq(adapter->pdev->irq);
-}
-#endif
-
 /**
  * ixgb_io_error_detected - called when PCI error is detected
  * @pdev:    pointer to pci device with error
index 9a23d33a47ed52bfeb10d79d970e114ee4702d6e..f27d73a7bf16f084ea8f4ab12d905b031f514cf8 100644 (file)
@@ -8768,28 +8768,6 @@ static int ixgbe_del_sanmac_netdev(struct net_device *dev)
        return err;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void ixgbe_netpoll(struct net_device *netdev)
-{
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__IXGBE_DOWN, &adapter->state))
-               return;
-
-       /* loop through and schedule all active queues */
-       for (i = 0; i < adapter->num_q_vectors; i++)
-               ixgbe_msix_clean_rings(0, adapter->q_vector[i]);
-}
-
-#endif
-
 static void ixgbe_get_ring_stats64(struct rtnl_link_stats64 *stats,
                                   struct ixgbe_ring *ring)
 {
@@ -10251,9 +10229,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_get_vf_config      = ixgbe_ndo_get_vf_config,
        .ndo_get_stats64        = ixgbe_get_stats64,
        .ndo_setup_tc           = __ixgbe_setup_tc,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ixgbe_netpoll,
-#endif
 #ifdef IXGBE_FCOE
        .ndo_select_queue       = ixgbe_select_queue,
        .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
index d86446d202d5ed95826db225139b095d7c7a683c..5a228582423b74726de2bd040a388eb8e59df764 100644 (file)
@@ -4233,24 +4233,6 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
        return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void ixgbevf_netpoll(struct net_device *netdev)
-{
-       struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__IXGBEVF_DOWN, &adapter->state))
-               return;
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               ixgbevf_msix_clean_rings(0, adapter->q_vector[i]);
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
 static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4482,9 +4464,6 @@ static const struct net_device_ops ixgbevf_netdev_ops = {
        .ndo_tx_timeout         = ixgbevf_tx_timeout,
        .ndo_vlan_rx_add_vid    = ixgbevf_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ixgbevf_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ixgbevf_netpoll,
-#endif
        .ndo_features_check     = ixgbevf_features_check,
        .ndo_bpf                = ixgbevf_xdp,
 };
index 7a637b51c7d2302b63f2eb579adea4e0459e7430..e08301d833e2ed91bda977109404175f556f563f 100644 (file)
@@ -274,6 +274,7 @@ ltq_etop_hw_init(struct net_device *dev)
                struct ltq_etop_chan *ch = &priv->ch[i];
 
                ch->idx = ch->dma.nr = i;
+               ch->dma.dev = &priv->pdev->dev;
 
                if (IS_TX(i)) {
                        ltq_dma_alloc_tx(&ch->dma);
index bc80a678abc30e22910400c5c39f847317aac8ec..b4ed7d394d079e0acb05a89d8866e8e97d0e252d 100644 (file)
@@ -1890,8 +1890,8 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
                if (!data || !(rx_desc->buf_phys_addr))
                        continue;
 
-               dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
-                                MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
+               dma_unmap_page(pp->dev->dev.parent, rx_desc->buf_phys_addr,
+                              PAGE_SIZE, DMA_FROM_DEVICE);
                __free_page(data);
        }
 }
@@ -2008,8 +2008,8 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
                                skb_add_rx_frag(rxq->skb, frag_num, page,
                                                frag_offset, frag_size,
                                                PAGE_SIZE);
-                               dma_unmap_single(dev->dev.parent, phys_addr,
-                                                PAGE_SIZE, DMA_FROM_DEVICE);
+                               dma_unmap_page(dev->dev.parent, phys_addr,
+                                              PAGE_SIZE, DMA_FROM_DEVICE);
                                rxq->left_size -= frag_size;
                        }
                } else {
@@ -2039,9 +2039,8 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
                                                frag_offset, frag_size,
                                                PAGE_SIZE);
 
-                               dma_unmap_single(dev->dev.parent, phys_addr,
-                                                PAGE_SIZE,
-                                                DMA_FROM_DEVICE);
+                               dma_unmap_page(dev->dev.parent, phys_addr,
+                                              PAGE_SIZE, DMA_FROM_DEVICE);
 
                                rxq->left_size -= frag_size;
                        }
index 28500417843ed3db0b7b0d53e705f7384b3341b1..38cc01beea79ee53e8cd2970092f0575b1b1f374 100644 (file)
@@ -58,6 +58,8 @@ static struct {
  */
 static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
                             const struct phylink_link_state *state);
+static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
+                             phy_interface_t interface, struct phy_device *phy);
 
 /* Queue modes */
 #define MVPP2_QDIST_SINGLE_MODE        0
@@ -3053,10 +3055,12 @@ static int mvpp2_poll(struct napi_struct *napi, int budget)
                                   cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
        }
 
-       cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
-       if (cause_tx) {
-               cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
-               mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
+       if (port->has_tx_irqs) {
+               cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
+               if (cause_tx) {
+                       cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
+                       mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
+               }
        }
 
        /* Process RX packets */
@@ -3142,6 +3146,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
                mvpp22_mode_reconfigure(port);
 
        if (port->phylink) {
+               netif_carrier_off(port->dev);
                phylink_start(port->phylink);
        } else {
                /* Phylink isn't used as of now for ACPI, so the MAC has to be
@@ -3150,9 +3155,10 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
                 */
                struct phylink_link_state state = {
                        .interface = port->phy_interface,
-                       .link = 1,
                };
                mvpp2_mac_config(port->dev, MLO_AN_INBAND, &state);
+               mvpp2_mac_link_up(port->dev, MLO_AN_INBAND, port->phy_interface,
+                                 NULL);
        }
 
        netif_tx_start_all_queues(port->dev);
@@ -4495,10 +4501,6 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
                return;
        }
 
-       netif_tx_stop_all_queues(port->dev);
-       if (!port->has_phy)
-               netif_carrier_off(port->dev);
-
        /* Make sure the port is disabled when reconfiguring the mode */
        mvpp2_port_disable(port);
 
@@ -4523,16 +4525,7 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
        if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK)
                mvpp2_port_loopback_set(port, state);
 
-       /* If the port already was up, make sure it's still in the same state */
-       if (state->link || !port->has_phy) {
-               mvpp2_port_enable(port);
-
-               mvpp2_egress_enable(port);
-               mvpp2_ingress_enable(port);
-               if (!port->has_phy)
-                       netif_carrier_on(dev);
-               netif_tx_wake_all_queues(dev);
-       }
+       mvpp2_port_enable(port);
 }
 
 static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
index 6785661d1a72627d7cc6895359e0ece284577d96..fe49384eba48cb3f75bd33f5bfb9cf1fa15af791 100644 (file)
@@ -1286,20 +1286,6 @@ static void mlx4_en_do_set_rx_mode(struct work_struct *work)
        mutex_unlock(&mdev->state_lock);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void mlx4_en_netpoll(struct net_device *dev)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_cq *cq;
-       int i;
-
-       for (i = 0; i < priv->tx_ring_num[TX]; i++) {
-               cq = priv->tx_cq[TX][i];
-               napi_schedule(&cq->napi);
-       }
-}
-#endif
-
 static int mlx4_en_set_rss_steer_rules(struct mlx4_en_priv *priv)
 {
        u64 reg_id;
@@ -2946,9 +2932,6 @@ static const struct net_device_ops mlx4_netdev_ops = {
        .ndo_tx_timeout         = mlx4_en_tx_timeout,
        .ndo_vlan_rx_add_vid    = mlx4_en_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = mlx4_en_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = mlx4_en_netpoll,
-#endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
        .ndo_setup_tc           = __mlx4_en_setup_tc,
@@ -2983,9 +2966,6 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
        .ndo_set_vf_link_state  = mlx4_en_set_vf_link_state,
        .ndo_get_vf_stats       = mlx4_en_get_vf_stats,
        .ndo_get_vf_config      = mlx4_en_get_vf_config,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = mlx4_en_netpoll,
-#endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
        .ndo_setup_tc           = __mlx4_en_setup_tc,
index 1f3372c1802ed0185cdb4f8ef309479549ceb3db..2df92dbd38e101aae78c99a6456aeefc76e4bb64 100644 (file)
@@ -240,7 +240,8 @@ static void mlx4_set_eq_affinity_hint(struct mlx4_priv *priv, int vec)
        struct mlx4_dev *dev = &priv->dev;
        struct mlx4_eq *eq = &priv->eq_table.eq[vec];
 
-       if (!eq->affinity_mask || cpumask_empty(eq->affinity_mask))
+       if (!cpumask_available(eq->affinity_mask) ||
+           cpumask_empty(eq->affinity_mask))
                return;
 
        hint_err = irq_set_affinity_hint(eq->irq, eq->affinity_mask);
index 3ce14d42ddc8984eecc2c19cb73f8d379b7f6498..a53736c26c0cec416b119878356e2beffe17b37e 100644 (file)
@@ -206,7 +206,7 @@ static void poll_timeout(struct mlx5_cmd_work_ent *ent)
        u8 own;
 
        do {
-               own = ent->lay->status_own;
+               own = READ_ONCE(ent->lay->status_own);
                if (!(own & CMD_OWNER_HW)) {
                        ent->ret = 0;
                        return;
index b994b80d5714ad142a3af4711c65d62b7b1d5a6c..37ba7c78859db17aa7ecfa76648ca54adb71790b 100644 (file)
@@ -132,11 +132,11 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
        delayed_event_start(priv);
 
        dev_ctx->context = intf->add(dev);
-       set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
-       if (intf->attach)
-               set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
-
        if (dev_ctx->context) {
+               set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
+               if (intf->attach)
+                       set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
+
                spin_lock_irq(&priv->ctx_lock);
                list_add_tail(&dev_ctx->list, &priv->ctx_list);
 
@@ -211,12 +211,17 @@ static void mlx5_attach_interface(struct mlx5_interface *intf, struct mlx5_priv
        if (intf->attach) {
                if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state))
                        goto out;
-               intf->attach(dev, dev_ctx->context);
+               if (intf->attach(dev, dev_ctx->context))
+                       goto out;
+
                set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
        } else {
                if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
                        goto out;
                dev_ctx->context = intf->add(dev);
+               if (!dev_ctx->context)
+                       goto out;
+
                set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
        }
 
@@ -391,16 +396,17 @@ void mlx5_remove_dev_by_protocol(struct mlx5_core_dev *dev, int protocol)
                }
 }
 
-static u16 mlx5_gen_pci_id(struct mlx5_core_dev *dev)
+static u32 mlx5_gen_pci_id(struct mlx5_core_dev *dev)
 {
-       return (u16)((dev->pdev->bus->number << 8) |
+       return (u32)((pci_domain_nr(dev->pdev->bus) << 16) |
+                    (dev->pdev->bus->number << 8) |
                     PCI_SLOT(dev->pdev->devfn));
 }
 
 /* Must be called with intf_mutex held */
 struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev)
 {
-       u16 pci_id = mlx5_gen_pci_id(dev);
+       u32 pci_id = mlx5_gen_pci_id(dev);
        struct mlx5_core_dev *res = NULL;
        struct mlx5_core_dev *tmp_dev;
        struct mlx5_priv *priv;
index eddd7702680bce0284f8518e2f04920116a80e0b..e88340e196f79a4dca519f85ce174c54c144e5af 100644 (file)
@@ -183,12 +183,13 @@ static const struct tlsdev_ops mlx5e_tls_ops = {
 
 void mlx5e_tls_build_netdev(struct mlx5e_priv *priv)
 {
-       u32 caps = mlx5_accel_tls_device_caps(priv->mdev);
        struct net_device *netdev = priv->netdev;
+       u32 caps;
 
        if (!mlx5_accel_is_tls_device(priv->mdev))
                return;
 
+       caps = mlx5_accel_tls_device_caps(priv->mdev);
        if (caps & MLX5_ACCEL_TLS_TX) {
                netdev->features          |= NETIF_F_HW_TLS_TX;
                netdev->hw_features       |= NETIF_F_HW_TLS_TX;
index 75bb981e00b7205ad10b467dc64a821a4f8867a9..41cde926cdab6d3d061d62d424ed1bff8c860c9d 100644 (file)
@@ -191,7 +191,7 @@ set_udp(void *headers_c, void *headers_v, __be16 psrc_m, __be16 psrc_v,
 {
        if (psrc_m) {
                MLX5E_FTE_SET(headers_c, udp_sport, 0xffff);
-               MLX5E_FTE_SET(headers_c, udp_sport, ntohs(psrc_v));
+               MLX5E_FTE_SET(headers_v, udp_sport, ntohs(psrc_v));
        }
 
        if (pdst_m) {
index 5a7939e7019026aa9c08d4fba759f95cb0a813c5..54118b77dc1f6d478c5b08e7c01526dd3e5dc740 100644 (file)
@@ -4315,22 +4315,6 @@ static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
        }
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Fake "interrupt" called by netpoll (eg netconsole) to send skbs without
- * reenabling interrupts.
- */
-static void mlx5e_netpoll(struct net_device *dev)
-{
-       struct mlx5e_priv *priv = netdev_priv(dev);
-       struct mlx5e_channels *chs = &priv->channels;
-
-       int i;
-
-       for (i = 0; i < chs->num; i++)
-               napi_schedule(&chs->c[i]->napi);
-}
-#endif
-
 static const struct net_device_ops mlx5e_netdev_ops = {
        .ndo_open                = mlx5e_open,
        .ndo_stop                = mlx5e_close,
@@ -4356,9 +4340,6 @@ static const struct net_device_ops mlx5e_netdev_ops = {
 #ifdef CONFIG_MLX5_EN_ARFS
        .ndo_rx_flow_steer       = mlx5e_rx_flow_steer,
 #endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller     = mlx5e_netpoll,
-#endif
 #ifdef CONFIG_MLX5_ESWITCH
        /* SRIOV E-Switch NDOs */
        .ndo_set_vf_mac          = mlx5e_set_vf_mac,
index f72b5c9dcfe95f98cc388676462207bf76247504..3028e8d90920e2940cc3247775bd7a498fd906ef 100644 (file)
@@ -663,6 +663,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
        if (err)
                goto miss_rule_err;
 
+       kvfree(flow_group_in);
        return 0;
 
 miss_rule_err:
index f418541af7cf13f96ea24613648150bb727397be..37d114c668b7ba70ca968f76c88c42af84967f25 100644 (file)
@@ -1578,6 +1578,33 @@ static u64 matched_fgs_get_version(struct list_head *match_head)
        return version;
 }
 
+static struct fs_fte *
+lookup_fte_locked(struct mlx5_flow_group *g,
+                 u32 *match_value,
+                 bool take_write)
+{
+       struct fs_fte *fte_tmp;
+
+       if (take_write)
+               nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
+       else
+               nested_down_read_ref_node(&g->node, FS_LOCK_PARENT);
+       fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value,
+                                        rhash_fte);
+       if (!fte_tmp || !tree_get_node(&fte_tmp->node)) {
+               fte_tmp = NULL;
+               goto out;
+       }
+
+       nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
+out:
+       if (take_write)
+               up_write_ref_node(&g->node);
+       else
+               up_read_ref_node(&g->node);
+       return fte_tmp;
+}
+
 static struct mlx5_flow_handle *
 try_add_to_existing_fg(struct mlx5_flow_table *ft,
                       struct list_head *match_head,
@@ -1600,10 +1627,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
        if (IS_ERR(fte))
                return  ERR_PTR(-ENOMEM);
 
-       list_for_each_entry(iter, match_head, list) {
-               nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT);
-       }
-
 search_again_locked:
        version = matched_fgs_get_version(match_head);
        /* Try to find a fg that already contains a matching fte */
@@ -1611,20 +1634,9 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
                struct fs_fte *fte_tmp;
 
                g = iter->g;
-               fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, spec->match_value,
-                                                rhash_fte);
-               if (!fte_tmp || !tree_get_node(&fte_tmp->node))
+               fte_tmp = lookup_fte_locked(g, spec->match_value, take_write);
+               if (!fte_tmp)
                        continue;
-
-               nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
-               if (!take_write) {
-                       list_for_each_entry(iter, match_head, list)
-                               up_read_ref_node(&iter->g->node);
-               } else {
-                       list_for_each_entry(iter, match_head, list)
-                               up_write_ref_node(&iter->g->node);
-               }
-
                rule = add_rule_fg(g, spec->match_value,
                                   flow_act, dest, dest_num, fte_tmp);
                up_write_ref_node(&fte_tmp->node);
@@ -1633,19 +1645,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
                return rule;
        }
 
-       /* No group with matching fte found. Try to add a new fte to any
-        * matching fg.
-        */
-
-       if (!take_write) {
-               list_for_each_entry(iter, match_head, list)
-                       up_read_ref_node(&iter->g->node);
-               list_for_each_entry(iter, match_head, list)
-                       nested_down_write_ref_node(&iter->g->node,
-                                                  FS_LOCK_PARENT);
-               take_write = true;
-       }
-
        /* Check the ft version, for case that new flow group
         * was added while the fgs weren't locked
         */
@@ -1657,27 +1656,30 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
        /* Check the fgs version, for case the new FTE with the
         * same values was added while the fgs weren't locked
         */
-       if (version != matched_fgs_get_version(match_head))
+       if (version != matched_fgs_get_version(match_head)) {
+               take_write = true;
                goto search_again_locked;
+       }
 
        list_for_each_entry(iter, match_head, list) {
                g = iter->g;
 
                if (!g->node.active)
                        continue;
+
+               nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
+
                err = insert_fte(g, fte);
                if (err) {
+                       up_write_ref_node(&g->node);
                        if (err == -ENOSPC)
                                continue;
-                       list_for_each_entry(iter, match_head, list)
-                               up_write_ref_node(&iter->g->node);
                        kmem_cache_free(steering->ftes_cache, fte);
                        return ERR_PTR(err);
                }
 
                nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
-               list_for_each_entry(iter, match_head, list)
-                       up_write_ref_node(&iter->g->node);
+               up_write_ref_node(&g->node);
                rule = add_rule_fg(g, spec->match_value,
                                   flow_act, dest, dest_num, fte);
                up_write_ref_node(&fte->node);
@@ -1686,8 +1688,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
        }
        rule = ERR_PTR(-ENOENT);
 out:
-       list_for_each_entry(iter, match_head, list)
-               up_write_ref_node(&iter->g->node);
        kmem_cache_free(steering->ftes_cache, fte);
        return rule;
 }
@@ -1726,6 +1726,8 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
        if (err) {
                if (take_write)
                        up_write_ref_node(&ft->node);
+               else
+                       up_read_ref_node(&ft->node);
                return ERR_PTR(err);
        }
 
index d39b0b7011b2d9cf194180813a5a30d9fe226b6d..9f39aeca863f321fe169fb3d69ef1cff98bbaf18 100644 (file)
@@ -331,9 +331,17 @@ void mlx5_start_health_poll(struct mlx5_core_dev *dev)
        add_timer(&health->timer);
 }
 
-void mlx5_stop_health_poll(struct mlx5_core_dev *dev)
+void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health)
 {
        struct mlx5_core_health *health = &dev->priv.health;
+       unsigned long flags;
+
+       if (disable_health) {
+               spin_lock_irqsave(&health->wq_lock, flags);
+               set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
+               set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
+               spin_unlock_irqrestore(&health->wq_lock, flags);
+       }
 
        del_timer_sync(&health->timer);
 }
index cf3e4a6590524e1c9cdd9fb2da7ab512abbb2efc..b5e9f664fc66758d5642b18e2396503baf351415 100644 (file)
@@ -878,8 +878,10 @@ static int mlx5_pci_init(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
        priv->numa_node = dev_to_node(&dev->pdev->dev);
 
        priv->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), mlx5_debugfs_root);
-       if (!priv->dbg_root)
+       if (!priv->dbg_root) {
+               dev_err(&pdev->dev, "Cannot create debugfs dir, aborting\n");
                return -ENOMEM;
+       }
 
        err = mlx5_pci_enable_device(dev);
        if (err) {
@@ -928,7 +930,7 @@ static void mlx5_pci_close(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
        pci_clear_master(dev->pdev);
        release_bar(dev->pdev);
        mlx5_pci_disable_device(dev);
-       debugfs_remove(priv->dbg_root);
+       debugfs_remove_recursive(priv->dbg_root);
 }
 
 static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
@@ -1286,7 +1288,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
                mlx5_cleanup_once(dev);
 
 err_stop_poll:
-       mlx5_stop_health_poll(dev);
+       mlx5_stop_health_poll(dev, boot);
        if (mlx5_cmd_teardown_hca(dev)) {
                dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n");
                goto out_err;
@@ -1346,7 +1348,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
        mlx5_free_irq_vectors(dev);
        if (cleanup)
                mlx5_cleanup_once(dev);
-       mlx5_stop_health_poll(dev);
+       mlx5_stop_health_poll(dev, cleanup);
        err = mlx5_cmd_teardown_hca(dev);
        if (err) {
                dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n");
@@ -1608,7 +1610,7 @@ static int mlx5_try_fast_unload(struct mlx5_core_dev *dev)
         * with the HCA, so the health polll is no longer needed.
         */
        mlx5_drain_health_wq(dev);
-       mlx5_stop_health_poll(dev);
+       mlx5_stop_health_poll(dev, false);
 
        ret = mlx5_cmd_force_teardown_hca(dev);
        if (ret) {
index dae1c5c5d27c5abfeac951465f8fab240bd69ff0..d2f76070ea7ca87bcc98c1382cd95504e0a60104 100644 (file)
@@ -509,7 +509,7 @@ static int mlx5_hairpin_modify_sq(struct mlx5_core_dev *peer_mdev, u32 sqn,
 
        sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
 
-       if (next_state == MLX5_RQC_STATE_RDY) {
+       if (next_state == MLX5_SQC_STATE_RDY) {
                MLX5_SET(sqc, sqc, hairpin_peer_rq, peer_rq);
                MLX5_SET(sqc, sqc, hairpin_peer_vhca, peer_vhca);
        }
index c8c315eb512804033fd88723c217504007010453..68e7f8df2a6d310989a2b6ee9b2e6c488c3b17e0 100644 (file)
@@ -39,9 +39,9 @@ u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq)
        return (u32)wq->fbc.sz_m1 + 1;
 }
 
-u32 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq)
+u16 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq)
 {
-       return (u32)wq->fbc.frag_sz_m1 + 1;
+       return wq->fbc.frag_sz_m1 + 1;
 }
 
 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq)
@@ -138,7 +138,7 @@ int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                      void *qpc, struct mlx5_wq_qp *wq,
                      struct mlx5_wq_ctrl *wq_ctrl)
 {
-       u32 sq_strides_offset;
+       u16 sq_strides_offset;
        u32 rq_pg_remainder;
        int err;
 
index 2bd4c3184eba21d866ea8df66699a41145e3ec10..3a1a170bb2d7f3244e7761a6acf6c1fb4a3534c3 100644 (file)
@@ -80,7 +80,7 @@ int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                       void *wqc, struct mlx5_wq_cyc *wq,
                       struct mlx5_wq_ctrl *wq_ctrl);
 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq);
-u32 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq);
+u16 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq);
 
 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                      void *qpc, struct mlx5_wq_qp *wq,
index 930700413b1d07dd8a62ffbabf47aea995d062cf..b492152c8881bdd41a56f0a2b361a4b6bb86e40d 100644 (file)
@@ -44,8 +44,8 @@
 #define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
 
 #define MLXSW_SP1_FWREV_MAJOR 13
-#define MLXSW_SP1_FWREV_MINOR 1702
-#define MLXSW_SP1_FWREV_SUBMINOR 6
+#define MLXSW_SP1_FWREV_MINOR 1703
+#define MLXSW_SP1_FWREV_SUBMINOR 4
 #define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702
 
 static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
index 4327487553c5338581b200469136cc1077d028bf..3589432d164375240e013d476df8cd57e1c7c0ed 100644 (file)
@@ -337,14 +337,14 @@ static const struct mlxsw_sp_sb_cm mlxsw_sp_sb_cms_egress[] = {
        MLXSW_SP_SB_CM(1500, 9, 0),
        MLXSW_SP_SB_CM(1500, 9, 0),
        MLXSW_SP_SB_CM(1500, 9, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
-       MLXSW_SP_SB_CM(0, 0, 0),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
+       MLXSW_SP_SB_CM(0, 140000, 15),
        MLXSW_SP_SB_CM(1, 0xff, 0),
 };
 
index e7dce79ff2c910a090de7e55bf3e3efae3e0f2b7..001b5f714c1b767e80835aa62fb4afa8be5e06d7 100644 (file)
@@ -2850,7 +2850,7 @@ static void lan743x_pcidev_shutdown(struct pci_dev *pdev)
        lan743x_hardware_cleanup(adapter);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static u16 lan743x_pm_wakeframe_crc16(const u8 *buf, int len)
 {
        return bitrev16(crc16(0xFFFF, buf, len));
@@ -3016,7 +3016,7 @@ static int lan743x_pm_resume(struct device *dev)
 static const struct dev_pm_ops lan743x_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(lan743x_pm_suspend, lan743x_pm_resume)
 };
-#endif /*CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static const struct pci_device_id lan743x_pcidev_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7430) },
@@ -3028,7 +3028,7 @@ static struct pci_driver lan743x_pcidev_driver = {
        .id_table = lan743x_pcidev_tbl,
        .probe    = lan743x_pcidev_probe,
        .remove   = lan743x_pcidev_remove,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
        .driver.pm = &lan743x_pm_ops,
 #endif
        .shutdown = lan743x_pcidev_shutdown,
index 26bb3b18f3be0f9f20149e5e689c561074c60a26..3cdf63e35b53bc1ea3e2f445e6a3746a56655bd3 100644 (file)
@@ -91,7 +91,7 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
                struct sk_buff *skb;
                struct net_device *dev;
                u32 *buf;
-               int sz, len;
+               int sz, len, buf_len;
                u32 ifh[4];
                u32 val;
                struct frame_info info;
@@ -116,14 +116,20 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
                        err = -ENOMEM;
                        break;
                }
-               buf = (u32 *)skb_put(skb, info.len);
+               buf_len = info.len - ETH_FCS_LEN;
+               buf = (u32 *)skb_put(skb, buf_len);
 
                len = 0;
                do {
                        sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
                        *buf++ = val;
                        len += sz;
-               } while ((sz == 4) && (len < info.len));
+               } while (len < buf_len);
+
+               /* Read the FCS and discard it */
+               sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
+               /* Update the statistics if part of the FCS was read before */
+               len -= ETH_FCS_LEN - sz;
 
                if (sz < 0) {
                        err = sz;
index 9044496803e627e8a992fbcac23eb8e0201e1e76..46ba0cf257c6d8cdb80b0d84e80e078618d11c36 100644 (file)
@@ -52,6 +52,7 @@
 #define NFP_FL_TUNNEL_CSUM                     cpu_to_be16(0x01)
 #define NFP_FL_TUNNEL_KEY                      cpu_to_be16(0x04)
 #define NFP_FL_TUNNEL_GENEVE_OPT               cpu_to_be16(0x0800)
+#define NFP_FL_SUPPORTED_TUNNEL_INFO_FLAGS     IP_TUNNEL_INFO_TX
 #define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS    (NFP_FL_TUNNEL_CSUM | \
                                                 NFP_FL_TUNNEL_KEY | \
                                                 NFP_FL_TUNNEL_GENEVE_OPT)
@@ -741,11 +742,16 @@ nfp_flower_loop_action(struct nfp_app *app, const struct tc_action *a,
                nfp_fl_push_vlan(psh_v, a);
                *a_len += sizeof(struct nfp_fl_push_vlan);
        } else if (is_tcf_tunnel_set(a)) {
+               struct ip_tunnel_info *ip_tun = tcf_tunnel_info(a);
                struct nfp_repr *repr = netdev_priv(netdev);
+
                *tun_type = nfp_fl_get_tun_from_act_l4_port(repr->app, a);
                if (*tun_type == NFP_FL_TUNNEL_NONE)
                        return -EOPNOTSUPP;
 
+               if (ip_tun->mode & ~NFP_FL_SUPPORTED_TUNNEL_INFO_FLAGS)
+                       return -EOPNOTSUPP;
+
                /* Pre-tunnel action is required for tunnel encap.
                 * This checks for next hop entries on NFP.
                 * If none, the packet falls back before applying other actions.
index 85f8209bf007e8f133fefd1bfbb7c7309bae2e7f..81d941ab895c9f5bd6267d74ca9501c8ef5dff98 100644 (file)
@@ -70,6 +70,7 @@ struct nfp_app;
 #define NFP_FL_FEATS_GENEVE            BIT(0)
 #define NFP_FL_NBI_MTU_SETTING         BIT(1)
 #define NFP_FL_FEATS_GENEVE_OPT                BIT(2)
+#define NFP_FL_FEATS_VLAN_PCP          BIT(3)
 #define NFP_FL_FEATS_LAG               BIT(31)
 
 struct nfp_fl_mask_id {
index a0c72f277faa1b6972b727393c68f23fb79bdb06..17acb8cc60440ee4272b642ccf62b62df90ef019 100644 (file)
@@ -56,7 +56,7 @@ nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *frame,
                                                      FLOW_DISSECTOR_KEY_VLAN,
                                                      target);
                /* Populate the tci field. */
-               if (flow_vlan->vlan_id) {
+               if (flow_vlan->vlan_id || flow_vlan->vlan_priority) {
                        tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
                                             flow_vlan->vlan_priority) |
                                  FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
index 2edab01c3beb6287a545b585b59f5f5b508d86e1..bd19624f10cf48e3d7187f6721ec6b3eecac98da 100644 (file)
@@ -192,6 +192,17 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
                key_size += sizeof(struct nfp_flower_mac_mpls);
        }
 
+       if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
+               struct flow_dissector_key_vlan *flow_vlan;
+
+               flow_vlan = skb_flow_dissector_target(flow->dissector,
+                                                     FLOW_DISSECTOR_KEY_VLAN,
+                                                     flow->mask);
+               if (!(priv->flower_ext_feats & NFP_FL_FEATS_VLAN_PCP) &&
+                   flow_vlan->vlan_priority)
+                       return -EOPNOTSUPP;
+       }
+
        if (dissector_uses_key(flow->dissector,
                               FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
                struct flow_dissector_key_ipv4_addrs *mask_ipv4 = NULL;
index 253bdaef150557a7e20ded3de921021a051a9ca7..8ed38fd5a8520e0e125d96bc2ee7c53d891a5969 100644 (file)
@@ -3146,21 +3146,6 @@ nfp_net_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
        return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void nfp_net_netpoll(struct net_device *netdev)
-{
-       struct nfp_net *nn = netdev_priv(netdev);
-       int i;
-
-       /* nfp_net's NAPIs are statically allocated so even if there is a race
-        * with reconfig path this will simply try to schedule some disabled
-        * NAPI instances.
-        */
-       for (i = 0; i < nn->dp.num_stack_tx_rings; i++)
-               napi_schedule_irqoff(&nn->r_vecs[i].napi);
-}
-#endif
-
 static void nfp_net_stat64(struct net_device *netdev,
                           struct rtnl_link_stats64 *stats)
 {
@@ -3519,9 +3504,6 @@ const struct net_device_ops nfp_net_netdev_ops = {
        .ndo_get_stats64        = nfp_net_stat64,
        .ndo_vlan_rx_add_vid    = nfp_net_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = nfp_net_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = nfp_net_netpoll,
-#endif
        .ndo_set_vf_mac         = nfp_app_set_vf_mac,
        .ndo_set_vf_vlan        = nfp_app_set_vf_vlan,
        .ndo_set_vf_spoofchk    = nfp_app_set_vf_spoofchk,
index 6bb76e6d3c141c7fb5f4854dbd6cef514b090bf1..f5459de6d60a6abe4d2fec817b429dc5897d74ba 100644 (file)
@@ -190,10 +190,8 @@ qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data)
 
 static void
 qed_dcbx_set_params(struct qed_dcbx_results *p_data,
-                   struct qed_hw_info *p_info,
-                   bool enable,
-                   u8 prio,
-                   u8 tc,
+                   struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                   bool enable, u8 prio, u8 tc,
                    enum dcbx_protocol_type type,
                    enum qed_pci_personality personality)
 {
@@ -206,19 +204,30 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,
        else
                p_data->arr[type].update = DONT_UPDATE_DCB_DSCP;
 
+       /* Do not add vlan tag 0 when DCB is enabled and port in UFP/OV mode */
+       if ((test_bit(QED_MF_8021Q_TAGGING, &p_hwfn->cdev->mf_bits) ||
+            test_bit(QED_MF_8021AD_TAGGING, &p_hwfn->cdev->mf_bits)))
+               p_data->arr[type].dont_add_vlan0 = true;
+
        /* QM reconf data */
-       if (p_info->personality == personality)
-               qed_hw_info_set_offload_tc(p_info, tc);
+       if (p_hwfn->hw_info.personality == personality)
+               qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc);
+
+       /* Configure dcbx vlan priority in doorbell block for roce EDPM */
+       if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits) &&
+           type == DCBX_PROTOCOL_ROCE) {
+               qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1);
+               qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_PCP_BB_K2, prio << 1);
+       }
 }
 
 /* Update app protocol data and hw_info fields with the TLV info */
 static void
 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
-                        struct qed_hwfn *p_hwfn,
-                        bool enable,
-                        u8 prio, u8 tc, enum dcbx_protocol_type type)
+                        struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                        bool enable, u8 prio, u8 tc,
+                        enum dcbx_protocol_type type)
 {
-       struct qed_hw_info *p_info = &p_hwfn->hw_info;
        enum qed_pci_personality personality;
        enum dcbx_protocol_type id;
        int i;
@@ -231,7 +240,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
 
                personality = qed_dcbx_app_update[i].personality;
 
-               qed_dcbx_set_params(p_data, p_info, enable,
+               qed_dcbx_set_params(p_data, p_hwfn, p_ptt, enable,
                                    prio, tc, type, personality);
        }
 }
@@ -265,7 +274,7 @@ qed_dcbx_get_app_protocol_type(struct qed_hwfn *p_hwfn,
  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
  */
 static int
-qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
+qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
                     struct qed_dcbx_results *p_data,
                     struct dcbx_app_priority_entry *p_tbl,
                     u32 pri_tc_tbl, int count, u8 dcbx_version)
@@ -309,7 +318,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
                                enable = true;
                        }
 
-                       qed_dcbx_update_app_info(p_data, p_hwfn, enable,
+                       qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
                                                 priority, tc, type);
                }
        }
@@ -331,7 +340,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
                        continue;
 
                enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
-               qed_dcbx_update_app_info(p_data, p_hwfn, enable,
+               qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
                                         priority, tc, type);
        }
 
@@ -341,7 +350,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
 /* Parse app TLV's to update TC information in hw_info structure for
  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
  */
-static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn)
+static int
+qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        struct dcbx_app_priority_feature *p_app;
        struct dcbx_app_priority_entry *p_tbl;
@@ -365,7 +375,7 @@ static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn)
        p_info = &p_hwfn->hw_info;
        num_entries = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES);
 
-       rc = qed_dcbx_process_tlv(p_hwfn, &data, p_tbl, pri_tc_tbl,
+       rc = qed_dcbx_process_tlv(p_hwfn, p_ptt, &data, p_tbl, pri_tc_tbl,
                                  num_entries, dcbx_version);
        if (rc)
                return rc;
@@ -891,7 +901,7 @@ qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn,
                return rc;
 
        if (type == QED_DCBX_OPERATIONAL_MIB) {
-               rc = qed_dcbx_process_mib_info(p_hwfn);
+               rc = qed_dcbx_process_mib_info(p_hwfn, p_ptt);
                if (!rc) {
                        /* reconfigure tcs of QM queues according
                         * to negotiation results
@@ -954,6 +964,7 @@ static void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
        p_data->dcb_enable_flag = p_src->arr[type].enable;
        p_data->dcb_priority = p_src->arr[type].priority;
        p_data->dcb_tc = p_src->arr[type].tc;
+       p_data->dcb_dont_add_vlan0 = p_src->arr[type].dont_add_vlan0;
 }
 
 /* Set pf update ramrod command params */
index a4d688c04e1827ab750bc6fec1d442ea2eca7840..01f253ea4b229201c727fd22284759aadf3bc59c 100644 (file)
@@ -55,6 +55,7 @@ struct qed_dcbx_app_data {
        u8 update;              /* Update indication */
        u8 priority;            /* Priority */
        u8 tc;                  /* Traffic Class */
+       bool dont_add_vlan0;    /* Do not insert a vlan tag with id 0 */
 };
 
 #define QED_DCBX_VERSION_DISABLED       0
index 016ca8a7ec8aa11fe8fc3b035dadfd431ad8d4fc..97f073fd3725d7bbc8481a1f8cfd748087a55bef 100644 (file)
@@ -1706,7 +1706,7 @@ static int qed_vf_start(struct qed_hwfn *p_hwfn,
 int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
 {
        struct qed_load_req_params load_req_params;
-       u32 load_code, param, drv_mb_param;
+       u32 load_code, resp, param, drv_mb_param;
        bool b_default_mtu = true;
        struct qed_hwfn *p_hwfn;
        int rc = 0, mfw_rc, i;
@@ -1852,6 +1852,19 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
 
        if (IS_PF(cdev)) {
                p_hwfn = QED_LEADING_HWFN(cdev);
+
+               /* Get pre-negotiated values for stag, bandwidth etc. */
+               DP_VERBOSE(p_hwfn,
+                          QED_MSG_SPQ,
+                          "Sending GET_OEM_UPDATES command to trigger stag/bandwidth attention handling\n");
+               drv_mb_param = 1 << DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET;
+               rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
+                                DRV_MSG_CODE_GET_OEM_UPDATES,
+                                drv_mb_param, &resp, &param);
+               if (rc)
+                       DP_NOTICE(p_hwfn,
+                                 "Failed to send GET_OEM_UPDATES attention request\n");
+
                drv_mb_param = STORM_FW_VERSION;
                rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
                                 DRV_MSG_CODE_OV_UPDATE_STORM_FW_VER,
index 8faceb691657ff26fb2b95d962e19d75efa867c5..9b3ef00e57824a5fd72e7ae06e3d1d44b59b176b 100644 (file)
@@ -12414,6 +12414,7 @@ struct public_drv_mb {
 #define DRV_MSG_SET_RESOURCE_VALUE_MSG         0x35000000
 #define DRV_MSG_CODE_OV_UPDATE_WOL              0x38000000
 #define DRV_MSG_CODE_OV_UPDATE_ESWITCH_MODE     0x39000000
+#define DRV_MSG_CODE_GET_OEM_UPDATES            0x41000000
 
 #define DRV_MSG_CODE_BW_UPDATE_ACK             0x32000000
 #define DRV_MSG_CODE_NIG_DRAIN                 0x30000000
@@ -12541,6 +12542,9 @@ struct public_drv_mb {
 #define DRV_MB_PARAM_ESWITCH_MODE_VEB  0x1
 #define DRV_MB_PARAM_ESWITCH_MODE_VEPA 0x2
 
+#define DRV_MB_PARAM_DUMMY_OEM_UPDATES_MASK    0x1
+#define DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET  0
+
 #define DRV_MB_PARAM_SET_LED_MODE_OPER         0x0
 #define DRV_MB_PARAM_SET_LED_MODE_ON           0x1
 #define DRV_MB_PARAM_SET_LED_MODE_OFF          0x2
index 5d37ec7e9b0b7b2bc3785ec00ce2e23314b7c955..58c7eb9d8e1b85893ea33c7de48426e5f555bdc5 100644 (file)
@@ -1581,13 +1581,29 @@ static void qed_mcp_update_stag(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
        p_hwfn->mcp_info->func_info.ovlan = (u16)shmem_info.ovlan_stag &
                                                 FUNC_MF_CFG_OV_STAG_MASK;
        p_hwfn->hw_info.ovlan = p_hwfn->mcp_info->func_info.ovlan;
-       if ((p_hwfn->hw_info.hw_mode & BIT(MODE_MF_SD)) &&
-           (p_hwfn->hw_info.ovlan != QED_MCP_VLAN_UNSET)) {
-               qed_wr(p_hwfn, p_ptt,
-                      NIG_REG_LLH_FUNC_TAG_VALUE, p_hwfn->hw_info.ovlan);
+       if (test_bit(QED_MF_OVLAN_CLSS, &p_hwfn->cdev->mf_bits)) {
+               if (p_hwfn->hw_info.ovlan != QED_MCP_VLAN_UNSET) {
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_VALUE,
+                              p_hwfn->hw_info.ovlan);
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_EN, 1);
+
+                       /* Configure DB to add external vlan to EDPM packets */
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1);
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_EXT_VID_BB_K2,
+                              p_hwfn->hw_info.ovlan);
+               } else {
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_EN, 0);
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_VALUE, 0);
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 0);
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_EXT_VID_BB_K2, 0);
+               }
+
                qed_sp_pf_update_stag(p_hwfn);
        }
 
+       DP_VERBOSE(p_hwfn, QED_MSG_SP, "ovlan  = %d hw_mode = 0x%x\n",
+                  p_hwfn->mcp_info->func_info.ovlan, p_hwfn->hw_info.hw_mode);
+
        /* Acknowledge the MFW */
        qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_S_TAG_UPDATE_ACK, 0,
                    &resp, &param);
index f736f70956fd3763f3f94bffa0e009dec28b9516..2440970882c48766c9869a57084826a31a8ffcfe 100644 (file)
        0x00c000UL
 #define  DORQ_REG_IFEN \
        0x100040UL
+#define DORQ_REG_TAG1_OVRD_MODE \
+       0x1008b4UL
+#define DORQ_REG_PF_PCP_BB_K2 \
+       0x1008c4UL
+#define DORQ_REG_PF_EXT_VID_BB_K2 \
+       0x1008c8UL
 #define DORQ_REG_DB_DROP_REASON \
        0x100a2cUL
 #define DORQ_REG_DB_DROP_DETAILS \
index ffe7a16bdfc840d859292f6939938b75fba15a41..6c8543fb90c0a3ac780edd36aa701b01e7c9d94a 100644 (file)
@@ -45,34 +45,33 @@ qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result)
 {
        __be16 rx_data;
        __be16 tx_data;
-       struct spi_transfer *transfer;
-       struct spi_message *msg;
+       struct spi_transfer transfer[2];
+       struct spi_message msg;
        int ret;
 
+       memset(transfer, 0, sizeof(transfer));
+
+       spi_message_init(&msg);
+
        tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg);
+       *result = 0;
+
+       transfer[0].tx_buf = &tx_data;
+       transfer[0].len = QCASPI_CMD_LEN;
+       transfer[1].rx_buf = &rx_data;
+       transfer[1].len = QCASPI_CMD_LEN;
+
+       spi_message_add_tail(&transfer[0], &msg);
 
        if (qca->legacy_mode) {
-               msg = &qca->spi_msg1;
-               transfer = &qca->spi_xfer1;
-               transfer->tx_buf = &tx_data;
-               transfer->rx_buf = NULL;
-               transfer->len = QCASPI_CMD_LEN;
-               spi_sync(qca->spi_dev, msg);
-       } else {
-               msg = &qca->spi_msg2;
-               transfer = &qca->spi_xfer2[0];
-               transfer->tx_buf = &tx_data;
-               transfer->rx_buf = NULL;
-               transfer->len = QCASPI_CMD_LEN;
-               transfer = &qca->spi_xfer2[1];
+               spi_sync(qca->spi_dev, &msg);
+               spi_message_init(&msg);
        }
-       transfer->tx_buf = NULL;
-       transfer->rx_buf = &rx_data;
-       transfer->len = QCASPI_CMD_LEN;
-       ret = spi_sync(qca->spi_dev, msg);
+       spi_message_add_tail(&transfer[1], &msg);
+       ret = spi_sync(qca->spi_dev, &msg);
 
        if (!ret)
-               ret = msg->status;
+               ret = msg.status;
 
        if (ret)
                qcaspi_spi_error(qca);
@@ -86,35 +85,32 @@ int
 qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value)
 {
        __be16 tx_data[2];
-       struct spi_transfer *transfer;
-       struct spi_message *msg;
+       struct spi_transfer transfer[2];
+       struct spi_message msg;
        int ret;
 
+       memset(&transfer, 0, sizeof(transfer));
+
+       spi_message_init(&msg);
+
        tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg);
        tx_data[1] = cpu_to_be16(value);
 
+       transfer[0].tx_buf = &tx_data[0];
+       transfer[0].len = QCASPI_CMD_LEN;
+       transfer[1].tx_buf = &tx_data[1];
+       transfer[1].len = QCASPI_CMD_LEN;
+
+       spi_message_add_tail(&transfer[0], &msg);
        if (qca->legacy_mode) {
-               msg = &qca->spi_msg1;
-               transfer = &qca->spi_xfer1;
-               transfer->tx_buf = &tx_data[0];
-               transfer->rx_buf = NULL;
-               transfer->len = QCASPI_CMD_LEN;
-               spi_sync(qca->spi_dev, msg);
-       } else {
-               msg = &qca->spi_msg2;
-               transfer = &qca->spi_xfer2[0];
-               transfer->tx_buf = &tx_data[0];
-               transfer->rx_buf = NULL;
-               transfer->len = QCASPI_CMD_LEN;
-               transfer = &qca->spi_xfer2[1];
+               spi_sync(qca->spi_dev, &msg);
+               spi_message_init(&msg);
        }
-       transfer->tx_buf = &tx_data[1];
-       transfer->rx_buf = NULL;
-       transfer->len = QCASPI_CMD_LEN;
-       ret = spi_sync(qca->spi_dev, msg);
+       spi_message_add_tail(&transfer[1], &msg);
+       ret = spi_sync(qca->spi_dev, &msg);
 
        if (!ret)
-               ret = msg->status;
+               ret = msg.status;
 
        if (ret)
                qcaspi_spi_error(qca);
index 206f0266463e362a0e34fe8ff5b626519500e2ed..66b775d462fd8ed111dbb18e845ad4d9af1b6d2b 100644 (file)
@@ -99,22 +99,24 @@ static u32
 qcaspi_write_burst(struct qcaspi *qca, u8 *src, u32 len)
 {
        __be16 cmd;
-       struct spi_message *msg = &qca->spi_msg2;
-       struct spi_transfer *transfer = &qca->spi_xfer2[0];
+       struct spi_message msg;
+       struct spi_transfer transfer[2];
        int ret;
 
+       memset(&transfer, 0, sizeof(transfer));
+       spi_message_init(&msg);
+
        cmd = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL);
-       transfer->tx_buf = &cmd;
-       transfer->rx_buf = NULL;
-       transfer->len = QCASPI_CMD_LEN;
-       transfer = &qca->spi_xfer2[1];
-       transfer->tx_buf = src;
-       transfer->rx_buf = NULL;
-       transfer->len = len;
+       transfer[0].tx_buf = &cmd;
+       transfer[0].len = QCASPI_CMD_LEN;
+       transfer[1].tx_buf = src;
+       transfer[1].len = len;
 
-       ret = spi_sync(qca->spi_dev, msg);
+       spi_message_add_tail(&transfer[0], &msg);
+       spi_message_add_tail(&transfer[1], &msg);
+       ret = spi_sync(qca->spi_dev, &msg);
 
-       if (ret || (msg->actual_length != QCASPI_CMD_LEN + len)) {
+       if (ret || (msg.actual_length != QCASPI_CMD_LEN + len)) {
                qcaspi_spi_error(qca);
                return 0;
        }
@@ -125,17 +127,20 @@ qcaspi_write_burst(struct qcaspi *qca, u8 *src, u32 len)
 static u32
 qcaspi_write_legacy(struct qcaspi *qca, u8 *src, u32 len)
 {
-       struct spi_message *msg = &qca->spi_msg1;
-       struct spi_transfer *transfer = &qca->spi_xfer1;
+       struct spi_message msg;
+       struct spi_transfer transfer;
        int ret;
 
-       transfer->tx_buf = src;
-       transfer->rx_buf = NULL;
-       transfer->len = len;
+       memset(&transfer, 0, sizeof(transfer));
+       spi_message_init(&msg);
+
+       transfer.tx_buf = src;
+       transfer.len = len;
 
-       ret = spi_sync(qca->spi_dev, msg);
+       spi_message_add_tail(&transfer, &msg);
+       ret = spi_sync(qca->spi_dev, &msg);
 
-       if (ret || (msg->actual_length != len)) {
+       if (ret || (msg.actual_length != len)) {
                qcaspi_spi_error(qca);
                return 0;
        }
@@ -146,23 +151,25 @@ qcaspi_write_legacy(struct qcaspi *qca, u8 *src, u32 len)
 static u32
 qcaspi_read_burst(struct qcaspi *qca, u8 *dst, u32 len)
 {
-       struct spi_message *msg = &qca->spi_msg2;
+       struct spi_message msg;
        __be16 cmd;
-       struct spi_transfer *transfer = &qca->spi_xfer2[0];
+       struct spi_transfer transfer[2];
        int ret;
 
+       memset(&transfer, 0, sizeof(transfer));
+       spi_message_init(&msg);
+
        cmd = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL);
-       transfer->tx_buf = &cmd;
-       transfer->rx_buf = NULL;
-       transfer->len = QCASPI_CMD_LEN;
-       transfer = &qca->spi_xfer2[1];
-       transfer->tx_buf = NULL;
-       transfer->rx_buf = dst;
-       transfer->len = len;
+       transfer[0].tx_buf = &cmd;
+       transfer[0].len = QCASPI_CMD_LEN;
+       transfer[1].rx_buf = dst;
+       transfer[1].len = len;
 
-       ret = spi_sync(qca->spi_dev, msg);
+       spi_message_add_tail(&transfer[0], &msg);
+       spi_message_add_tail(&transfer[1], &msg);
+       ret = spi_sync(qca->spi_dev, &msg);
 
-       if (ret || (msg->actual_length != QCASPI_CMD_LEN + len)) {
+       if (ret || (msg.actual_length != QCASPI_CMD_LEN + len)) {
                qcaspi_spi_error(qca);
                return 0;
        }
@@ -173,17 +180,20 @@ qcaspi_read_burst(struct qcaspi *qca, u8 *dst, u32 len)
 static u32
 qcaspi_read_legacy(struct qcaspi *qca, u8 *dst, u32 len)
 {
-       struct spi_message *msg = &qca->spi_msg1;
-       struct spi_transfer *transfer = &qca->spi_xfer1;
+       struct spi_message msg;
+       struct spi_transfer transfer;
        int ret;
 
-       transfer->tx_buf = NULL;
-       transfer->rx_buf = dst;
-       transfer->len = len;
+       memset(&transfer, 0, sizeof(transfer));
+       spi_message_init(&msg);
 
-       ret = spi_sync(qca->spi_dev, msg);
+       transfer.rx_buf = dst;
+       transfer.len = len;
 
-       if (ret || (msg->actual_length != len)) {
+       spi_message_add_tail(&transfer, &msg);
+       ret = spi_sync(qca->spi_dev, &msg);
+
+       if (ret || (msg.actual_length != len)) {
                qcaspi_spi_error(qca);
                return 0;
        }
@@ -195,19 +205,23 @@ static int
 qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd)
 {
        __be16 tx_data;
-       struct spi_message *msg = &qca->spi_msg1;
-       struct spi_transfer *transfer = &qca->spi_xfer1;
+       struct spi_message msg;
+       struct spi_transfer transfer;
        int ret;
 
+       memset(&transfer, 0, sizeof(transfer));
+
+       spi_message_init(&msg);
+
        tx_data = cpu_to_be16(cmd);
-       transfer->len = sizeof(tx_data);
-       transfer->tx_buf = &tx_data;
-       transfer->rx_buf = NULL;
+       transfer.len = sizeof(cmd);
+       transfer.tx_buf = &tx_data;
+       spi_message_add_tail(&transfer, &msg);
 
-       ret = spi_sync(qca->spi_dev, msg);
+       ret = spi_sync(qca->spi_dev, &msg);
 
        if (!ret)
-               ret = msg->status;
+               ret = msg.status;
 
        if (ret)
                qcaspi_spi_error(qca);
@@ -835,16 +849,6 @@ qcaspi_netdev_setup(struct net_device *dev)
        qca = netdev_priv(dev);
        memset(qca, 0, sizeof(struct qcaspi));
 
-       memset(&qca->spi_xfer1, 0, sizeof(struct spi_transfer));
-       memset(&qca->spi_xfer2, 0, sizeof(struct spi_transfer) * 2);
-
-       spi_message_init(&qca->spi_msg1);
-       spi_message_add_tail(&qca->spi_xfer1, &qca->spi_msg1);
-
-       spi_message_init(&qca->spi_msg2);
-       spi_message_add_tail(&qca->spi_xfer2[0], &qca->spi_msg2);
-       spi_message_add_tail(&qca->spi_xfer2[1], &qca->spi_msg2);
-
        memset(&qca->txr, 0, sizeof(qca->txr));
        qca->txr.count = TX_RING_MAX_LEN;
 }
index fc4beb1b32d1a070a101b3c48cc092bd14561150..fc0e98726b3613ddd3774169fa13aa6099a5c6e5 100644 (file)
@@ -83,11 +83,6 @@ struct qcaspi {
        struct tx_ring txr;
        struct qcaspi_stats stats;
 
-       struct spi_message spi_msg1;
-       struct spi_message spi_msg2;
-       struct spi_transfer spi_xfer1;
-       struct spi_transfer spi_xfer2[2];
-
        u8 *rx_buffer;
        u32 buffer_size;
        u8 sync;
index b08d51bf7a20482cece8df7c95e6e861cfbffe4f..ab30aaeac6d377e6303fafc57f820e3022ae7773 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
@@ -631,7 +632,7 @@ struct rtl8169_tc_offsets {
 };
 
 enum rtl_flag {
-       RTL_FLAG_TASK_ENABLED,
+       RTL_FLAG_TASK_ENABLED = 0,
        RTL_FLAG_TASK_SLOW_PENDING,
        RTL_FLAG_TASK_RESET_PENDING,
        RTL_FLAG_MAX
@@ -665,6 +666,7 @@ struct rtl8169_private {
 
        u16 event_slow;
        const struct rtl_coalesce_info *coalesce_info;
+       struct clk *clk;
 
        struct mdio_ops {
                void (*write)(struct rtl8169_private *, int, int);
@@ -4069,6 +4071,15 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
        phy_speed_up(dev->phydev);
 
        genphy_soft_reset(dev->phydev);
+
+       /* It was reported that chip version 33 ends up with 10MBit/Half on a
+        * 1GBit link after resuming from S3. For whatever reason the PHY on
+        * this chip doesn't properly start a renegotiation when soft-reset.
+        * Explicitly requesting a renegotiation fixes this.
+        */
+       if (tp->mac_version == RTL_GIGA_MAC_VER_33 &&
+           dev->phydev->autoneg == AUTONEG_ENABLE)
+               phy_restart_aneg(dev->phydev);
 }
 
 static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
@@ -4634,13 +4645,13 @@ static void rtl_hw_start(struct  rtl8169_private *tp)
 
        rtl_set_rx_max_size(tp);
        rtl_set_rx_tx_desc_registers(tp);
-       rtl_set_tx_config_registers(tp);
        RTL_W8(tp, Cfg9346, Cfg9346_Lock);
 
        /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
        RTL_R8(tp, IntrMask);
        RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
        rtl_init_rxcfg(tp);
+       rtl_set_tx_config_registers(tp);
 
        rtl_set_rx_mode(tp->dev);
        /* no early-rx interrupts */
@@ -4775,12 +4786,14 @@ static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable)
 static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
 {
        if (enable) {
-               RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn);
                RTL_W8(tp, Config5, RTL_R8(tp, Config5) | ASPM_en);
+               RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn);
        } else {
                RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
                RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
        }
+
+       udelay(10);
 }
 
 static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
@@ -5625,6 +5638,8 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
 
 static void rtl_hw_start_8106(struct rtl8169_private *tp)
 {
+       rtl_hw_aspm_clkreq_enable(tp, false);
+
        /* Force LAN exit from ASPM if Rx/Tx are not idle */
        RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
 
@@ -5633,6 +5648,7 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)
        RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
 
        rtl_pcie_state_l2l3_enable(tp, false);
+       rtl_hw_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8101(struct rtl8169_private *tp)
@@ -6655,7 +6671,8 @@ static int rtl8169_close(struct net_device *dev)
        rtl8169_update_counters(tp);
 
        rtl_lock_work(tp);
-       clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+       /* Clear all task flags */
+       bitmap_zero(tp->wk.flags, RTL_FLAG_MAX);
 
        rtl8169_down(dev);
        rtl_unlock_work(tp);
@@ -6838,7 +6855,9 @@ static void rtl8169_net_suspend(struct net_device *dev)
 
        rtl_lock_work(tp);
        napi_disable(&tp->napi);
-       clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+       /* Clear all task flags */
+       bitmap_zero(tp->wk.flags, RTL_FLAG_MAX);
+
        rtl_unlock_work(tp);
 
        rtl_pll_power_down(tp);
@@ -7254,6 +7273,11 @@ static int rtl_jumbo_max(struct rtl8169_private *tp)
        }
 }
 
+static void rtl_disable_clk(void *data)
+{
+       clk_disable_unprepare(data);
+}
+
 static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
@@ -7274,6 +7298,32 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
        tp->supports_gmii = cfg->has_gmii;
 
+       /* Get the *optional* external "ether_clk" used on some boards */
+       tp->clk = devm_clk_get(&pdev->dev, "ether_clk");
+       if (IS_ERR(tp->clk)) {
+               rc = PTR_ERR(tp->clk);
+               if (rc == -ENOENT) {
+                       /* clk-core allows NULL (for suspend / resume) */
+                       tp->clk = NULL;
+               } else if (rc == -EPROBE_DEFER) {
+                       return rc;
+               } else {
+                       dev_err(&pdev->dev, "failed to get clk: %d\n", rc);
+                       return rc;
+               }
+       } else {
+               rc = clk_prepare_enable(tp->clk);
+               if (rc) {
+                       dev_err(&pdev->dev, "failed to enable clk: %d\n", rc);
+                       return rc;
+               }
+
+               rc = devm_add_action_or_reset(&pdev->dev, rtl_disable_clk,
+                                             tp->clk);
+               if (rc)
+                       return rc;
+       }
+
        /* enable device (incl. PCI PM wakeup and hotplug setup) */
        rc = pcim_enable_device(pdev);
        if (rc < 0) {
index f3f7477043ce106155ca30ba7c07fb7d20e968bc..bb0ebdfd4459b5d9849e65989ee1209360e7dca7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # Renesas device configuration
 #
index a05102a7df02150cbfae6644eadeb971e35d7a3a..f21ab8c02af0e2263b46db68321192d3cd2850dc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for the Renesas device drivers.
 #
index 1470fc12282b255181838457ff6a07a362e3e321..9b6bf557a2f5ffde5fe405f17e3307014f0c6a05 100644 (file)
@@ -428,6 +428,7 @@ enum EIS_BIT {
        EIS_CULF1       = 0x00000080,
        EIS_TFFF        = 0x00000100,
        EIS_QFS         = 0x00010000,
+       EIS_RESERVED    = (GENMASK(31, 17) | GENMASK(15, 11)),
 };
 
 /* RIC0 */
@@ -472,6 +473,7 @@ enum RIS0_BIT {
        RIS0_FRF15      = 0x00008000,
        RIS0_FRF16      = 0x00010000,
        RIS0_FRF17      = 0x00020000,
+       RIS0_RESERVED   = GENMASK(31, 18),
 };
 
 /* RIC1 */
@@ -528,6 +530,7 @@ enum RIS2_BIT {
        RIS2_QFF16      = 0x00010000,
        RIS2_QFF17      = 0x00020000,
        RIS2_RFFF       = 0x80000000,
+       RIS2_RESERVED   = GENMASK(30, 18),
 };
 
 /* TIC */
@@ -544,6 +547,7 @@ enum TIS_BIT {
        TIS_FTF1        = 0x00000002,   /* Undocumented? */
        TIS_TFUF        = 0x00000100,
        TIS_TFWF        = 0x00000200,
+       TIS_RESERVED    = (GENMASK(31, 20) | GENMASK(15, 12) | GENMASK(7, 4))
 };
 
 /* ISS */
@@ -617,6 +621,7 @@ enum GIC_BIT {
 enum GIS_BIT {
        GIS_PTCF        = 0x00000001,   /* Undocumented? */
        GIS_PTMF        = 0x00000004,
+       GIS_RESERVED    = GENMASK(15, 10),
 };
 
 /* GIE (R-Car Gen3 only) */
index aff5516b781e27067efc9c1cca19f11bea19dd19..d6f753925352d41758945aca8d5ef6340cceee9a 100644 (file)
@@ -739,10 +739,11 @@ static void ravb_error_interrupt(struct net_device *ndev)
        u32 eis, ris2;
 
        eis = ravb_read(ndev, EIS);
-       ravb_write(ndev, ~EIS_QFS, EIS);
+       ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS);
        if (eis & EIS_QFS) {
                ris2 = ravb_read(ndev, RIS2);
-               ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF), RIS2);
+               ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED),
+                          RIS2);
 
                /* Receive Descriptor Empty int */
                if (ris2 & RIS2_QFF0)
@@ -795,7 +796,7 @@ static bool ravb_timestamp_interrupt(struct net_device *ndev)
        u32 tis = ravb_read(ndev, TIS);
 
        if (tis & TIS_TFUF) {
-               ravb_write(ndev, ~TIS_TFUF, TIS);
+               ravb_write(ndev, ~(TIS_TFUF | TIS_RESERVED), TIS);
                ravb_get_tx_tstamp(ndev);
                return true;
        }
@@ -930,7 +931,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
                /* Processing RX Descriptor Ring */
                if (ris0 & mask) {
                        /* Clear RX interrupt */
-                       ravb_write(ndev, ~mask, RIS0);
+                       ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
                        if (ravb_rx(ndev, &quota, q))
                                goto out;
                }
@@ -938,7 +939,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
                if (tis & mask) {
                        spin_lock_irqsave(&priv->lock, flags);
                        /* Clear TX interrupt */
-                       ravb_write(ndev, ~mask, TIS);
+                       ravb_write(ndev, ~(mask | TIS_RESERVED), TIS);
                        ravb_tx_free(ndev, q, true);
                        netif_wake_subqueue(ndev, q);
                        mmiowb();
index eede70ec37f8c02759727ff7e881464adf7fe707..dce2a40a31e336d6a45b8e393a384787743859f9 100644 (file)
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /* PTP 1588 clock using the Renesas Ethernet AVB
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  * Copyright (C) 2015 Renesas Solutions Corp.
  * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
  */
 
 #include "ravb.h"
@@ -319,7 +315,7 @@ void ravb_ptp_interrupt(struct net_device *ndev)
                }
        }
 
-       ravb_write(ndev, ~gis, GIS);
+       ravb_write(ndev, ~(gis | GIS_RESERVED), GIS);
 }
 
 void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
index c5bc124b41a93a69cffccd7ca44602292309686c..d1bb73bf99148b2cd29aff4e8c2f943369b0ab4c 100644 (file)
@@ -77,7 +77,8 @@ static void   ether3_setmulticastlist(struct net_device *dev);
 static int     ether3_rx(struct net_device *dev, unsigned int maxcnt);
 static void    ether3_tx(struct net_device *dev);
 static int     ether3_open (struct net_device *dev);
-static int     ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t     ether3_sendpacket(struct sk_buff *skb,
+                                         struct net_device *dev);
 static irqreturn_t ether3_interrupt (int irq, void *dev_id);
 static int     ether3_close (struct net_device *dev);
 static void    ether3_setmulticastlist (struct net_device *dev);
@@ -481,7 +482,7 @@ static void ether3_timeout(struct net_device *dev)
 /*
  * Transmit a packet
  */
-static int
+static netdev_tx_t
 ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long flags;
index 573691bc3b71fb31390dc33c071599a2e83c0ad9..70cce63a6081698169f5737d7eda9c4d3fc069fe 100644 (file)
@@ -578,7 +578,8 @@ static inline int sgiseeq_reset(struct net_device *dev)
        return 0;
 }
 
-static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct sgiseeq_private *sp = netdev_priv(dev);
        struct hpc3_ethregs *hregs = sp->hregs;
index 18d533fdf14c491a1afa48ea83a27103ac340caf..3140999642ba93dbcfe9609783fe18963e93088b 100644 (file)
@@ -99,7 +99,7 @@ struct ioc3_private {
 
 static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void ioc3_set_multicast_list(struct net_device *dev);
-static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void ioc3_timeout(struct net_device *dev);
 static inline unsigned int ioc3_hash(const unsigned char *addr);
 static inline void ioc3_stop(struct ioc3_private *ip);
@@ -1390,7 +1390,7 @@ static struct pci_driver ioc3_driver = {
        .remove         = ioc3_remove_one,
 };
 
-static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long data;
        struct ioc3_private *ip = netdev_priv(dev);
index ea55abd62ec7094f4be4182f0602abe6b7e5e466..703fbbefea44d1c830b4f4244fd416ec504f88d2 100644 (file)
@@ -697,7 +697,7 @@ static void meth_add_to_tx_ring(struct meth_private *priv, struct sk_buff *skb)
 /*
  * Transmit a packet (called by the kernel)
  */
-static int meth_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t meth_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct meth_private *priv = netdev_priv(dev);
        unsigned long flags;
index 1854f270ad6611a57d381f48bdf0956caf3fdad9..b1b305f8f4143626fc664445182c5e2afc38b87c 100644 (file)
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT           0xff
 #define MIN_DMA_RIWT           0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   40000
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK        100000
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES       64
+#define STMMAC_TX_FRAMES       25
 
 /* Packets types */
 enum packets_types {
index c0a855b7ab3b4304a0ba734117ee63d903701df8..63e1064b27a245435255c2de9e1c934ccbef8ffb 100644 (file)
@@ -48,6 +48,8 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+       u32 tx_count_frames;
+       struct timer_list txtimer;
        u32 queue_index;
        struct stmmac_priv *priv_data;
        struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
@@ -73,7 +75,14 @@ struct stmmac_rx_queue {
        u32 rx_zeroc_thresh;
        dma_addr_t dma_rx_phy;
        u32 rx_tail_addr;
+};
+
+struct stmmac_channel {
        struct napi_struct napi ____cacheline_aligned_in_smp;
+       struct stmmac_priv *priv_data;
+       u32 index;
+       int has_rx;
+       int has_tx;
 };
 
 struct stmmac_tc_entry {
@@ -109,14 +118,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
        /* Frequently used values are kept adjacent for cache effect */
-       u32 tx_count_frames;
        u32 tx_coal_frames;
        u32 tx_coal_timer;
 
        int tx_coalesce;
        int hwts_tx_en;
        bool tx_path_in_lpi_mode;
-       struct timer_list txtimer;
        bool tso;
 
        unsigned int dma_buf_sz;
@@ -137,6 +144,9 @@ struct stmmac_priv {
        /* TX Queue */
        struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
 
+       /* Generic channel for NAPI */
+       struct stmmac_channel channel[STMMAC_CH_MAX];
+
        bool oldlink;
        int speed;
        int oldduplex;
index 9f458bb16f2a6edb6ab8cca33c00176b1cce1d67..75896d6ba6e2b8e5990df01f7c3ff9d7abe96137 100644 (file)
@@ -148,12 +148,14 @@ static void stmmac_verify_args(void)
 static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 {
        u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+       u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+       u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
        u32 queue;
 
-       for (queue = 0; queue < rx_queues_cnt; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
 
-               napi_disable(&rx_q->napi);
+               napi_disable(&ch->napi);
        }
 }
 
@@ -164,12 +166,14 @@ static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 static void stmmac_enable_all_queues(struct stmmac_priv *priv)
 {
        u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+       u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+       u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
        u32 queue;
 
-       for (queue = 0; queue < rx_queues_cnt; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
 
-               napi_enable(&rx_q->napi);
+               napi_enable(&ch->napi);
        }
 }
 
@@ -1843,18 +1847,18 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources after transmission completes.
  */
-static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
+static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
 {
        struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
        unsigned int bytes_compl = 0, pkts_compl = 0;
-       unsigned int entry;
+       unsigned int entry, count = 0;
 
-       netif_tx_lock(priv->dev);
+       __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
 
        priv->xstats.tx_clean++;
 
        entry = tx_q->dirty_tx;
-       while (entry != tx_q->cur_tx) {
+       while ((entry != tx_q->cur_tx) && (count < budget)) {
                struct sk_buff *skb = tx_q->tx_skbuff[entry];
                struct dma_desc *p;
                int status;
@@ -1870,6 +1874,8 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
                if (unlikely(status & tx_dma_own))
                        break;
 
+               count++;
+
                /* Make sure descriptor fields are read after reading
                 * the own bit.
                 */
@@ -1937,7 +1943,10 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
                stmmac_enable_eee_mode(priv);
                mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
        }
-       netif_tx_unlock(priv->dev);
+
+       __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
+
+       return count;
 }
 
 /**
@@ -2020,6 +2029,33 @@ static bool stmmac_safety_feat_interrupt(struct stmmac_priv *priv)
        return false;
 }
 
+static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan)
+{
+       int status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
+                                                &priv->xstats, chan);
+       struct stmmac_channel *ch = &priv->channel[chan];
+       bool needs_work = false;
+
+       if ((status & handle_rx) && ch->has_rx) {
+               needs_work = true;
+       } else {
+               status &= ~handle_rx;
+       }
+
+       if ((status & handle_tx) && ch->has_tx) {
+               needs_work = true;
+       } else {
+               status &= ~handle_tx;
+       }
+
+       if (needs_work && napi_schedule_prep(&ch->napi)) {
+               stmmac_disable_dma_irq(priv, priv->ioaddr, chan);
+               __napi_schedule(&ch->napi);
+       }
+
+       return status;
+}
+
 /**
  * stmmac_dma_interrupt - DMA ISR
  * @priv: driver private structure
@@ -2034,57 +2070,14 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
        u32 channels_to_check = tx_channel_count > rx_channel_count ?
                                tx_channel_count : rx_channel_count;
        u32 chan;
-       bool poll_scheduled = false;
        int status[max_t(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)];
 
        /* Make sure we never check beyond our status buffer. */
        if (WARN_ON_ONCE(channels_to_check > ARRAY_SIZE(status)))
                channels_to_check = ARRAY_SIZE(status);
 
-       /* Each DMA channel can be used for rx and tx simultaneously, yet
-        * napi_struct is embedded in struct stmmac_rx_queue rather than in a
-        * stmmac_channel struct.
-        * Because of this, stmmac_poll currently checks (and possibly wakes)
-        * all tx queues rather than just a single tx queue.
-        */
        for (chan = 0; chan < channels_to_check; chan++)
-               status[chan] = stmmac_dma_interrupt_status(priv, priv->ioaddr,
-                               &priv->xstats, chan);
-
-       for (chan = 0; chan < rx_channel_count; chan++) {
-               if (likely(status[chan] & handle_rx)) {
-                       struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan];
-
-                       if (likely(napi_schedule_prep(&rx_q->napi))) {
-                               stmmac_disable_dma_irq(priv, priv->ioaddr, chan);
-                               __napi_schedule(&rx_q->napi);
-                               poll_scheduled = true;
-                       }
-               }
-       }
-
-       /* If we scheduled poll, we already know that tx queues will be checked.
-        * If we didn't schedule poll, see if any DMA channel (used by tx) has a
-        * completed transmission, if so, call stmmac_poll (once).
-        */
-       if (!poll_scheduled) {
-               for (chan = 0; chan < tx_channel_count; chan++) {
-                       if (status[chan] & handle_tx) {
-                               /* It doesn't matter what rx queue we choose
-                                * here. We use 0 since it always exists.
-                                */
-                               struct stmmac_rx_queue *rx_q =
-                                       &priv->rx_queue[0];
-
-                               if (likely(napi_schedule_prep(&rx_q->napi))) {
-                                       stmmac_disable_dma_irq(priv,
-                                                       priv->ioaddr, chan);
-                                       __napi_schedule(&rx_q->napi);
-                               }
-                               break;
-                       }
-               }
-       }
+               status[chan] = stmmac_napi_check(priv, chan);
 
        for (chan = 0; chan < tx_channel_count; chan++) {
                if (unlikely(status[chan] & tx_hard_error_bump_tc)) {
@@ -2220,8 +2213,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
                stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
                                    tx_q->dma_tx_phy, chan);
 
-               tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-                           (DMA_TX_SIZE * sizeof(struct dma_desc));
+               tx_q->tx_tail_addr = tx_q->dma_tx_phy;
                stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
                                       tx_q->tx_tail_addr, chan);
        }
@@ -2233,6 +2225,13 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
        return ret;
 }
 
+static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
+{
+       struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
+
+       mod_timer(&tx_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer));
+}
+
 /**
  * stmmac_tx_timer - mitigation sw timer for tx.
  * @data: data pointer
@@ -2241,13 +2240,14 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
  */
 static void stmmac_tx_timer(struct timer_list *t)
 {
-       struct stmmac_priv *priv = from_timer(priv, t, txtimer);
-       u32 tx_queues_count = priv->plat->tx_queues_to_use;
-       u32 queue;
+       struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
+       struct stmmac_priv *priv = tx_q->priv_data;
+       struct stmmac_channel *ch;
+
+       ch = &priv->channel[tx_q->queue_index];
 
-       /* let's scan all the tx queues */
-       for (queue = 0; queue < tx_queues_count; queue++)
-               stmmac_tx_clean(priv, queue);
+       if (likely(napi_schedule_prep(&ch->napi)))
+               __napi_schedule(&ch->napi);
 }
 
 /**
@@ -2260,11 +2260,17 @@ static void stmmac_tx_timer(struct timer_list *t)
  */
 static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
 {
+       u32 tx_channel_count = priv->plat->tx_queues_to_use;
+       u32 chan;
+
        priv->tx_coal_frames = STMMAC_TX_FRAMES;
        priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
-       timer_setup(&priv->txtimer, stmmac_tx_timer, 0);
-       priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer);
-       add_timer(&priv->txtimer);
+
+       for (chan = 0; chan < tx_channel_count; chan++) {
+               struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
+
+               timer_setup(&tx_q->txtimer, stmmac_tx_timer, 0);
+       }
 }
 
 static void stmmac_set_rings_length(struct stmmac_priv *priv)
@@ -2592,6 +2598,7 @@ static void stmmac_hw_teardown(struct net_device *dev)
 static int stmmac_open(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       u32 chan;
        int ret;
 
        stmmac_check_ether_addr(priv);
@@ -2688,7 +2695,9 @@ static int stmmac_open(struct net_device *dev)
        if (dev->phydev)
                phy_stop(dev->phydev);
 
-       del_timer_sync(&priv->txtimer);
+       for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
+               del_timer_sync(&priv->tx_queue[chan].txtimer);
+
        stmmac_hw_teardown(dev);
 init_error:
        free_dma_desc_resources(priv);
@@ -2708,6 +2717,7 @@ static int stmmac_open(struct net_device *dev)
 static int stmmac_release(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       u32 chan;
 
        if (priv->eee_enabled)
                del_timer_sync(&priv->eee_ctrl_timer);
@@ -2722,7 +2732,8 @@ static int stmmac_release(struct net_device *dev)
 
        stmmac_disable_all_queues(priv);
 
-       del_timer_sync(&priv->txtimer);
+       for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
+               del_timer_sync(&priv->tx_queue[chan].txtimer);
 
        /* Free the IRQ lines */
        free_irq(dev->irq, dev);
@@ -2936,14 +2947,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
        priv->xstats.tx_tso_nfrags += nfrags;
 
        /* Manage tx mitigation */
-       priv->tx_count_frames += nfrags + 1;
-       if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {
-               mod_timer(&priv->txtimer,
-                         STMMAC_COAL_TIMER(priv->tx_coal_timer));
-       } else {
-               priv->tx_count_frames = 0;
+       tx_q->tx_count_frames += nfrags + 1;
+       if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
+               tx_q->tx_count_frames = 0;
+       } else {
+               stmmac_tx_timer_arm(priv, queue);
        }
 
        skb_tx_timestamp(skb);
@@ -2992,6 +3002,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
        netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
+       tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
        stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
        return NETDEV_TX_OK;
@@ -3146,14 +3157,13 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
         * This approach takes care about the fragments: desc is the first
         * element in case of no SG.
         */
-       priv->tx_count_frames += nfrags + 1;
-       if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {
-               mod_timer(&priv->txtimer,
-                         STMMAC_COAL_TIMER(priv->tx_coal_timer));
-       } else {
-               priv->tx_count_frames = 0;
+       tx_q->tx_count_frames += nfrags + 1;
+       if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
+               tx_q->tx_count_frames = 0;
+       } else {
+               stmmac_tx_timer_arm(priv, queue);
        }
 
        skb_tx_timestamp(skb);
@@ -3199,6 +3209,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
        stmmac_enable_dma_transmission(priv, priv->ioaddr);
+
+       tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
        stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
        return NETDEV_TX_OK;
@@ -3319,6 +3331,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
 static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 {
        struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       struct stmmac_channel *ch = &priv->channel[queue];
        unsigned int entry = rx_q->cur_rx;
        int coe = priv->hw->rx_csum;
        unsigned int next_entry;
@@ -3491,7 +3504,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
                        else
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-                       napi_gro_receive(&rx_q->napi, skb);
+                       napi_gro_receive(&ch->napi, skb);
 
                        priv->dev->stats.rx_packets++;
                        priv->dev->stats.rx_bytes += frame_len;
@@ -3514,27 +3527,33 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
  *  Description :
  *  To look at the incoming frames and clear the tx resources.
  */
-static int stmmac_poll(struct napi_struct *napi, int budget)
+static int stmmac_napi_poll(struct napi_struct *napi, int budget)
 {
-       struct stmmac_rx_queue *rx_q =
-               container_of(napi, struct stmmac_rx_queue, napi);
-       struct stmmac_priv *priv = rx_q->priv_data;
-       u32 tx_count = priv->plat->tx_queues_to_use;
-       u32 chan = rx_q->queue_index;
-       int work_done = 0;
-       u32 queue;
+       struct stmmac_channel *ch =
+               container_of(napi, struct stmmac_channel, napi);
+       struct stmmac_priv *priv = ch->priv_data;
+       int work_done = 0, work_rem = budget;
+       u32 chan = ch->index;
 
        priv->xstats.napi_poll++;
 
-       /* check all the queues */
-       for (queue = 0; queue < tx_count; queue++)
-               stmmac_tx_clean(priv, queue);
+       if (ch->has_tx) {
+               int done = stmmac_tx_clean(priv, work_rem, chan);
 
-       work_done = stmmac_rx(priv, budget, rx_q->queue_index);
-       if (work_done < budget) {
-               napi_complete_done(napi, work_done);
-               stmmac_enable_dma_irq(priv, priv->ioaddr, chan);
+               work_done += done;
+               work_rem -= done;
+       }
+
+       if (ch->has_rx) {
+               int done = stmmac_rx(priv, work_rem, chan);
+
+               work_done += done;
+               work_rem -= done;
        }
+
+       if (work_done < budget && napi_complete_done(napi, work_done))
+               stmmac_enable_dma_irq(priv, priv->ioaddr, chan);
+
        return work_done;
 }
 
@@ -4198,8 +4217,8 @@ int stmmac_dvr_probe(struct device *device,
 {
        struct net_device *ndev = NULL;
        struct stmmac_priv *priv;
+       u32 queue, maxq;
        int ret = 0;
-       u32 queue;
 
        ndev = alloc_etherdev_mqs(sizeof(struct stmmac_priv),
                                  MTL_MAX_TX_QUEUES,
@@ -4322,11 +4341,22 @@ int stmmac_dvr_probe(struct device *device,
                         "Enable RX Mitigation via HW Watchdog Timer\n");
        }
 
-       for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       /* Setup channels NAPI */
+       maxq = max(priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);
 
-               netif_napi_add(ndev, &rx_q->napi, stmmac_poll,
-                              (8 * priv->plat->rx_queues_to_use));
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
+
+               ch->priv_data = priv;
+               ch->index = queue;
+
+               if (queue < priv->plat->rx_queues_to_use)
+                       ch->has_rx = true;
+               if (queue < priv->plat->tx_queues_to_use)
+                       ch->has_tx = true;
+
+               netif_napi_add(ndev, &ch->napi, stmmac_napi_poll,
+                              NAPI_POLL_WEIGHT);
        }
 
        mutex_init(&priv->lock);
@@ -4372,10 +4402,10 @@ int stmmac_dvr_probe(struct device *device,
            priv->hw->pcs != STMMAC_PCS_RTBI)
                stmmac_mdio_unregister(ndev);
 error_mdio_register:
-       for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
 
-               netif_napi_del(&rx_q->napi);
+               netif_napi_del(&ch->napi);
        }
 error_hw_init:
        destroy_workqueue(priv->wq);
index 3609c7b696c7a0b22e8c88cc1854495aa80b65fe..2b800ce1d5bf42ca23b378d4b9c8c35addc41da9 100644 (file)
@@ -67,7 +67,7 @@ static int dwmac1000_validate_mcast_bins(int mcast_bins)
  * Description:
  * This function validates the number of Unicast address entries supported
  * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
- * supports 132, 64, or 128 Unicast filter entries for it's Unicast filter
+ * supports 1..32, 64, or 128 Unicast filter entries for it's Unicast filter
  * logic. This function validates a valid, supported configuration is
  * selected, and defaults to 1 Unicast address if an unsupported
  * configuration is selected.
@@ -77,8 +77,7 @@ static int dwmac1000_validate_ucast_entries(int ucast_entries)
        int x = ucast_entries;
 
        switch (x) {
-       case 1:
-       case 32:
+       case 1 ... 32:
        case 64:
        case 128:
                break;
index 9263d638bd6d0ffaec45aa1da2fd57b981faa38d..f932923f7d5619b1d8b2aa7cb66acf15b1c608f5 100644 (file)
@@ -41,6 +41,7 @@ config TI_DAVINCI_MDIO
 config TI_DAVINCI_CPDMA
        tristate "TI DaVinci CPDMA Support"
        depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST
+       select GENERIC_ALLOCATOR
        ---help---
          This driver supports TI's DaVinci CPDMA dma engine.
 
index 2bdfb39215e9ce749ecc5fac8f4a22226c081bc4..d8ba512f166ad38f10f6a01c1ef10c564bdd808e 100644 (file)
@@ -835,7 +835,7 @@ static void w5100_tx_work(struct work_struct *work)
        w5100_tx_skb(priv->ndev, skb);
 }
 
-static int w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
 {
        struct w5100_priv *priv = netdev_priv(ndev);
 
index 56ae573001e8e76c8cbd5300ad4fca4873cbc2ae..80fdbff67d82a7519a3a2eff210cb71c029ee126 100644 (file)
@@ -365,7 +365,7 @@ static void w5300_tx_timeout(struct net_device *ndev)
        netif_wake_queue(ndev);
 }
 
-static int w5300_start_tx(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t w5300_start_tx(struct sk_buff *skb, struct net_device *ndev)
 {
        struct w5300_priv *priv = netdev_priv(ndev);
 
index 31c3d77b4733f0aa9900138b5c49f398d0642db4..fe01e141c8f87d50e42a5cb2670ff5ba4921744a 100644 (file)
@@ -1203,6 +1203,9 @@ static void netvsc_send_vf(struct net_device *ndev,
 
        net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated;
        net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial;
+       netdev_info(ndev, "VF slot %u %s\n",
+                   net_device_ctx->vf_serial,
+                   net_device_ctx->vf_alloc ? "added" : "removed");
 }
 
 static  void netvsc_receive_inband(struct net_device *ndev,
index 70921bbe0e28b448256d18cd8897eba9ae731c31..3af6d8d15233756e411500a8753d2789d544f076 100644 (file)
@@ -1894,20 +1894,6 @@ static void netvsc_link_change(struct work_struct *w)
        rtnl_unlock();
 }
 
-static struct net_device *get_netvsc_bymac(const u8 *mac)
-{
-       struct net_device_context *ndev_ctx;
-
-       list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
-               struct net_device *dev = hv_get_drvdata(ndev_ctx->device_ctx);
-
-               if (ether_addr_equal(mac, dev->perm_addr))
-                       return dev;
-       }
-
-       return NULL;
-}
-
 static struct net_device *get_netvsc_byref(struct net_device *vf_netdev)
 {
        struct net_device_context *net_device_ctx;
@@ -2036,26 +2022,48 @@ static void netvsc_vf_setup(struct work_struct *w)
        rtnl_unlock();
 }
 
+/* Find netvsc by VMBus serial number.
+ * The PCI hyperv controller records the serial number as the slot.
+ */
+static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
+{
+       struct device *parent = vf_netdev->dev.parent;
+       struct net_device_context *ndev_ctx;
+       struct pci_dev *pdev;
+
+       if (!parent || !dev_is_pci(parent))
+               return NULL; /* not a PCI device */
+
+       pdev = to_pci_dev(parent);
+       if (!pdev->slot) {
+               netdev_notice(vf_netdev, "no PCI slot information\n");
+               return NULL;
+       }
+
+       list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
+               if (!ndev_ctx->vf_alloc)
+                       continue;
+
+               if (ndev_ctx->vf_serial == pdev->slot->number)
+                       return hv_get_drvdata(ndev_ctx->device_ctx);
+       }
+
+       netdev_notice(vf_netdev,
+                     "no netdev found for slot %u\n", pdev->slot->number);
+       return NULL;
+}
+
 static int netvsc_register_vf(struct net_device *vf_netdev)
 {
-       struct net_device *ndev;
        struct net_device_context *net_device_ctx;
-       struct device *pdev = vf_netdev->dev.parent;
        struct netvsc_device *netvsc_dev;
+       struct net_device *ndev;
        int ret;
 
        if (vf_netdev->addr_len != ETH_ALEN)
                return NOTIFY_DONE;
 
-       if (!pdev || !dev_is_pci(pdev) || dev_is_pf(pdev))
-               return NOTIFY_DONE;
-
-       /*
-        * We will use the MAC address to locate the synthetic interface to
-        * associate with the VF interface. If we don't find a matching
-        * synthetic interface, move on.
-        */
-       ndev = get_netvsc_bymac(vf_netdev->perm_addr);
+       ndev = get_netvsc_byslot(vf_netdev);
        if (!ndev)
                return NOTIFY_DONE;
 
@@ -2272,17 +2280,15 @@ static int netvsc_remove(struct hv_device *dev)
 
        cancel_delayed_work_sync(&ndev_ctx->dwork);
 
-       rcu_read_lock();
-       nvdev = rcu_dereference(ndev_ctx->nvdev);
-
-       if  (nvdev)
+       rtnl_lock();
+       nvdev = rtnl_dereference(ndev_ctx->nvdev);
+       if (nvdev)
                cancel_work_sync(&nvdev->subchan_work);
 
        /*
         * Call to the vsc driver to let it know that the device is being
         * removed. Also blocks mtu and channel changes.
         */
-       rtnl_lock();
        vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
        if (vf_netdev)
                netvsc_unregister_vf(vf_netdev);
@@ -2294,7 +2300,6 @@ static int netvsc_remove(struct hv_device *dev)
        list_del(&ndev_ctx->list);
 
        rtnl_unlock();
-       rcu_read_unlock();
 
        hv_set_drvdata(dev, NULL);
 
index 740655261e5b7347116d2a5b53445c8d023cb49c..83060fb349f4d5d458e762eb540afe0de2b935d6 100644 (file)
@@ -349,6 +349,7 @@ static int sfp_register_bus(struct sfp_bus *bus)
        }
        if (bus->started)
                bus->socket_ops->start(bus->sfp);
+       bus->netdev->sfp_bus = bus;
        bus->registered = true;
        return 0;
 }
@@ -357,6 +358,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
 {
        const struct sfp_upstream_ops *ops = bus->upstream_ops;
 
+       bus->netdev->sfp_bus = NULL;
        if (bus->registered) {
                if (bus->started)
                        bus->socket_ops->stop(bus->sfp);
@@ -438,7 +440,6 @@ static void sfp_upstream_clear(struct sfp_bus *bus)
 {
        bus->upstream_ops = NULL;
        bus->upstream = NULL;
-       bus->netdev->sfp_bus = NULL;
        bus->netdev = NULL;
 }
 
@@ -467,7 +468,6 @@ struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
                bus->upstream_ops = ops;
                bus->upstream = upstream;
                bus->netdev = ndev;
-               ndev->sfp_bus = bus;
 
                if (bus->sfp) {
                        ret = sfp_register_bus(bus);
index ce61231e96ea5fe27f512fbd0d80d4609997e508..62dc564b251d5e0c2019035355aa17426471cc8e 100644 (file)
@@ -429,6 +429,9 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
        if (!skb)
                goto out;
 
+       if (skb_mac_header_len(skb) < ETH_HLEN)
+               goto drop;
+
        if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
                goto drop;
 
index ebd07ad82431ec78c3801999fdc986188216655a..e2648b5a3861e51dc6c40d19e1198a5f3f7ca7af 100644 (file)
@@ -1153,43 +1153,6 @@ static netdev_features_t tun_net_fix_features(struct net_device *dev,
 
        return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
 }
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void tun_poll_controller(struct net_device *dev)
-{
-       /*
-        * Tun only receives frames when:
-        * 1) the char device endpoint gets data from user space
-        * 2) the tun socket gets a sendmsg call from user space
-        * If NAPI is not enabled, since both of those are synchronous
-        * operations, we are guaranteed never to have pending data when we poll
-        * for it so there is nothing to do here but return.
-        * We need this though so netpoll recognizes us as an interface that
-        * supports polling, which enables bridge devices in virt setups to
-        * still use netconsole
-        * If NAPI is enabled, however, we need to schedule polling for all
-        * queues unless we are using napi_gro_frags(), which we call in
-        * process context and not in NAPI context.
-        */
-       struct tun_struct *tun = netdev_priv(dev);
-
-       if (tun->flags & IFF_NAPI) {
-               struct tun_file *tfile;
-               int i;
-
-               if (tun_napi_frags_enabled(tun))
-                       return;
-
-               rcu_read_lock();
-               for (i = 0; i < tun->numqueues; i++) {
-                       tfile = rcu_dereference(tun->tfiles[i]);
-                       if (tfile->napi_enabled)
-                               napi_schedule(&tfile->napi);
-               }
-               rcu_read_unlock();
-       }
-       return;
-}
-#endif
 
 static void tun_set_headroom(struct net_device *dev, int new_hr)
 {
@@ -1283,9 +1246,6 @@ static const struct net_device_ops tun_netdev_ops = {
        .ndo_start_xmit         = tun_net_xmit,
        .ndo_fix_features       = tun_net_fix_features,
        .ndo_select_queue       = tun_select_queue,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = tun_poll_controller,
-#endif
        .ndo_set_rx_headroom    = tun_set_headroom,
        .ndo_get_stats64        = tun_net_get_stats64,
 };
@@ -1365,9 +1325,6 @@ static const struct net_device_ops tap_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_select_queue       = tun_select_queue,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = tun_poll_controller,
-#endif
        .ndo_features_check     = passthru_features_check,
        .ndo_set_rx_headroom    = tun_set_headroom,
        .ndo_get_stats64        = tun_net_get_stats64,
index cb0cc30c3d6a190e8d3132b6bab4c5d67e29979c..533b6fb8d923161ad34b539883713bd3e5a65af4 100644 (file)
@@ -967,6 +967,13 @@ static const struct usb_device_id products[] = {
                USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
                .driver_info = (unsigned long)&qmi_wwan_info,
        },
+       {       /* Quectel EP06/EG06/EM06 */
+               USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x0306,
+                                             USB_CLASS_VENDOR_SPEC,
+                                             USB_SUBCLASS_VENDOR_SPEC,
+                                             0xff),
+               .driver_info        = (unsigned long)&qmi_wwan_info_quirk_dtr,
+       },
 
        /* 3. Combined interface devices matching on interface number */
        {QMI_FIXED_INTF(0x0408, 0xea42, 4)},    /* Yota / Megafon M100-1 */
@@ -1206,13 +1213,13 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x9061, 8)},    /* Sierra Wireless Modem */
        {QMI_FIXED_INTF(0x1199, 0x9063, 8)},    /* Sierra Wireless EM7305 */
        {QMI_FIXED_INTF(0x1199, 0x9063, 10)},   /* Sierra Wireless EM7305 */
-       {QMI_FIXED_INTF(0x1199, 0x9071, 8)},    /* Sierra Wireless MC74xx */
-       {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx */
-       {QMI_FIXED_INTF(0x1199, 0x9079, 8)},    /* Sierra Wireless EM74xx */
-       {QMI_FIXED_INTF(0x1199, 0x9079, 10)},   /* Sierra Wireless EM74xx */
-       {QMI_FIXED_INTF(0x1199, 0x907b, 8)},    /* Sierra Wireless EM74xx */
-       {QMI_FIXED_INTF(0x1199, 0x907b, 10)},   /* Sierra Wireless EM74xx */
-       {QMI_FIXED_INTF(0x1199, 0x9091, 8)},    /* Sierra Wireless EM7565 */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x9071, 10)},/* Sierra Wireless MC74xx */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x9079, 10)},/* Sierra Wireless EM74xx */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x907b, 10)},/* Sierra Wireless EM74xx */
+       {QMI_QUIRK_SET_DTR(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
        {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},    /* Alcatel L800MA */
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
@@ -1255,7 +1262,6 @@ static const struct usb_device_id products[] = {
        {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */
        {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */
        {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)},    /* Quectel BG96 */
-       {QMI_QUIRK_SET_DTR(0x2c7c, 0x0306, 4)}, /* Quectel EP06 Mini PCIe */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
@@ -1331,6 +1337,19 @@ static bool quectel_ec20_detected(struct usb_interface *intf)
        return false;
 }
 
+static bool quectel_ep06_diag_detected(struct usb_interface *intf)
+{
+       struct usb_device *dev = interface_to_usbdev(intf);
+       struct usb_interface_descriptor intf_desc = intf->cur_altsetting->desc;
+
+       if (le16_to_cpu(dev->descriptor.idVendor) == 0x2c7c &&
+           le16_to_cpu(dev->descriptor.idProduct) == 0x0306 &&
+           intf_desc.bNumEndpoints == 2)
+               return true;
+
+       return false;
+}
+
 static int qmi_wwan_probe(struct usb_interface *intf,
                          const struct usb_device_id *prod)
 {
@@ -1365,6 +1384,15 @@ static int qmi_wwan_probe(struct usb_interface *intf,
                return -ENODEV;
        }
 
+       /* Quectel EP06/EM06/EG06 supports dynamic interface configuration, so
+        * we need to match on class/subclass/protocol. These values are
+        * identical for the diagnostic- and QMI-interface, but bNumEndpoints is
+        * different. Ignore the current interface if the number of endpoints
+        * the number for the diag interface (two).
+        */
+       if (quectel_ep06_diag_detected(intf))
+               return -ENODEV;
+
        return usbnet_probe(intf, id);
 }
 
index 8d679c8b7f25c753d77cfb8821d9d2528c9c9048..41a00cd76955bf39047fafc0a1641eb347c6ee21 100644 (file)
@@ -463,6 +463,8 @@ static struct sk_buff *veth_xdp_rcv_skb(struct veth_rq *rq, struct sk_buff *skb,
        int mac_len, delta, off;
        struct xdp_buff xdp;
 
+       skb_orphan(skb);
+
        rcu_read_lock();
        xdp_prog = rcu_dereference(rq->xdp_prog);
        if (unlikely(!xdp_prog)) {
@@ -508,8 +510,6 @@ static struct sk_buff *veth_xdp_rcv_skb(struct veth_rq *rq, struct sk_buff *skb,
                skb_copy_header(nskb, skb);
                head_off = skb_headroom(nskb) - skb_headroom(skb);
                skb_headers_offset_update(nskb, head_off);
-               if (skb->sk)
-                       skb_set_owner_w(nskb, skb->sk);
                consume_skb(skb);
                skb = nskb;
        }
index 73f596a90c691a471a55951264b1a6fedf189e6e..f17f602e6171203acd39ee448c305cba719ff1de 100644 (file)
@@ -87,8 +87,7 @@ struct netfront_cb {
 /* IRQ name is queue name with "-tx" or "-rx" appended */
 #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)
 
-static DECLARE_WAIT_QUEUE_HEAD(module_load_q);
-static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
+static DECLARE_WAIT_QUEUE_HEAD(module_wq);
 
 struct netfront_stats {
        u64                     packets;
@@ -909,7 +908,11 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
                        BUG_ON(pull_to <= skb_headlen(skb));
                        __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
                }
-               BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
+               if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
+                       queue->rx.rsp_cons = ++cons;
+                       kfree_skb(nskb);
+                       return ~0U;
+               }
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                skb_frag_page(nfrag),
@@ -1046,6 +1049,8 @@ static int xennet_poll(struct napi_struct *napi, int budget)
                skb->len += rx->status;
 
                i = xennet_fill_frags(queue, skb, &tmpq);
+               if (unlikely(i == ~0U))
+                       goto err;
 
                if (rx->flags & XEN_NETRXF_csum_blank)
                        skb->ip_summed = CHECKSUM_PARTIAL;
@@ -1332,11 +1337,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
        netif_carrier_off(netdev);
 
        xenbus_switch_state(dev, XenbusStateInitialising);
-       wait_event(module_load_q,
-                          xenbus_read_driver_state(dev->otherend) !=
-                          XenbusStateClosed &&
-                          xenbus_read_driver_state(dev->otherend) !=
-                          XenbusStateUnknown);
+       wait_event(module_wq,
+                  xenbus_read_driver_state(dev->otherend) !=
+                  XenbusStateClosed &&
+                  xenbus_read_driver_state(dev->otherend) !=
+                  XenbusStateUnknown);
        return netdev;
 
  exit:
@@ -2010,15 +2015,14 @@ static void netback_changed(struct xenbus_device *dev,
 
        dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state));
 
+       wake_up_all(&module_wq);
+
        switch (backend_state) {
        case XenbusStateInitialising:
        case XenbusStateInitialised:
        case XenbusStateReconfiguring:
        case XenbusStateReconfigured:
-               break;
-
        case XenbusStateUnknown:
-               wake_up_all(&module_unload_q);
                break;
 
        case XenbusStateInitWait:
@@ -2034,12 +2038,10 @@ static void netback_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateClosed:
-               wake_up_all(&module_unload_q);
                if (dev->state == XenbusStateClosed)
                        break;
                /* Missed the backend's CLOSING state -- fallthrough */
        case XenbusStateClosing:
-               wake_up_all(&module_unload_q);
                xenbus_frontend_closed(dev);
                break;
        }
@@ -2147,14 +2149,14 @@ static int xennet_remove(struct xenbus_device *dev)
 
        if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) {
                xenbus_switch_state(dev, XenbusStateClosing);
-               wait_event(module_unload_q,
+               wait_event(module_wq,
                           xenbus_read_driver_state(dev->otherend) ==
                           XenbusStateClosing ||
                           xenbus_read_driver_state(dev->otherend) ==
                           XenbusStateUnknown);
 
                xenbus_switch_state(dev, XenbusStateClosed);
-               wait_event(module_unload_q,
+               wait_event(module_wq,
                           xenbus_read_driver_state(dev->otherend) ==
                           XenbusStateClosed ||
                           xenbus_read_driver_state(dev->otherend) ==
index 5a9562881d4ef87ddfbd749555f1c8eccf01acc5..9fe3fff818b8a42281b30bcd3bba83c0e0dd36f8 100644 (file)
@@ -537,8 +537,10 @@ int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
 
        INIT_WORK(&ctrl->ana_work, nvme_ana_work);
        ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL);
-       if (!ctrl->ana_log_buf)
+       if (!ctrl->ana_log_buf) {
+               error = -ENOMEM;
                goto out;
+       }
 
        error = nvme_read_ana_log(ctrl, true);
        if (error)
@@ -547,7 +549,7 @@ int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
 out_free_ana_log_buf:
        kfree(ctrl->ana_log_buf);
 out:
-       return -ENOMEM;
+       return error;
 }
 
 void nvme_mpath_uninit(struct nvme_ctrl *ctrl)
index a21caea1e0806a56c43a9f1c6d74d1ac3feae00f..2008fa62a373bb9ba84775e39b5b8956dd25bca6 100644 (file)
@@ -245,6 +245,10 @@ static void nvmet_execute_get_log_page_ana(struct nvmet_req *req)
                offset += len;
                ngrps++;
        }
+       for ( ; grpid <= NVMET_MAX_ANAGRPS; grpid++) {
+               if (nvmet_ana_group_enabled[grpid])
+                       ngrps++;
+       }
 
        hdr.chgcnt = cpu_to_le64(nvmet_ana_chgcnt);
        hdr.ngrps = cpu_to_le16(ngrps);
index 3533e918ea376bbb221489f086047521443c17e8..bfc4da660bb4036c9d53764793824f5befb3edb2 100644 (file)
@@ -66,6 +66,7 @@ struct nvmet_rdma_rsp {
 
        struct nvmet_req        req;
 
+       bool                    allocated;
        u8                      n_rdma;
        u32                     flags;
        u32                     invalidate_rkey;
@@ -174,11 +175,19 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
        unsigned long flags;
 
        spin_lock_irqsave(&queue->rsps_lock, flags);
-       rsp = list_first_entry(&queue->free_rsps,
+       rsp = list_first_entry_or_null(&queue->free_rsps,
                                struct nvmet_rdma_rsp, free_list);
-       list_del(&rsp->free_list);
+       if (likely(rsp))
+               list_del(&rsp->free_list);
        spin_unlock_irqrestore(&queue->rsps_lock, flags);
 
+       if (unlikely(!rsp)) {
+               rsp = kmalloc(sizeof(*rsp), GFP_KERNEL);
+               if (unlikely(!rsp))
+                       return NULL;
+               rsp->allocated = true;
+       }
+
        return rsp;
 }
 
@@ -187,6 +196,11 @@ nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp)
 {
        unsigned long flags;
 
+       if (rsp->allocated) {
+               kfree(rsp);
+               return;
+       }
+
        spin_lock_irqsave(&rsp->queue->rsps_lock, flags);
        list_add_tail(&rsp->free_list, &rsp->queue->free_rsps);
        spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags);
@@ -776,6 +790,15 @@ static void nvmet_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc)
 
        cmd->queue = queue;
        rsp = nvmet_rdma_get_rsp(queue);
+       if (unlikely(!rsp)) {
+               /*
+                * we get here only under memory pressure,
+                * silently drop and have the host retry
+                * as we can't even fail it.
+                */
+               nvmet_rdma_post_recv(queue->dev, cmd);
+               return;
+       }
        rsp->queue = queue;
        rsp->cmd = cmd;
        rsp->flags = 0;
index 9095b8290150c5bd2b8da3916d9f6c9243f24c56..74eaedd5b860f1c1fd42faa187d5cda802d0ae8e 100644 (file)
@@ -140,6 +140,9 @@ void of_populate_phandle_cache(void)
                if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
                        phandles++;
 
+       if (!phandles)
+               goto out;
+
        cache_entries = roundup_pow_of_two(phandles);
        phandle_cache_mask = cache_entries - 1;
 
index 778c4f76a884320b0fad349260251acf796462a2..2153956a0b207cae268ffabf8392a3025f22432b 100644 (file)
@@ -135,7 +135,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
                if (val & PCIE_ATU_ENABLE)
                        return;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Outbound iATU is not being enabled\n");
 }
@@ -178,7 +178,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
                if (val & PCIE_ATU_ENABLE)
                        return;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Outbound iATU is not being enabled\n");
 }
@@ -236,7 +236,7 @@ static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
                if (val & PCIE_ATU_ENABLE)
                        return 0;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Inbound iATU is not being enabled\n");
 
@@ -282,7 +282,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
                if (val & PCIE_ATU_ENABLE)
                        return 0;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Inbound iATU is not being enabled\n");
 
index 96126fd8403ccd79450936b7d4f52de551d07c40..9f1a5e399b7033eba9918a7981bdfdb0ea957a7a 100644 (file)
@@ -26,8 +26,7 @@
 
 /* Parameters for the waiting for iATU enabled routine */
 #define LINK_WAIT_MAX_IATU_RETRIES     5
-#define LINK_WAIT_IATU_MIN             9000
-#define LINK_WAIT_IATU_MAX             10000
+#define LINK_WAIT_IATU                 9
 
 /* Synopsys-specific PCIe configuration registers */
 #define PCIE_PORT_LINK_CONTROL         0x710
index c00f82cc54aacac60c6b24ce424402cb3e4dfea1..9ba4d12c179c7551d8a10b59433a33ed5be044cd 100644 (file)
@@ -89,6 +89,9 @@ static enum pci_protocol_version_t pci_protocol_version;
 
 #define STATUS_REVISION_MISMATCH 0xC0000059
 
+/* space for 32bit serial number as string */
+#define SLOT_NAME_SIZE 11
+
 /*
  * Message Types
  */
@@ -494,6 +497,7 @@ struct hv_pci_dev {
        struct list_head list_entry;
        refcount_t refs;
        enum hv_pcichild_state state;
+       struct pci_slot *pci_slot;
        struct pci_function_description desc;
        bool reported_missing;
        struct hv_pcibus_device *hbus;
@@ -1457,6 +1461,36 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus)
        spin_unlock_irqrestore(&hbus->device_list_lock, flags);
 }
 
+/*
+ * Assign entries in sysfs pci slot directory.
+ *
+ * Note that this function does not need to lock the children list
+ * because it is called from pci_devices_present_work which
+ * is serialized with hv_eject_device_work because they are on the
+ * same ordered workqueue. Therefore hbus->children list will not change
+ * even when pci_create_slot sleeps.
+ */
+static void hv_pci_assign_slots(struct hv_pcibus_device *hbus)
+{
+       struct hv_pci_dev *hpdev;
+       char name[SLOT_NAME_SIZE];
+       int slot_nr;
+
+       list_for_each_entry(hpdev, &hbus->children, list_entry) {
+               if (hpdev->pci_slot)
+                       continue;
+
+               slot_nr = PCI_SLOT(wslot_to_devfn(hpdev->desc.win_slot.slot));
+               snprintf(name, SLOT_NAME_SIZE, "%u", hpdev->desc.ser);
+               hpdev->pci_slot = pci_create_slot(hbus->pci_bus, slot_nr,
+                                         name, NULL);
+               if (IS_ERR(hpdev->pci_slot)) {
+                       pr_warn("pci_create slot %s failed\n", name);
+                       hpdev->pci_slot = NULL;
+               }
+       }
+}
+
 /**
  * create_root_hv_pci_bus() - Expose a new root PCI bus
  * @hbus:      Root PCI bus, as understood by this driver
@@ -1480,6 +1514,7 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)
        pci_lock_rescan_remove();
        pci_scan_child_bus(hbus->pci_bus);
        pci_bus_assign_resources(hbus->pci_bus);
+       hv_pci_assign_slots(hbus);
        pci_bus_add_devices(hbus->pci_bus);
        pci_unlock_rescan_remove();
        hbus->state = hv_pcibus_installed;
@@ -1742,6 +1777,7 @@ static void pci_devices_present_work(struct work_struct *work)
                 */
                pci_lock_rescan_remove();
                pci_scan_child_bus(hbus->pci_bus);
+               hv_pci_assign_slots(hbus);
                pci_unlock_rescan_remove();
                break;
 
@@ -1858,6 +1894,9 @@ static void hv_eject_device_work(struct work_struct *work)
        list_del(&hpdev->list_entry);
        spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
 
+       if (hpdev->pci_slot)
+               pci_destroy_slot(hpdev->pci_slot);
+
        memset(&ctxt, 0, sizeof(ctxt));
        ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;
        ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE;
index ef0b1b6ba86f8fad2a570187252e7579e12ea129..12afa7fdf77e9569d78f517a77b01de129151937 100644 (file)
@@ -457,17 +457,18 @@ static void acpiphp_native_scan_bridge(struct pci_dev *bridge)
 /**
  * enable_slot - enable, configure a slot
  * @slot: slot to be enabled
+ * @bridge: true if enable is for the whole bridge (not a single slot)
  *
  * This function should be called per *physical slot*,
  * not per each slot object in ACPI namespace.
  */
-static void enable_slot(struct acpiphp_slot *slot)
+static void enable_slot(struct acpiphp_slot *slot, bool bridge)
 {
        struct pci_dev *dev;
        struct pci_bus *bus = slot->bus;
        struct acpiphp_func *func;
 
-       if (bus->self && hotplug_is_native(bus->self)) {
+       if (bridge && bus->self && hotplug_is_native(bus->self)) {
                /*
                 * If native hotplug is used, it will take care of hotplug
                 * slot management and resource allocation for hotplug
@@ -701,7 +702,7 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)
                                        trim_stale_devices(dev);
 
                        /* configure all functions */
-                       enable_slot(slot);
+                       enable_slot(slot, true);
                } else {
                        disable_slot(slot);
                }
@@ -785,7 +786,7 @@ static void hotplug_event(u32 type, struct acpiphp_context *context)
                if (bridge)
                        acpiphp_check_bridge(bridge);
                else if (!(slot->flags & SLOT_IS_GOING_AWAY))
-                       enable_slot(slot);
+                       enable_slot(slot, false);
 
                break;
 
@@ -973,7 +974,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
 
        /* configure all functions */
        if (!(slot->flags & SLOT_ENABLED))
-               enable_slot(slot);
+               enable_slot(slot, false);
 
        pci_unlock_rescan_remove();
        return 0;
index 7136e34309250aa2a3cc0d2880f563a3b183e895..a938abdb41ceeb575dc62af740d78d278104280c 100644 (file)
@@ -496,7 +496,7 @@ int pciehp_power_on_slot(struct slot *slot)
        u16 slot_status;
        int retval;
 
-       /* Clear sticky power-fault bit from previous power failures */
+       /* Clear power-fault bit from previous power failures */
        pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
        if (slot_status & PCI_EXP_SLTSTA_PFD)
                pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
@@ -646,6 +646,14 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
                pciehp_handle_button_press(slot);
        }
 
+       /* Check Power Fault Detected */
+       if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
+               ctrl->power_fault_detected = 1;
+               ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot));
+               pciehp_set_attention_status(slot, 1);
+               pciehp_green_led_off(slot);
+       }
+
        /*
         * Disable requests have higher priority than Presence Detect Changed
         * or Data Link Layer State Changed events.
@@ -657,14 +665,6 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
                pciehp_handle_presence_or_link_change(slot, events);
        up_read(&ctrl->reset_lock);
 
-       /* Check Power Fault Detected */
-       if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
-               ctrl->power_fault_detected = 1;
-               ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot));
-               pciehp_set_attention_status(slot, 1);
-               pciehp_green_led_off(slot);
-       }
-
        pci_config_pm_runtime_put(pdev);
        wake_up(&ctrl->requester);
        return IRQ_HANDLED;
index 29ff9619b5fa8e3623778a696cd2b9d572801c43..1835f3a7aa8d2f5a502a0629bfb0c0cc96420dd4 100644 (file)
@@ -4547,6 +4547,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev)
 
        return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS);
 }
+EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
 
 static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
 {
@@ -5200,7 +5201,7 @@ static int __pci_reset_bus(struct pci_bus *bus)
  */
 int pci_reset_bus(struct pci_dev *pdev)
 {
-       return pci_probe_reset_slot(pdev->slot) ?
+       return (!pci_probe_reset_slot(pdev->slot)) ?
            __pci_reset_slot(pdev->slot) : __pci_reset_bus(pdev->bus);
 }
 EXPORT_SYMBOL_GPL(pci_reset_bus);
index ec784009a36b8d7b694ebb8f0b26a3f3810636f5..201f9e5ff55c0a97e330d9dcf139f8d2cd96bad1 100644 (file)
@@ -2074,6 +2074,7 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev)
 {
 #ifdef CONFIG_PCI_PASID
        struct pci_dev *bridge;
+       int pcie_type;
        u32 cap;
 
        if (!pci_is_pcie(dev))
@@ -2083,7 +2084,9 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev)
        if (!(cap & PCI_EXP_DEVCAP2_EE_PREFIX))
                return;
 
-       if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+       pcie_type = pci_pcie_type(dev);
+       if (pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
+           pcie_type == PCI_EXP_TYPE_RC_END)
                dev->eetlp_prefix_path = 1;
        else {
                bridge = pci_upstream_bridge(dev);
index ef7143a274e00c9431a26c14702443dbd7853aa1..6bc27b7fd452ad591626625c69454d85041c1a02 100644 (file)
@@ -4355,11 +4355,6 @@ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
  *
  * 0x9d10-0x9d1b PCI Express Root port #{1-12}
  *
- * The 300 series chipset suffers from the same bug so include those root
- * ports here as well.
- *
- * 0xa32c-0xa343 PCI Express Root port #{0-24}
- *
  * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html
  * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html
  * [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html
@@ -4377,7 +4372,6 @@ static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev)
        case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */
        case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */
        case 0x9d10 ... 0x9d1b: /* 7th & 8th Gen Mobile */
-       case 0xa32c ... 0xa343:                         /* 300 series */
                return true;
        }
 
index 9940cc70f38b0c6a92c1f1381c401ea395b36d1a..54a8b30dda38c446c8c4f839ba2c6cb8be504a8d 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/poll.h>
 #include <linux/wait.h>
 
+#include <linux/nospec.h>
+
 MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
@@ -909,6 +911,8 @@ static int ioctl_port_to_pff(struct switchtec_dev *stdev,
        default:
                if (p.port > ARRAY_SIZE(pcfg->dsp_pff_inst_id))
                        return -EINVAL;
+               p.port = array_index_nospec(p.port,
+                                       ARRAY_SIZE(pcfg->dsp_pff_inst_id) + 1);
                p.pff = ioread32(&pcfg->dsp_pff_inst_id[p.port - 1]);
                break;
        }
index ece41fb2848f20edbd995176fbb6b7fd6ab3004e..c4f4d904e4a61e4c0d622a08fcb85e1f5e63b6a7 100644 (file)
@@ -1040,7 +1040,7 @@ static int madera_pin_probe(struct platform_device *pdev)
        }
 
        /* if the configuration is provided through pdata, apply it */
-       if (pdata) {
+       if (pdata && pdata->gpio_configs) {
                ret = pinctrl_register_mappings(pdata->gpio_configs,
                                                pdata->n_gpio_configs);
                if (ret) {
index fb1afe55bf53fb80e14208e66bfab4aa02268719..e7f45d96b0cbd61e4cf7adfb050fbde547bcf752 100644 (file)
 
 #include "pinctrl-intel.h"
 
-#define CNL_PAD_OWN    0x020
-#define CNL_PADCFGLOCK 0x080
-#define CNL_HOSTSW_OWN 0x0b0
-#define CNL_GPI_IE     0x120
+#define CNL_PAD_OWN            0x020
+#define CNL_PADCFGLOCK         0x080
+#define CNL_LP_HOSTSW_OWN      0x0b0
+#define CNL_H_HOSTSW_OWN       0x0c0
+#define CNL_GPI_IE             0x120
 
 #define CNL_GPP(r, s, e, g)                            \
        {                                               \
 
 #define CNL_NO_GPIO    -1
 
-#define CNL_COMMUNITY(b, s, e, g)                      \
+#define CNL_COMMUNITY(b, s, e, o, g)                   \
        {                                               \
                .barno = (b),                           \
                .padown_offset = CNL_PAD_OWN,           \
                .padcfglock_offset = CNL_PADCFGLOCK,    \
-               .hostown_offset = CNL_HOSTSW_OWN,       \
+               .hostown_offset = (o),                  \
                .ie_offset = CNL_GPI_IE,                \
                .pin_base = (s),                        \
                .npins = ((e) - (s) + 1),               \
                .ngpps = ARRAY_SIZE(g),                 \
        }
 
+#define CNLLP_COMMUNITY(b, s, e, g)                    \
+       CNL_COMMUNITY(b, s, e, CNL_LP_HOSTSW_OWN, g)
+
+#define CNLH_COMMUNITY(b, s, e, g)                     \
+       CNL_COMMUNITY(b, s, e, CNL_H_HOSTSW_OWN, g)
+
 /* Cannon Lake-H */
 static const struct pinctrl_pin_desc cnlh_pins[] = {
        /* GPP_A */
@@ -379,7 +386,7 @@ static const struct intel_padgroup cnlh_community1_gpps[] = {
 static const struct intel_padgroup cnlh_community3_gpps[] = {
        CNL_GPP(0, 155, 178, 192),              /* GPP_K */
        CNL_GPP(1, 179, 202, 224),              /* GPP_H */
-       CNL_GPP(2, 203, 215, 258),              /* GPP_E */
+       CNL_GPP(2, 203, 215, 256),              /* GPP_E */
        CNL_GPP(3, 216, 239, 288),              /* GPP_F */
        CNL_GPP(4, 240, 248, CNL_NO_GPIO),      /* SPI */
 };
@@ -442,10 +449,10 @@ static const struct intel_function cnlh_functions[] = {
 };
 
 static const struct intel_community cnlh_communities[] = {
-       CNL_COMMUNITY(0, 0, 50, cnlh_community0_gpps),
-       CNL_COMMUNITY(1, 51, 154, cnlh_community1_gpps),
-       CNL_COMMUNITY(2, 155, 248, cnlh_community3_gpps),
-       CNL_COMMUNITY(3, 249, 298, cnlh_community4_gpps),
+       CNLH_COMMUNITY(0, 0, 50, cnlh_community0_gpps),
+       CNLH_COMMUNITY(1, 51, 154, cnlh_community1_gpps),
+       CNLH_COMMUNITY(2, 155, 248, cnlh_community3_gpps),
+       CNLH_COMMUNITY(3, 249, 298, cnlh_community4_gpps),
 };
 
 static const struct intel_pinctrl_soc_data cnlh_soc_data = {
@@ -803,9 +810,9 @@ static const struct intel_padgroup cnllp_community4_gpps[] = {
 };
 
 static const struct intel_community cnllp_communities[] = {
-       CNL_COMMUNITY(0, 0, 67, cnllp_community0_gpps),
-       CNL_COMMUNITY(1, 68, 180, cnllp_community1_gpps),
-       CNL_COMMUNITY(2, 181, 243, cnllp_community4_gpps),
+       CNLLP_COMMUNITY(0, 0, 67, cnllp_community0_gpps),
+       CNLLP_COMMUNITY(1, 68, 180, cnllp_community1_gpps),
+       CNLLP_COMMUNITY(2, 181, 243, cnllp_community4_gpps),
 };
 
 static const struct intel_pinctrl_soc_data cnllp_soc_data = {
index 62b009b27eda3979a9ff6957218f189c33392809..1ea3438ea67e925aa82b6e57e503efb72689fde3 100644 (file)
@@ -747,13 +747,63 @@ static const struct pinctrl_desc intel_pinctrl_desc = {
        .owner = THIS_MODULE,
 };
 
+/**
+ * intel_gpio_to_pin() - Translate from GPIO offset to pin number
+ * @pctrl: Pinctrl structure
+ * @offset: GPIO offset from gpiolib
+ * @commmunity: Community is filled here if not %NULL
+ * @padgrp: Pad group is filled here if not %NULL
+ *
+ * When coming through gpiolib irqchip, the GPIO offset is not
+ * automatically translated to pinctrl pin number. This function can be
+ * used to find out the corresponding pinctrl pin.
+ */
+static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
+                            const struct intel_community **community,
+                            const struct intel_padgroup **padgrp)
+{
+       int i;
+
+       for (i = 0; i < pctrl->ncommunities; i++) {
+               const struct intel_community *comm = &pctrl->communities[i];
+               int j;
+
+               for (j = 0; j < comm->ngpps; j++) {
+                       const struct intel_padgroup *pgrp = &comm->gpps[j];
+
+                       if (pgrp->gpio_base < 0)
+                               continue;
+
+                       if (offset >= pgrp->gpio_base &&
+                           offset < pgrp->gpio_base + pgrp->size) {
+                               int pin;
+
+                               pin = pgrp->base + offset - pgrp->gpio_base;
+                               if (community)
+                                       *community = comm;
+                               if (padgrp)
+                                       *padgrp = pgrp;
+
+                               return pin;
+                       }
+               }
+       }
+
+       return -EINVAL;
+}
+
 static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
        void __iomem *reg;
        u32 padcfg0;
+       int pin;
 
-       reg = intel_get_padcfg(pctrl, offset, PADCFG0);
+       pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+       if (pin < 0)
+               return -EINVAL;
+
+       reg = intel_get_padcfg(pctrl, pin, PADCFG0);
        if (!reg)
                return -EINVAL;
 
@@ -770,8 +820,13 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        unsigned long flags;
        void __iomem *reg;
        u32 padcfg0;
+       int pin;
 
-       reg = intel_get_padcfg(pctrl, offset, PADCFG0);
+       pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+       if (pin < 0)
+               return;
+
+       reg = intel_get_padcfg(pctrl, pin, PADCFG0);
        if (!reg)
                return;
 
@@ -790,8 +845,13 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
        struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
        void __iomem *reg;
        u32 padcfg0;
+       int pin;
 
-       reg = intel_get_padcfg(pctrl, offset, PADCFG0);
+       pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+       if (pin < 0)
+               return -EINVAL;
+
+       reg = intel_get_padcfg(pctrl, pin, PADCFG0);
        if (!reg)
                return -EINVAL;
 
@@ -827,81 +887,6 @@ static const struct gpio_chip intel_gpio_chip = {
        .set_config = gpiochip_generic_config,
 };
 
-/**
- * intel_gpio_to_pin() - Translate from GPIO offset to pin number
- * @pctrl: Pinctrl structure
- * @offset: GPIO offset from gpiolib
- * @commmunity: Community is filled here if not %NULL
- * @padgrp: Pad group is filled here if not %NULL
- *
- * When coming through gpiolib irqchip, the GPIO offset is not
- * automatically translated to pinctrl pin number. This function can be
- * used to find out the corresponding pinctrl pin.
- */
-static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
-                            const struct intel_community **community,
-                            const struct intel_padgroup **padgrp)
-{
-       int i;
-
-       for (i = 0; i < pctrl->ncommunities; i++) {
-               const struct intel_community *comm = &pctrl->communities[i];
-               int j;
-
-               for (j = 0; j < comm->ngpps; j++) {
-                       const struct intel_padgroup *pgrp = &comm->gpps[j];
-
-                       if (pgrp->gpio_base < 0)
-                               continue;
-
-                       if (offset >= pgrp->gpio_base &&
-                           offset < pgrp->gpio_base + pgrp->size) {
-                               int pin;
-
-                               pin = pgrp->base + offset - pgrp->gpio_base;
-                               if (community)
-                                       *community = comm;
-                               if (padgrp)
-                                       *padgrp = pgrp;
-
-                               return pin;
-                       }
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int intel_gpio_irq_reqres(struct irq_data *d)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
-       int pin;
-       int ret;
-
-       pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
-       if (pin >= 0) {
-               ret = gpiochip_lock_as_irq(gc, pin);
-               if (ret) {
-                       dev_err(pctrl->dev, "unable to lock HW IRQ %d for IRQ\n",
-                               pin);
-                       return ret;
-               }
-       }
-       return 0;
-}
-
-static void intel_gpio_irq_relres(struct irq_data *d)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
-       int pin;
-
-       pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
-       if (pin >= 0)
-               gpiochip_unlock_as_irq(gc, pin);
-}
-
 static void intel_gpio_irq_ack(struct irq_data *d)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -1117,8 +1102,6 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
 
 static struct irq_chip intel_gpio_irqchip = {
        .name = "intel-gpio",
-       .irq_request_resources = intel_gpio_irq_reqres,
-       .irq_release_resources = intel_gpio_irq_relres,
        .irq_enable = intel_gpio_irq_enable,
        .irq_ack = intel_gpio_irq_ack,
        .irq_mask = intel_gpio_irq_mask,
index 41ccc759b8b8867a09b992371eafafca35899a0e..1425c2874d4028b5140cc74933733a2bf4f8f22b 100644 (file)
@@ -348,21 +348,12 @@ static void amd_gpio_irq_enable(struct irq_data *d)
        unsigned long flags;
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
-       u32 mask = BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF);
 
        raw_spin_lock_irqsave(&gpio_dev->lock, flags);
        pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
        pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
        pin_reg |= BIT(INTERRUPT_MASK_OFF);
        writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
-       /*
-        * When debounce logic is enabled it takes ~900 us before interrupts
-        * can be enabled.  During this "debounce warm up" period the
-        * "INTERRUPT_ENABLE" bit will read as 0. Poll the bit here until it
-        * reads back as 1, signaling that interrupts are now enabled.
-        */
-       while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
-               continue;
        raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 }
 
@@ -426,7 +417,7 @@ static void amd_gpio_irq_eoi(struct irq_data *d)
 static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 {
        int ret = 0;
-       u32 pin_reg;
+       u32 pin_reg, pin_reg_irq_en, mask;
        unsigned long flags, irq_flags;
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
@@ -495,6 +486,28 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        }
 
        pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF;
+       /*
+        * If WAKE_INT_MASTER_REG.MaskStsEn is set, a software write to the
+        * debounce registers of any GPIO will block wake/interrupt status
+        * generation for *all* GPIOs for a lenght of time that depends on
+        * WAKE_INT_MASTER_REG.MaskStsLength[11:0].  During this period the
+        * INTERRUPT_ENABLE bit will read as 0.
+        *
+        * We temporarily enable irq for the GPIO whose configuration is
+        * changing, and then wait for it to read back as 1 to know when
+        * debounce has settled and then disable the irq again.
+        * We do this polling with the spinlock held to ensure other GPIO
+        * access routines do not read an incorrect value for the irq enable
+        * bit of other GPIOs.  We keep the GPIO masked while polling to avoid
+        * spurious irqs, and disable the irq again after polling.
+        */
+       mask = BIT(INTERRUPT_ENABLE_OFF);
+       pin_reg_irq_en = pin_reg;
+       pin_reg_irq_en |= mask;
+       pin_reg_irq_en &= ~BIT(INTERRUPT_MASK_OFF);
+       writel(pin_reg_irq_en, gpio_dev->base + (d->hwirq)*4);
+       while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
+               continue;
        writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
        raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
index 6a1b6058b9910269c60c448cbca3350bce399af6..628817c40e3bbc79cc1098368a23fc2d75e587e5 100644 (file)
@@ -793,7 +793,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
 
                err = pinctrl_generic_add_group(jzpc->pctl, group->name,
                                group->pins, group->num_pins, group->data);
-               if (err) {
+               if (err < 0) {
                        dev_err(dev, "Failed to register group %s\n",
                                        group->name);
                        return err;
@@ -806,7 +806,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
                err = pinmux_generic_add_function(jzpc->pctl, func->name,
                                func->group_names, func->num_group_names,
                                func->data);
-               if (err) {
+               if (err < 0) {
                        dev_err(dev, "Failed to register function %s\n",
                                        func->name);
                        return err;
index 2155a30c282b24e20ba440e1398e8d71b308647e..5d72ffad32c299eb2db1e24c5827a11a54a4084e 100644 (file)
@@ -634,6 +634,29 @@ static void msm_gpio_irq_mask(struct irq_data *d)
        raw_spin_lock_irqsave(&pctrl->lock, flags);
 
        val = readl(pctrl->regs + g->intr_cfg_reg);
+       /*
+        * There are two bits that control interrupt forwarding to the CPU. The
+        * RAW_STATUS_EN bit causes the level or edge sensed on the line to be
+        * latched into the interrupt status register when the hardware detects
+        * an irq that it's configured for (either edge for edge type or level
+        * for level type irq). The 'non-raw' status enable bit causes the
+        * hardware to assert the summary interrupt to the CPU if the latched
+        * status bit is set. There's a bug though, the edge detection logic
+        * seems to have a problem where toggling the RAW_STATUS_EN bit may
+        * cause the status bit to latch spuriously when there isn't any edge
+        * so we can't touch that bit for edge type irqs and we have to keep
+        * the bit set anyway so that edges are latched while the line is masked.
+        *
+        * To make matters more complicated, leaving the RAW_STATUS_EN bit
+        * enabled all the time causes level interrupts to re-latch into the
+        * status register because the level is still present on the line after
+        * we ack it. We clear the raw status enable bit during mask here and
+        * set the bit on unmask so the interrupt can't latch into the hardware
+        * while it's masked.
+        */
+       if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
+               val &= ~BIT(g->intr_raw_status_bit);
+
        val &= ~BIT(g->intr_enable_bit);
        writel(val, pctrl->regs + g->intr_cfg_reg);
 
@@ -655,6 +678,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
        raw_spin_lock_irqsave(&pctrl->lock, flags);
 
        val = readl(pctrl->regs + g->intr_cfg_reg);
+       val |= BIT(g->intr_raw_status_bit);
        val |= BIT(g->intr_enable_bit);
        writel(val, pctrl->regs + g->intr_cfg_reg);
 
index d975462a4c576748eb6163f512a607d4d3b8d19e..f10af5c383c551d7632d0e66b751792ae9dc7abd 100644 (file)
@@ -536,6 +536,7 @@ static acpi_status alienware_wmax_command(struct wmax_basic_args *in_args,
                if (obj && obj->type == ACPI_TYPE_INTEGER)
                        *out_data = (u32) obj->integer.value;
        }
+       kfree(output.pointer);
        return status;
 
 }
index 88afe5651d24aec8e1d30b748cd67f295d1558d5..cf2229ece9ff6f11cce316f2e51c8088c30053ec 100644 (file)
@@ -78,6 +78,7 @@ static int run_smbios_call(struct wmi_device *wdev)
        dev_dbg(&wdev->dev, "result: [%08x,%08x,%08x,%08x]\n",
                priv->buf->std.output[0], priv->buf->std.output[1],
                priv->buf->std.output[2], priv->buf->std.output[3]);
+       kfree(output.pointer);
 
        return 0;
 }
index 0f8ac8dec3e16a21e066e9f76318d14ec6c9d78f..a1bd8aaf4d983bcd8b8bdfa10ae944918fabeb75 100644 (file)
@@ -569,6 +569,25 @@ static int bd71837_probe(struct platform_device *pdev)
                        BD71837_REG_REGLOCK);
        }
 
+       /*
+        * There is a HW quirk in BD71837. The shutdown sequence timings for
+        * bucks/LDOs which are controlled via register interface are changed.
+        * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
+        * beginning of shut-down sequence. As bucks 6 and 7 are parent
+        * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
+        * monitoring to errorneously detect under voltage and force PMIC to
+        * emergency state instead of poweroff. In order to avoid this we
+        * disable voltage monitoring for LDO5 and LDO6
+        */
+       err = regmap_update_bits(pmic->mfd->regmap, BD718XX_REG_MVRFLTMASK2,
+                                BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80,
+                                BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80);
+       if (err) {
+               dev_err(&pmic->pdev->dev,
+                       "Failed to disable voltage monitoring\n");
+               goto err;
+       }
+
        for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
 
                struct regulator_desc *desc;
index bb1324f93143f66e609fea2602329230f70ed4ce..9577d89418468a06f1030ff69d2699f71b5710bc 100644 (file)
@@ -3161,7 +3161,7 @@ static inline int regulator_suspend_toggle(struct regulator_dev *rdev,
        if (!rstate->changeable)
                return -EPERM;
 
-       rstate->enabled = en;
+       rstate->enabled = (en) ? ENABLE_IN_SUSPEND : DISABLE_IN_SUSPEND;
 
        return 0;
 }
@@ -4395,13 +4395,13 @@ regulator_register(const struct regulator_desc *regulator_desc,
            !rdev->desc->fixed_uV)
                rdev->is_switch = true;
 
+       dev_set_drvdata(&rdev->dev, rdev);
        ret = device_register(&rdev->dev);
        if (ret != 0) {
                put_device(&rdev->dev);
                goto unset_supplies;
        }
 
-       dev_set_drvdata(&rdev->dev, rdev);
        rdev_init_debugfs(rdev);
 
        /* try to resolve regulators supply since a new one was registered */
index 638f17d4c8485e11fa7d0a9486fc3ec131a341cd..210fc20f7de7a9cd26dbbee68e24a7c0bc2dc94a 100644 (file)
@@ -213,8 +213,6 @@ static void of_get_regulation_constraints(struct device_node *np,
                else if (of_property_read_bool(suspend_np,
                                        "regulator-off-in-suspend"))
                        suspend_state->enabled = DISABLE_IN_SUSPEND;
-               else
-                       suspend_state->enabled = DO_NOTHING_IN_SUSPEND;
 
                if (!of_property_read_u32(np, "regulator-suspend-min-microvolt",
                                          &pval))
index ec891bc7d10a69b4aa2771ae3da4fc9f50028fa9..f039266b275dad7c31559e897f094a056a8c3c2c 100644 (file)
@@ -872,8 +872,6 @@ static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
        if (bits & 0x07)
                return -EINVAL;
 
-       memset(bitmap, 0, bits / 8);
-
        if (str[0] == '0' && str[1] == 'x')
                str++;
        if (*str == 'x')
@@ -895,25 +893,23 @@ static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
 }
 
 /*
- * str2clrsetmasks() - parse bitmask argument and set the clear and
- * the set bitmap mask. A concatenation (done with ',') of these terms
- * is recognized:
+ * modify_bitmap() - parse bitmask argument and modify an existing
+ * bit mask accordingly. A concatenation (done with ',') of these
+ * terms is recognized:
  *   +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]
  * <bitnr> may be any valid number (hex, decimal or octal) in the range
  * 0...bits-1; the leading + or - is required. Here are some examples:
  *   +0-15,+32,-128,-0xFF
  *   -0-255,+1-16,+0x128
  *   +1,+2,+3,+4,-5,-7-10
- * Returns a clear and a set bitmask. Every positive value in the string
- * results in a bit set in the set mask and every negative value in the
- * string results in a bit SET in the clear mask. As a bit may be touched
- * more than once, the last 'operation' wins: +0-255,-128 = all but bit
- * 128 set in the set mask, only bit 128 set in the clear mask.
+ * Returns the new bitmap after all changes have been applied. Every
+ * positive value in the string will set a bit and every negative value
+ * in the string will clear a bit. As a bit may be touched more than once,
+ * the last 'operation' wins:
+ * +0-255,-128 = first bits 0-255 will be set, then bit 128 will be
+ * cleared again. All other bits are unmodified.
  */
-static int str2clrsetmasks(const char *str,
-                          unsigned long *clrmap,
-                          unsigned long *setmap,
-                          int bits)
+static int modify_bitmap(const char *str, unsigned long *bitmap, int bits)
 {
        int a, i, z;
        char *np, sign;
@@ -922,9 +918,6 @@ static int str2clrsetmasks(const char *str,
        if (bits & 0x07)
                return -EINVAL;
 
-       memset(clrmap, 0, bits / 8);
-       memset(setmap, 0, bits / 8);
-
        while (*str) {
                sign = *str++;
                if (sign != '+' && sign != '-')
@@ -940,13 +933,10 @@ static int str2clrsetmasks(const char *str,
                        str = np;
                }
                for (i = a; i <= z; i++)
-                       if (sign == '+') {
-                               set_bit_inv(i, setmap);
-                               clear_bit_inv(i, clrmap);
-                       } else {
-                               clear_bit_inv(i, setmap);
-                               set_bit_inv(i, clrmap);
-                       }
+                       if (sign == '+')
+                               set_bit_inv(i, bitmap);
+                       else
+                               clear_bit_inv(i, bitmap);
                while (*str == ',' || *str == '\n')
                        str++;
        }
@@ -970,44 +960,34 @@ static int process_mask_arg(const char *str,
                            unsigned long *bitmap, int bits,
                            struct mutex *lock)
 {
-       int i;
+       unsigned long *newmap, size;
+       int rc;
 
        /* bits needs to be a multiple of 8 */
        if (bits & 0x07)
                return -EINVAL;
 
+       size = BITS_TO_LONGS(bits)*sizeof(unsigned long);
+       newmap = kmalloc(size, GFP_KERNEL);
+       if (!newmap)
+               return -ENOMEM;
+       if (mutex_lock_interruptible(lock)) {
+               kfree(newmap);
+               return -ERESTARTSYS;
+       }
+
        if (*str == '+' || *str == '-') {
-               DECLARE_BITMAP(clrm, bits);
-               DECLARE_BITMAP(setm, bits);
-
-               i = str2clrsetmasks(str, clrm, setm, bits);
-               if (i)
-                       return i;
-               if (mutex_lock_interruptible(lock))
-                       return -ERESTARTSYS;
-               for (i = 0; i < bits; i++) {
-                       if (test_bit_inv(i, clrm))
-                               clear_bit_inv(i, bitmap);
-                       if (test_bit_inv(i, setm))
-                               set_bit_inv(i, bitmap);
-               }
+               memcpy(newmap, bitmap, size);
+               rc = modify_bitmap(str, newmap, bits);
        } else {
-               DECLARE_BITMAP(setm, bits);
-
-               i = hex2bitmap(str, setm, bits);
-               if (i)
-                       return i;
-               if (mutex_lock_interruptible(lock))
-                       return -ERESTARTSYS;
-               for (i = 0; i < bits; i++)
-                       if (test_bit_inv(i, setm))
-                               set_bit_inv(i, bitmap);
-                       else
-                               clear_bit_inv(i, bitmap);
+               memset(newmap, 0, size);
+               rc = hex2bitmap(str, newmap, bits);
        }
+       if (rc == 0)
+               memcpy(bitmap, newmap, size);
        mutex_unlock(lock);
-
-       return 0;
+       kfree(newmap);
+       return rc;
 }
 
 /*
index 49f64eb3eab0f759d06a5e3edff6550a06d8af40..de8282420f966f0d0f984c72868d9ebddcf11207 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/netdevice.h>
 #include <linux/netdev_features.h>
 #include <linux/skbuff.h>
+#include <linux/vmalloc.h>
 
 #include <net/iucv/af_iucv.h>
 #include <net/dsfield.h>
@@ -4699,7 +4700,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
 
        priv.buffer_len = oat_data.buffer_len;
        priv.response_len = 0;
-       priv.buffer =  kzalloc(oat_data.buffer_len, GFP_KERNEL);
+       priv.buffer = vzalloc(oat_data.buffer_len);
        if (!priv.buffer) {
                rc = -ENOMEM;
                goto out;
@@ -4740,7 +4741,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
                        rc = -EFAULT;
 
 out_free:
-       kfree(priv.buffer);
+       vfree(priv.buffer);
 out:
        return rc;
 }
@@ -5706,6 +5707,8 @@ static struct net_device *qeth_alloc_netdev(struct qeth_card *card)
                dev->priv_flags &= ~IFF_TX_SKB_SHARING;
                dev->hw_features |= NETIF_F_SG;
                dev->vlan_features |= NETIF_F_SG;
+               if (IS_IQD(card))
+                       dev->features |= NETIF_F_SG;
        }
 
        return dev;
@@ -5768,8 +5771,10 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
        qeth_update_from_chp_desc(card);
 
        card->dev = qeth_alloc_netdev(card);
-       if (!card->dev)
+       if (!card->dev) {
+               rc = -ENOMEM;
                goto err_card;
+       }
 
        qeth_determine_capabilities(card);
        enforced_disc = qeth_enforce_discipline(card);
index 710fa74892ae55a65f3849147bb3986946c68bf8..b5e38531733f26e49a90158acf481744106dd42f 100644 (file)
@@ -423,7 +423,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
                default:
                        dev_kfree_skb_any(skb);
                        QETH_CARD_TEXT(card, 3, "inbunkno");
-                       QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
+                       QETH_DBF_HEX(CTRL, 3, hdr, sizeof(*hdr));
                        continue;
                }
                work_done++;
index 7175086677fb4be85cc41dd2748157e71986fd30..ada258c01a08e084b11d02d73e553404bfce82cb 100644 (file)
@@ -1390,7 +1390,7 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
                default:
                        dev_kfree_skb_any(skb);
                        QETH_CARD_TEXT(card, 3, "inbunkno");
-                       QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
+                       QETH_DBF_HEX(CTRL, 3, hdr, sizeof(*hdr));
                        continue;
                }
                work_done++;
index fac377320158d2a075978be6a8c96adea51e9305..f42a619198c46caa816c2e2ae6e6fef1cc4d959b 100644 (file)
@@ -3474,11 +3474,10 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
                vscsi->dds.window[LOCAL].liobn,
                vscsi->dds.window[REMOTE].liobn);
 
-       strcpy(vscsi->eye, "VSCSI ");
-       strncat(vscsi->eye, vdev->name, MAX_EYE);
+       snprintf(vscsi->eye, sizeof(vscsi->eye), "VSCSI %s", vdev->name);
 
        vscsi->dds.unit_id = vdev->unit_address;
-       strncpy(vscsi->dds.partition_name, partition_name,
+       strscpy(vscsi->dds.partition_name, partition_name,
                sizeof(vscsi->dds.partition_name));
        vscsi->dds.partition_num = partition_number;
 
index f2ec80b0ffc080d614909dab1040b34342769930..271990bc065b924dda965bc8ee777aface7a5b47 100644 (file)
@@ -3335,6 +3335,65 @@ static void ipr_release_dump(struct kref *kref)
        LEAVE;
 }
 
+static void ipr_add_remove_thread(struct work_struct *work)
+{
+       unsigned long lock_flags;
+       struct ipr_resource_entry *res;
+       struct scsi_device *sdev;
+       struct ipr_ioa_cfg *ioa_cfg =
+               container_of(work, struct ipr_ioa_cfg, scsi_add_work_q);
+       u8 bus, target, lun;
+       int did_work;
+
+       ENTER;
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+
+restart:
+       do {
+               did_work = 0;
+               if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                       return;
+               }
+
+               list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+                       if (res->del_from_ml && res->sdev) {
+                               did_work = 1;
+                               sdev = res->sdev;
+                               if (!scsi_device_get(sdev)) {
+                                       if (!res->add_to_ml)
+                                               list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+                                       else
+                                               res->del_from_ml = 0;
+                                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                                       scsi_remove_device(sdev);
+                                       scsi_device_put(sdev);
+                                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+                               }
+                               break;
+                       }
+               }
+       } while (did_work);
+
+       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+               if (res->add_to_ml) {
+                       bus = res->bus;
+                       target = res->target;
+                       lun = res->lun;
+                       res->add_to_ml = 0;
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                       scsi_add_device(ioa_cfg->host, bus, target, lun);
+                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+                       goto restart;
+               }
+       }
+
+       ioa_cfg->scan_done = 1;
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+       kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
+       LEAVE;
+}
+
 /**
  * ipr_worker_thread - Worker thread
  * @work:              ioa config struct
@@ -3349,13 +3408,9 @@ static void ipr_release_dump(struct kref *kref)
 static void ipr_worker_thread(struct work_struct *work)
 {
        unsigned long lock_flags;
-       struct ipr_resource_entry *res;
-       struct scsi_device *sdev;
        struct ipr_dump *dump;
        struct ipr_ioa_cfg *ioa_cfg =
                container_of(work, struct ipr_ioa_cfg, work_q);
-       u8 bus, target, lun;
-       int did_work;
 
        ENTER;
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -3393,49 +3448,9 @@ static void ipr_worker_thread(struct work_struct *work)
                return;
        }
 
-restart:
-       do {
-               did_work = 0;
-               if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
-                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-                       return;
-               }
+       schedule_work(&ioa_cfg->scsi_add_work_q);
 
-               list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-                       if (res->del_from_ml && res->sdev) {
-                               did_work = 1;
-                               sdev = res->sdev;
-                               if (!scsi_device_get(sdev)) {
-                                       if (!res->add_to_ml)
-                                               list_move_tail(&res->queue, &ioa_cfg->free_res_q);
-                                       else
-                                               res->del_from_ml = 0;
-                                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-                                       scsi_remove_device(sdev);
-                                       scsi_device_put(sdev);
-                                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-                               }
-                               break;
-                       }
-               }
-       } while (did_work);
-
-       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if (res->add_to_ml) {
-                       bus = res->bus;
-                       target = res->target;
-                       lun = res->lun;
-                       res->add_to_ml = 0;
-                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-                       scsi_add_device(ioa_cfg->host, bus, target, lun);
-                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-                       goto restart;
-               }
-       }
-
-       ioa_cfg->scan_done = 1;
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-       kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
        LEAVE;
 }
 
@@ -9933,6 +9948,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
        INIT_LIST_HEAD(&ioa_cfg->free_res_q);
        INIT_LIST_HEAD(&ioa_cfg->used_res_q);
        INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
+       INIT_WORK(&ioa_cfg->scsi_add_work_q, ipr_add_remove_thread);
        init_waitqueue_head(&ioa_cfg->reset_wait_q);
        init_waitqueue_head(&ioa_cfg->msi_wait_q);
        init_waitqueue_head(&ioa_cfg->eeh_wait_q);
index 68afbbde54d352f4c88cb4a3b5695ad3bd713ba0..f6baa23513139a53676b3f5005474cd419818098 100644 (file)
@@ -1575,6 +1575,7 @@ struct ipr_ioa_cfg {
        u8 saved_mode_page_len;
 
        struct work_struct work_q;
+       struct work_struct scsi_add_work_q;
        struct workqueue_struct *reset_work_q;
 
        wait_queue_head_t reset_wait_q;
index 057a60abe664d269af64a2e85a4cea2faf740cfc..1a6ed9b0a249397880b4fac46c36d3acd23fc613 100644 (file)
@@ -360,12 +360,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
                goto buffer_done;
 
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+               nrport = NULL;
+               spin_lock(&vport->phba->hbalock);
                rport = lpfc_ndlp_get_nrport(ndlp);
-               if (!rport)
-                       continue;
-
-               /* local short-hand pointer. */
-               nrport = rport->remoteport;
+               if (rport)
+                       nrport = rport->remoteport;
+               spin_unlock(&vport->phba->hbalock);
                if (!nrport)
                        continue;
 
@@ -3386,6 +3386,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
        struct lpfc_nodelist  *ndlp;
 #if (IS_ENABLED(CONFIG_NVME_FC))
        struct lpfc_nvme_rport *rport;
+       struct nvme_fc_remote_port *remoteport = NULL;
 #endif
 
        shost = lpfc_shost_from_vport(vport);
@@ -3396,8 +3397,12 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
                if (ndlp->rport)
                        ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
 #if (IS_ENABLED(CONFIG_NVME_FC))
+               spin_lock(&vport->phba->hbalock);
                rport = lpfc_ndlp_get_nrport(ndlp);
                if (rport)
+                       remoteport = rport->remoteport;
+               spin_unlock(&vport->phba->hbalock);
+               if (remoteport)
                        nvme_fc_set_remoteport_devloss(rport->remoteport,
                                                       vport->cfg_devloss_tmo);
 #endif
index 9df0c051349f68220cf19a4d6cacd6f236186f34..aec5b10a8c855ff9d37433afed149beddc670104 100644 (file)
@@ -551,7 +551,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
        unsigned char *statep;
        struct nvme_fc_local_port *localport;
        struct lpfc_nvmet_tgtport *tgtp;
-       struct nvme_fc_remote_port *nrport;
+       struct nvme_fc_remote_port *nrport = NULL;
        struct lpfc_nvme_rport *rport;
 
        cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
@@ -696,11 +696,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
        len += snprintf(buf + len, size - len, "\tRport List:\n");
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
                /* local short-hand pointer. */
+               spin_lock(&phba->hbalock);
                rport = lpfc_ndlp_get_nrport(ndlp);
-               if (!rport)
-                       continue;
-
-               nrport = rport->remoteport;
+               if (rport)
+                       nrport = rport->remoteport;
+               spin_unlock(&phba->hbalock);
                if (!nrport)
                        continue;
 
index 028462e5994d2ea9329d3cacd3845ff77f6cb013..918ae18ef8a8273f9385e2eb872947bac8a7275c 100644 (file)
@@ -2725,7 +2725,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
        rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
 
+       spin_lock_irq(&vport->phba->hbalock);
        oldrport = lpfc_ndlp_get_nrport(ndlp);
+       spin_unlock_irq(&vport->phba->hbalock);
        if (!oldrport)
                lpfc_nlp_get(ndlp);
 
@@ -2840,7 +2842,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        struct nvme_fc_local_port *localport;
        struct lpfc_nvme_lport *lport;
        struct lpfc_nvme_rport *rport;
-       struct nvme_fc_remote_port *remoteport;
+       struct nvme_fc_remote_port *remoteport = NULL;
 
        localport = vport->localport;
 
@@ -2854,11 +2856,14 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        if (!lport)
                goto input_err;
 
+       spin_lock_irq(&vport->phba->hbalock);
        rport = lpfc_ndlp_get_nrport(ndlp);
-       if (!rport)
+       if (rport)
+               remoteport = rport->remoteport;
+       spin_unlock_irq(&vport->phba->hbalock);
+       if (!remoteport)
                goto input_err;
 
-       remoteport = rport->remoteport;
        lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
                         "6033 Unreg nvme remoteport %p, portname x%llx, "
                         "port_id x%06x, portstate x%x port type x%x\n",
index fc3babc15fa3e9b423d7bdf23d64c960899322c0..a6f96b35e971ea52b0f3508308f7ff2b7c056be7 100644 (file)
@@ -77,6 +77,11 @@ enum qedi_nvm_tgts {
        QEDI_NVM_TGT_SEC,
 };
 
+struct qedi_nvm_iscsi_image {
+       struct nvm_iscsi_cfg iscsi_cfg;
+       u32 crc;
+};
+
 struct qedi_uio_ctrl {
        /* meta data */
        u32 uio_hsi_version;
@@ -294,7 +299,7 @@ struct qedi_ctx {
        void *bdq_pbl_list;
        dma_addr_t bdq_pbl_list_dma;
        u8 bdq_pbl_list_num_entries;
-       struct nvm_iscsi_cfg *iscsi_cfg;
+       struct qedi_nvm_iscsi_image *iscsi_image;
        dma_addr_t nvm_buf_dma;
        void __iomem *bdq_primary_prod;
        void __iomem *bdq_secondary_prod;
index aa96bccb5a9645d1b43f6fae77543a56dd89f58b..cc8e64dc65ad896d8d5ce3e7fa7495d88d95ccfb 100644 (file)
@@ -1346,23 +1346,26 @@ static int qedi_setup_int(struct qedi_ctx *qedi)
 
 static void qedi_free_nvm_iscsi_cfg(struct qedi_ctx *qedi)
 {
-       if (qedi->iscsi_cfg)
+       if (qedi->iscsi_image)
                dma_free_coherent(&qedi->pdev->dev,
-                                 sizeof(struct nvm_iscsi_cfg),
-                                 qedi->iscsi_cfg, qedi->nvm_buf_dma);
+                                 sizeof(struct qedi_nvm_iscsi_image),
+                                 qedi->iscsi_image, qedi->nvm_buf_dma);
 }
 
 static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi)
 {
-       qedi->iscsi_cfg = dma_zalloc_coherent(&qedi->pdev->dev,
-                                            sizeof(struct nvm_iscsi_cfg),
-                                            &qedi->nvm_buf_dma, GFP_KERNEL);
-       if (!qedi->iscsi_cfg) {
+       struct qedi_nvm_iscsi_image nvm_image;
+
+       qedi->iscsi_image = dma_zalloc_coherent(&qedi->pdev->dev,
+                                               sizeof(nvm_image),
+                                               &qedi->nvm_buf_dma,
+                                               GFP_KERNEL);
+       if (!qedi->iscsi_image) {
                QEDI_ERR(&qedi->dbg_ctx, "Could not allocate NVM BUF.\n");
                return -ENOMEM;
        }
        QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
-                 "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_cfg,
+                 "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_image,
                  qedi->nvm_buf_dma);
 
        return 0;
@@ -1905,7 +1908,7 @@ qedi_get_nvram_block(struct qedi_ctx *qedi)
        struct nvm_iscsi_block *block;
 
        pf = qedi->dev_info.common.abs_pf_id;
-       block = &qedi->iscsi_cfg->block[0];
+       block = &qedi->iscsi_image->iscsi_cfg.block[0];
        for (i = 0; i < NUM_OF_ISCSI_PF_SUPPORTED; i++, block++) {
                flags = ((block->id) & NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK) >>
                        NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET;
@@ -2194,15 +2197,14 @@ static void qedi_boot_release(void *data)
 static int qedi_get_boot_info(struct qedi_ctx *qedi)
 {
        int ret = 1;
-       u16 len;
-
-       len = sizeof(struct nvm_iscsi_cfg);
+       struct qedi_nvm_iscsi_image nvm_image;
 
        QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
                  "Get NVM iSCSI CFG image\n");
        ret = qedi_ops->common->nvm_get_image(qedi->cdev,
                                              QED_NVM_IMAGE_ISCSI_CFG,
-                                             (char *)qedi->iscsi_cfg, len);
+                                             (char *)qedi->iscsi_image,
+                                             sizeof(nvm_image));
        if (ret)
                QEDI_ERR(&qedi->dbg_ctx,
                         "Could not get NVM image. ret = %d\n", ret);
index fecf96f0225c6e2b010cb5e6e2411d1c00540ab7..199d3ba1916d5ef5b302e762f4d4e29a33066413 100644 (file)
@@ -374,8 +374,8 @@ struct atio_from_isp {
 static inline int fcpcmd_is_corrupted(struct atio *atio)
 {
        if (atio->entry_type == ATIO_TYPE7 &&
-           (le16_to_cpu(atio->attr_n_length & FCP_CMD_LENGTH_MASK) <
-           FCP_CMD_LENGTH_MIN))
+           ((le16_to_cpu(atio->attr_n_length) & FCP_CMD_LENGTH_MASK) <
+            FCP_CMD_LENGTH_MIN))
                return 1;
        else
                return 0;
index b79b366a94f7993d2dc83c2b0c757c70ed753e75..4a57ffecc7e616fd2bcc4a7897996994deec1543 100644 (file)
@@ -1276,7 +1276,8 @@ static int sd_init_command(struct scsi_cmnd *cmd)
        case REQ_OP_ZONE_RESET:
                return sd_zbc_setup_reset_cmnd(cmd);
        default:
-               BUG();
+               WARN_ON_ONCE(1);
+               return BLKPREP_KILL;
        }
 }
 
@@ -2959,6 +2960,9 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
        if (rot == 1) {
                blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
                blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
+       } else {
+               blk_queue_flag_clear(QUEUE_FLAG_NONROT, q);
+               blk_queue_flag_set(QUEUE_FLAG_ADD_RANDOM, q);
        }
 
        if (sdkp->device->type == TYPE_ZBC) {
index 9d5d2ca7fc4ff6648127abdbd32947dec5182dee..c55f38ec391ca7d07e5ae1714168596f64acb125 100644 (file)
@@ -7940,6 +7940,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
                err = -ENOMEM;
                goto out_error;
        }
+
+       /*
+        * Do not use blk-mq at this time because blk-mq does not support
+        * runtime pm.
+        */
+       host->use_blk_mq = false;
+
        hba = shost_priv(host);
        hba->host = host;
        hba->dev = dev;
index 4b5e250e86159f5585205498b8029d85abf39879..e5c7e1ef63188914bfc655b1d187da5fa44166a1 100644 (file)
@@ -899,9 +899,10 @@ static void sdw_release_master_stream(struct sdw_stream_runtime *stream)
        struct sdw_master_runtime *m_rt = stream->m_rt;
        struct sdw_slave_runtime *s_rt, *_s_rt;
 
-       list_for_each_entry_safe(s_rt, _s_rt,
-                       &m_rt->slave_rt_list, m_rt_node)
-               sdw_stream_remove_slave(s_rt->slave, stream);
+       list_for_each_entry_safe(s_rt, _s_rt, &m_rt->slave_rt_list, m_rt_node) {
+               sdw_slave_port_release(s_rt->slave->bus, s_rt->slave, stream);
+               sdw_release_slave_stream(s_rt->slave, stream);
+       }
 
        list_del(&m_rt->bus_node);
 }
@@ -1112,7 +1113,7 @@ int sdw_stream_add_master(struct sdw_bus *bus,
                                "Master runtime config failed for stream:%s",
                                stream->name);
                ret = -ENOMEM;
-               goto error;
+               goto unlock;
        }
 
        ret = sdw_config_stream(bus->dev, stream, stream_config, false);
@@ -1123,11 +1124,11 @@ int sdw_stream_add_master(struct sdw_bus *bus,
        if (ret)
                goto stream_error;
 
-       stream->state = SDW_STREAM_CONFIGURED;
+       goto unlock;
 
 stream_error:
        sdw_release_master_stream(stream);
-error:
+unlock:
        mutex_unlock(&bus->bus_lock);
        return ret;
 }
@@ -1141,6 +1142,10 @@ EXPORT_SYMBOL(sdw_stream_add_master);
  * @stream: SoundWire stream
  * @port_config: Port configuration for audio stream
  * @num_ports: Number of ports
+ *
+ * It is expected that Slave is added before adding Master
+ * to the Stream.
+ *
  */
 int sdw_stream_add_slave(struct sdw_slave *slave,
                struct sdw_stream_config *stream_config,
@@ -1186,6 +1191,12 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
        if (ret)
                goto stream_error;
 
+       /*
+        * Change stream state to CONFIGURED on first Slave add.
+        * Bus is not aware of number of Slave(s) in a stream at this
+        * point so cannot depend on all Slave(s) to be added in order to
+        * change stream state to CONFIGURED.
+        */
        stream->state = SDW_STREAM_CONFIGURED;
        goto error;
 
index 7cb3ab0a35a009f619ced0409f449e308fd51096..3082e72e4f6c62ed00651e389381ee2896336c52 100644 (file)
 
 #define DRIVER_NAME "fsl-dspi"
 
+#ifdef CONFIG_M5441x
+#define DSPI_FIFO_SIZE                 16
+#else
 #define DSPI_FIFO_SIZE                 4
+#endif
 #define DSPI_DMA_BUFSIZE               (DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR                0x00
@@ -623,9 +627,11 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
 static void dspi_eoq_write(struct fsl_dspi *dspi)
 {
        int fifo_size = DSPI_FIFO_SIZE;
+       u16 xfer_cmd = dspi->tx_cmd;
 
        /* Fill TX FIFO with as many transfers as possible */
        while (dspi->len && fifo_size--) {
+               dspi->tx_cmd = xfer_cmd;
                /* Request EOQF for last transfer in FIFO */
                if (dspi->len == dspi->bytes_per_word || fifo_size == 0)
                        dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ;
index 0626e6e3ea0c05dee66e177aa4d2a0c75b703247..421bfc7dda67413bd72ae96055c3767d01a33fa7 100644 (file)
@@ -300,8 +300,8 @@ static int spi_gpio_request(struct device *dev,
                *mflags |= SPI_MASTER_NO_RX;
 
        spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
-       if (IS_ERR(spi_gpio->mosi))
-               return PTR_ERR(spi_gpio->mosi);
+       if (IS_ERR(spi_gpio->sck))
+               return PTR_ERR(spi_gpio->sck);
 
        for (i = 0; i < num_chipselects; i++) {
                spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
index 95dc4d78618df29c2b15d92fa6d11e3b84bb7ed1..b37de1d991d6abe1e0a25c5fffcf04d9851aba3e 100644 (file)
@@ -598,11 +598,13 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
 
        ret = wait_event_interruptible_timeout(rspi->wait,
                                               rspi->dma_callbacked, HZ);
-       if (ret > 0 && rspi->dma_callbacked)
+       if (ret > 0 && rspi->dma_callbacked) {
                ret = 0;
-       else if (!ret) {
-               dev_err(&rspi->master->dev, "DMA timeout\n");
-               ret = -ETIMEDOUT;
+       } else {
+               if (!ret) {
+                       dev_err(&rspi->master->dev, "DMA timeout\n");
+                       ret = -ETIMEDOUT;
+               }
                if (tx)
                        dmaengine_terminate_all(rspi->master->dma_tx);
                if (rx)
@@ -1350,12 +1352,36 @@ static const struct platform_device_id spi_driver_ids[] = {
 
 MODULE_DEVICE_TABLE(platform, spi_driver_ids);
 
+#ifdef CONFIG_PM_SLEEP
+static int rspi_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rspi_data *rspi = platform_get_drvdata(pdev);
+
+       return spi_master_suspend(rspi->master);
+}
+
+static int rspi_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rspi_data *rspi = platform_get_drvdata(pdev);
+
+       return spi_master_resume(rspi->master);
+}
+
+static SIMPLE_DEV_PM_OPS(rspi_pm_ops, rspi_suspend, rspi_resume);
+#define DEV_PM_OPS     &rspi_pm_ops
+#else
+#define DEV_PM_OPS     NULL
+#endif /* CONFIG_PM_SLEEP */
+
 static struct platform_driver rspi_driver = {
        .probe =        rspi_probe,
        .remove =       rspi_remove,
        .id_table =     spi_driver_ids,
        .driver         = {
                .name = "renesas_spi",
+               .pm = DEV_PM_OPS,
                .of_match_table = of_match_ptr(rspi_of_match),
        },
 };
index 539d6d1a277a6179f7053698cbee772083354828..101cd6aae2ea520afcac89671071cdabe2341f8f 100644 (file)
@@ -397,7 +397,8 @@ static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,
 
 static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p)
 {
-       sh_msiof_write(p, STR, sh_msiof_read(p, STR));
+       sh_msiof_write(p, STR,
+                      sh_msiof_read(p, STR) & ~(STR_TDREQ | STR_RDREQ));
 }
 
 static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p,
@@ -1426,12 +1427,37 @@ static const struct platform_device_id spi_driver_ids[] = {
 };
 MODULE_DEVICE_TABLE(platform, spi_driver_ids);
 
+#ifdef CONFIG_PM_SLEEP
+static int sh_msiof_spi_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
+
+       return spi_master_suspend(p->master);
+}
+
+static int sh_msiof_spi_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
+
+       return spi_master_resume(p->master);
+}
+
+static SIMPLE_DEV_PM_OPS(sh_msiof_spi_pm_ops, sh_msiof_spi_suspend,
+                        sh_msiof_spi_resume);
+#define DEV_PM_OPS     &sh_msiof_spi_pm_ops
+#else
+#define DEV_PM_OPS     NULL
+#endif /* CONFIG_PM_SLEEP */
+
 static struct platform_driver sh_msiof_spi_drv = {
        .probe          = sh_msiof_spi_probe,
        .remove         = sh_msiof_spi_remove,
        .id_table       = spi_driver_ids,
        .driver         = {
                .name           = "spi_sh_msiof",
+               .pm             = DEV_PM_OPS,
                .of_match_table = of_match_ptr(sh_msiof_match),
        },
 };
index 6f7b946b5cedf103cbed9886d7ec3079bbdcf6de..1427f343b39a3dc4468e14c3612814508993b3c0 100644 (file)
@@ -1063,6 +1063,24 @@ static int tegra_slink_probe(struct platform_device *pdev)
                goto exit_free_master;
        }
 
+       /* disabled clock may cause interrupt storm upon request */
+       tspi->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(tspi->clk)) {
+               ret = PTR_ERR(tspi->clk);
+               dev_err(&pdev->dev, "Can not get clock %d\n", ret);
+               goto exit_free_master;
+       }
+       ret = clk_prepare(tspi->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Clock prepare failed %d\n", ret);
+               goto exit_free_master;
+       }
+       ret = clk_enable(tspi->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Clock enable failed %d\n", ret);
+               goto exit_free_master;
+       }
+
        spi_irq = platform_get_irq(pdev, 0);
        tspi->irq = spi_irq;
        ret = request_threaded_irq(tspi->irq, tegra_slink_isr,
@@ -1071,14 +1089,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
                                        tspi->irq);
-               goto exit_free_master;
-       }
-
-       tspi->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(tspi->clk)) {
-               dev_err(&pdev->dev, "can not get clock\n");
-               ret = PTR_ERR(tspi->clk);
-               goto exit_free_irq;
+               goto exit_clk_disable;
        }
 
        tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
@@ -1138,6 +1149,8 @@ static int tegra_slink_probe(struct platform_device *pdev)
        tegra_slink_deinit_dma_param(tspi, true);
 exit_free_irq:
        free_irq(spi_irq, tspi);
+exit_clk_disable:
+       clk_disable(tspi->clk);
 exit_free_master:
        spi_master_put(master);
        return ret;
@@ -1150,6 +1163,8 @@ static int tegra_slink_remove(struct platform_device *pdev)
 
        free_irq(tspi->irq, tspi);
 
+       clk_disable(tspi->clk);
+
        if (tspi->tx_dma_chan)
                tegra_slink_deinit_dma_param(tspi, false);
 
index ec395a6baf9cacbae1830cf062fb40ae7e778f62..9da0bc5a036cfff6af0395ace48cad20ae9852d6 100644 (file)
@@ -2143,8 +2143,17 @@ int spi_register_controller(struct spi_controller *ctlr)
         */
        if (ctlr->num_chipselect == 0)
                return -EINVAL;
-       /* allocate dynamic bus number using Linux idr */
-       if ((ctlr->bus_num < 0) && ctlr->dev.of_node) {
+       if (ctlr->bus_num >= 0) {
+               /* devices with a fixed bus num must check-in with the num */
+               mutex_lock(&board_lock);
+               id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num,
+                       ctlr->bus_num + 1, GFP_KERNEL);
+               mutex_unlock(&board_lock);
+               if (WARN(id < 0, "couldn't get idr"))
+                       return id == -ENOSPC ? -EBUSY : id;
+               ctlr->bus_num = id;
+       } else if (ctlr->dev.of_node) {
+               /* allocate dynamic bus number using Linux idr */
                id = of_alias_get_id(ctlr->dev.of_node, "spi");
                if (id >= 0) {
                        ctlr->bus_num = id;
index 96f614934df12f75aebd943cc229fb60a25e826c..663b755bf2fbf1d5b2afb6a8991d78a8b7bcf799 100644 (file)
@@ -2,7 +2,7 @@
 
 config EROFS_FS
        tristate "EROFS filesystem support"
-       depends on BROKEN
+       depends on BLOCK
        help
          EROFS(Enhanced Read-Only File System) is a lightweight
          read-only file system with modern designs (eg. page-sized
index 1aec509c805feddf35b9db78e2db78bdcd5b00fd..2df9768edac96d1dc199071698558c6fb1e5da5d 100644 (file)
@@ -340,7 +340,7 @@ static int erofs_read_super(struct super_block *sb,
                goto err_sbread;
 
        sb->s_magic = EROFS_SUPER_MAGIC;
-       sb->s_flags |= MS_RDONLY | MS_NOATIME;
+       sb->s_flags |= SB_RDONLY | SB_NOATIME;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        sb->s_time_gran = 1;
 
@@ -627,7 +627,7 @@ static int erofs_remount(struct super_block *sb, int *flags, char *data)
 {
        BUG_ON(!sb_rdonly(sb));
 
-       *flags |= MS_RDONLY;
+       *flags |= SB_RDONLY;
        return 0;
 }
 
index 7e64c7e438f04c527cd730b4853321968d32f94a..a9f4802bb6bec4a6d0570c8a6917962b849bafd4 100644 (file)
@@ -2,3 +2,7 @@
   GPIO descriptor API in <linux/gpio/consumer.h> and look up GPIO
   lines from device tree, ACPI or board files, board files should
   use <linux/gpio/machine.h>
+
+* convert all these over to drm_simple_display_pipe and submit for inclusion
+  into the DRM subsystem under drivers/gpu/drm - fbdev doesn't take any new
+  drivers anymore.
index 6ff8e01b04cc8f190c2edf08cd4e3ebd35b6aa07..5b1865f8af2d9f46014451e0da4ecc9b3b423c03 100644 (file)
@@ -1,9 +1,22 @@
 This is a list of things that need to be done to get this driver out of the
 staging directory.
+
+- Implement the gasket framework's functionality through UIO instead of
+  introducing a new user-space drivers framework that is quite similar.
+
+  UIO provides the necessary bits to implement user-space drivers. Meanwhile
+  the gasket APIs adds some extra conveniences like PCI BAR mapping, and
+  MSI interrupts. Add these features to the UIO subsystem, then re-implement
+  the Apex driver as a basic UIO driver instead (include/linux/uio_driver.h)
+
 - Document sysfs files with Documentation/ABI/ entries.
+
 - Use misc interface instead of major number for driver version description.
+
 - Add descriptions of module_param's
+
 - apex_get_status() should actually check status.
+
 - "drivers" should never be dealing with "raw" sysfs calls or mess around with
   kobjects at all. The driver core should handle all of this for you
   automaically. There should not be a need for raw attribute macros.
index f48e06a03cdbf621a8951f50dc38ea95ef5fce77..9a58aaf72edd6978dea5930f33789386bd3266aa 100644 (file)
@@ -1,9 +1,3 @@
-config SOC_CAMERA_IMX074
-       tristate "imx074 support (DEPRECATED)"
-       depends on SOC_CAMERA && I2C
-       help
-         This driver supports IMX074 cameras from Sony
-
 config SOC_CAMERA_MT9T031
        tristate "mt9t031 support (DEPRECATED)"
        depends on SOC_CAMERA && I2C
index da92c493f1577ab7d35da20c73dd70f052fffc77..69cc508af1bce1aa52e244f74b2628fcdba35eb9 100644 (file)
@@ -59,6 +59,11 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                ret = PTR_ERR(dev);
                goto err_drv_alloc;
        }
+
+       ret = pci_enable_device(pdev);
+       if (ret)
+               goto err_pci_enable;
+
        dev->pdev = pdev;
        pci_set_drvdata(pdev, dev);
 
@@ -75,6 +80,8 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  err_drv_dev_register:
        vbox_driver_unload(dev);
  err_vbox_driver_load:
+       pci_disable_device(pdev);
+ err_pci_enable:
        drm_dev_put(dev);
  err_drv_alloc:
        return ret;
index a83eac8668d02f009044ccd491ea5aa3091874a7..79836c8fb909d6851ed1edb014146aae07326ea0 100644 (file)
@@ -323,6 +323,11 @@ static int vbox_crtc_page_flip(struct drm_crtc *crtc,
        if (rc)
                return rc;
 
+       mutex_lock(&vbox->hw_mutex);
+       vbox_set_view(crtc);
+       vbox_do_modeset(crtc, &crtc->mode);
+       mutex_unlock(&vbox->hw_mutex);
+
        spin_lock_irqsave(&drm->event_lock, flags);
 
        if (event)
index f7b07c0b5ce2ece87b057d8257a2ae225f8854cb..ee7e26b886a563e8743d6fdf4a3948de9eaec453 100644 (file)
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_WILC1000) += wilc1000.o
 
 ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
                -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
@@ -11,9 +12,7 @@ wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
                        wilc_wlan.o
 
 obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
-wilc1000-sdio-objs += $(wilc1000-objs)
 wilc1000-sdio-objs += wilc_sdio.o
 
 obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o
-wilc1000-spi-objs += $(wilc1000-objs)
 wilc1000-spi-objs += wilc_spi.o
index 01cf4bd2e192da2069a27784d1769e36c7affdc8..3b8d237decbf179b7016242583909fc46146c99c 100644 (file)
@@ -1038,8 +1038,8 @@ void wilc_netdev_cleanup(struct wilc *wilc)
        }
 
        kfree(wilc);
-       wilc_debugfs_remove();
 }
+EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
 
 static const struct net_device_ops wilc_netdev_ops = {
        .ndo_init = mac_init_fn,
@@ -1062,7 +1062,6 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
        if (!wl)
                return -ENOMEM;
 
-       wilc_debugfs_init();
        *wilc = wl;
        wl->io_type = io_type;
        wl->hif_func = ops;
@@ -1124,3 +1123,6 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(wilc_netdev_init);
+
+MODULE_LICENSE("GPL");
index edc72876458de06448543de1f1d571a561e37642..8001df66b8c26fd06bee036a0997cb2da4f1d74c 100644 (file)
@@ -19,6 +19,7 @@ static struct dentry *wilc_dir;
 
 #define DBG_LEVEL_ALL  (DEBUG | INFO | WRN | ERR)
 static atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
+EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
 
 static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf,
                                     size_t count, loff_t *ppos)
@@ -87,7 +88,7 @@ static struct wilc_debugfs_info_t debugfs_info[] = {
        },
 };
 
-int wilc_debugfs_init(void)
+static int __init wilc_debugfs_init(void)
 {
        int i;
        struct wilc_debugfs_info_t *info;
@@ -103,10 +104,12 @@ int wilc_debugfs_init(void)
        }
        return 0;
 }
+module_init(wilc_debugfs_init);
 
-void wilc_debugfs_remove(void)
+static void __exit wilc_debugfs_remove(void)
 {
        debugfs_remove_recursive(wilc_dir);
 }
+module_exit(wilc_debugfs_remove);
 
 #endif
index 6787b6e9f124379bc1aa02bdd4eea44c9263256b..8b184aa30d25d958dab26ddd1adc73583965debd 100644 (file)
@@ -417,6 +417,7 @@ void chip_allow_sleep(struct wilc *wilc)
        wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0));
        wilc->hif_func->hif_write_reg(wilc, 0xfa, 0);
 }
+EXPORT_SYMBOL_GPL(chip_allow_sleep);
 
 void chip_wakeup(struct wilc *wilc)
 {
@@ -471,6 +472,7 @@ void chip_wakeup(struct wilc *wilc)
        }
        chip_ps_state = CHIP_WAKEDUP;
 }
+EXPORT_SYMBOL_GPL(chip_wakeup);
 
 void wilc_chip_sleep_manually(struct wilc *wilc)
 {
@@ -484,6 +486,7 @@ void wilc_chip_sleep_manually(struct wilc *wilc)
        chip_ps_state = CHIP_SLEEPING_MANUAL;
        release_bus(wilc, RELEASE_ONLY);
 }
+EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually);
 
 void host_wakeup_notify(struct wilc *wilc)
 {
@@ -491,6 +494,7 @@ void host_wakeup_notify(struct wilc *wilc)
        wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1);
        release_bus(wilc, RELEASE_ONLY);
 }
+EXPORT_SYMBOL_GPL(host_wakeup_notify);
 
 void host_sleep_notify(struct wilc *wilc)
 {
@@ -498,6 +502,7 @@ void host_sleep_notify(struct wilc *wilc)
        wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1);
        release_bus(wilc, RELEASE_ONLY);
 }
+EXPORT_SYMBOL_GPL(host_sleep_notify);
 
 int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
 {
@@ -871,6 +876,7 @@ void wilc_handle_isr(struct wilc *wilc)
 
        release_bus(wilc, RELEASE_ALLOW_SLEEP);
 }
+EXPORT_SYMBOL_GPL(wilc_handle_isr);
 
 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
                                u32 buffer_size)
index 00d13b153f8045e047e321a42f37a46d5f9ed9ef..b81a73b9bd67e674a9a45ce785708e775edb5d01 100644 (file)
@@ -831,6 +831,4 @@ struct wilc;
 int wilc_wlan_init(struct net_device *dev);
 u32 wilc_get_chipid(struct wilc *wilc, bool update);
 
-int wilc_debugfs_init(void);
-void wilc_debugfs_remove(void);
 #endif
index 94bad43c41ffc2c7c33c1d3b48b0f0773fd87aa6..cc756a123fd8c33f8ccfcad75edd783efb15698d 100644 (file)
@@ -1416,7 +1416,8 @@ static void iscsit_do_crypto_hash_buf(struct ahash_request *hash,
 
        sg_init_table(sg, ARRAY_SIZE(sg));
        sg_set_buf(sg, buf, payload_length);
-       sg_set_buf(sg + 1, pad_bytes, padding);
+       if (padding)
+               sg_set_buf(sg + 1, pad_bytes, padding);
 
        ahash_request_set_crypt(hash, sg, data_crc, payload_length + padding);
 
@@ -3910,10 +3911,14 @@ static bool iscsi_target_check_conn_state(struct iscsi_conn *conn)
 static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
 {
        int ret;
-       u8 buffer[ISCSI_HDR_LEN], opcode;
+       u8 *buffer, opcode;
        u32 checksum = 0, digest = 0;
        struct kvec iov;
 
+       buffer = kcalloc(ISCSI_HDR_LEN, sizeof(*buffer), GFP_KERNEL);
+       if (!buffer)
+               return;
+
        while (!kthread_should_stop()) {
                /*
                 * Ensure that both TX and RX per connection kthreads
@@ -3921,7 +3926,6 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
                 */
                iscsit_thread_check_cpumask(conn, current, 0);
 
-               memset(buffer, 0, ISCSI_HDR_LEN);
                memset(&iov, 0, sizeof(struct kvec));
 
                iov.iov_base    = buffer;
@@ -3930,7 +3934,7 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
                ret = rx_data(conn, &iov, 1, ISCSI_HDR_LEN);
                if (ret != ISCSI_HDR_LEN) {
                        iscsit_rx_thread_wait_for_tcp(conn);
-                       return;
+                       break;
                }
 
                if (conn->conn_ops->HeaderDigest) {
@@ -3940,7 +3944,7 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
                        ret = rx_data(conn, &iov, 1, ISCSI_CRC_LEN);
                        if (ret != ISCSI_CRC_LEN) {
                                iscsit_rx_thread_wait_for_tcp(conn);
-                               return;
+                               break;
                        }
 
                        iscsit_do_crypto_hash_buf(conn->conn_rx_hash, buffer,
@@ -3964,7 +3968,7 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
                }
 
                if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)
-                       return;
+                       break;
 
                opcode = buffer[0] & ISCSI_OPCODE_MASK;
 
@@ -3975,13 +3979,15 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
                        " while in Discovery Session, rejecting.\n", opcode);
                        iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
                                          buffer);
-                       return;
+                       break;
                }
 
                ret = iscsi_target_rx_opcode(conn, buffer);
                if (ret < 0)
-                       return;
+                       break;
        }
+
+       kfree(buffer);
 }
 
 int iscsi_target_rx_thread(void *arg)
@@ -4208,22 +4214,15 @@ int iscsit_close_connection(
                crypto_free_ahash(tfm);
        }
 
-       free_cpumask_var(conn->conn_cpumask);
-
-       kfree(conn->conn_ops);
-       conn->conn_ops = NULL;
-
        if (conn->sock)
                sock_release(conn->sock);
 
        if (conn->conn_transport->iscsit_free_conn)
                conn->conn_transport->iscsit_free_conn(conn);
 
-       iscsit_put_transport(conn->conn_transport);
-
        pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
        conn->conn_state = TARG_CONN_STATE_FREE;
-       kfree(conn);
+       iscsit_free_conn(conn);
 
        spin_lock_bh(&sess->conn_lock);
        atomic_dec(&sess->nconn);
index 9518ffd8b8bac81cc1b725046857d5f229e58b15..4e680d753941f71ea299d87b6c0cd18fc307b50f 100644 (file)
 #include "iscsi_target_nego.h"
 #include "iscsi_target_auth.h"
 
-static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len)
-{
-       int j = DIV_ROUND_UP(len, 2), rc;
-
-       rc = hex2bin(dst, src, j);
-       if (rc < 0)
-               pr_debug("CHAP string contains non hex digit symbols\n");
-
-       dst[j] = '\0';
-       return j;
-}
-
-static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len)
-{
-       int i;
-
-       for (i = 0; i < src_len; i++) {
-               sprintf(&dst[i*2], "%02x", (int) src[i] & 0xff);
-       }
-}
-
 static int chap_gen_challenge(
        struct iscsi_conn *conn,
        int caller,
@@ -62,7 +41,7 @@ static int chap_gen_challenge(
        ret = get_random_bytes_wait(chap->challenge, CHAP_CHALLENGE_LENGTH);
        if (unlikely(ret))
                return ret;
-       chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge,
+       bin2hex(challenge_asciihex, chap->challenge,
                                CHAP_CHALLENGE_LENGTH);
        /*
         * Set CHAP_C, and copy the generated challenge into c_str.
@@ -248,9 +227,16 @@ static int chap_server_compute_md5(
                pr_err("Could not find CHAP_R.\n");
                goto out;
        }
+       if (strlen(chap_r) != MD5_SIGNATURE_SIZE * 2) {
+               pr_err("Malformed CHAP_R\n");
+               goto out;
+       }
+       if (hex2bin(client_digest, chap_r, MD5_SIGNATURE_SIZE) < 0) {
+               pr_err("Malformed CHAP_R\n");
+               goto out;
+       }
 
        pr_debug("[server] Got CHAP_R=%s\n", chap_r);
-       chap_string_to_hex(client_digest, chap_r, strlen(chap_r));
 
        tfm = crypto_alloc_shash("md5", 0, 0);
        if (IS_ERR(tfm)) {
@@ -294,7 +280,7 @@ static int chap_server_compute_md5(
                goto out;
        }
 
-       chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE);
+       bin2hex(response, server_digest, MD5_SIGNATURE_SIZE);
        pr_debug("[server] MD5 Server Digest: %s\n", response);
 
        if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) {
@@ -349,9 +335,7 @@ static int chap_server_compute_md5(
                pr_err("Could not find CHAP_C.\n");
                goto out;
        }
-       pr_debug("[server] Got CHAP_C=%s\n", challenge);
-       challenge_len = chap_string_to_hex(challenge_binhex, challenge,
-                               strlen(challenge));
+       challenge_len = DIV_ROUND_UP(strlen(challenge), 2);
        if (!challenge_len) {
                pr_err("Unable to convert incoming challenge\n");
                goto out;
@@ -360,6 +344,11 @@ static int chap_server_compute_md5(
                pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
                goto out;
        }
+       if (hex2bin(challenge_binhex, challenge, challenge_len) < 0) {
+               pr_err("Malformed CHAP_C\n");
+               goto out;
+       }
+       pr_debug("[server] Got CHAP_C=%s\n", challenge);
        /*
         * During mutual authentication, the CHAP_C generated by the
         * initiator must not match the original CHAP_C generated by
@@ -413,7 +402,7 @@ static int chap_server_compute_md5(
        /*
         * Convert response from binary hex to ascii hext.
         */
-       chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE);
+       bin2hex(response, digest, MD5_SIGNATURE_SIZE);
        *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
                        response);
        *nr_out_len += 1;
index 9e74f8bc29636aef1855ff43e1c340aa062d8453..bb90c80ff3889bdde58df0877a6f7c603bc3eb05 100644 (file)
@@ -67,45 +67,10 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsi_conn *conn)
                goto out_req_buf;
        }
 
-       conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL);
-       if (!conn->conn_ops) {
-               pr_err("Unable to allocate memory for"
-                       " struct iscsi_conn_ops.\n");
-               goto out_rsp_buf;
-       }
-
-       init_waitqueue_head(&conn->queues_wq);
-       INIT_LIST_HEAD(&conn->conn_list);
-       INIT_LIST_HEAD(&conn->conn_cmd_list);
-       INIT_LIST_HEAD(&conn->immed_queue_list);
-       INIT_LIST_HEAD(&conn->response_queue_list);
-       init_completion(&conn->conn_post_wait_comp);
-       init_completion(&conn->conn_wait_comp);
-       init_completion(&conn->conn_wait_rcfr_comp);
-       init_completion(&conn->conn_waiting_on_uc_comp);
-       init_completion(&conn->conn_logout_comp);
-       init_completion(&conn->rx_half_close_comp);
-       init_completion(&conn->tx_half_close_comp);
-       init_completion(&conn->rx_login_comp);
-       spin_lock_init(&conn->cmd_lock);
-       spin_lock_init(&conn->conn_usage_lock);
-       spin_lock_init(&conn->immed_queue_lock);
-       spin_lock_init(&conn->nopin_timer_lock);
-       spin_lock_init(&conn->response_queue_lock);
-       spin_lock_init(&conn->state_lock);
-
-       if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) {
-               pr_err("Unable to allocate conn->conn_cpumask\n");
-               goto out_conn_ops;
-       }
        conn->conn_login = login;
 
        return login;
 
-out_conn_ops:
-       kfree(conn->conn_ops);
-out_rsp_buf:
-       kfree(login->rsp_buf);
 out_req_buf:
        kfree(login->req_buf);
 out_login:
@@ -310,11 +275,9 @@ static int iscsi_login_zero_tsih_s1(
                return -ENOMEM;
        }
 
-       ret = iscsi_login_set_conn_values(sess, conn, pdu->cid);
-       if (unlikely(ret)) {
-               kfree(sess);
-               return ret;
-       }
+       if (iscsi_login_set_conn_values(sess, conn, pdu->cid))
+               goto free_sess;
+
        sess->init_task_tag     = pdu->itt;
        memcpy(&sess->isid, pdu->isid, 6);
        sess->exp_cmd_sn        = be32_to_cpu(pdu->cmdsn);
@@ -1149,6 +1112,75 @@ iscsit_conn_set_transport(struct iscsi_conn *conn, struct iscsit_transport *t)
        return 0;
 }
 
+static struct iscsi_conn *iscsit_alloc_conn(struct iscsi_np *np)
+{
+       struct iscsi_conn *conn;
+
+       conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
+       if (!conn) {
+               pr_err("Could not allocate memory for new connection\n");
+               return NULL;
+       }
+       pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
+       conn->conn_state = TARG_CONN_STATE_FREE;
+
+       init_waitqueue_head(&conn->queues_wq);
+       INIT_LIST_HEAD(&conn->conn_list);
+       INIT_LIST_HEAD(&conn->conn_cmd_list);
+       INIT_LIST_HEAD(&conn->immed_queue_list);
+       INIT_LIST_HEAD(&conn->response_queue_list);
+       init_completion(&conn->conn_post_wait_comp);
+       init_completion(&conn->conn_wait_comp);
+       init_completion(&conn->conn_wait_rcfr_comp);
+       init_completion(&conn->conn_waiting_on_uc_comp);
+       init_completion(&conn->conn_logout_comp);
+       init_completion(&conn->rx_half_close_comp);
+       init_completion(&conn->tx_half_close_comp);
+       init_completion(&conn->rx_login_comp);
+       spin_lock_init(&conn->cmd_lock);
+       spin_lock_init(&conn->conn_usage_lock);
+       spin_lock_init(&conn->immed_queue_lock);
+       spin_lock_init(&conn->nopin_timer_lock);
+       spin_lock_init(&conn->response_queue_lock);
+       spin_lock_init(&conn->state_lock);
+
+       timer_setup(&conn->nopin_response_timer,
+                   iscsit_handle_nopin_response_timeout, 0);
+       timer_setup(&conn->nopin_timer, iscsit_handle_nopin_timeout, 0);
+
+       if (iscsit_conn_set_transport(conn, np->np_transport) < 0)
+               goto free_conn;
+
+       conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL);
+       if (!conn->conn_ops) {
+               pr_err("Unable to allocate memory for struct iscsi_conn_ops.\n");
+               goto put_transport;
+       }
+
+       if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) {
+               pr_err("Unable to allocate conn->conn_cpumask\n");
+               goto free_mask;
+       }
+
+       return conn;
+
+free_mask:
+       free_cpumask_var(conn->conn_cpumask);
+put_transport:
+       iscsit_put_transport(conn->conn_transport);
+free_conn:
+       kfree(conn);
+       return NULL;
+}
+
+void iscsit_free_conn(struct iscsi_conn *conn)
+{
+       free_cpumask_var(conn->conn_cpumask);
+       kfree(conn->conn_ops);
+       iscsit_put_transport(conn->conn_transport);
+       kfree(conn);
+}
+
 void iscsi_target_login_sess_out(struct iscsi_conn *conn,
                struct iscsi_np *np, bool zero_tsih, bool new_sess)
 {
@@ -1198,10 +1230,6 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
                crypto_free_ahash(tfm);
        }
 
-       free_cpumask_var(conn->conn_cpumask);
-
-       kfree(conn->conn_ops);
-
        if (conn->param_list) {
                iscsi_release_param_list(conn->param_list);
                conn->param_list = NULL;
@@ -1219,8 +1247,7 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
        if (conn->conn_transport->iscsit_free_conn)
                conn->conn_transport->iscsit_free_conn(conn);
 
-       iscsit_put_transport(conn->conn_transport);
-       kfree(conn);
+       iscsit_free_conn(conn);
 }
 
 static int __iscsi_target_login_thread(struct iscsi_np *np)
@@ -1250,31 +1277,16 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
        }
        spin_unlock_bh(&np->np_thread_lock);
 
-       conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
+       conn = iscsit_alloc_conn(np);
        if (!conn) {
-               pr_err("Could not allocate memory for"
-                       " new connection\n");
                /* Get another socket */
                return 1;
        }
-       pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
-       conn->conn_state = TARG_CONN_STATE_FREE;
-
-       timer_setup(&conn->nopin_response_timer,
-                   iscsit_handle_nopin_response_timeout, 0);
-       timer_setup(&conn->nopin_timer, iscsit_handle_nopin_timeout, 0);
-
-       if (iscsit_conn_set_transport(conn, np->np_transport) < 0) {
-               kfree(conn);
-               return 1;
-       }
 
        rc = np->np_transport->iscsit_accept_np(np, conn);
        if (rc == -ENOSYS) {
                complete(&np->np_restart_comp);
-               iscsit_put_transport(conn->conn_transport);
-               kfree(conn);
-               conn = NULL;
+               iscsit_free_conn(conn);
                goto exit;
        } else if (rc < 0) {
                spin_lock_bh(&np->np_thread_lock);
@@ -1282,17 +1294,13 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
                        np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
                        spin_unlock_bh(&np->np_thread_lock);
                        complete(&np->np_restart_comp);
-                       iscsit_put_transport(conn->conn_transport);
-                       kfree(conn);
-                       conn = NULL;
+                       iscsit_free_conn(conn);
                        /* Get another socket */
                        return 1;
                }
                spin_unlock_bh(&np->np_thread_lock);
-               iscsit_put_transport(conn->conn_transport);
-               kfree(conn);
-               conn = NULL;
-               goto out;
+               iscsit_free_conn(conn);
+               return 1;
        }
        /*
         * Perform the remaining iSCSI connection initialization items..
@@ -1442,7 +1450,6 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
                tpg_np = NULL;
        }
 
-out:
        return 1;
 
 exit:
index 74ac3abc44a02564ba1231e96c1338b1ecd87bd7..3b8e3639ff5d01c6dbeb31ffb1201bb2453a822c 100644 (file)
@@ -19,7 +19,7 @@ extern int iscsi_target_setup_login_socket(struct iscsi_np *,
 extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *);
 extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *);
 extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32);
-extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *);
+extern void iscsit_free_conn(struct iscsi_conn *);
 extern int iscsit_start_kthreads(struct iscsi_conn *);
 extern void iscsi_post_login_handler(struct iscsi_np *, struct iscsi_conn *, u8);
 extern void iscsi_target_login_sess_out(struct iscsi_conn *, struct iscsi_np *,
index 5414c4a87bea3980eba7c2fce8e9896ff919cbef..27284a2dcd2b62395c5b140900ccca85a68ab683 100644 (file)
@@ -522,6 +522,8 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
                return -EIO;
 
        while (count > 0) {
+               int ret = 0;
+
                spin_lock_irqsave(&hp->lock, flags);
 
                rsize = hp->outbuf_size - hp->n_outbuf;
@@ -537,10 +539,13 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
                }
 
                if (hp->n_outbuf > 0)
-                       hvc_push(hp);
+                       ret = hvc_push(hp);
 
                spin_unlock_irqrestore(&hp->lock, flags);
 
+               if (!ret)
+                       break;
+
                if (count) {
                        if (hp->n_outbuf > 0)
                                hvc_flush(hp);
@@ -623,6 +628,15 @@ static int hvc_chars_in_buffer(struct tty_struct *tty)
 #define MAX_TIMEOUT            (2000)
 static u32 timeout = MIN_TIMEOUT;
 
+/*
+ * Maximum number of bytes to get from the console driver if hvc_poll is
+ * called from driver (and can't sleep). Any more than this and we break
+ * and start polling with khvcd. This value was derived from from an OpenBMC
+ * console with the OPAL driver that results in about 0.25ms interrupts off
+ * latency.
+ */
+#define HVC_ATOMIC_READ_MAX    128
+
 #define HVC_POLL_READ  0x00000001
 #define HVC_POLL_WRITE 0x00000002
 
@@ -669,8 +683,8 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep)
        if (!hp->irq_requested)
                poll_mask |= HVC_POLL_READ;
 
+ read_again:
        /* Read data if any */
-
        count = tty_buffer_request_room(&hp->port, N_INBUF);
 
        /* If flip is full, just reschedule a later read */
@@ -717,9 +731,23 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep)
 #endif /* CONFIG_MAGIC_SYSRQ */
                tty_insert_flip_char(&hp->port, buf[i], 0);
        }
-       if (n == count)
-               poll_mask |= HVC_POLL_READ;
-       read_total = n;
+       read_total += n;
+
+       if (may_sleep) {
+               /* Keep going until the flip is full */
+               spin_unlock_irqrestore(&hp->lock, flags);
+               cond_resched();
+               spin_lock_irqsave(&hp->lock, flags);
+               goto read_again;
+       } else if (read_total < HVC_ATOMIC_READ_MAX) {
+               /* Break and defer if it's a large read in atomic */
+               goto read_again;
+       }
+
+       /*
+        * Latency break, schedule another poll immediately.
+        */
+       poll_mask |= HVC_POLL_READ;
 
  out:
        /* Wakeup write queue if necessary */
index 24a5f05e769bee9f7972319c13fb84745773583c..e5389591bb4f1f83a207ee5be7e3577648972599 100644 (file)
@@ -1054,8 +1054,8 @@ static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
        /* Get the address of the host memory buffer.
         */
        bdp = pinfo->rx_cur;
-       while (bdp->cbd_sc & BD_SC_EMPTY)
-               ;
+       if (bdp->cbd_sc & BD_SC_EMPTY)
+               return NO_POLL_CHAR;
 
        /* If the buffer address is in the CPM DPRAM, don't
         * convert it.
@@ -1090,7 +1090,11 @@ static int cpm_get_poll_char(struct uart_port *port)
                poll_chars = 0;
        }
        if (poll_chars <= 0) {
-               poll_chars = poll_wait_key(poll_buf, pinfo);
+               int ret = poll_wait_key(poll_buf, pinfo);
+
+               if (ret == NO_POLL_CHAR)
+                       return ret;
+               poll_chars = ret;
                pollp = poll_buf;
        }
        poll_chars--;
index 51e47a63d61accef957c87909eedbef40c0ef42e..3f8d1274fc85c2ee0306d93db03042e55c7e193d 100644 (file)
@@ -979,7 +979,8 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
        struct circ_buf *ring = &sport->rx_ring;
        int ret, nent;
        int bits, baud;
-       struct tty_struct *tty = tty_port_tty_get(&sport->port.state->port);
+       struct tty_port *port = &sport->port.state->port;
+       struct tty_struct *tty = port->tty;
        struct ktermios *termios = &tty->termios;
 
        baud = tty_get_baud_rate(tty);
index 239c0fa2e9816805cd134fad697495f7f7929d4b..0f67197a3783ffdd62eccd3b41a813a80d66b6df 100644 (file)
@@ -2351,6 +2351,14 @@ static int imx_uart_probe(struct platform_device *pdev)
                                ret);
                        return ret;
                }
+
+               ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0,
+                                      dev_name(&pdev->dev), sport);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request rts irq: %d\n",
+                               ret);
+                       return ret;
+               }
        } else {
                ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0,
                                       dev_name(&pdev->dev), sport);
index d04b5eeea3c6989e9313c00d1085bbd801ffe9cd..170e446a2f625c4af4bf29c05f87931182979a73 100644 (file)
@@ -511,6 +511,7 @@ static void mvebu_uart_set_termios(struct uart_port *port,
                termios->c_iflag |= old->c_iflag & ~(INPCK | IGNPAR);
                termios->c_cflag &= CREAD | CBAUD;
                termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD);
+               termios->c_cflag |= CS8;
        }
 
        spin_unlock_irqrestore(&port->lock, flags);
index 32bc3e3fe4d30bcea455fb7dc13657b63b111cd9..5e5da9acaf0a9f2522b0b1659968499d91a97e4a 100644 (file)
@@ -1255,6 +1255,7 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *
 static int tty_reopen(struct tty_struct *tty)
 {
        struct tty_driver *driver = tty->driver;
+       int retval;
 
        if (driver->type == TTY_DRIVER_TYPE_PTY &&
            driver->subtype == PTY_TYPE_MASTER)
@@ -1268,10 +1269,14 @@ static int tty_reopen(struct tty_struct *tty)
 
        tty->count++;
 
-       if (!tty->ldisc)
-               return tty_ldisc_reinit(tty, tty->termios.c_line);
+       if (tty->ldisc)
+               return 0;
 
-       return 0;
+       retval = tty_ldisc_reinit(tty, tty->termios.c_line);
+       if (retval)
+               tty->count--;
+
+       return retval;
 }
 
 /**
index a78ad10a119b5b17e53e7391d2f73057193f4c1e..73cdc0d633dd62c12e6ed1ca6545846b8dabaa09 100644 (file)
@@ -32,6 +32,8 @@
 #include <asm/io.h>
 #include <linux/uaccess.h>
 
+#include <linux/nospec.h>
+
 #include <linux/kbd_kern.h>
 #include <linux/vt_kern.h>
 #include <linux/kbd_diacr.h>
@@ -700,6 +702,8 @@ int vt_ioctl(struct tty_struct *tty,
                if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
                        ret = -ENXIO;
                else {
+                       vsa.console = array_index_nospec(vsa.console,
+                                                        MAX_NR_CONSOLES + 1);
                        vsa.console--;
                        console_lock();
                        ret = vc_allocate(vsa.console);
index 27346d69f3938c0222fc59b467bbeb6e9ce778e7..f9b40a9dc4d33eb458d6a3469a0d41acdeab404b 100644 (file)
@@ -780,20 +780,9 @@ static int acm_tty_write(struct tty_struct *tty,
        }
 
        if (acm->susp_count) {
-               if (acm->putbuffer) {
-                       /* now to preserve order */
-                       usb_anchor_urb(acm->putbuffer->urb, &acm->delayed);
-                       acm->putbuffer = NULL;
-               }
                usb_anchor_urb(wb->urb, &acm->delayed);
                spin_unlock_irqrestore(&acm->write_lock, flags);
                return count;
-       } else {
-               if (acm->putbuffer) {
-                       /* at this point there is no good way to handle errors */
-                       acm_start_wb(acm, acm->putbuffer);
-                       acm->putbuffer = NULL;
-               }
        }
 
        stat = acm_start_wb(acm, wb);
@@ -804,66 +793,6 @@ static int acm_tty_write(struct tty_struct *tty,
        return count;
 }
 
-static void acm_tty_flush_chars(struct tty_struct *tty)
-{
-       struct acm *acm = tty->driver_data;
-       struct acm_wb *cur;
-       int err;
-       unsigned long flags;
-
-       spin_lock_irqsave(&acm->write_lock, flags);
-
-       cur = acm->putbuffer;
-       if (!cur) /* nothing to do */
-               goto out;
-
-       acm->putbuffer = NULL;
-       err = usb_autopm_get_interface_async(acm->control);
-       if (err < 0) {
-               cur->use = 0;
-               acm->putbuffer = cur;
-               goto out;
-       }
-
-       if (acm->susp_count)
-               usb_anchor_urb(cur->urb, &acm->delayed);
-       else
-               acm_start_wb(acm, cur);
-out:
-       spin_unlock_irqrestore(&acm->write_lock, flags);
-       return;
-}
-
-static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch)
-{
-       struct acm *acm = tty->driver_data;
-       struct acm_wb *cur;
-       int wbn;
-       unsigned long flags;
-
-overflow:
-       cur = acm->putbuffer;
-       if (!cur) {
-               spin_lock_irqsave(&acm->write_lock, flags);
-               wbn = acm_wb_alloc(acm);
-               if (wbn >= 0) {
-                       cur = &acm->wb[wbn];
-                       acm->putbuffer = cur;
-               }
-               spin_unlock_irqrestore(&acm->write_lock, flags);
-               if (!cur)
-                       return 0;
-       }
-
-       if (cur->len == acm->writesize) {
-               acm_tty_flush_chars(tty);
-               goto overflow;
-       }
-
-       cur->buf[cur->len++] = ch;
-       return 1;
-}
-
 static int acm_tty_write_room(struct tty_struct *tty)
 {
        struct acm *acm = tty->driver_data;
@@ -1987,8 +1916,6 @@ static const struct tty_operations acm_ops = {
        .cleanup =              acm_tty_cleanup,
        .hangup =               acm_tty_hangup,
        .write =                acm_tty_write,
-       .put_char =             acm_tty_put_char,
-       .flush_chars =          acm_tty_flush_chars,
        .write_room =           acm_tty_write_room,
        .ioctl =                acm_tty_ioctl,
        .throttle =             acm_tty_throttle,
index eacc116e83da2ccf38b2640aa5b5b02b5b3621c8..ca06b20d7af9cc9567da1f243ad99935f8bc99e7 100644 (file)
@@ -96,7 +96,6 @@ struct acm {
        unsigned long read_urbs_free;
        struct urb *read_urbs[ACM_NR];
        struct acm_rb read_buffers[ACM_NR];
-       struct acm_wb *putbuffer;                       /* for acm_tty_put_char() */
        int rx_buflimit;
        spinlock_t read_lock;
        u8 *notification_buffer;                        /* to reassemble fragmented notifications */
index 50a2362ed3ea118fb7b796bf0c546d01ca1c1d7e..48277bbc15e4d155fc9c1c7315fcf57d6347b51e 100644 (file)
@@ -246,6 +246,31 @@ int of_usb_update_otg_caps(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(of_usb_update_otg_caps);
 
+/**
+ * usb_of_get_companion_dev - Find the companion device
+ * @dev: the device pointer to find a companion
+ *
+ * Find the companion device from platform bus.
+ *
+ * Takes a reference to the returned struct device which needs to be dropped
+ * after use.
+ *
+ * Return: On success, a pointer to the companion device, %NULL on failure.
+ */
+struct device *usb_of_get_companion_dev(struct device *dev)
+{
+       struct device_node *node;
+       struct platform_device *pdev = NULL;
+
+       node = of_parse_phandle(dev->of_node, "companion", 0);
+       if (node)
+               pdev = of_find_device_by_node(node);
+
+       of_node_put(node);
+
+       return pdev ? &pdev->dev : NULL;
+}
+EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
 #endif
 
 MODULE_LICENSE("GPL");
index 15cc76e22123e7044c77dc5b436ec13916dc83f1..99116af07f1d9ca1e7c275a70122f370ec0d32a3 100644 (file)
@@ -109,8 +109,15 @@ static void *usb_role_switch_match(struct device_connection *con, int ep,
  */
 struct usb_role_switch *usb_role_switch_get(struct device *dev)
 {
-       return device_connection_find_match(dev, "usb-role-switch", NULL,
-                                           usb_role_switch_match);
+       struct usb_role_switch *sw;
+
+       sw = device_connection_find_match(dev, "usb-role-switch", NULL,
+                                         usb_role_switch_match);
+
+       if (!IS_ERR_OR_NULL(sw))
+               WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
+
+       return sw;
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get);
 
@@ -122,8 +129,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get);
  */
 void usb_role_switch_put(struct usb_role_switch *sw)
 {
-       if (!IS_ERR_OR_NULL(sw))
+       if (!IS_ERR_OR_NULL(sw)) {
                put_device(&sw->dev);
+               module_put(sw->dev.parent->driver->owner);
+       }
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_put);
 
index 6ce77b33da61302281dd1c49284e457ff04b73bd..244417d0dfd1fdc74c2f0c8ee58e35f14dd9e7db 100644 (file)
@@ -1434,10 +1434,13 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        struct async *as = NULL;
        struct usb_ctrlrequest *dr = NULL;
        unsigned int u, totlen, isofrmlen;
-       int i, ret, is_in, num_sgs = 0, ifnum = -1;
+       int i, ret, num_sgs = 0, ifnum = -1;
        int number_of_packets = 0;
        unsigned int stream_id = 0;
        void *buf;
+       bool is_in;
+       bool allow_short = false;
+       bool allow_zero = false;
        unsigned long mask =    USBDEVFS_URB_SHORT_NOT_OK |
                                USBDEVFS_URB_BULK_CONTINUATION |
                                USBDEVFS_URB_NO_FSBR |
@@ -1471,6 +1474,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        u = 0;
        switch (uurb->type) {
        case USBDEVFS_URB_TYPE_CONTROL:
+               if (is_in)
+                       allow_short = true;
                if (!usb_endpoint_xfer_control(&ep->desc))
                        return -EINVAL;
                /* min 8 byte setup packet */
@@ -1511,6 +1516,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
                break;
 
        case USBDEVFS_URB_TYPE_BULK:
+               if (!is_in)
+                       allow_zero = true;
+               else
+                       allow_short = true;
                switch (usb_endpoint_type(&ep->desc)) {
                case USB_ENDPOINT_XFER_CONTROL:
                case USB_ENDPOINT_XFER_ISOC:
@@ -1531,6 +1540,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
                if (!usb_endpoint_xfer_int(&ep->desc))
                        return -EINVAL;
  interrupt_urb:
+               if (!is_in)
+                       allow_zero = true;
+               else
+                       allow_short = true;
                break;
 
        case USBDEVFS_URB_TYPE_ISO:
@@ -1676,14 +1689,19 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        u = (is_in ? URB_DIR_IN : URB_DIR_OUT);
        if (uurb->flags & USBDEVFS_URB_ISO_ASAP)
                u |= URB_ISO_ASAP;
-       if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in)
+       if (allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
                u |= URB_SHORT_NOT_OK;
-       if (uurb->flags & USBDEVFS_URB_ZERO_PACKET)
+       if (allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET)
                u |= URB_ZERO_PACKET;
        if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT)
                u |= URB_NO_INTERRUPT;
        as->urb->transfer_flags = u;
 
+       if (!allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
+               dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_SHORT_NOT_OK.\n");
+       if (!allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET)
+               dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_ZERO_PACKET.\n");
+
        as->urb->transfer_buffer_length = uurb->buffer_length;
        as->urb->setup_packet = (unsigned char *)dr;
        dr = NULL;
index e76e95f62f7628a907d0132c31261b2ffc641e49..a1f225f077cd23b3ebbf07951b0734183c209bf5 100644 (file)
@@ -512,7 +512,6 @@ int usb_driver_claim_interface(struct usb_driver *driver,
        struct device *dev;
        struct usb_device *udev;
        int retval = 0;
-       int lpm_disable_error = -ENODEV;
 
        if (!iface)
                return -ENODEV;
@@ -533,16 +532,6 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 
        iface->condition = USB_INTERFACE_BOUND;
 
-       /* See the comment about disabling LPM in usb_probe_interface(). */
-       if (driver->disable_hub_initiated_lpm) {
-               lpm_disable_error = usb_unlocked_disable_lpm(udev);
-               if (lpm_disable_error) {
-                       dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n",
-                               __func__, driver->name);
-                       return -ENOMEM;
-               }
-       }
-
        /* Claimed interfaces are initially inactive (suspended) and
         * runtime-PM-enabled, but only if the driver has autosuspend
         * support.  Otherwise they are marked active, to prevent the
@@ -561,9 +550,20 @@ int usb_driver_claim_interface(struct usb_driver *driver,
        if (device_is_registered(dev))
                retval = device_bind_driver(dev);
 
-       /* Attempt to re-enable USB3 LPM, if the disable was successful. */
-       if (!lpm_disable_error)
-               usb_unlocked_enable_lpm(udev);
+       if (retval) {
+               dev->driver = NULL;
+               usb_set_intfdata(iface, NULL);
+               iface->needs_remote_wakeup = 0;
+               iface->condition = USB_INTERFACE_UNBOUND;
+
+               /*
+                * Unbound interfaces are always runtime-PM-disabled
+                * and runtime-PM-suspended
+                */
+               if (driver->supports_autosuspend)
+                       pm_runtime_disable(dev);
+               pm_runtime_set_suspended(dev);
+       }
 
        return retval;
 }
index 66fe1b78d952969ebdedbecef8cc59f2805c2672..03432467b05fb12810d7cac77d954a11ed0a002a 100644 (file)
@@ -515,8 +515,6 @@ static int resume_common(struct device *dev, int event)
                                event == PM_EVENT_RESTORE);
                if (retval) {
                        dev_err(dev, "PCI post-resume error %d!\n", retval);
-                       if (hcd->shared_hcd)
-                               usb_hc_died(hcd->shared_hcd);
                        usb_hc_died(hcd);
                }
        }
index 228672f2c4a15eb841809a1f3d42caa925eb5fee..bfa5eda0cc2606a79373651fd079f87526238f36 100644 (file)
@@ -1341,6 +1341,11 @@ void usb_enable_interface(struct usb_device *dev,
  * is submitted that needs that bandwidth.  Some other operating systems
  * allocate bandwidth early, when a configuration is chosen.
  *
+ * xHCI reserves bandwidth and configures the alternate setting in
+ * usb_hcd_alloc_bandwidth(). If it fails the original interface altsetting
+ * may be disabled. Drivers cannot rely on any particular alternate
+ * setting being in effect after a failure.
+ *
  * This call is synchronous, and may not be used in an interrupt context.
  * Also, drivers must not change altsettings while urbs are scheduled for
  * endpoints in that interface; all such urbs must first be completed
@@ -1376,6 +1381,12 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
                         alternate);
                return -EINVAL;
        }
+       /*
+        * usb3 hosts configure the interface in usb_hcd_alloc_bandwidth,
+        * including freeing dropped endpoint ring buffers.
+        * Make sure the interface endpoints are flushed before that
+        */
+       usb_disable_interface(dev, iface, false);
 
        /* Make sure we have enough bandwidth for this alternate interface.
         * Remove the current alt setting and add the new alt setting.
index fd77442c2d12e1c9eba50b606d990fbb48c84e8b..651708d8c9083b99df235dddc3eddde12b9e5188 100644 (file)
@@ -105,29 +105,3 @@ usb_of_get_interface_node(struct usb_device *udev, u8 config, u8 ifnum)
        return NULL;
 }
 EXPORT_SYMBOL_GPL(usb_of_get_interface_node);
-
-/**
- * usb_of_get_companion_dev - Find the companion device
- * @dev: the device pointer to find a companion
- *
- * Find the companion device from platform bus.
- *
- * Takes a reference to the returned struct device which needs to be dropped
- * after use.
- *
- * Return: On success, a pointer to the companion device, %NULL on failure.
- */
-struct device *usb_of_get_companion_dev(struct device *dev)
-{
-       struct device_node *node;
-       struct platform_device *pdev = NULL;
-
-       node = of_parse_phandle(dev->of_node, "companion", 0);
-       if (node)
-               pdev = of_find_device_by_node(node);
-
-       of_node_put(node);
-
-       return pdev ? &pdev->dev : NULL;
-}
-EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
index 097057d2eacf7bcb18316473c6f0def8a5744b62..178d6c6063c0280a06c6dc3dc6611394d8233479 100644 (file)
@@ -58,6 +58,7 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp)
        quirk_list = kcalloc(quirk_count, sizeof(struct quirk_entry),
                             GFP_KERNEL);
        if (!quirk_list) {
+               quirk_count = 0;
                mutex_unlock(&quirk_mutex);
                return -ENOMEM;
        }
@@ -154,7 +155,7 @@ static struct kparam_string quirks_param_string = {
        .string = quirks_param,
 };
 
-module_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0644);
+device_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0644);
 MODULE_PARM_DESC(quirks, "Add/modify USB quirks by specifying quirks=vendorID:productID:quirks");
 
 /* Lists of quirky USB devices, split in device quirks and interface quirks.
@@ -178,6 +179,10 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* CBM - Flash disk */
        { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* WORLDE Controller KS49 or Prodipe MIDI 49C USB controller */
+       { USB_DEVICE(0x0218, 0x0201), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
+
        /* WORLDE easy key (easykey.25) MIDI controller  */
        { USB_DEVICE(0x0218, 0x0401), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
@@ -406,6 +411,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x2040, 0x7200), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
 
+       /* DJI CineSSD */
+       { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
+
        /* INTEL VALUE SSD */
        { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
 
index 623be3174fb32e1036c697430f34adafd4f22d0f..79d8bd7a612e65b5c765f16e0c5567a440cdc1da 100644 (file)
@@ -228,6 +228,8 @@ struct usb_host_interface *usb_find_alt_setting(
        struct usb_interface_cache *intf_cache = NULL;
        int i;
 
+       if (!config)
+               return NULL;
        for (i = 0; i < config->desc.bNumInterfaces; i++) {
                if (config->intf_cache[i]->altsetting[0].desc.bInterfaceNumber
                                == iface_num) {
index 9a53a58e676e0ae775550fb872ed168c65598f84..577642895b57d118eb37115cdb005089ee5c6e08 100644 (file)
@@ -412,8 +412,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
        dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
                (unsigned long)res->start, hsotg->regs);
 
-       hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
-
        retval = dwc2_lowlevel_hw_init(hsotg);
        if (retval)
                return retval;
@@ -438,6 +436,8 @@ static int dwc2_driver_probe(struct platform_device *dev)
        if (retval)
                return retval;
 
+       hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
+
        retval = dwc2_get_dr_mode(hsotg);
        if (retval)
                goto error;
index 40bf9e0bbc59754e756c0eb2b0c752a5c8baef61..4c2771c5e7276528d70941d73024ae2b4aedd977 100644 (file)
@@ -180,8 +180,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int dwc3_of_simple_runtime_suspend(struct device *dev)
+static int __maybe_unused dwc3_of_simple_runtime_suspend(struct device *dev)
 {
        struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
        int                     i;
@@ -192,7 +191,7 @@ static int dwc3_of_simple_runtime_suspend(struct device *dev)
        return 0;
 }
 
-static int dwc3_of_simple_runtime_resume(struct device *dev)
+static int __maybe_unused dwc3_of_simple_runtime_resume(struct device *dev)
 {
        struct dwc3_of_simple   *simple = dev_get_drvdata(dev);
        int                     ret;
@@ -210,7 +209,7 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
        return 0;
 }
 
-static int dwc3_of_simple_suspend(struct device *dev)
+static int __maybe_unused dwc3_of_simple_suspend(struct device *dev)
 {
        struct dwc3_of_simple *simple = dev_get_drvdata(dev);
 
@@ -220,7 +219,7 @@ static int dwc3_of_simple_suspend(struct device *dev)
        return 0;
 }
 
-static int dwc3_of_simple_resume(struct device *dev)
+static int __maybe_unused dwc3_of_simple_resume(struct device *dev)
 {
        struct dwc3_of_simple *simple = dev_get_drvdata(dev);
 
@@ -229,7 +228,6 @@ static int dwc3_of_simple_resume(struct device *dev)
 
        return 0;
 }
-#endif
 
 static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(dwc3_of_simple_suspend, dwc3_of_simple_resume)
index 5edd7947036832f3042f503dbe8cdd9d0d5b0cba..1286076a8890308a66d6ef494b85169ae92d7798 100644 (file)
@@ -85,8 +85,8 @@ static int dwc3_byt_enable_ulpi_refclock(struct pci_dev *pci)
        u32             value;
 
        reg = pcim_iomap(pci, GP_RWBAR, 0);
-       if (IS_ERR(reg))
-               return PTR_ERR(reg);
+       if (!reg)
+               return -ENOMEM;
 
        value = readl(reg + GP_RWREG1);
        if (!(value & GP_RWREG1_ULPI_REFCLK_DISABLE))
index 032ea7d709ba534907c6baf02bb3a634a4fa44f5..2b53194081bafd3041f0fa7278711e984dd75237 100644 (file)
@@ -473,7 +473,6 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep)
 
 /**
  * dwc3_gadget_start_config - configure ep resources
- * @dwc: pointer to our controller context structure
  * @dep: endpoint that is being enabled
  *
  * Issue a %DWC3_DEPCMD_DEPSTARTCFG command to @dep. After the command's
index 53a48f561458619f56fb71d079052441dc848ff6..587c5037ff079e0d74984703c91cc5dbca8428cd 100644 (file)
@@ -1063,12 +1063,15 @@ static const struct usb_gadget_ops fotg210_gadget_ops = {
 static int fotg210_udc_remove(struct platform_device *pdev)
 {
        struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
+       int i;
 
        usb_del_gadget_udc(&fotg210->gadget);
        iounmap(fotg210->reg);
        free_irq(platform_get_irq(pdev, 0), fotg210);
 
        fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
+       for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
+               kfree(fotg210->ep[i]);
        kfree(fotg210);
 
        return 0;
@@ -1099,7 +1102,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
        /* initialize udc */
        fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL);
        if (fotg210 == NULL)
-               goto err_alloc;
+               goto err;
 
        for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
                _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
@@ -1111,7 +1114,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
        fotg210->reg = ioremap(res->start, resource_size(res));
        if (fotg210->reg == NULL) {
                pr_err("ioremap error.\n");
-               goto err_map;
+               goto err_alloc;
        }
 
        spin_lock_init(&fotg210->lock);
@@ -1159,7 +1162,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
        fotg210->ep0_req = fotg210_ep_alloc_request(&fotg210->ep[0]->ep,
                                GFP_KERNEL);
        if (fotg210->ep0_req == NULL)
-               goto err_req;
+               goto err_map;
 
        fotg210_init(fotg210);
 
@@ -1187,12 +1190,14 @@ static int fotg210_udc_probe(struct platform_device *pdev)
        fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
 
 err_map:
-       if (fotg210->reg)
-               iounmap(fotg210->reg);
+       iounmap(fotg210->reg);
 
 err_alloc:
+       for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
+               kfree(fotg210->ep[i]);
        kfree(fotg210);
 
+err:
        return ret;
 }
 
index 318246d8b2e2b574178acc9745e7d48602742485..b02ab2a8d927f6f76fb3173113b83dbd6555363a 100644 (file)
@@ -1545,11 +1545,14 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on)
                writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
        } else {
                writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
-               stop_activity(dev, dev->driver);
+               stop_activity(dev, NULL);
        }
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
+       if (!is_on && dev->driver)
+               dev->driver->disconnect(&dev->gadget);
+
        return 0;
 }
 
@@ -2466,8 +2469,11 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
                nuke(&dev->ep[i]);
 
        /* report disconnect; the driver is already quiesced */
-       if (driver)
+       if (driver) {
+               spin_unlock(&dev->lock);
                driver->disconnect(&dev->gadget);
+               spin_lock(&dev->lock);
+       }
 
        usb_reinit(dev);
 }
@@ -3341,6 +3347,8 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
                BIT(PCI_RETRY_ABORT_INTERRUPT))
 
 static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
+__releases(dev->lock)
+__acquires(dev->lock)
 {
        struct net2280_ep       *ep;
        u32                     tmp, num, mask, scratch;
@@ -3381,12 +3389,14 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
                        if (disconnect || reset) {
                                stop_activity(dev, dev->driver);
                                ep0_start(dev);
+                               spin_unlock(&dev->lock);
                                if (reset)
                                        usb_gadget_udc_reset
                                                (&dev->gadget, dev->driver);
                                else
                                        (dev->driver->disconnect)
                                                (&dev->gadget);
+                               spin_lock(&dev->lock);
                                return;
                        }
                }
@@ -3405,6 +3415,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
        tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT);
        if (stat & tmp) {
                writel(tmp, &dev->regs->irqstat1);
+               spin_unlock(&dev->lock);
                if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) {
                        if (dev->driver->suspend)
                                dev->driver->suspend(&dev->gadget);
@@ -3415,6 +3426,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
                                dev->driver->resume(&dev->gadget);
                        /* at high speed, note erratum 0133 */
                }
+               spin_lock(&dev->lock);
                stat &= ~tmp;
        }
 
index 1f879b3f2c96ad1f7dc417da185a545d0e52a484..e1656f361e081d398d8ab55820a00cf9497f3562 100644 (file)
@@ -812,12 +812,15 @@ static void usb3_irq_epc_int_1_speed(struct renesas_usb3 *usb3)
        switch (speed) {
        case USB_STA_SPEED_SS:
                usb3->gadget.speed = USB_SPEED_SUPER;
+               usb3->gadget.ep0->maxpacket = USB3_EP0_SS_MAX_PACKET_SIZE;
                break;
        case USB_STA_SPEED_HS:
                usb3->gadget.speed = USB_SPEED_HIGH;
+               usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE;
                break;
        case USB_STA_SPEED_FS:
                usb3->gadget.speed = USB_SPEED_FULL;
+               usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE;
                break;
        default:
                usb3->gadget.speed = USB_SPEED_UNKNOWN;
@@ -2513,7 +2516,7 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev,
                        /* for control pipe */
                        usb3->gadget.ep0 = &usb3_ep->ep;
                        usb_ep_set_maxpacket_limit(&usb3_ep->ep,
-                                               USB3_EP0_HSFS_MAX_PACKET_SIZE);
+                                               USB3_EP0_SS_MAX_PACKET_SIZE);
                        usb3_ep->ep.caps.type_control = true;
                        usb3_ep->ep.caps.dir_in = true;
                        usb3_ep->ep.caps.dir_out = true;
index 072bd5d5738e730f896260b7ab7db95f5cbd63e9..5b8a3d9530c4a89bacb3850852c72d3a19c979dd 100644 (file)
@@ -2555,7 +2555,7 @@ static int u132_get_frame(struct usb_hcd *hcd)
        } else {
                int frame = 0;
                dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n");
-               msleep(100);
+               mdelay(100);
                return frame;
        }
 }
index ef350c33dc4a8615a0188af0cea13ae29a876532..b1f27aa38b1008c0edc8f425e0caf4b4a2c06959 100644 (file)
@@ -1613,6 +1613,10 @@ void xhci_endpoint_copy(struct xhci_hcd *xhci,
        in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2;
        in_ep_ctx->deq = out_ep_ctx->deq;
        in_ep_ctx->tx_info = out_ep_ctx->tx_info;
+       if (xhci->quirks & XHCI_MTK_HOST) {
+               in_ep_ctx->reserved[0] = out_ep_ctx->reserved[0];
+               in_ep_ctx->reserved[1] = out_ep_ctx->reserved[1];
+       }
 }
 
 /* Copy output xhci_slot_ctx to the input xhci_slot_ctx.
index 8dc77e34a85989d78246ad0489635ac393cad636..94e939249b2b6dc0f65fb197a0b084889a7fb153 100644 (file)
@@ -153,7 +153,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
 {
        const struct xhci_plat_priv *priv_match;
        const struct hc_driver  *driver;
-       struct device           *sysdev;
+       struct device           *sysdev, *tmpdev;
        struct xhci_hcd         *xhci;
        struct resource         *res;
        struct usb_hcd          *hcd;
@@ -273,19 +273,24 @@ static int xhci_plat_probe(struct platform_device *pdev)
                goto disable_clk;
        }
 
-       if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
-               xhci->quirks |= XHCI_HW_LPM_DISABLE;
+       /* imod_interval is the interrupt moderation value in nanoseconds. */
+       xhci->imod_interval = 40000;
 
-       if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
-               xhci->quirks |= XHCI_LPM_SUPPORT;
+       /* Iterate over all parent nodes for finding quirks */
+       for (tmpdev = &pdev->dev; tmpdev; tmpdev = tmpdev->parent) {
 
-       if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
-               xhci->quirks |= XHCI_BROKEN_PORT_PED;
+               if (device_property_read_bool(tmpdev, "usb2-lpm-disable"))
+                       xhci->quirks |= XHCI_HW_LPM_DISABLE;
 
-       /* imod_interval is the interrupt moderation value in nanoseconds. */
-       xhci->imod_interval = 40000;
-       device_property_read_u32(sysdev, "imod-interval-ns",
-                                &xhci->imod_interval);
+               if (device_property_read_bool(tmpdev, "usb3-lpm-capable"))
+                       xhci->quirks |= XHCI_LPM_SUPPORT;
+
+               if (device_property_read_bool(tmpdev, "quirk-broken-port-ped"))
+                       xhci->quirks |= XHCI_BROKEN_PORT_PED;
+
+               device_property_read_u32(tmpdev, "imod-interval-ns",
+                                        &xhci->imod_interval);
+       }
 
        hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
        if (IS_ERR(hcd->usb_phy)) {
index 61f48b17e57b6688599e9269c6933cfeb51fdf92..0420eefa647a15cb5321dfa5fd95556a5a5432e5 100644 (file)
@@ -37,6 +37,21 @@ static unsigned long long quirks;
 module_param(quirks, ullong, S_IRUGO);
 MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
 
+static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
+{
+       struct xhci_segment *seg = ring->first_seg;
+
+       if (!td || !td->start_seg)
+               return false;
+       do {
+               if (seg == td->start_seg)
+                       return true;
+               seg = seg->next;
+       } while (seg && seg != ring->first_seg);
+
+       return false;
+}
+
 /* TODO: copied from ehci-hcd.c - can this be refactored? */
 /*
  * xhci_handshake - spin reading hc until handshake completes or fails
@@ -1571,6 +1586,21 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                goto done;
        }
 
+       /*
+        * check ring is not re-allocated since URB was enqueued. If it is, then
+        * make sure none of the ring related pointers in this URB private data
+        * are touched, such as td_list, otherwise we overwrite freed data
+        */
+       if (!td_on_ring(&urb_priv->td[0], ep_ring)) {
+               xhci_err(xhci, "Canceled URB td not found on endpoint ring");
+               for (i = urb_priv->num_tds_done; i < urb_priv->num_tds; i++) {
+                       td = &urb_priv->td[i];
+                       if (!list_empty(&td->cancelled_td_list))
+                               list_del_init(&td->cancelled_td_list);
+               }
+               goto err_giveback;
+       }
+
        if (xhci->xhc_state & XHCI_STATE_HALTED) {
                xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                                "HC halted, freeing TD manually.");
index 82f220631bd7b9ffa77599008c42e6611426887f..b5d6616442635b8bf4c814bfd629a9ec18e927a3 100644 (file)
@@ -369,7 +369,7 @@ static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned ch
        mask &= 0x0f;
        val &= 0x0f;
        d = (priv->reg[1] & (~mask)) ^ val;
-       if (set_1284_register(pp, 2, d, GFP_KERNEL))
+       if (set_1284_register(pp, 2, d, GFP_ATOMIC))
                return 0;
        priv->reg[1] = d;
        return d & 0xf;
@@ -379,7 +379,7 @@ static unsigned char parport_uss720_read_status(struct parport *pp)
 {
        unsigned char ret;
 
-       if (get_1284_register(pp, 1, &ret, GFP_KERNEL))
+       if (get_1284_register(pp, 1, &ret, GFP_ATOMIC))
                return 0;
        return ret & 0xf8;
 }
index 3be40eaa1ac9b2caf493a8fd21e8980982b5d9a1..6d9fd5f649036e8fb47c39eaeffa26f856724e99 100644 (file)
@@ -413,6 +413,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
        spin_unlock_irqrestore(&dev->lock, flags);
        mutex_unlock(&dev->io_mutex);
 
+       if (WARN_ON_ONCE(len >= sizeof(in_buffer)))
+               return -EIO;
+
        return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
 }
 
@@ -421,13 +424,13 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
 {
        struct usb_yurex *dev;
        int i, set = 0, retval = 0;
-       char buffer[16];
+       char buffer[16 + 1];
        char *data = buffer;
        unsigned long long c, c2 = 0;
        signed long timeout = 0;
        DEFINE_WAIT(wait);
 
-       count = min(sizeof(buffer), count);
+       count = min(sizeof(buffer) - 1, count);
        dev = file->private_data;
 
        /* verify that we actually have some data to write */
@@ -446,6 +449,7 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
                retval = -EFAULT;
                goto error;
        }
+       buffer[count] = 0;
        memset(dev->cntl_buffer, CMD_PADDING, YUREX_BUF_SIZE);
 
        switch (buffer[0]) {
index eecfd067136287a65c89bb58409bf054f9ea6e1c..d045d8458f81c27930a090ab06ee1539cfeb420a 100644 (file)
@@ -107,8 +107,12 @@ static int mtu3_device_enable(struct mtu3 *mtu)
                (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN |
                SSUSB_U2_PORT_HOST_SEL));
 
-       if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG)
+       if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) {
                mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
+               if (mtu->is_u3_ip)
+                       mtu3_setbits(ibase, SSUSB_U3_CTRL(0),
+                                    SSUSB_U3_PORT_DUAL_MODE);
+       }
 
        return ssusb_check_clocks(mtu->ssusb, check_clk);
 }
index 6ee371478d89e320e53318161007771608b64713..a45bb253939f2c8e1a85c1e7ee7b84ad3f0182a5 100644 (file)
 
 /* U3D_SSUSB_U3_CTRL_0P */
 #define SSUSB_U3_PORT_SSP_SPEED        BIT(9)
+#define SSUSB_U3_PORT_DUAL_MODE        BIT(7)
 #define SSUSB_U3_PORT_HOST_SEL         BIT(2)
 #define SSUSB_U3_PORT_PDN              BIT(1)
 #define SSUSB_U3_PORT_DIS              BIT(0)
index df827ff57b0d0c08b0dd1d9763ab0ebcb7fa3199..23a0df79ef2129323d3b8f0548f06c25d1421916 100644 (file)
@@ -658,16 +658,6 @@ dsps_dma_controller_create(struct musb *musb, void __iomem *base)
        return controller;
 }
 
-static void dsps_dma_controller_destroy(struct dma_controller *c)
-{
-       struct musb *musb = c->musb;
-       struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
-       void __iomem *usbss_base = glue->usbss_base;
-
-       musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP);
-       cppi41_dma_controller_destroy(c);
-}
-
 #ifdef CONFIG_PM_SLEEP
 static void dsps_dma_controller_suspend(struct dsps_glue *glue)
 {
@@ -697,7 +687,7 @@ static struct musb_platform_ops dsps_ops = {
 
 #ifdef CONFIG_USB_TI_CPPI41_DMA
        .dma_init       = dsps_dma_controller_create,
-       .dma_exit       = dsps_dma_controller_destroy,
+       .dma_exit       = cppi41_dma_controller_destroy,
 #endif
        .enable         = dsps_musb_enable,
        .disable        = dsps_musb_disable,
index e53c682610176bf694e3130031181d669e3b83fa..9bbcee37524e56ccf7e9473b23c271924bedaf7d 100644 (file)
@@ -173,7 +173,7 @@ struct ump_interrupt {
 }  __attribute__((packed));
 
 
-#define TIUMP_GET_PORT_FROM_CODE(c)    (((c) >> 4) - 3)
+#define TIUMP_GET_PORT_FROM_CODE(c)    (((c) >> 6) & 0x01)
 #define TIUMP_GET_FUNC_FROM_CODE(c)    ((c) & 0x0f)
 #define TIUMP_INTERRUPT_CODE_LSR       0x03
 #define TIUMP_INTERRUPT_CODE_MSR       0x04
index 3010878f7f8ed9004bb78a15f63e1eb83261742e..e3c5832337e0bdbb83df78285a697ac5f5a8af3f 100644 (file)
@@ -1119,7 +1119,7 @@ static void ti_break(struct tty_struct *tty, int break_state)
 
 static int ti_get_port_from_code(unsigned char code)
 {
-       return (code >> 4) - 3;
+       return (code >> 6) & 0x01;
 }
 
 static int ti_get_func_from_code(unsigned char code)
index c267f2812a046db0920670e3834a8dbb472f534d..e227bb5b794fe3905965647a442bbd43254d5099 100644 (file)
@@ -376,6 +376,15 @@ static int queuecommand_lck(struct scsi_cmnd *srb,
                return 0;
        }
 
+       if ((us->fflags & US_FL_NO_ATA_1X) &&
+                       (srb->cmnd[0] == ATA_12 || srb->cmnd[0] == ATA_16)) {
+               memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
+                      sizeof(usb_stor_sense_invalidCDB));
+               srb->result = SAM_STAT_CHECK_CONDITION;
+               done(srb);
+               return 0;
+       }
+
        /* enqueue the command and wake up the control thread */
        srb->scsi_done = done;
        us->srb = srb;
index 9e9de5452860d39c2a6da87546459a38086b21b9..1f7b401c4d041d44390f3fa519dd95b46aab1b42 100644 (file)
@@ -842,6 +842,27 @@ static int uas_slave_configure(struct scsi_device *sdev)
                sdev->skip_ms_page_8 = 1;
                sdev->wce_default_on = 1;
        }
+
+       /*
+        * Some disks return the total number of blocks in response
+        * to READ CAPACITY rather than the highest block number.
+        * If this device makes that mistake, tell the sd driver.
+        */
+       if (devinfo->flags & US_FL_FIX_CAPACITY)
+               sdev->fix_capacity = 1;
+
+       /*
+        * Some devices don't like MODE SENSE with page=0x3f,
+        * which is the command used for checking if a device
+        * is write-protected.  Now that we tell the sd driver
+        * to do a 192-byte transfer with this command the
+        * majority of devices work fine, but a few still can't
+        * handle it.  The sd driver will simply assume those
+        * devices are write-enabled.
+        */
+       if (devinfo->flags & US_FL_NO_WP_DETECT)
+               sdev->skip_ms_page_3f = 1;
+
        scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
        return 0;
 }
index 22fcfccf453afeec176b5ab35390d6688e8953f4..f7f83b21dc746ab922d7f7e7c61add76a55fc560 100644 (file)
@@ -2288,6 +2288,13 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_GO_SLOW ),
 
+/* Reported-by: Tim Anderson <tsa@biglakesoftware.com> */
+UNUSUAL_DEV(  0x2ca3, 0x0031, 0x0000, 0x9999,
+               "DJI",
+               "CineSSD",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_ATA_1X),
+
 /*
  * Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
  * Mio Moov 330
index 95a2b10127db564607dfbb9f7a529a6719fd0e31..76299b6ff06dae4eb29e49960d7403b66c39e3d8 100644 (file)
@@ -255,12 +255,13 @@ EXPORT_SYMBOL_GPL(typec_altmode_unregister_driver);
 /* API for the port drivers */
 
 /**
- * typec_match_altmode - Match SVID to an array of alternate modes
+ * typec_match_altmode - Match SVID and mode to an array of alternate modes
  * @altmodes: Array of alternate modes
- * @n: Number of elements in the array, or -1 for NULL termiated arrays
+ * @n: Number of elements in the array, or -1 for NULL terminated arrays
  * @svid: Standard or Vendor ID to match with
+ * @mode: Mode to match with
  *
- * Return pointer to an alternate mode with SVID mathing @svid, or NULL when no
+ * Return pointer to an alternate mode with SVID matching @svid, or NULL when no
  * match is found.
  */
 struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes,
index c202975f8097eb37f05cfe29d63dedf26d8a1d11..e61dffb27a0c64bab899c36f674f922278d92f6e 100644 (file)
@@ -1484,7 +1484,6 @@ EXPORT_SYMBOL_GPL(typec_set_mode);
  * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
  * @port: USB Type-C Port that supports the alternate mode
  * @desc: Description of the alternate mode
- * @drvdata: Private pointer to driver specific info
  *
  * This routine is used to register an alternate mode that @port is capable of
  * supporting.
index ddaac63ecf1225385d53a53f13521bb7b0ae9e00..d990aa510fabf008a332706c34fe3f61b2929e82 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/usb/typec_mux.h>
 
@@ -49,8 +50,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
        mutex_lock(&switch_lock);
        sw = device_connection_find_match(dev, "typec-switch", NULL,
                                          typec_switch_match);
-       if (!IS_ERR_OR_NULL(sw))
+       if (!IS_ERR_OR_NULL(sw)) {
+               WARN_ON(!try_module_get(sw->dev->driver->owner));
                get_device(sw->dev);
+       }
        mutex_unlock(&switch_lock);
 
        return sw;
@@ -65,8 +68,10 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
  */
 void typec_switch_put(struct typec_switch *sw)
 {
-       if (!IS_ERR_OR_NULL(sw))
+       if (!IS_ERR_OR_NULL(sw)) {
+               module_put(sw->dev->driver->owner);
                put_device(sw->dev);
+       }
 }
 EXPORT_SYMBOL_GPL(typec_switch_put);
 
@@ -136,8 +141,10 @@ struct typec_mux *typec_mux_get(struct device *dev, const char *name)
 
        mutex_lock(&mux_lock);
        mux = device_connection_find_match(dev, name, NULL, typec_mux_match);
-       if (!IS_ERR_OR_NULL(mux))
+       if (!IS_ERR_OR_NULL(mux)) {
+               WARN_ON(!try_module_get(mux->dev->driver->owner));
                get_device(mux->dev);
+       }
        mutex_unlock(&mux_lock);
 
        return mux;
@@ -152,8 +159,10 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
  */
 void typec_mux_put(struct typec_mux *mux)
 {
-       if (!IS_ERR_OR_NULL(mux))
+       if (!IS_ERR_OR_NULL(mux)) {
+               module_put(mux->dev->driver->owner);
                put_device(mux->dev);
+       }
 }
 EXPORT_SYMBOL_GPL(typec_mux_put);
 
index b459edfacff35e0526fdc912cd0179ef8126ea74..90d387b50ab747f505597e87b439f1dcfe5f489f 100644 (file)
@@ -79,15 +79,19 @@ config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
          This value is used to allocate enough space in internal
          tables needed for physical memory administration.
 
-config XEN_SCRUB_PAGES
-       bool "Scrub pages before returning them to system"
+config XEN_SCRUB_PAGES_DEFAULT
+       bool "Scrub pages before returning them to system by default"
        depends on XEN_BALLOON
        default y
        help
          Scrub pages before returning them to the system for reuse by
          other domains.  This makes sure that any confidential data
          is not accidentally visible to other domains.  Is it more
-         secure, but slightly less efficient.
+         secure, but slightly less efficient. This can be controlled with
+         xen_scrub_pages=0 parameter and
+         /sys/devices/system/xen_memory/xen_memory0/scrub_pages.
+         This option only sets the default value.
+
          If in doubt, say yes.
 
 config XEN_DEV_EVTCHN
index d4265c8ebb22a24b1ab8794ab79b592793d14908..b1357aa4bc552eb3a5989dab5eeacf9295d2a2d8 100644 (file)
@@ -19,15 +19,16 @@ static void enable_hotplug_cpu(int cpu)
 
 static void disable_hotplug_cpu(int cpu)
 {
-       if (cpu_online(cpu)) {
-               lock_device_hotplug();
+       if (!cpu_is_hotpluggable(cpu))
+               return;
+       lock_device_hotplug();
+       if (cpu_online(cpu))
                device_offline(get_cpu_device(cpu));
-               unlock_device_hotplug();
-       }
-       if (cpu_present(cpu))
+       if (!cpu_online(cpu) && cpu_present(cpu)) {
                xen_arch_unregister_cpu(cpu);
-
-       set_cpu_present(cpu, false);
+               set_cpu_present(cpu, false);
+       }
+       unlock_device_hotplug();
 }
 
 static int vcpu_online(unsigned int cpu)
index 08e4af04d6f2c32850a049a83721933a82883b8c..e6c1934734b7d9bdde87e8a9e006e1584c88f15d 100644 (file)
@@ -138,7 +138,7 @@ static int set_evtchn_to_irq(unsigned evtchn, unsigned irq)
                clear_evtchn_to_irq_row(row);
        }
 
-       evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)] = irq;
+       evtchn_to_irq[row][col] = irq;
        return 0;
 }
 
index 57390c7666e5dd8d44bfe9bdf1e503afb13de189..b0b02a5011672b6670e136728b2c2a8a8f2ee68e 100644 (file)
@@ -492,12 +492,19 @@ static bool in_range(struct gntdev_grant_map *map,
        return true;
 }
 
-static void unmap_if_in_range(struct gntdev_grant_map *map,
-                             unsigned long start, unsigned long end)
+static int unmap_if_in_range(struct gntdev_grant_map *map,
+                             unsigned long start, unsigned long end,
+                             bool blockable)
 {
        unsigned long mstart, mend;
        int err;
 
+       if (!in_range(map, start, end))
+               return 0;
+
+       if (!blockable)
+               return -EAGAIN;
+
        mstart = max(start, map->vma->vm_start);
        mend   = min(end,   map->vma->vm_end);
        pr_debug("map %d+%d (%lx %lx), range %lx %lx, mrange %lx %lx\n",
@@ -508,6 +515,8 @@ static void unmap_if_in_range(struct gntdev_grant_map *map,
                                (mstart - map->vma->vm_start) >> PAGE_SHIFT,
                                (mend - mstart) >> PAGE_SHIFT);
        WARN_ON(err);
+
+       return 0;
 }
 
 static int mn_invl_range_start(struct mmu_notifier *mn,
@@ -519,25 +528,20 @@ static int mn_invl_range_start(struct mmu_notifier *mn,
        struct gntdev_grant_map *map;
        int ret = 0;
 
-       /* TODO do we really need a mutex here? */
        if (blockable)
                mutex_lock(&priv->lock);
        else if (!mutex_trylock(&priv->lock))
                return -EAGAIN;
 
        list_for_each_entry(map, &priv->maps, next) {
-               if (in_range(map, start, end)) {
-                       ret = -EAGAIN;
+               ret = unmap_if_in_range(map, start, end, blockable);
+               if (ret)
                        goto out_unlock;
-               }
-               unmap_if_in_range(map, start, end);
        }
        list_for_each_entry(map, &priv->freeable_maps, next) {
-               if (in_range(map, start, end)) {
-                       ret = -EAGAIN;
+               ret = unmap_if_in_range(map, start, end, blockable);
+               if (ret)
                        goto out_unlock;
-               }
-               unmap_if_in_range(map, start, end);
        }
 
 out_unlock:
index 7bafa703a9929b086304be135e2ed1ba67dcabf8..84575baceebc829305e49b8855a0cad9c188a9fc 100644 (file)
@@ -1040,18 +1040,33 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
                return ret;
 
        for (i = 0; i < count; i++) {
-               /* Retry eagain maps */
-               if (map_ops[i].status == GNTST_eagain)
-                       gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i,
-                                               &map_ops[i].status, __func__);
-
-               if (map_ops[i].status == GNTST_okay) {
+               switch (map_ops[i].status) {
+               case GNTST_okay:
+               {
                        struct xen_page_foreign *foreign;
 
                        SetPageForeign(pages[i]);
                        foreign = xen_page_foreign(pages[i]);
                        foreign->domid = map_ops[i].dom;
                        foreign->gref = map_ops[i].ref;
+                       break;
+               }
+
+               case GNTST_no_device_space:
+                       pr_warn_ratelimited("maptrack limit reached, can't map all guest pages\n");
+                       break;
+
+               case GNTST_eagain:
+                       /* Retry eagain maps */
+                       gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref,
+                                               map_ops + i,
+                                               &map_ops[i].status, __func__);
+                       /* Test status in next loop iteration. */
+                       i--;
+                       break;
+
+               default:
+                       break;
                }
        }
 
index c93d8ef8df3483bbc393b2101c189120f844b634..5bb01a62f214da835ca2e941c3c928b50cf733a0 100644 (file)
@@ -280,9 +280,11 @@ static void sysrq_handler(struct xenbus_watch *watch, const char *path,
                /*
                 * The Xenstore watch fires directly after registering it and
                 * after a suspend/resume cycle. So ENOENT is no error but
-                * might happen in those cases.
+                * might happen in those cases. ERANGE is observed when we get
+                * an empty value (''), this happens when we acknowledge the
+                * request by writing '\0' below.
                 */
-               if (err != -ENOENT)
+               if (err != -ENOENT && err != -ERANGE)
                        pr_err("Error %d reading sysrq code in control/sysrq\n",
                               err);
                xenbus_transaction_end(xbt, 1);
index 084799c6180e6e6cb281eb882637b42999a1e683..3782cf070338e3fa5f830184a784dd9e2d0c666a 100644 (file)
 
 #include <xen/interface/memory.h>
 #include <xen/mem-reservation.h>
+#include <linux/moduleparam.h>
+
+bool __read_mostly xen_scrub_pages = IS_ENABLED(CONFIG_XEN_SCRUB_PAGES_DEFAULT);
+core_param(xen_scrub_pages, xen_scrub_pages, bool, 0);
 
 /*
  * Use one extent per PAGE_SIZE to avoid to break down the page into
index 294f35ce9e46bc063a7e01061462cf3e298b4364..63c1494a8d73bf2f53f0f0a1887290f338ae454a 100644 (file)
@@ -44,6 +44,7 @@
 #include <xen/xenbus.h>
 #include <xen/features.h>
 #include <xen/page.h>
+#include <xen/mem-reservation.h>
 
 #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
 
@@ -137,6 +138,7 @@ static DEVICE_ULONG_ATTR(schedule_delay, 0444, balloon_stats.schedule_delay);
 static DEVICE_ULONG_ATTR(max_schedule_delay, 0644, balloon_stats.max_schedule_delay);
 static DEVICE_ULONG_ATTR(retry_count, 0444, balloon_stats.retry_count);
 static DEVICE_ULONG_ATTR(max_retry_count, 0644, balloon_stats.max_retry_count);
+static DEVICE_BOOL_ATTR(scrub_pages, 0644, xen_scrub_pages);
 
 static ssize_t show_target_kb(struct device *dev, struct device_attribute *attr,
                              char *buf)
@@ -203,6 +205,7 @@ static struct attribute *balloon_attrs[] = {
        &dev_attr_max_schedule_delay.attr.attr,
        &dev_attr_retry_count.attr.attr,
        &dev_attr_max_retry_count.attr.attr,
+       &dev_attr_scrub_pages.attr.attr,
        NULL
 };
 
index 35c83fe7dba0115007a344821d0a4d5dfcbbd23d..abcd78e332feb05ad8fa7f540d14917d2835f68b 100644 (file)
@@ -6,6 +6,7 @@ config CIFS
        select CRYPTO_MD4
        select CRYPTO_MD5
        select CRYPTO_SHA256
+       select CRYPTO_SHA512
        select CRYPTO_CMAC
        select CRYPTO_HMAC
        select CRYPTO_ARC4
index dc2f4cf08fe94a22def3309b4d35b4f0358a0ec3..5657b79dbc99f1e7fd87061a8270504d97743dfc 100644 (file)
@@ -601,10 +601,15 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
        }
 
        count = 0;
+       /*
+        * We know that all the name entries in the protocols array
+        * are short (< 16 bytes anyway) and are NUL terminated.
+        */
        for (i = 0; i < CIFS_NUM_PROT; i++) {
-               strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
-               count += strlen(protocols[i].name) + 1;
-               /* null at end of source and target buffers anyway */
+               size_t len = strlen(protocols[i].name) + 1;
+
+               memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
+               count += len;
        }
        inc_rfc1001_len(pSMB, count);
        pSMB->ByteCount = cpu_to_le16(count);
index dacb2c05674c5d7f11f7c4c9144646a95039d106..6926685e513cf4a3691df7efba36eb3dcb578b83 100644 (file)
@@ -402,9 +402,17 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
                        (struct smb_com_transaction_change_notify_rsp *)buf;
                struct file_notify_information *pnotify;
                __u32 data_offset = 0;
+               size_t len = srv->total_read - sizeof(pSMBr->hdr.smb_buf_length);
+
                if (get_bcc(buf) > sizeof(struct file_notify_information)) {
                        data_offset = le32_to_cpu(pSMBr->DataOffset);
 
+                       if (data_offset >
+                           len - sizeof(struct file_notify_information)) {
+                               cifs_dbg(FYI, "invalid data_offset %u\n",
+                                        data_offset);
+                               return true;
+                       }
                        pnotify = (struct file_notify_information *)
                                ((char *)&pSMBr->hdr.Protocol + data_offset);
                        cifs_dbg(FYI, "dnotify on %s Action: 0x%x\n",
index eeab81c9452f86e61948198b0d938ea8b6a9a5dd..e169e1a5fd358c5ac9649f1f24e7a4fb876d3635 100644 (file)
@@ -376,8 +376,15 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
 
                new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) +
                                pfData->FileNameLength;
-       } else
-               new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
+       } else {
+               u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset);
+
+               if (old_entry + next_offset < old_entry) {
+                       cifs_dbg(VFS, "invalid offset %u\n", next_offset);
+                       return NULL;
+               }
+               new_entry = old_entry + next_offset;
+       }
        cifs_dbg(FYI, "new entry %p old entry %p\n", new_entry, old_entry);
        /* validate that new_entry is not past end of SMB */
        if (new_entry >= end_of_smb) {
index c08acfc77abcf6f5190a0ce65d110a1b2f897875..f54d07bda067c224c3bac6f511458330dbcc502e 100644 (file)
@@ -2459,14 +2459,14 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
        /* We check for obvious errors in the output buffer length and offset */
        if (*plen == 0)
                goto ioctl_exit; /* server returned no data */
-       else if (*plen > 0xFF00) {
+       else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) {
                cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
                *plen = 0;
                rc = -EIO;
                goto ioctl_exit;
        }
 
-       if (rsp_iov.iov_len < le32_to_cpu(rsp->OutputOffset) + *plen) {
+       if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) {
                cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
                        le32_to_cpu(rsp->OutputOffset));
                *plen = 0;
@@ -3577,33 +3577,38 @@ num_entries(char *bufstart, char *end_of_buf, char **lastentry, size_t size)
        int len;
        unsigned int entrycount = 0;
        unsigned int next_offset = 0;
-       FILE_DIRECTORY_INFO *entryptr;
+       char *entryptr;
+       FILE_DIRECTORY_INFO *dir_info;
 
        if (bufstart == NULL)
                return 0;
 
-       entryptr = (FILE_DIRECTORY_INFO *)bufstart;
+       entryptr = bufstart;
 
        while (1) {
-               entryptr = (FILE_DIRECTORY_INFO *)
-                                       ((char *)entryptr + next_offset);
-
-               if ((char *)entryptr + size > end_of_buf) {
+               if (entryptr + next_offset < entryptr ||
+                   entryptr + next_offset > end_of_buf ||
+                   entryptr + next_offset + size > end_of_buf) {
                        cifs_dbg(VFS, "malformed search entry would overflow\n");
                        break;
                }
 
-               len = le32_to_cpu(entryptr->FileNameLength);
-               if ((char *)entryptr + len + size > end_of_buf) {
+               entryptr = entryptr + next_offset;
+               dir_info = (FILE_DIRECTORY_INFO *)entryptr;
+
+               len = le32_to_cpu(dir_info->FileNameLength);
+               if (entryptr + len < entryptr ||
+                   entryptr + len > end_of_buf ||
+                   entryptr + len + size > end_of_buf) {
                        cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
                                 end_of_buf);
                        break;
                }
 
-               *lastentry = (char *)entryptr;
+               *lastentry = entryptr;
                entrycount++;
 
-               next_offset = le32_to_cpu(entryptr->NextEntryOffset);
+               next_offset = le32_to_cpu(dir_info->NextEntryOffset);
                if (!next_offset)
                        break;
        }
index f32d7125ad0f237d61173cd72383683ac380c4e4..b68ce484e1be7f58ea9379cce298e82bd88ebcfd 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1120,21 +1120,12 @@ static vm_fault_t dax_load_hole(struct address_space *mapping, void *entry,
 {
        struct inode *inode = mapping->host;
        unsigned long vaddr = vmf->address;
-       vm_fault_t ret = VM_FAULT_NOPAGE;
-       struct page *zero_page;
-       pfn_t pfn;
-
-       zero_page = ZERO_PAGE(0);
-       if (unlikely(!zero_page)) {
-               ret = VM_FAULT_OOM;
-               goto out;
-       }
+       pfn_t pfn = pfn_to_pfn_t(my_zero_pfn(vaddr));
+       vm_fault_t ret;
 
-       pfn = page_to_pfn_t(zero_page);
        dax_insert_mapping_entry(mapping, vmf, entry, pfn, RADIX_DAX_ZERO_PAGE,
                        false);
        ret = vmf_insert_mixed(vmf->vma, vaddr, pfn);
-out:
        trace_dax_load_hole(inode, vmf, ret);
        return ret;
 }
index 7f7ee18fe179c258ca9ccb41148592d816ec96f6..e4bb9386c04551e1af155154213285c6da688531 100644 (file)
@@ -1448,6 +1448,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
        }
        inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
+       ext2_set_inode_flags(inode);
        ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
        ei->i_frag_no = raw_inode->i_frag;
        ei->i_frag_size = raw_inode->i_fsize;
@@ -1517,7 +1518,6 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
                           new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
        }
        brelse (bh);
-       ext2_set_inode_flags(inode);
        unlock_new_inode(inode);
        return inode;
        
index e2902d394f1badb78bd4c96cbb45d3814fb74265..f93f9881ec184c351e69af715a849d1a01562b95 100644 (file)
@@ -76,7 +76,7 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
        else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
                error_msg = "rec_len is too small for name_len";
        else if (unlikely(((char *) de - buf) + rlen > size))
-               error_msg = "directory entry across range";
+               error_msg = "directory entry overrun";
        else if (unlikely(le32_to_cpu(de->inode) >
                        le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
                error_msg = "inode out of bounds";
@@ -85,18 +85,16 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
 
        if (filp)
                ext4_error_file(filp, function, line, bh->b_blocknr,
-                               "bad entry in directory: %s - offset=%u(%u), "
-                               "inode=%u, rec_len=%d, name_len=%d",
-                               error_msg, (unsigned) (offset % size),
-                               offset, le32_to_cpu(de->inode),
-                               rlen, de->name_len);
+                               "bad entry in directory: %s - offset=%u, "
+                               "inode=%u, rec_len=%d, name_len=%d, size=%d",
+                               error_msg, offset, le32_to_cpu(de->inode),
+                               rlen, de->name_len, size);
        else
                ext4_error_inode(dir, function, line, bh->b_blocknr,
-                               "bad entry in directory: %s - offset=%u(%u), "
-                               "inode=%u, rec_len=%d, name_len=%d",
-                               error_msg, (unsigned) (offset % size),
-                               offset, le32_to_cpu(de->inode),
-                               rlen, de->name_len);
+                               "bad entry in directory: %s - offset=%u, "
+                               "inode=%u, rec_len=%d, name_len=%d, size=%d",
+                                error_msg, offset, le32_to_cpu(de->inode),
+                                rlen, de->name_len, size);
 
        return 1;
 }
index 0f0edd1cd0cd259f81eb0349e25ae9efb34641cc..caff935fbeb8f100049bf0aab09f7e14c53fa40e 100644 (file)
 #define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION)
 #include <linux/fscrypt.h>
 
+#include <linux/compiler.h>
+
+/* Until this gets included into linux/compiler-gcc.h */
+#ifndef __nonstring
+#if defined(GCC_VERSION) && (GCC_VERSION >= 80000)
+#define __nonstring __attribute__((nonstring))
+#else
+#define __nonstring
+#endif
+#endif
+
 /*
  * The fourth extended filesystem constants/structures
  */
@@ -675,6 +686,9 @@ enum {
 /* Max physical block we can address w/o extents */
 #define EXT4_MAX_BLOCK_FILE_PHYS       0xFFFFFFFF
 
+/* Max logical block we can support */
+#define EXT4_MAX_LOGICAL_BLOCK         0xFFFFFFFF
+
 /*
  * Structure of an inode on the disk
  */
@@ -1226,7 +1240,7 @@ struct ext4_super_block {
        __le32  s_feature_ro_compat;    /* readonly-compatible feature set */
 /*68*/ __u8    s_uuid[16];             /* 128-bit uuid for volume */
 /*78*/ char    s_volume_name[16];      /* volume name */
-/*88*/ char    s_last_mounted[64];     /* directory where last mounted */
+/*88*/ char    s_last_mounted[64] __nonstring; /* directory where last mounted */
 /*C8*/ __le32  s_algorithm_usage_bitmap; /* For compression */
        /*
         * Performance hints.  Directory preallocation should only
@@ -1277,13 +1291,13 @@ struct ext4_super_block {
        __le32  s_first_error_time;     /* first time an error happened */
        __le32  s_first_error_ino;      /* inode involved in first error */
        __le64  s_first_error_block;    /* block involved of first error */
-       __u8    s_first_error_func[32]; /* function where the error happened */
+       __u8    s_first_error_func[32] __nonstring;     /* function where the error happened */
        __le32  s_first_error_line;     /* line number where error happened */
        __le32  s_last_error_time;      /* most recent time of an error */
        __le32  s_last_error_ino;       /* inode involved in last error */
        __le32  s_last_error_line;      /* line number where error happened */
        __le64  s_last_error_block;     /* block involved of last error */
-       __u8    s_last_error_func[32];  /* function where the error happened */
+       __u8    s_last_error_func[32] __nonstring;      /* function where the error happened */
 #define EXT4_S_ERR_END offsetof(struct ext4_super_block, s_mount_opts)
        __u8    s_mount_opts[64];
        __le32  s_usr_quota_inum;       /* inode for tracking user quota */
index 3543fe80a3c442364d752fcbb74a7edd4df97dc9..7b47360227612926f1da1f3f95f94d3e4f4f6ab0 100644 (file)
@@ -1753,6 +1753,7 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data)
 {
        int err, inline_size;
        struct ext4_iloc iloc;
+       size_t inline_len;
        void *inline_pos;
        unsigned int offset;
        struct ext4_dir_entry_2 *de;
@@ -1780,8 +1781,9 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data)
                goto out;
        }
 
+       inline_len = ext4_get_inline_size(dir);
        offset = EXT4_INLINE_DOTDOT_SIZE;
-       while (offset < dir->i_size) {
+       while (offset < inline_len) {
                de = ext4_get_inline_entry(dir, &iloc, offset,
                                           &inline_pos, &inline_size);
                if (ext4_check_dir_entry(dir, NULL, de,
index d0dd585add6a005684c569d6edaecc481f926f2d..d767e993591d93f335ae85b876a5c12ceae35b7a 100644 (file)
@@ -3413,12 +3413,16 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
 {
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        unsigned int blkbits = inode->i_blkbits;
-       unsigned long first_block = offset >> blkbits;
-       unsigned long last_block = (offset + length - 1) >> blkbits;
+       unsigned long first_block, last_block;
        struct ext4_map_blocks map;
        bool delalloc = false;
        int ret;
 
+       if ((offset >> blkbits) > EXT4_MAX_LOGICAL_BLOCK)
+               return -EINVAL;
+       first_block = offset >> blkbits;
+       last_block = min_t(loff_t, (offset + length - 1) >> blkbits,
+                          EXT4_MAX_LOGICAL_BLOCK);
 
        if (flags & IOMAP_REPORT) {
                if (ext4_has_inline_data(inode)) {
@@ -3948,6 +3952,7 @@ static const struct address_space_operations ext4_dax_aops = {
        .writepages             = ext4_dax_writepages,
        .direct_IO              = noop_direct_IO,
        .set_page_dirty         = noop_set_page_dirty,
+       .bmap                   = ext4_bmap,
        .invalidatepage         = noop_invalidatepage,
 };
 
@@ -4192,9 +4197,8 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
        return 0;
 }
 
-static void ext4_wait_dax_page(struct ext4_inode_info *ei, bool *did_unlock)
+static void ext4_wait_dax_page(struct ext4_inode_info *ei)
 {
-       *did_unlock = true;
        up_write(&ei->i_mmap_sem);
        schedule();
        down_write(&ei->i_mmap_sem);
@@ -4204,14 +4208,12 @@ int ext4_break_layouts(struct inode *inode)
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
        struct page *page;
-       bool retry;
        int error;
 
        if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
                return -EINVAL;
 
        do {
-               retry = false;
                page = dax_layout_busy_page(inode->i_mapping);
                if (!page)
                        return 0;
@@ -4219,8 +4221,8 @@ int ext4_break_layouts(struct inode *inode)
                error = ___wait_var_event(&page->_refcount,
                                atomic_read(&page->_refcount) == 1,
                                TASK_INTERRUPTIBLE, 0, 0,
-                               ext4_wait_dax_page(ei, &retry));
-       } while (error == 0 && retry);
+                               ext4_wait_dax_page(ei));
+       } while (error == 0);
 
        return error;
 }
@@ -4895,6 +4897,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
                 * not initialized on a new filesystem. */
        }
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
+       ext4_set_inode_flags(inode);
        inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
        ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
        if (ext4_has_feature_64bit(sb))
@@ -5041,7 +5044,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
                goto bad_inode;
        }
        brelse(iloc.bh);
-       ext4_set_inode_flags(inode);
 
        unlock_new_inode(inode);
        return inode;
index 39b07c2d3384013298a7533a4353dce66e0ab842..2305b4374fd3e020eea80de3293040fd59d5de84 100644 (file)
@@ -49,7 +49,6 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
         */
        sb_start_write(sb);
        ext4_mmp_csum_set(sb, mmp);
-       mark_buffer_dirty(bh);
        lock_buffer(bh);
        bh->b_end_io = end_buffer_write_sync;
        get_bh(bh);
index 116ff68c5bd4337b7cb751330d091fcab24eecba..377d516c475f06400452f6e83642baa18661486a 100644 (file)
@@ -3478,6 +3478,12 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
        int credits;
        u8 old_file_type;
 
+       if (new.inode && new.inode->i_nlink == 0) {
+               EXT4_ERROR_INODE(new.inode,
+                                "target of rename is already freed");
+               return -EFSCORRUPTED;
+       }
+
        if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT)) &&
            (!projid_eq(EXT4_I(new_dir)->i_projid,
                        EXT4_I(old_dentry->d_inode)->i_projid)))
index e5fb38451a733cc947a5c9f77c478545b5699013..ebbc663d07985038ef17520fb41c5fae0e5d3637 100644 (file)
@@ -19,6 +19,7 @@
 
 int ext4_resize_begin(struct super_block *sb)
 {
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
        int ret = 0;
 
        if (!capable(CAP_SYS_RESOURCE))
@@ -29,7 +30,7 @@ int ext4_resize_begin(struct super_block *sb)
          * because the user tools have no way of handling this.  Probably a
          * bad time to do it anyways.
          */
-       if (EXT4_SB(sb)->s_sbh->b_blocknr !=
+       if (EXT4_B2C(sbi, sbi->s_sbh->b_blocknr) !=
            le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
                ext4_warning(sb, "won't resize using backup superblock at %llu",
                        (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
@@ -1986,6 +1987,26 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
                }
        }
 
+       /*
+        * Make sure the last group has enough space so that it's
+        * guaranteed to have enough space for all metadata blocks
+        * that it might need to hold.  (We might not need to store
+        * the inode table blocks in the last block group, but there
+        * will be cases where this might be needed.)
+        */
+       if ((ext4_group_first_block_no(sb, n_group) +
+            ext4_group_overhead_blocks(sb, n_group) + 2 +
+            sbi->s_itb_per_group + sbi->s_cluster_ratio) >= n_blocks_count) {
+               n_blocks_count = ext4_group_first_block_no(sb, n_group);
+               n_group--;
+               n_blocks_count_retry = 0;
+               if (resize_inode) {
+                       iput(resize_inode);
+                       resize_inode = NULL;
+               }
+               goto retry;
+       }
+
        /* extend the last group */
        if (n_group == o_group)
                add = n_blocks_count - o_blocks_count;
index 5863fd22e90bb20c102274f3e320637858bdef87..1145109968efd356a812744537d94d929b62f7ce 100644 (file)
@@ -2145,6 +2145,8 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
                SEQ_OPTS_PRINT("max_dir_size_kb=%u", sbi->s_max_dir_size_kb);
        if (test_opt(sb, DATA_ERR_ABORT))
                SEQ_OPTS_PUTS("data_err=abort");
+       if (DUMMY_ENCRYPTION_ENABLED(sbi))
+               SEQ_OPTS_PUTS("test_dummy_encryption");
 
        ext4_show_quota_options(seq, sb);
        return 0;
@@ -4378,11 +4380,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        block = ext4_count_free_clusters(sb);
        ext4_free_blocks_count_set(sbi->s_es, 
                                   EXT4_C2B(sbi, block));
+       ext4_superblock_csum_set(sb);
        err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
                                  GFP_KERNEL);
        if (!err) {
                unsigned long freei = ext4_count_free_inodes(sb);
                sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
+               ext4_superblock_csum_set(sb);
                err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
                                          GFP_KERNEL);
        }
index 34830f6457ea252a2b56b9ef379b6ca3551f4f46..8220a168282e054164cb5b3bb8534f76be89faa7 100644 (file)
@@ -1637,6 +1637,14 @@ static void nfs_state_set_delegation(struct nfs4_state *state,
        write_sequnlock(&state->seqlock);
 }
 
+static void nfs_state_clear_delegation(struct nfs4_state *state)
+{
+       write_seqlock(&state->seqlock);
+       nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+       clear_bit(NFS_DELEGATED_STATE, &state->flags);
+       write_sequnlock(&state->seqlock);
+}
+
 static int update_open_stateid(struct nfs4_state *state,
                const nfs4_stateid *open_stateid,
                const nfs4_stateid *delegation,
@@ -2145,10 +2153,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
        if (IS_ERR(opendata))
                return PTR_ERR(opendata);
        nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
-       write_seqlock(&state->seqlock);
-       nfs4_stateid_copy(&state->stateid, &state->open_stateid);
-       write_sequnlock(&state->seqlock);
-       clear_bit(NFS_DELEGATED_STATE, &state->flags);
+       nfs_state_clear_delegation(state);
        switch (type & (FMODE_READ|FMODE_WRITE)) {
        case FMODE_READ|FMODE_WRITE:
        case FMODE_WRITE:
@@ -2601,10 +2606,7 @@ static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state,
                const nfs4_stateid *stateid)
 {
        nfs_remove_bad_delegation(state->inode, stateid);
-       write_seqlock(&state->seqlock);
-       nfs4_stateid_copy(&state->stateid, &state->open_stateid);
-       write_sequnlock(&state->seqlock);
-       clear_bit(NFS_DELEGATED_STATE, &state->flags);
+       nfs_state_clear_delegation(state);
 }
 
 static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
@@ -2672,15 +2674,20 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
        delegation = rcu_dereference(NFS_I(state->inode)->delegation);
        if (delegation == NULL) {
                rcu_read_unlock();
+               nfs_state_clear_delegation(state);
                return;
        }
 
        nfs4_stateid_copy(&stateid, &delegation->stateid);
-       if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) ||
-               !test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
-                       &delegation->flags)) {
+       if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
+               rcu_read_unlock();
+               nfs_state_clear_delegation(state);
+               return;
+       }
+
+       if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
+                               &delegation->flags)) {
                rcu_read_unlock();
-               nfs_finish_clear_delegation_stateid(state, &stateid);
                return;
        }
 
index 3df0eb52da1c97d3802c34702068a36f31f02d69..40a08cd483f051072508b53eee362167ce26904f 100644 (file)
@@ -1390,6 +1390,8 @@ int nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_
 
        if (!nfs4_state_mark_reclaim_nograce(clp, state))
                return -EBADF;
+       nfs_inode_find_delegation_state_and_recover(state->inode,
+                       &state->stateid);
        dprintk("%s: scheduling stateid recovery for server %s\n", __func__,
                        clp->cl_hostname);
        nfs4_schedule_state_manager(clp);
index a275fba93170c2ba190987e8b546f194868e4394..b1483b303e0bf35a268bccad1823fd6b89015e97 100644 (file)
@@ -1137,7 +1137,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event,
                TP_fast_assign(
                        __entry->error = error;
                        __entry->fhandle = nfs_fhandle_hash(fhandle);
-                       if (inode != NULL) {
+                       if (!IS_ERR_OR_NULL(inode)) {
                                __entry->fileid = NFS_FILEID(inode);
                                __entry->dev = inode->i_sb->s_dev;
                        } else {
@@ -1194,7 +1194,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event,
                TP_fast_assign(
                        __entry->error = error;
                        __entry->fhandle = nfs_fhandle_hash(fhandle);
-                       if (inode != NULL) {
+                       if (!IS_ERR_OR_NULL(inode)) {
                                __entry->fileid = NFS_FILEID(inode);
                                __entry->dev = inode->i_sb->s_dev;
                        } else {
index e8f232de484f4d591666c6789b9932404e6fc5cb..7d9a51e6b847c65df159d6632a98ac891370f80f 100644 (file)
@@ -1740,16 +1740,16 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
        return ret;
 }
 
-static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
+static int pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
 {
        /*
         * send layoutcommit as it can hold up layoutreturn due to lseg
         * reference
         */
        pnfs_layoutcommit_inode(lo->plh_inode, false);
-       return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
+       return wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
                                   nfs_wait_bit_killable,
-                                  TASK_UNINTERRUPTIBLE);
+                                  TASK_KILLABLE);
 }
 
 static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo)
@@ -1830,7 +1830,9 @@ pnfs_update_layout(struct inode *ino,
        }
 
 lookup_again:
-       nfs4_client_recover_expired_lease(clp);
+       lseg = ERR_PTR(nfs4_client_recover_expired_lease(clp));
+       if (IS_ERR(lseg))
+               goto out;
        first = false;
        spin_lock(&ino->i_lock);
        lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
@@ -1863,9 +1865,9 @@ pnfs_update_layout(struct inode *ino,
        if (list_empty(&lo->plh_segs) &&
            atomic_read(&lo->plh_outstanding) != 0) {
                spin_unlock(&ino->i_lock);
-               if (wait_var_event_killable(&lo->plh_outstanding,
-                                       atomic_read(&lo->plh_outstanding) == 0
-                                       || !list_empty(&lo->plh_segs)))
+               lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
+                                       atomic_read(&lo->plh_outstanding)));
+               if (IS_ERR(lseg) || !list_empty(&lo->plh_segs))
                        goto out_put_layout_hdr;
                pnfs_put_layout_hdr(lo);
                goto lookup_again;
@@ -1898,8 +1900,11 @@ pnfs_update_layout(struct inode *ino,
                if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET,
                                     &lo->plh_flags)) {
                        spin_unlock(&ino->i_lock);
-                       wait_on_bit(&lo->plh_flags, NFS_LAYOUT_FIRST_LAYOUTGET,
-                                   TASK_UNINTERRUPTIBLE);
+                       lseg = ERR_PTR(wait_on_bit(&lo->plh_flags,
+                                               NFS_LAYOUT_FIRST_LAYOUTGET,
+                                               TASK_KILLABLE));
+                       if (IS_ERR(lseg))
+                               goto out_put_layout_hdr;
                        pnfs_put_layout_hdr(lo);
                        dprintk("%s retrying\n", __func__);
                        goto lookup_again;
@@ -1925,7 +1930,8 @@ pnfs_update_layout(struct inode *ino,
        if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
                spin_unlock(&ino->i_lock);
                dprintk("%s wait for layoutreturn\n", __func__);
-               if (pnfs_prepare_to_retry_layoutget(lo)) {
+               lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo));
+               if (!IS_ERR(lseg)) {
                        if (first)
                                pnfs_clear_first_layoutget(lo);
                        pnfs_put_layout_hdr(lo);
index d9ebe11c89909b8587fa3d7faa491c75426bed87..1d098c3c00e023540d6f0665720390647945af58 100644 (file)
@@ -342,6 +342,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
                                 * for this bh as it's not marked locally
                                 * uptodate. */
                                status = -EIO;
+                               clear_buffer_needs_validate(bh);
                                put_bh(bh);
                                bhs[i] = NULL;
                                continue;
index 32e9282893c93467df0f967be3d9ee848b373244..aeaefd2a551b015d63b47cbe9ab25a204a9d3cb3 100644 (file)
@@ -131,9 +131,6 @@ static int ovl_open(struct inode *inode, struct file *file)
        if (IS_ERR(realfile))
                return PTR_ERR(realfile);
 
-       /* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */
-       file->f_mapping = realfile->f_mapping;
-
        file->private_data = realfile;
 
        return 0;
@@ -334,6 +331,25 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
        return ret;
 }
 
+static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
+{
+       struct fd real;
+       const struct cred *old_cred;
+       int ret;
+
+       ret = ovl_real_fdget(file, &real);
+       if (ret)
+               return ret;
+
+       old_cred = ovl_override_creds(file_inode(file)->i_sb);
+       ret = vfs_fadvise(real.file, offset, len, advice);
+       revert_creds(old_cred);
+
+       fdput(real);
+
+       return ret;
+}
+
 static long ovl_real_ioctl(struct file *file, unsigned int cmd,
                           unsigned long arg)
 {
@@ -502,6 +518,7 @@ const struct file_operations ovl_file_operations = {
        .fsync          = ovl_fsync,
        .mmap           = ovl_mmap,
        .fallocate      = ovl_fallocate,
+       .fadvise        = ovl_fadvise,
        .unlocked_ioctl = ovl_ioctl,
        .compat_ioctl   = ovl_compat_ioctl,
 
index e0bb217c01e2a6c8389bf9ec2dfb2f56f0fab7c8..b6ac545b5a32188297352dd0793565423fee2fcb 100644 (file)
@@ -467,6 +467,10 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                return -EOPNOTSUPP;
 
        old_cred = ovl_override_creds(inode->i_sb);
+
+       if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
+               filemap_write_and_wait(realinode->i_mapping);
+
        err = realinode->i_op->fiemap(realinode, fieinfo, start, len);
        revert_creds(old_cred);
 
@@ -500,6 +504,11 @@ static const struct inode_operations ovl_special_inode_operations = {
        .update_time    = ovl_update_time,
 };
 
+const struct address_space_operations ovl_aops = {
+       /* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */
+       .direct_IO              = noop_direct_IO,
+};
+
 /*
  * It is possible to stack overlayfs instance on top of another
  * overlayfs instance as lower layer. We need to annonate the
@@ -571,6 +580,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev,
        case S_IFREG:
                inode->i_op = &ovl_file_inode_operations;
                inode->i_fop = &ovl_file_operations;
+               inode->i_mapping->a_ops = &ovl_aops;
                break;
 
        case S_IFDIR:
index 2e0fc93c2c06646ccf5c67c43836f9d4989da501..30adc9d408a0df84455b86811ee468faf439c0c1 100644 (file)
@@ -982,16 +982,6 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath)
        if (err)
                goto out;
 
-       err = -EBUSY;
-       if (ovl_inuse_trylock(upperpath->dentry)) {
-               ofs->upperdir_locked = true;
-       } else if (ofs->config.index) {
-               pr_err("overlayfs: upperdir is in-use by another mount, mount with '-o index=off' to override exclusive upperdir protection.\n");
-               goto out;
-       } else {
-               pr_warn("overlayfs: upperdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n");
-       }
-
        upper_mnt = clone_private_mount(upperpath);
        err = PTR_ERR(upper_mnt);
        if (IS_ERR(upper_mnt)) {
@@ -1002,6 +992,17 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath)
        /* Don't inherit atime flags */
        upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME);
        ofs->upper_mnt = upper_mnt;
+
+       err = -EBUSY;
+       if (ovl_inuse_trylock(ofs->upper_mnt->mnt_root)) {
+               ofs->upperdir_locked = true;
+       } else if (ofs->config.index) {
+               pr_err("overlayfs: upperdir is in-use by another mount, mount with '-o index=off' to override exclusive upperdir protection.\n");
+               goto out;
+       } else {
+               pr_warn("overlayfs: upperdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n");
+       }
+
        err = 0;
 out:
        return err;
@@ -1101,8 +1102,10 @@ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
                goto out;
        }
 
+       ofs->workbasedir = dget(workpath.dentry);
+
        err = -EBUSY;
-       if (ovl_inuse_trylock(workpath.dentry)) {
+       if (ovl_inuse_trylock(ofs->workbasedir)) {
                ofs->workdir_locked = true;
        } else if (ofs->config.index) {
                pr_err("overlayfs: workdir is in-use by another mount, mount with '-o index=off' to override exclusive workdir protection.\n");
@@ -1111,7 +1114,6 @@ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
                pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n");
        }
 
-       ofs->workbasedir = dget(workpath.dentry);
        err = ovl_make_workdir(ofs, &workpath);
        if (err)
                goto out;
index ad72261ee3fe8d1959038fa0ee9bf6d0ff276449..d297fe4472a960b29fd62018535400c5b96a975f 100644 (file)
@@ -464,6 +464,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                                ret = -EFAULT;
                                goto out;
                        }
+                       m = NULL;       /* skip the list anchor */
                } else if (m->type == KCORE_VMALLOC) {
                        vread(buf, (char *)start, tsz);
                        /* we have to zero-fill user buffer even if no read */
index 951a14edcf518bb95a5ec01c9e98ae678cb1e67f..0792595ebcfb65869b5e82c5eec87e2bc89c1efc 100644 (file)
@@ -429,7 +429,12 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
        vaddr = vmap(pages, page_count, VM_MAP, prot);
        kfree(pages);
 
-       return vaddr;
+       /*
+        * Since vmap() uses page granularity, we must add the offset
+        * into the page here, to get the byte granularity address
+        * into the mapping to represent the actual "start" location.
+        */
+       return vaddr + offset_in_page(start);
 }
 
 static void *persistent_ram_iomap(phys_addr_t start, size_t size,
@@ -448,6 +453,11 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
        else
                va = ioremap_wc(start, size);
 
+       /*
+        * Since request_mem_region() and ioremap() are byte-granularity
+        * there is no need handle anything special like we do when the
+        * vmap() case in persistent_ram_vmap() above.
+        */
        return va;
 }
 
@@ -468,7 +478,7 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
                return -ENOMEM;
        }
 
-       prz->buffer = prz->vaddr + offset_in_page(start);
+       prz->buffer = prz->vaddr;
        prz->buffer_size = size - sizeof(struct persistent_ram_buffer);
 
        return 0;
@@ -515,7 +525,8 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
 
        if (prz->vaddr) {
                if (pfn_valid(prz->paddr >> PAGE_SHIFT)) {
-                       vunmap(prz->vaddr);
+                       /* We must vunmap() at page-granularity. */
+                       vunmap(prz->vaddr - offset_in_page(prz->paddr));
                } else {
                        iounmap(prz->vaddr);
                        release_mem_region(prz->paddr, prz->size);
index 23e7042666a755dd361720e3a29b1a56585fee33..bf000c8aeffbb30fe8b1ebbed322540021f0bb55 100644 (file)
@@ -1912,7 +1912,9 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
                mutex_unlock(&c->bu_mutex);
        }
 
-       ubifs_assert(c, c->lst.taken_empty_lebs > 0);
+       if (!c->need_recovery)
+               ubifs_assert(c, c->lst.taken_empty_lebs > 0);
+
        return 0;
 }
 
@@ -1954,6 +1956,9 @@ static struct ubi_volume_desc *open_ubi(const char *name, int mode)
        int dev, vol;
        char *endptr;
 
+       if (!name || !*name)
+               return ERR_PTR(-EINVAL);
+
        /* First, try to open using the device node path method */
        ubi = ubi_open_volume_path(name, mode);
        if (!IS_ERR(ubi))
index 61afdfee4b28bcacf49c65096e1d66d3603b9a2c..f5ad1ede7990789518d96ec45218dd667476fb87 100644 (file)
@@ -152,12 +152,6 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
        ui->data_len = size;
 
        mutex_lock(&host_ui->ui_mutex);
-
-       if (!host->i_nlink) {
-               err = -ENOENT;
-               goto out_noent;
-       }
-
        host->i_ctime = current_time(host);
        host_ui->xattr_cnt += 1;
        host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
@@ -190,7 +184,6 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
        host_ui->xattr_size -= CALC_XATTR_BYTES(size);
        host_ui->xattr_names -= fname_len(nm);
        host_ui->flags &= ~UBIFS_CRYPT_FL;
-out_noent:
        mutex_unlock(&host_ui->ui_mutex);
 out_free:
        make_bad_inode(inode);
@@ -242,12 +235,6 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
        mutex_unlock(&ui->ui_mutex);
 
        mutex_lock(&host_ui->ui_mutex);
-
-       if (!host->i_nlink) {
-               err = -ENOENT;
-               goto out_noent;
-       }
-
        host->i_ctime = current_time(host);
        host_ui->xattr_size -= CALC_XATTR_BYTES(old_size);
        host_ui->xattr_size += CALC_XATTR_BYTES(size);
@@ -269,7 +256,6 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
 out_cancel:
        host_ui->xattr_size -= CALC_XATTR_BYTES(size);
        host_ui->xattr_size += CALC_XATTR_BYTES(old_size);
-out_noent:
        mutex_unlock(&host_ui->ui_mutex);
        make_bad_inode(inode);
 out_free:
@@ -496,12 +482,6 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
                return err;
 
        mutex_lock(&host_ui->ui_mutex);
-
-       if (!host->i_nlink) {
-               err = -ENOENT;
-               goto out_noent;
-       }
-
        host->i_ctime = current_time(host);
        host_ui->xattr_cnt -= 1;
        host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
@@ -521,7 +501,6 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
        host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
        host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
        host_ui->xattr_names += fname_len(nm);
-out_noent:
        mutex_unlock(&host_ui->ui_mutex);
        ubifs_release_budget(c, &req);
        make_bad_inode(inode);
@@ -561,9 +540,6 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
 
        ubifs_assert(c, inode_is_locked(host));
 
-       if (!host->i_nlink)
-               return -ENOENT;
-
        if (fname_len(&nm) > UBIFS_MAX_NLEN)
                return -ENAMETOOLONG;
 
index 66d1d45fa2e1c11dcf17231f0a32f883bb2c1a12..d356f802945ae3348540c0cd099372a3a97f1e9e 100644 (file)
@@ -1026,7 +1026,8 @@ static inline void __iomem *ioremap_wt(phys_addr_t offset, size_t size)
 #define ioport_map ioport_map
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
-       return PCI_IOBASE + (port & MMIO_UPPER_LIMIT);
+       port &= IO_SPACE_LIMIT;
+       return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
 }
 #endif
 
index 46a8009784df1227f784774bdab50d39e03dceb5..152b3055e9e1feb449b682c8102df23d18a64df5 100644 (file)
@@ -675,7 +675,7 @@ static inline bool drm_core_check_feature(struct drm_device *dev, int feature)
 static inline bool drm_drv_uses_atomic_modeset(struct drm_device *dev)
 {
        return drm_core_check_feature(dev, DRIVER_ATOMIC) ||
-               dev->mode_config.funcs->atomic_commit != NULL;
+               (dev->mode_config.funcs && dev->mode_config.funcs->atomic_commit != NULL);
 }
 
 
index 582a0ec0aa70448e07b39f5de7f49868e5787953..777814755fa62baff930d0f2cd46e0cec1525500 100644 (file)
@@ -89,7 +89,6 @@ struct drm_panel {
        struct drm_device *drm;
        struct drm_connector *connector;
        struct device *dev;
-       struct device_link *link;
 
        const struct drm_panel_funcs *funcs;
 
index d6869e0e2b64c2b60c2916de71c9a8cd1875b732..6980014357d477793079164ce67393659def6052 100644 (file)
@@ -54,7 +54,7 @@ struct blk_stat_callback;
  * Maximum number of blkcg policies allowed to be registered concurrently.
  * Defined here to simplify include dependency.
  */
-#define BLKCG_MAX_POLS         3
+#define BLKCG_MAX_POLS         5
 
 typedef void (rq_end_io_fn)(struct request *, blk_status_t);
 
index 763bbad1e258048d9ea3e32764f4a79b8c5b59fb..4d36b27214fda629b7808ce662216d61d47e0265 100644 (file)
 #define __noretpoline __attribute__((indirect_branch("keep")))
 #endif
 
-/*
- * it doesn't make sense on ARM (currently the only user of __naked)
- * to trace naked functions because then mcount is called without
- * stack and frame pointer being set up and there is no chance to
- * restore the lr register to the value before mcount was called.
- *
- * The asm() bodies of naked functions often depend on standard calling
- * conventions, therefore they must be noinline and noclone.
- *
- * GCC 4.[56] currently fail to enforce this, so we must do so ourselves.
- * See GCC PR44290.
- */
-#define __naked                __attribute__((naked)) noinline __noclone notrace
-
 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
 
 #define __optimize(level)      __attribute__((__optimize__(level)))
index 3525c179698c238c70145574c03e71620054777c..db192becfec4998df459bc46eb739676a066852e 100644 (file)
@@ -226,6 +226,14 @@ struct ftrace_likely_data {
 #define notrace                        __attribute__((no_instrument_function))
 #endif
 
+/*
+ * it doesn't make sense on ARM (currently the only user of __naked)
+ * to trace naked functions because then mcount is called without
+ * stack and frame pointer being set up and there is no chance to
+ * restore the lr register to the value before mcount was called.
+ */
+#define __naked                        __attribute__((naked)) notrace
+
 #define __compiler_offsetof(a, b)      __builtin_offsetof(a, b)
 
 /*
index 33322702c910b9cb879d05a03c070c51487c0d26..6c0b4a1c22ff5bd84c5c4e29ce07b0366b7bc5b1 100644 (file)
@@ -1763,6 +1763,7 @@ struct file_operations {
                        u64);
        int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t,
                        u64);
+       int (*fadvise)(struct file *, loff_t, loff_t, int);
 } __randomize_layout;
 
 struct inode_operations {
@@ -3459,4 +3460,8 @@ static inline bool dir_relax_shared(struct inode *inode)
 extern bool path_noexec(const struct path *path);
 extern void inode_nohighmem(struct inode *inode);
 
+/* mm/fadvise.c */
+extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len,
+                      int advice);
+
 #endif /* _LINUX_FS_H */
index 57864422a2c8813b9f6ddd902a3c6b8794c2f4ee..25c08c6c7f99e36545dcbcc221ad865a4bcebeca 100644 (file)
@@ -83,10 +83,10 @@ struct partition {
 } __attribute__((packed));
 
 struct disk_stats {
+       u64 nsecs[NR_STAT_GROUPS];
        unsigned long sectors[NR_STAT_GROUPS];
        unsigned long ios[NR_STAT_GROUPS];
        unsigned long merges[NR_STAT_GROUPS];
-       unsigned long ticks[NR_STAT_GROUPS];
        unsigned long io_ticks;
        unsigned long time_in_queue;
 };
@@ -354,6 +354,9 @@ static inline void free_part_stats(struct hd_struct *part)
 
 #endif /* CONFIG_SMP */
 
+#define part_stat_read_msecs(part, which)                              \
+       div_u64(part_stat_read(part, nsecs[which]), NSEC_PER_MSEC)
+
 #define part_stat_read_accum(part, field)                              \
        (part_stat_read(part, field[STAT_READ]) +                       \
         part_stat_read(part, field[STAT_WRITE]) +                      \
index 834e6461a69059b059556a93e29092cd68a976fc..d44a783629425aef596d5152b23a18cdf3841c62 100644 (file)
@@ -526,6 +526,7 @@ struct hid_input {
        const char *name;
        bool registered;
        struct list_head reports;       /* the list of reports */
+       unsigned int application;       /* application usage for this input */
 };
 
 enum hid_type {
index 0205aee44dedd8522be52ffe7d3237dd3819656a..c926698040e0dad67df08b34012f9bfb6a111d7a 100644 (file)
@@ -733,8 +733,6 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu);
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
 int kvm_vcpu_yield_to(struct kvm_vcpu *target);
 void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu, bool usermode_vcpu_not_eligible);
-void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
-void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
 
 void kvm_flush_remote_tlbs(struct kvm *kvm);
 void kvm_reload_remote_mmus(struct kvm *kvm);
index 8a125701ef7ba8a4f12edef6029e2e99eb00288c..50bed4f89c1a3ce86e3c9e7d606a09426badeed5 100644 (file)
@@ -21,7 +21,7 @@
 /*
  * Regulator configuration
  */
-/* DA9063 regulator IDs */
+/* DA9063 and DA9063L regulator IDs */
 enum {
        /* BUCKs */
        DA9063_ID_BCORE1,
@@ -37,18 +37,20 @@ enum {
        DA9063_ID_BMEM_BIO_MERGED,
        /* When two BUCKs are merged, they cannot be reused separately */
 
-       /* LDOs */
+       /* LDOs on both DA9063 and DA9063L */
+       DA9063_ID_LDO3,
+       DA9063_ID_LDO7,
+       DA9063_ID_LDO8,
+       DA9063_ID_LDO9,
+       DA9063_ID_LDO11,
+
+       /* DA9063-only LDOs */
        DA9063_ID_LDO1,
        DA9063_ID_LDO2,
-       DA9063_ID_LDO3,
        DA9063_ID_LDO4,
        DA9063_ID_LDO5,
        DA9063_ID_LDO6,
-       DA9063_ID_LDO7,
-       DA9063_ID_LDO8,
-       DA9063_ID_LDO9,
        DA9063_ID_LDO10,
-       DA9063_ID_LDO11,
 };
 
 /* Regulators platform data */
index a528747f8aedb048b873353d40426d76058cffd1..e8338e5dc10bfd5e6bb415337ff3667c39e008f1 100644 (file)
@@ -78,9 +78,9 @@ enum {
        BD71837_REG_TRANS_COND0        = 0x1F,
        BD71837_REG_TRANS_COND1        = 0x20,
        BD71837_REG_VRFAULTEN          = 0x21,
-       BD71837_REG_MVRFLTMASK0        = 0x22,
-       BD71837_REG_MVRFLTMASK1        = 0x23,
-       BD71837_REG_MVRFLTMASK2        = 0x24,
+       BD718XX_REG_MVRFLTMASK0        = 0x22,
+       BD718XX_REG_MVRFLTMASK1        = 0x23,
+       BD718XX_REG_MVRFLTMASK2        = 0x24,
        BD71837_REG_RCVCFG             = 0x25,
        BD71837_REG_RCVNUM             = 0x26,
        BD71837_REG_PWRONCONFIG0       = 0x27,
@@ -159,6 +159,33 @@ enum {
 #define BUCK8_MASK             0x3F
 #define BUCK8_DEFAULT          0x1E
 
+/* BD718XX Voltage monitoring masks */
+#define BD718XX_BUCK1_VRMON80           0x1
+#define BD718XX_BUCK1_VRMON130          0x2
+#define BD718XX_BUCK2_VRMON80           0x4
+#define BD718XX_BUCK2_VRMON130          0x8
+#define BD718XX_1ST_NODVS_BUCK_VRMON80  0x1
+#define BD718XX_1ST_NODVS_BUCK_VRMON130 0x2
+#define BD718XX_2ND_NODVS_BUCK_VRMON80  0x4
+#define BD718XX_2ND_NODVS_BUCK_VRMON130 0x8
+#define BD718XX_3RD_NODVS_BUCK_VRMON80  0x10
+#define BD718XX_3RD_NODVS_BUCK_VRMON130 0x20
+#define BD718XX_4TH_NODVS_BUCK_VRMON80  0x40
+#define BD718XX_4TH_NODVS_BUCK_VRMON130 0x80
+#define BD718XX_LDO1_VRMON80            0x1
+#define BD718XX_LDO2_VRMON80            0x2
+#define BD718XX_LDO3_VRMON80            0x4
+#define BD718XX_LDO4_VRMON80            0x8
+#define BD718XX_LDO5_VRMON80            0x10
+#define BD718XX_LDO6_VRMON80            0x20
+
+/* BD71837 specific voltage monitoring masks */
+#define BD71837_BUCK3_VRMON80           0x10
+#define BD71837_BUCK3_VRMON130          0x20
+#define BD71837_BUCK4_VRMON80           0x40
+#define BD71837_BUCK4_VRMON130          0x80
+#define BD71837_LDO7_VRMON80            0x40
+
 /* BD71837_REG_IRQ bits */
 #define IRQ_SWRST              0x40
 #define IRQ_PWRON_S            0x20
index 7a452716de4be0a7902f26ccc97ce124c6b168ff..66d94b4557cf789906455683e4e69e40750f3b2c 100644 (file)
@@ -362,8 +362,8 @@ struct mlx5_frag_buf {
 struct mlx5_frag_buf_ctrl {
        struct mlx5_frag_buf    frag_buf;
        u32                     sz_m1;
-       u32                     frag_sz_m1;
-       u32                     strides_offset;
+       u16                     frag_sz_m1;
+       u16                     strides_offset;
        u8                      log_sz;
        u8                      log_stride;
        u8                      log_frag_strides;
@@ -995,7 +995,7 @@ static inline u32 mlx5_base_mkey(const u32 key)
 }
 
 static inline void mlx5_fill_fbc_offset(u8 log_stride, u8 log_sz,
-                                       u32 strides_offset,
+                                       u16 strides_offset,
                                        struct mlx5_frag_buf_ctrl *fbc)
 {
        fbc->log_stride = log_stride;
@@ -1052,7 +1052,7 @@ int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn);
 void mlx5_health_cleanup(struct mlx5_core_dev *dev);
 int mlx5_health_init(struct mlx5_core_dev *dev);
 void mlx5_start_health_poll(struct mlx5_core_dev *dev);
-void mlx5_stop_health_poll(struct mlx5_core_dev *dev);
+void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health);
 void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
 void mlx5_trigger_health_work(struct mlx5_core_dev *dev);
 void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
index cd2bc939efd0db82d16cc3417b6d027771f8f1f4..5ed8f6292a533c2efbc4390d1a6a165bf4ad2252 100644 (file)
@@ -341,7 +341,7 @@ struct mm_struct {
        struct {
                struct vm_area_struct *mmap;            /* list of VMAs */
                struct rb_root mm_rb;
-               u32 vmacache_seqnum;                   /* per-thread vmacache */
+               u64 vmacache_seqnum;                   /* per-thread vmacache */
 #ifdef CONFIG_MMU
                unsigned long (*get_unmapped_area) (struct file *filp,
                                unsigned long addr, unsigned long len,
index 5fe87687664c7d78046060499cf96b28790190cb..d7016dcb245eeaff7ba8820a3fd73e267c0e46cb 100644 (file)
@@ -32,7 +32,7 @@
 #define VMACACHE_MASK (VMACACHE_SIZE - 1)
 
 struct vmacache {
-       u32 seqnum;
+       u64 seqnum;
        struct vm_area_struct *vmas[VMACACHE_SIZE];
 };
 
index 1298a7daa57d8aaf0148894523cba76180d5d46b..01797cb4587ede275db60176820571a3dea92c18 100644 (file)
@@ -754,6 +754,7 @@ struct tb_service_id {
  * struct typec_device_id - USB Type-C alternate mode identifiers
  * @svid: Standard or Vendor ID
  * @mode: Mode index
+ * @driver_data: Driver specific data
  */
 struct typec_device_id {
        __u16 svid;
index 67662d01130a7b4f69c8b4ec176f59b11e8ae33d..3ef82d3a78db51d958858470f8158f72cfd74fb3 100644 (file)
@@ -49,8 +49,9 @@ struct netpoll_info {
 };
 
 #ifdef CONFIG_NETPOLL
-extern void netpoll_poll_disable(struct net_device *dev);
-extern void netpoll_poll_enable(struct net_device *dev);
+void netpoll_poll_dev(struct net_device *dev);
+void netpoll_poll_disable(struct net_device *dev);
+void netpoll_poll_enable(struct net_device *dev);
 #else
 static inline void netpoll_poll_disable(struct net_device *dev) { return; }
 static inline void netpoll_poll_enable(struct net_device *dev) { return; }
index e72ca8dd6241b88cae56cc27de7e05e10182f267..6925828f9f250fae21e19ef8338d46694621e2a2 100644 (file)
@@ -1235,6 +1235,9 @@ void pci_bus_remove_resources(struct pci_bus *bus);
 int devm_request_pci_bus_resources(struct device *dev,
                                   struct list_head *resources);
 
+/* Temporary until new and working PCI SBR API in place */
+int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
+
 #define pci_bus_for_each_resource(bus, res, i)                         \
        for (i = 0;                                                     \
            (res = pci_bus_resource_n(bus, i)) || i < PCI_BRIDGE_RESOURCE_NUM; \
index 3468703d663af6d94bbf6fd07343d8bd9418b81a..a459a5e973a7294f171e192dd4dacf98d5b27c16 100644 (file)
@@ -48,9 +48,9 @@ struct regulator;
  * DISABLE_IN_SUSPEND  - turn off regulator in suspend states
  * ENABLE_IN_SUSPEND   - keep regulator on in suspend states
  */
-#define DO_NOTHING_IN_SUSPEND  (-1)
-#define DISABLE_IN_SUSPEND     0
-#define ENABLE_IN_SUSPEND      1
+#define DO_NOTHING_IN_SUSPEND  0
+#define DISABLE_IN_SUSPEND     1
+#define ENABLE_IN_SUSPEND      2
 
 /* Regulator active discharge flags */
 enum regulator_active_discharge {
index b2bd4b4127c46a2e8f2eb103d989b629d7169570..69ee30456864a05ceb76bac1d0dbe8df3a0e3448 100644 (file)
@@ -81,8 +81,10 @@ enum spi_mem_data_dir {
  * @dummy.buswidth: number of IO lanes used to transmit the dummy bytes
  * @data.buswidth: number of IO lanes used to send/receive the data
  * @data.dir: direction of the transfer
- * @data.buf.in: input buffer
- * @data.buf.out: output buffer
+ * @data.nbytes: number of data bytes to send/receive. Can be zero if the
+ *              operation does not involve transferring data
+ * @data.buf.in: input buffer (must be DMA-able)
+ * @data.buf.out: output buffer (must be DMA-able)
  */
 struct spi_mem_op {
        struct {
@@ -105,7 +107,6 @@ struct spi_mem_op {
                u8 buswidth;
                enum spi_mem_data_dir dir;
                unsigned int nbytes;
-               /* buf.{in,out} must be DMA-able. */
                union {
                        void *in;
                        const void *out;
index c43e9a01b892692b3901cfb1fd1459cdb428c553..7ddfc65586b046e80e3ae7357368b696b406507f 100644 (file)
@@ -30,6 +30,7 @@
 
 #define MTL_MAX_RX_QUEUES      8
 #define MTL_MAX_TX_QUEUES      8
+#define STMMAC_CH_MAX          8
 
 #define STMMAC_RX_COE_NONE     0
 #define STMMAC_RX_COE_TYPE1    1
index 409c845d4cd3dce5762c27a2e7e7c1c5c288f134..422b1c01ee0de0d679d7f6cb4276bb7d45e82186 100644 (file)
@@ -172,7 +172,7 @@ size_t copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i)
 static __always_inline __must_check
 size_t copy_to_iter_mcsafe(void *addr, size_t bytes, struct iov_iter *i)
 {
-       if (unlikely(!check_copy_size(addr, bytes, false)))
+       if (unlikely(!check_copy_size(addr, bytes, true)))
                return 0;
        else
                return _copy_to_iter_mcsafe(addr, bytes, i);
index a34539b7f7508e1a7ae37580823b44858d66ea84..7e6ac0114d556bda8580fba760e223fb57e7fd14 100644 (file)
@@ -133,15 +133,18 @@ struct vga_switcheroo_handler {
  * @can_switch: check if the device is in a position to switch now.
  *     Mandatory. The client should return false if a user space process
  *     has one of its device files open
+ * @gpu_bound: notify the client id to audio client when the GPU is bound.
  *
  * Client callbacks. A client can be either a GPU or an audio device on a GPU.
  * The @set_gpu_state and @can_switch methods are mandatory, @reprobe may be
  * set to NULL. For audio clients, the @reprobe member is bogus.
+ * OTOH, @gpu_bound is only for audio clients, and not used for GPU clients.
  */
 struct vga_switcheroo_client_ops {
        void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state);
        void (*reprobe)(struct pci_dev *dev);
        bool (*can_switch)(struct pci_dev *dev);
+       void (*gpu_bound)(struct pci_dev *dev, enum vga_switcheroo_client_id);
 };
 
 #if defined(CONFIG_VGA_SWITCHEROO)
index 5c7f010676a74206e06282337ca77b578058f2f1..47a3441cf4c4a4d59f588aac2c181ba1d8098c4f 100644 (file)
@@ -105,7 +105,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
 #ifdef CONFIG_DEBUG_VM_VMACACHE
                VMACACHE_FIND_CALLS,
                VMACACHE_FIND_HITS,
-               VMACACHE_FULL_FLUSHES,
 #endif
 #ifdef CONFIG_SWAP
                SWAP_RA,
index 3e9a963edd6a89f2d8d34616690dba2888aed7f7..6fce268a4588e5a064214b84309f4520f8759d65 100644 (file)
@@ -10,7 +10,6 @@ static inline void vmacache_flush(struct task_struct *tsk)
        memset(tsk->vmacache.vmas, 0, sizeof(tsk->vmacache.vmas));
 }
 
-extern void vmacache_flush_all(struct mm_struct *mm);
 extern void vmacache_update(unsigned long addr, struct vm_area_struct *newvma);
 extern struct vm_area_struct *vmacache_find(struct mm_struct *mm,
                                                    unsigned long addr);
@@ -24,10 +23,6 @@ extern struct vm_area_struct *vmacache_find_exact(struct mm_struct *mm,
 static inline void vmacache_invalidate(struct mm_struct *mm)
 {
        mm->vmacache_seqnum++;
-
-       /* deal with overflows */
-       if (unlikely(mm->vmacache_seqnum == 0))
-               vmacache_flush_all(mm);
 }
 
 #endif /* __LINUX_VMACACHE_H */
index d5f62cc6c2ae44473b6233182d7825ee8e5d1ef5..3394d75e1c80380c9a27fcb31fa67e831afb19c7 100644 (file)
@@ -30,7 +30,7 @@ struct nf_conn_timeout {
 };
 
 static inline unsigned int *
-nf_ct_timeout_data(struct nf_conn_timeout *t)
+nf_ct_timeout_data(const struct nf_conn_timeout *t)
 {
        struct nf_ct_timeout *timeout;
 
index 316694dafa5bae75363e34c035906e2d937c33c6..008f466d1da7ea60c7b46dc4b5133e8ed257c9c3 100644 (file)
@@ -87,7 +87,7 @@ struct nfc_hci_pipe {
  * According to specification 102 622 chapter 4.4 Pipes,
  * the pipe identifier is 7 bits long.
  */
-#define NFC_HCI_MAX_PIPES              127
+#define NFC_HCI_MAX_PIPES              128
 struct nfc_hci_init_data {
        u8 gate_count;
        struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES];
index d5c683e8bb22adf9654e07d791d2ad782d2dec02..0a769cf2f5f3e4fac6afb909d0af41acc166fbfb 100644 (file)
@@ -171,15 +171,14 @@ struct cipher_context {
        char *rec_seq;
 };
 
+union tls_crypto_context {
+       struct tls_crypto_info info;
+       struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
+};
+
 struct tls_context {
-       union {
-               struct tls_crypto_info crypto_send;
-               struct tls12_crypto_info_aes_gcm_128 crypto_send_aes_gcm_128;
-       };
-       union {
-               struct tls_crypto_info crypto_recv;
-               struct tls12_crypto_info_aes_gcm_128 crypto_recv_aes_gcm_128;
-       };
+       union tls_crypto_context crypto_send;
+       union tls_crypto_context crypto_recv;
 
        struct list_head list;
        struct net_device *netdev;
@@ -367,8 +366,8 @@ static inline void tls_fill_prepend(struct tls_context *ctx,
         * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE
         */
        buf[0] = record_type;
-       buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.version);
-       buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.version);
+       buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.info.version);
+       buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.info.version);
        /* we can use IV for nonce explicit according to spec */
        buf[3] = pkt_len >> 8;
        buf[4] = pkt_len & 0xFF;
index 6f1e1f3b30633927283a0bbf09df6fa4418c2f28..cd1773d0e08f07247a42788a035a0355da113493 100644 (file)
@@ -412,6 +412,7 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus);
 void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
 void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
 void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
+int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset);
 
 void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
 int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
index af9ef16cc34d36f6fd314cc2522997a4b2dbc12f..fdaaafdc7a0039a0c4a6e93b6d2b7ed88ea5b74a 100644 (file)
@@ -407,6 +407,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
 int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
 void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
 int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
+                        struct snd_soc_pcm_runtime *rtd,
                         const struct snd_soc_pcm_stream *params,
                         unsigned int num_params,
                         struct snd_soc_dapm_widget *source,
index 910cc4334b21557f98298082b16e2359a6414e01..7b8c9e19bad1c2bf72c21dcf6b358559d5e4b4ea 100644 (file)
@@ -65,7 +65,7 @@
 
 /* keyctl structures */
 struct keyctl_dh_params {
-       __s32 dh_private;
+       __s32 private;
        __s32 prime;
        __s32 base;
 };
index 07548de5c9889f5bcd425a7273b2732003bf3c30..251be353f950b35082eff384a97028f64ff593e5 100644 (file)
@@ -952,6 +952,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_HPAGE_1M 156
 #define KVM_CAP_NESTED_STATE 157
 #define KVM_CAP_ARM_INJECT_SERROR_ESR 158
+#define KVM_CAP_MSR_PLATFORM_INFO 159
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index eeb787b1c53c72771c8d684154b7a87dc029a45b..f35eb72739c09e3ad0bd22e279fa4a33119c15f6 100644 (file)
@@ -144,7 +144,7 @@ enum perf_event_sample_format {
 
        PERF_SAMPLE_MAX = 1U << 20,             /* non-ABI */
 
-       __PERF_SAMPLE_CALLCHAIN_EARLY           = 1ULL << 63,
+       __PERF_SAMPLE_CALLCHAIN_EARLY           = 1ULL << 63, /* non-ABI; internal use */
 };
 
 /*
index f58cafa42f183213113442b6bd55a85aa5d10301..f39352cef38223e4b1b5ab70693ca3deb5eee451 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef __HDA_TPLG_INTERFACE_H__
 #define __HDA_TPLG_INTERFACE_H__
 
+#include <linux/types.h>
+
 /*
  * Default types range from 0~12. type can range from 0 to 0xff
  * SST types start at higher to avoid any overlapping in future
@@ -143,10 +145,10 @@ enum skl_module_param_type {
 };
 
 struct skl_dfw_algo_data {
-       u32 set_params:2;
-       u32 rsvd:30;
-       u32 param_id;
-       u32 max;
+       __u32 set_params:2;
+       __u32 rsvd:30;
+       __u32 param_id;
+       __u32 max;
        char params[0];
 } __packed;
 
@@ -163,68 +165,68 @@ enum skl_tuple_type {
 /* v4 configuration data */
 
 struct skl_dfw_v4_module_pin {
-       u16 module_id;
-       u16 instance_id;
+       __u16 module_id;
+       __u16 instance_id;
 } __packed;
 
 struct skl_dfw_v4_module_fmt {
-       u32 channels;
-       u32 freq;
-       u32 bit_depth;
-       u32 valid_bit_depth;
-       u32 ch_cfg;
-       u32 interleaving_style;
-       u32 sample_type;
-       u32 ch_map;
+       __u32 channels;
+       __u32 freq;
+       __u32 bit_depth;
+       __u32 valid_bit_depth;
+       __u32 ch_cfg;
+       __u32 interleaving_style;
+       __u32 sample_type;
+       __u32 ch_map;
 } __packed;
 
 struct skl_dfw_v4_module_caps {
-       u32 set_params:2;
-       u32 rsvd:30;
-       u32 param_id;
-       u32 caps_size;
-       u32 caps[HDA_SST_CFG_MAX];
+       __u32 set_params:2;
+       __u32 rsvd:30;
+       __u32 param_id;
+       __u32 caps_size;
+       __u32 caps[HDA_SST_CFG_MAX];
 } __packed;
 
 struct skl_dfw_v4_pipe {
-       u8 pipe_id;
-       u8 pipe_priority;
-       u16 conn_type:4;
-       u16 rsvd:4;
-       u16 memory_pages:8;
+       __u8 pipe_id;
+       __u8 pipe_priority;
+       __u16 conn_type:4;
+       __u16 rsvd:4;
+       __u16 memory_pages:8;
 } __packed;
 
 struct skl_dfw_v4_module {
        char uuid[SKL_UUID_STR_SZ];
 
-       u16 module_id;
-       u16 instance_id;
-       u32 max_mcps;
-       u32 mem_pages;
-       u32 obs;
-       u32 ibs;
-       u32 vbus_id;
-
-       u32 max_in_queue:8;
-       u32 max_out_queue:8;
-       u32 time_slot:8;
-       u32 core_id:4;
-       u32 rsvd1:4;
-
-       u32 module_type:8;
-       u32 conn_type:4;
-       u32 dev_type:4;
-       u32 hw_conn_type:4;
-       u32 rsvd2:12;
-
-       u32 params_fixup:8;
-       u32 converter:8;
-       u32 input_pin_type:1;
-       u32 output_pin_type:1;
-       u32 is_dynamic_in_pin:1;
-       u32 is_dynamic_out_pin:1;
-       u32 is_loadable:1;
-       u32 rsvd3:11;
+       __u16 module_id;
+       __u16 instance_id;
+       __u32 max_mcps;
+       __u32 mem_pages;
+       __u32 obs;
+       __u32 ibs;
+       __u32 vbus_id;
+
+       __u32 max_in_queue:8;
+       __u32 max_out_queue:8;
+       __u32 time_slot:8;
+       __u32 core_id:4;
+       __u32 rsvd1:4;
+
+       __u32 module_type:8;
+       __u32 conn_type:4;
+       __u32 dev_type:4;
+       __u32 hw_conn_type:4;
+       __u32 rsvd2:12;
+
+       __u32 params_fixup:8;
+       __u32 converter:8;
+       __u32 input_pin_type:1;
+       __u32 output_pin_type:1;
+       __u32 is_dynamic_in_pin:1;
+       __u32 is_dynamic_out_pin:1;
+       __u32 is_loadable:1;
+       __u32 rsvd3:11;
 
        struct skl_dfw_v4_pipe pipe;
        struct skl_dfw_v4_module_fmt in_fmt[MAX_IN_QUEUE];
index 80b52b4945e965d96ce068fe3d729e9364cc9868..a2ab516fcd2caf33167f3e64a76c2e77b726d6df 100644 (file)
 
 #include <xen/page.h>
 
+extern bool xen_scrub_pages;
+
 static inline void xenmem_reservation_scrub_page(struct page *page)
 {
-#ifdef CONFIG_XEN_SCRUB_PAGES
-       clear_highpage(page);
-#endif
+       if (xen_scrub_pages)
+               clear_highpage(page);
 }
 
 #ifdef CONFIG_XEN_HAVE_PVMMU
index 2590700237c13cd7a1a7394c8797a0a2aafd063a..138f0302692ec4bfc1138075f69a858077221eb5 100644 (file)
@@ -1844,7 +1844,7 @@ static int btf_check_all_metas(struct btf_verifier_env *env)
 
        hdr = &btf->hdr;
        cur = btf->nohdr_data + hdr->type_off;
-       end = btf->nohdr_data + hdr->type_len;
+       end = cur + hdr->type_len;
 
        env->log_type_id = 1;
        while (cur < end) {
index 488ef9663c01f3b4d2cc44b9ca88863ced2860e7..0a0f2ec75370d83d8e0afdc24f04e8e65bf870b9 100644 (file)
@@ -132,6 +132,7 @@ struct smap_psock {
        struct work_struct gc_work;
 
        struct proto *sk_proto;
+       void (*save_unhash)(struct sock *sk);
        void (*save_close)(struct sock *sk, long timeout);
        void (*save_data_ready)(struct sock *sk);
        void (*save_write_space)(struct sock *sk);
@@ -143,6 +144,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
 static int bpf_tcp_sendpage(struct sock *sk, struct page *page,
                            int offset, size_t size, int flags);
+static void bpf_tcp_unhash(struct sock *sk);
 static void bpf_tcp_close(struct sock *sk, long timeout);
 
 static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
@@ -184,6 +186,7 @@ static void build_protos(struct proto prot[SOCKMAP_NUM_CONFIGS],
                         struct proto *base)
 {
        prot[SOCKMAP_BASE]                      = *base;
+       prot[SOCKMAP_BASE].unhash               = bpf_tcp_unhash;
        prot[SOCKMAP_BASE].close                = bpf_tcp_close;
        prot[SOCKMAP_BASE].recvmsg              = bpf_tcp_recvmsg;
        prot[SOCKMAP_BASE].stream_memory_read   = bpf_tcp_stream_read;
@@ -217,6 +220,7 @@ static int bpf_tcp_init(struct sock *sk)
                return -EBUSY;
        }
 
+       psock->save_unhash = sk->sk_prot->unhash;
        psock->save_close = sk->sk_prot->close;
        psock->sk_proto = sk->sk_prot;
 
@@ -305,30 +309,12 @@ static struct smap_psock_map_entry *psock_map_pop(struct sock *sk,
        return e;
 }
 
-static void bpf_tcp_close(struct sock *sk, long timeout)
+static void bpf_tcp_remove(struct sock *sk, struct smap_psock *psock)
 {
-       void (*close_fun)(struct sock *sk, long timeout);
        struct smap_psock_map_entry *e;
        struct sk_msg_buff *md, *mtmp;
-       struct smap_psock *psock;
        struct sock *osk;
 
-       lock_sock(sk);
-       rcu_read_lock();
-       psock = smap_psock_sk(sk);
-       if (unlikely(!psock)) {
-               rcu_read_unlock();
-               release_sock(sk);
-               return sk->sk_prot->close(sk, timeout);
-       }
-
-       /* The psock may be destroyed anytime after exiting the RCU critial
-        * section so by the time we use close_fun the psock may no longer
-        * be valid. However, bpf_tcp_close is called with the sock lock
-        * held so the close hook and sk are still valid.
-        */
-       close_fun = psock->save_close;
-
        if (psock->cork) {
                free_start_sg(psock->sock, psock->cork, true);
                kfree(psock->cork);
@@ -379,6 +365,42 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
                kfree(e);
                e = psock_map_pop(sk, psock);
        }
+}
+
+static void bpf_tcp_unhash(struct sock *sk)
+{
+       void (*unhash_fun)(struct sock *sk);
+       struct smap_psock *psock;
+
+       rcu_read_lock();
+       psock = smap_psock_sk(sk);
+       if (unlikely(!psock)) {
+               rcu_read_unlock();
+               if (sk->sk_prot->unhash)
+                       sk->sk_prot->unhash(sk);
+               return;
+       }
+       unhash_fun = psock->save_unhash;
+       bpf_tcp_remove(sk, psock);
+       rcu_read_unlock();
+       unhash_fun(sk);
+}
+
+static void bpf_tcp_close(struct sock *sk, long timeout)
+{
+       void (*close_fun)(struct sock *sk, long timeout);
+       struct smap_psock *psock;
+
+       lock_sock(sk);
+       rcu_read_lock();
+       psock = smap_psock_sk(sk);
+       if (unlikely(!psock)) {
+               rcu_read_unlock();
+               release_sock(sk);
+               return sk->sk_prot->close(sk, timeout);
+       }
+       close_fun = psock->save_close;
+       bpf_tcp_remove(sk, psock);
        rcu_read_unlock();
        release_sock(sk);
        close_fun(sk, timeout);
@@ -2097,8 +2119,12 @@ static int sock_map_update_elem(struct bpf_map *map,
                return -EINVAL;
        }
 
+       /* ULPs are currently supported only for TCP sockets in ESTABLISHED
+        * state.
+        */
        if (skops.sk->sk_type != SOCK_STREAM ||
-           skops.sk->sk_protocol != IPPROTO_TCP) {
+           skops.sk->sk_protocol != IPPROTO_TCP ||
+           skops.sk->sk_state != TCP_ESTABLISHED) {
                fput(socket->file);
                return -EOPNOTSUPP;
        }
@@ -2453,6 +2479,16 @@ static int sock_hash_update_elem(struct bpf_map *map,
                return -EINVAL;
        }
 
+       /* ULPs are currently supported only for TCP sockets in ESTABLISHED
+        * state.
+        */
+       if (skops.sk->sk_type != SOCK_STREAM ||
+           skops.sk->sk_protocol != IPPROTO_TCP ||
+           skops.sk->sk_state != TCP_ESTABLISHED) {
+               fput(socket->file);
+               return -EOPNOTSUPP;
+       }
+
        lock_sock(skops.sk);
        preempt_disable();
        rcu_read_lock();
@@ -2543,10 +2579,22 @@ const struct bpf_map_ops sock_hash_ops = {
        .map_check_btf = map_check_no_btf,
 };
 
+static bool bpf_is_valid_sock_op(struct bpf_sock_ops_kern *ops)
+{
+       return ops->op == BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB ||
+              ops->op == BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB;
+}
 BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,
           struct bpf_map *, map, void *, key, u64, flags)
 {
        WARN_ON_ONCE(!rcu_read_lock_held());
+
+       /* ULPs are currently supported only for TCP sockets in ESTABLISHED
+        * state. This checks that the sock ops triggering the update is
+        * one indicating we are (or will be soon) in an ESTABLISHED state.
+        */
+       if (!bpf_is_valid_sock_op(bpf_sock))
+               return -EOPNOTSUPP;
        return sock_map_ctx_update_elem(bpf_sock, map, key, flags);
 }
 
@@ -2565,6 +2613,9 @@ BPF_CALL_4(bpf_sock_hash_update, struct bpf_sock_ops_kern *, bpf_sock,
           struct bpf_map *, map, void *, key, u64, flags)
 {
        WARN_ON_ONCE(!rcu_read_lock_held());
+
+       if (!bpf_is_valid_sock_op(bpf_sock))
+               return -EOPNOTSUPP;
        return sock_hash_ctx_update_elem(bpf_sock, map, key, flags);
 }
 
index 92246117d2b0395e5eec8329455e7ee7c8320d58..bb07e74b34a225f1b21cc61ca0a43c848d3d532f 100644 (file)
@@ -3163,7 +3163,7 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                                 * an arbitrary scalar. Disallow all math except
                                 * pointer subtraction
                                 */
-                               if (opcode == BPF_SUB){
+                               if (opcode == BPF_SUB && env->allow_ptr_leaks) {
                                        mark_reg_unknown(env, regs, insn->dst_reg);
                                        return 0;
                                }
index 9bd54304446f8b477a61a799a2d75136672548bd..1b1d63b3634b580cf6b29384e162f76b28e05102 100644 (file)
@@ -23,6 +23,9 @@ config ARCH_HAS_SYNC_DMA_FOR_CPU
        bool
        select NEED_DMA_MAP_STATE
 
+config ARCH_HAS_SYNC_DMA_FOR_CPU_ALL
+       bool
+
 config DMA_DIRECT_OPS
        bool
        depends on HAS_DMA
index 2a62b96600ad91dede076a2dc8ad4e7fc16afe09..dcb093e7b37770a2bbdb0e80f984e1cccae7350d 100644 (file)
@@ -2867,16 +2867,11 @@ static int perf_event_modify_breakpoint(struct perf_event *bp,
        _perf_event_disable(bp);
 
        err = modify_user_hw_breakpoint_check(bp, attr, true);
-       if (err) {
-               if (!bp->attr.disabled)
-                       _perf_event_enable(bp);
 
-               return err;
-       }
-
-       if (!attr->disabled)
+       if (!bp->attr.disabled)
                _perf_event_enable(bp);
-       return 0;
+
+       return err;
 }
 
 static int perf_event_modify_attr(struct perf_event *event,
@@ -3940,6 +3935,12 @@ int perf_event_read_local(struct perf_event *event, u64 *value,
                goto out;
        }
 
+       /* If this is a pinned event it must be running on this CPU */
+       if (event->attr.pinned && event->oncpu != smp_processor_id()) {
+               ret = -EBUSY;
+               goto out;
+       }
+
        /*
         * If the event is currently on this CPU, its either a per-task event,
         * or local to this CPU. Furthermore it means its ACTIVE (otherwise
@@ -5948,6 +5949,7 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
                unsigned long sp;
                unsigned int rem;
                u64 dyn_size;
+               mm_segment_t fs;
 
                /*
                 * We dump:
@@ -5965,7 +5967,10 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
 
                /* Data. */
                sp = perf_user_stack_pointer(regs);
+               fs = get_fs();
+               set_fs(USER_DS);
                rem = __output_copy_user(handle, (void *) sp, dump_size);
+               set_fs(fs);
                dyn_size = dump_size - rem;
 
                perf_output_skip(handle, rem);
index b3814fce5ecb6bf7729ea858ec17ddb9018105f1..d6b56180827c73f29fa21eef238c73c1a01540ad 100644 (file)
@@ -509,6 +509,8 @@ modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *a
  */
 int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
 {
+       int err;
+
        /*
         * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
         * will not be possible to raise IPIs that invoke __perf_event_disable.
@@ -520,15 +522,12 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
        else
                perf_event_disable(bp);
 
-       if (!attr->disabled) {
-               int err = modify_user_hw_breakpoint_check(bp, attr, false);
+       err = modify_user_hw_breakpoint_check(bp, attr, false);
 
-               if (err)
-                       return err;
+       if (!bp->attr.disabled)
                perf_event_enable(bp);
-               bp->attr.disabled = 0;
-       }
-       return 0;
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
 
index 01ebdf1f9f40eb0b56810244bd115a62d07e88f2..2e62503bea0d7d4a598ff755bad1431bb166d790 100644 (file)
@@ -678,7 +678,7 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val,
        case MODULE_STATE_COMING:
                ret = jump_label_add_module(mod);
                if (ret) {
-                       WARN(1, "Failed to allocatote memory: jump_label may not work properly.\n");
+                       WARN(1, "Failed to allocate memory: jump_label may not work properly.\n");
                        jump_label_del_module(mod);
                }
                break;
index e406c5fdb41e9423aca5fd8db32ec8e692983d3b..dd13f865ad40e985553217b5e557aaaac5eaa229 100644 (file)
@@ -55,7 +55,6 @@
 
 #include "lockdep_internals.h"
 
-#include <trace/events/preemptirq.h>
 #define CREATE_TRACE_POINTS
 #include <trace/events/lock.h>
 
index 1a81a1257b3f3aca67e00bbe9a3a0b4e465b0e4f..3f8a35104285ab29fe2e9992430e75b6aefbff89 100644 (file)
@@ -389,7 +389,7 @@ static bool __ww_mutex_wound(struct mutex *lock,
                /*
                 * wake_up_process() paired with set_current_state()
                 * inserts sufficient barriers to make sure @owner either sees
-                * it's wounded in __ww_mutex_lock_check_stamp() or has a
+                * it's wounded in __ww_mutex_check_kill() or has a
                 * wakeup pending to re-read the wounded state.
                 */
                if (owner != current)
@@ -946,7 +946,6 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
        }
 
        debug_mutex_lock_common(lock, &waiter);
-       debug_mutex_add_waiter(lock, &waiter, current);
 
        lock_contended(&lock->dep_map, ip);
 
index 5b915b370d5a833fcf087bec26f06b8d07a59cda..0be047dbd8971dcd4ee1282936d3b3056f6ebfea 100644 (file)
@@ -324,7 +324,7 @@ static int __test_cycle(unsigned int nthreads)
                if (!cycle->result)
                        continue;
 
-               pr_err("cylic deadlock not resolved, ret[%d/%d] = %d\n",
+               pr_err("cyclic deadlock not resolved, ret[%d/%d] = %d\n",
                       n, nthreads, cycle->result);
                ret = -EINVAL;
                break;
index de1cfc4f75a2eb8df16e3d1018122226a1a30f14..cdf63e53a01425182d66f1c8883a249cedbaaa88 100644 (file)
@@ -195,7 +195,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
                idr_preload_end();
 
                if (nr < 0) {
-                       retval = nr;
+                       retval = (nr == -ENOSPC) ? -EAGAIN : nr;
                        goto out_free;
                }
 
index fd6f8ed28e010a0808c8e67a698372ce5fc411da..9bf5404397e0b224873456617437fc172617a637 100644 (file)
@@ -351,7 +351,6 @@ static int console_msg_format = MSG_FORMAT_DEFAULT;
  */
 
 enum log_flags {
-       LOG_NOCONS      = 1,    /* suppress print, do not print to console */
        LOG_NEWLINE     = 2,    /* text ended with a newline */
        LOG_PREFIX      = 4,    /* text started with a prefix */
        LOG_CONT        = 8,    /* text is a fragment of a continuation line */
@@ -1881,9 +1880,6 @@ int vprintk_store(int facility, int level,
        if (dict)
                lflags |= LOG_PREFIX|LOG_NEWLINE;
 
-       if (suppress_message_printing(level))
-               lflags |= LOG_NOCONS;
-
        return log_output(facility, level, lflags,
                          dict, dictlen, text, text_len);
 }
@@ -2032,6 +2028,7 @@ static void call_console_drivers(const char *ext_text, size_t ext_len,
                                 const char *text, size_t len) {}
 static size_t msg_print_text(const struct printk_log *msg,
                             bool syslog, char *buf, size_t size) { return 0; }
+static bool suppress_message_printing(int level) { return false; }
 
 #endif /* CONFIG_PRINTK */
 
@@ -2368,10 +2365,11 @@ void console_unlock(void)
                        break;
 
                msg = log_from_idx(console_idx);
-               if (msg->flags & LOG_NOCONS) {
+               if (suppress_message_printing(msg->level)) {
                        /*
-                        * Skip record if !ignore_loglevel, and
-                        * record has level above the console loglevel.
+                        * Skip record we have buffered and already printed
+                        * directly to the console when we received it, and
+                        * record that has level above the console loglevel.
                         */
                        console_idx = log_next(console_idx);
                        console_seq++;
index 625bc9897f628bec7abacd797a05bff4b4f2cd85..ad97f3ba5ec51c4a9379228b60416c72e6dc5b60 100644 (file)
@@ -1167,7 +1167,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
 
        if (task_cpu(p) != new_cpu) {
                if (p->sched_class->migrate_task_rq)
-                       p->sched_class->migrate_task_rq(p);
+                       p->sched_class->migrate_task_rq(p, new_cpu);
                p->se.nr_migrations++;
                rseq_migrate(p);
                perf_event_task_migrate(p);
index 997ea7b839fa048fece2738fa2a7a38472ca4f01..91e4202b0634569514659aa905fddf5b0ec6a6e7 100644 (file)
@@ -1607,7 +1607,7 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags)
        return cpu;
 }
 
-static void migrate_task_rq_dl(struct task_struct *p)
+static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused)
 {
        struct rq *rq;
 
index 6bd142d19549ad7bdc8bb296a468a6e547c83d10..1d92ed2eca8b1deb587652c206d9345810cd4e23 100644 (file)
@@ -1492,6 +1492,21 @@ struct task_numa_env {
 static void task_numa_assign(struct task_numa_env *env,
                             struct task_struct *p, long imp)
 {
+       struct rq *rq = cpu_rq(env->dst_cpu);
+
+       /* Bail out if run-queue part of active NUMA balance. */
+       if (xchg(&rq->numa_migrate_on, 1))
+               return;
+
+       /*
+        * Clear previous best_cpu/rq numa-migrate flag, since task now
+        * found a better CPU to move/swap.
+        */
+       if (env->best_cpu != -1) {
+               rq = cpu_rq(env->best_cpu);
+               WRITE_ONCE(rq->numa_migrate_on, 0);
+       }
+
        if (env->best_task)
                put_task_struct(env->best_task);
        if (p)
@@ -1530,6 +1545,13 @@ static bool load_too_imbalanced(long src_load, long dst_load,
        return (imb > old_imb);
 }
 
+/*
+ * Maximum NUMA importance can be 1998 (2*999);
+ * SMALLIMP @ 30 would be close to 1998/64.
+ * Used to deter task migration.
+ */
+#define SMALLIMP       30
+
 /*
  * This checks if the overall compute and NUMA accesses of the system would
  * be improved if the source tasks was migrated to the target dst_cpu taking
@@ -1547,6 +1569,9 @@ static void task_numa_compare(struct task_numa_env *env,
        long moveimp = imp;
        int dist = env->dist;
 
+       if (READ_ONCE(dst_rq->numa_migrate_on))
+               return;
+
        rcu_read_lock();
        cur = task_rcu_dereference(&dst_rq->curr);
        if (cur && ((cur->flags & PF_EXITING) || is_idle_task(cur)))
@@ -1560,7 +1585,7 @@ static void task_numa_compare(struct task_numa_env *env,
                goto unlock;
 
        if (!cur) {
-               if (maymove || imp > env->best_imp)
+               if (maymove && moveimp >= env->best_imp)
                        goto assign;
                else
                        goto unlock;
@@ -1603,15 +1628,21 @@ static void task_numa_compare(struct task_numa_env *env,
                               task_weight(cur, env->dst_nid, dist);
        }
 
-       if (imp <= env->best_imp)
-               goto unlock;
-
        if (maymove && moveimp > imp && moveimp > env->best_imp) {
-               imp = moveimp - 1;
+               imp = moveimp;
                cur = NULL;
                goto assign;
        }
 
+       /*
+        * If the NUMA importance is less than SMALLIMP,
+        * task migration might only result in ping pong
+        * of tasks and also hurt performance due to cache
+        * misses.
+        */
+       if (imp < SMALLIMP || imp <= env->best_imp + SMALLIMP / 2)
+               goto unlock;
+
        /*
         * In the overloaded case, try and keep the load balanced.
         */
@@ -1688,6 +1719,7 @@ static int task_numa_migrate(struct task_struct *p)
                .best_cpu = -1,
        };
        struct sched_domain *sd;
+       struct rq *best_rq;
        unsigned long taskweight, groupweight;
        int nid, ret, dist;
        long taskimp, groupimp;
@@ -1783,20 +1815,17 @@ static int task_numa_migrate(struct task_struct *p)
        if (env.best_cpu == -1)
                return -EAGAIN;
 
-       /*
-        * Reset the scan period if the task is being rescheduled on an
-        * alternative node to recheck if the tasks is now properly placed.
-        */
-       p->numa_scan_period = task_scan_start(p);
-
+       best_rq = cpu_rq(env.best_cpu);
        if (env.best_task == NULL) {
                ret = migrate_task_to(p, env.best_cpu);
+               WRITE_ONCE(best_rq->numa_migrate_on, 0);
                if (ret != 0)
                        trace_sched_stick_numa(p, env.src_cpu, env.best_cpu);
                return ret;
        }
 
        ret = migrate_swap(p, env.best_task, env.best_cpu, env.src_cpu);
+       WRITE_ONCE(best_rq->numa_migrate_on, 0);
 
        if (ret != 0)
                trace_sched_stick_numa(p, env.src_cpu, task_cpu(env.best_task));
@@ -2574,6 +2603,39 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr)
        }
 }
 
+static void update_scan_period(struct task_struct *p, int new_cpu)
+{
+       int src_nid = cpu_to_node(task_cpu(p));
+       int dst_nid = cpu_to_node(new_cpu);
+
+       if (!static_branch_likely(&sched_numa_balancing))
+               return;
+
+       if (!p->mm || !p->numa_faults || (p->flags & PF_EXITING))
+               return;
+
+       if (src_nid == dst_nid)
+               return;
+
+       /*
+        * Allow resets if faults have been trapped before one scan
+        * has completed. This is most likely due to a new task that
+        * is pulled cross-node due to wakeups or load balancing.
+        */
+       if (p->numa_scan_seq) {
+               /*
+                * Avoid scan adjustments if moving to the preferred
+                * node or if the task was not previously running on
+                * the preferred node.
+                */
+               if (dst_nid == p->numa_preferred_nid ||
+                   (p->numa_preferred_nid != -1 && src_nid != p->numa_preferred_nid))
+                       return;
+       }
+
+       p->numa_scan_period = task_scan_start(p);
+}
+
 #else
 static void task_tick_numa(struct rq *rq, struct task_struct *curr)
 {
@@ -2587,6 +2649,10 @@ static inline void account_numa_dequeue(struct rq *rq, struct task_struct *p)
 {
 }
 
+static inline void update_scan_period(struct task_struct *p, int new_cpu)
+{
+}
+
 #endif /* CONFIG_NUMA_BALANCING */
 
 static void
@@ -6280,7 +6346,7 @@ static void detach_entity_cfs_rq(struct sched_entity *se);
  * cfs_rq_of(p) references at time of call are still valid and identify the
  * previous CPU. The caller guarantees p->pi_lock or task_rq(p)->lock is held.
  */
-static void migrate_task_rq_fair(struct task_struct *p)
+static void migrate_task_rq_fair(struct task_struct *p, int new_cpu)
 {
        /*
         * As blocked tasks retain absolute vruntime the migration needs to
@@ -6333,6 +6399,8 @@ static void migrate_task_rq_fair(struct task_struct *p)
 
        /* We have migrated, no longer consider this task hot */
        p->se.exec_start = 0;
+
+       update_scan_period(p, new_cpu);
 }
 
 static void task_dead_fair(struct task_struct *p)
index 3a4ef8f73f08b0e593b06e037bca5d5d748cfa89..632804fa0b125e83fd62e9e4056386c052f697ac 100644 (file)
@@ -787,6 +787,7 @@ struct rq {
 #ifdef CONFIG_NUMA_BALANCING
        unsigned int            nr_numa_running;
        unsigned int            nr_preferred_running;
+       unsigned int            numa_migrate_on;
 #endif
        #define CPU_LOAD_IDX_MAX 5
        unsigned long           cpu_load[CPU_LOAD_IDX_MAX];
@@ -1531,7 +1532,7 @@ struct sched_class {
 
 #ifdef CONFIG_SMP
        int  (*select_task_rq)(struct task_struct *p, int task_cpu, int sd_flag, int flags);
-       void (*migrate_task_rq)(struct task_struct *p);
+       void (*migrate_task_rq)(struct task_struct *p, int new_cpu);
 
        void (*task_woken)(struct rq *this_rq, struct task_struct *task);
 
index cf5c67533ff1e1c02e296ed34d19501dd5f794dd..123bd73046ec6b19324452f0b9563617d7e40630 100644 (file)
@@ -71,9 +71,6 @@
 #include <asm/io.h>
 #include <asm/unistd.h>
 
-/* Hardening for Spectre-v1 */
-#include <linux/nospec.h>
-
 #include "uid16.h"
 
 #ifndef SET_UNALIGN_CTL
index 1d92d4a982fd468385b4b81b145d6e6353a766d4..65bd4616220db72b5e817cd0d1fdf1d4958a9501 100644 (file)
@@ -1546,6 +1546,8 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
        tmp_iter_page = first_page;
 
        do {
+               cond_resched();
+
                to_remove_page = tmp_iter_page;
                rb_inc_page(cpu_buffer, &tmp_iter_page);
 
index a550635ea5c353a8f226f7d1b429706a379a46a7..de64ea658716a8f1c63fcc03da45711c5d59f137 100644 (file)
@@ -637,6 +637,7 @@ config DEFERRED_STRUCT_PAGE_INIT
        depends on NO_BOOTMEM
        depends on SPARSEMEM
        depends on !NEED_PER_CPU_KM
+       depends on 64BIT
        help
          Ordinarily all struct pages are initialised during early boot in a
          single thread. On very large machines this can take a considerable
index 8716bdabe1e69f4758d1eedf9c6c8d9d98d2bec2..26ef77a3883b5c708659425229e975ac74069875 100644 (file)
@@ -32,7 +32,7 @@ ifdef CONFIG_CROSS_MEMORY_ATTACH
 mmu-$(CONFIG_MMU)      += process_vm_access.o
 endif
 
-obj-y                  := filemap.o mempool.o oom_kill.o \
+obj-y                  := filemap.o mempool.o oom_kill.o fadvise.o \
                           maccess.o page_alloc.o page-writeback.o \
                           readahead.o swap.o truncate.o vmscan.o shmem.o \
                           util.o mmzone.o vmstat.o backing-dev.o \
@@ -49,7 +49,6 @@ else
        obj-y           += bootmem.o
 endif
 
-obj-$(CONFIG_ADVISE_SYSCALLS)  += fadvise.o
 ifdef CONFIG_MMU
        obj-$(CONFIG_ADVISE_SYSCALLS)   += madvise.o
 endif
index 38c926520c9718b8929a72829931080a3a53502d..bd10aad8539a42bf5a1263518534946eeac6e050 100644 (file)
@@ -114,7 +114,7 @@ EXPORT_SYMBOL(dump_vma);
 
 void dump_mm(const struct mm_struct *mm)
 {
-       pr_emerg("mm %px mmap %px seqnum %d task_size %lu\n"
+       pr_emerg("mm %px mmap %px seqnum %llu task_size %lu\n"
 #ifdef CONFIG_MMU
                "get_unmapped_area %px\n"
 #endif
@@ -142,7 +142,7 @@ void dump_mm(const struct mm_struct *mm)
                "tlb_flush_pending %d\n"
                "def_flags: %#lx(%pGv)\n",
 
-               mm, mm->mmap, mm->vmacache_seqnum, mm->task_size,
+               mm, mm->mmap, (long long) mm->vmacache_seqnum, mm->task_size,
 #ifdef CONFIG_MMU
                mm->get_unmapped_area,
 #endif
index 2d8376e3c6408bf1ea058570dad64079cae7632d..467bcd032037a905e991cefe9fe48922f2031036 100644 (file)
@@ -27,9 +27,9 @@
  * deactivate the pages and clear PG_Referenced.
  */
 
-int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
+static int generic_fadvise(struct file *file, loff_t offset, loff_t len,
+                          int advice)
 {
-       struct fd f = fdget(fd);
        struct inode *inode;
        struct address_space *mapping;
        struct backing_dev_info *bdi;
@@ -37,22 +37,14 @@ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
        pgoff_t start_index;
        pgoff_t end_index;
        unsigned long nrpages;
-       int ret = 0;
-
-       if (!f.file)
-               return -EBADF;
 
-       inode = file_inode(f.file);
-       if (S_ISFIFO(inode->i_mode)) {
-               ret = -ESPIPE;
-               goto out;
-       }
+       inode = file_inode(file);
+       if (S_ISFIFO(inode->i_mode))
+               return -ESPIPE;
 
-       mapping = f.file->f_mapping;
-       if (!mapping || len < 0) {
-               ret = -EINVAL;
-               goto out;
-       }
+       mapping = file->f_mapping;
+       if (!mapping || len < 0)
+               return -EINVAL;
 
        bdi = inode_to_bdi(mapping->host);
 
@@ -67,9 +59,9 @@ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
                        /* no bad return value, but ignore advice */
                        break;
                default:
-                       ret = -EINVAL;
+                       return -EINVAL;
                }
-               goto out;
+               return 0;
        }
 
        /*
@@ -85,21 +77,21 @@ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
 
        switch (advice) {
        case POSIX_FADV_NORMAL:
-               f.file->f_ra.ra_pages = bdi->ra_pages;
-               spin_lock(&f.file->f_lock);
-               f.file->f_mode &= ~FMODE_RANDOM;
-               spin_unlock(&f.file->f_lock);
+               file->f_ra.ra_pages = bdi->ra_pages;
+               spin_lock(&file->f_lock);
+               file->f_mode &= ~FMODE_RANDOM;
+               spin_unlock(&file->f_lock);
                break;
        case POSIX_FADV_RANDOM:
-               spin_lock(&f.file->f_lock);
-               f.file->f_mode |= FMODE_RANDOM;
-               spin_unlock(&f.file->f_lock);
+               spin_lock(&file->f_lock);
+               file->f_mode |= FMODE_RANDOM;
+               spin_unlock(&file->f_lock);
                break;
        case POSIX_FADV_SEQUENTIAL:
-               f.file->f_ra.ra_pages = bdi->ra_pages * 2;
-               spin_lock(&f.file->f_lock);
-               f.file->f_mode &= ~FMODE_RANDOM;
-               spin_unlock(&f.file->f_lock);
+               file->f_ra.ra_pages = bdi->ra_pages * 2;
+               spin_lock(&file->f_lock);
+               file->f_mode &= ~FMODE_RANDOM;
+               spin_unlock(&file->f_lock);
                break;
        case POSIX_FADV_WILLNEED:
                /* First and last PARTIAL page! */
@@ -115,8 +107,7 @@ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
                 * Ignore return value because fadvise() shall return
                 * success even if filesystem can't retrieve a hint,
                 */
-               force_page_cache_readahead(mapping, f.file, start_index,
-                                          nrpages);
+               force_page_cache_readahead(mapping, file, start_index, nrpages);
                break;
        case POSIX_FADV_NOREUSE:
                break;
@@ -183,9 +174,32 @@ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
                }
                break;
        default:
-               ret = -EINVAL;
+               return -EINVAL;
        }
-out:
+       return 0;
+}
+
+int vfs_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
+{
+       if (file->f_op->fadvise)
+               return file->f_op->fadvise(file, offset, len, advice);
+
+       return generic_fadvise(file, offset, len, advice);
+}
+EXPORT_SYMBOL(vfs_fadvise);
+
+#ifdef CONFIG_ADVISE_SYSCALLS
+
+int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
+{
+       struct fd f = fdget(fd);
+       int ret;
+
+       if (!f.file)
+               return -EBADF;
+
+       ret = vfs_fadvise(f.file, offset, len, advice);
+
        fdput(f);
        return ret;
 }
@@ -203,3 +217,4 @@ SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
 }
 
 #endif
+#endif
index d6a2e89b086a43d77f155f6b525fc15326d9c035..4f1d894835b5d5efeb3d99acd29c070701c4acf5 100644 (file)
@@ -1867,16 +1867,24 @@ static unsigned int ratelimit_pages __read_mostly = 128 << (20 - PAGE_SHIFT);
 static bool numamigrate_update_ratelimit(pg_data_t *pgdat,
                                        unsigned long nr_pages)
 {
+       unsigned long next_window, interval;
+
+       next_window = READ_ONCE(pgdat->numabalancing_migrate_next_window);
+       interval = msecs_to_jiffies(migrate_interval_millisecs);
+
        /*
         * Rate-limit the amount of data that is being migrated to a node.
         * Optimal placement is no good if the memory bus is saturated and
         * all the time is being spent migrating!
         */
-       if (time_after(jiffies, pgdat->numabalancing_migrate_next_window)) {
-               spin_lock(&pgdat->numabalancing_migrate_lock);
+       if (time_after(jiffies, next_window) &&
+                       spin_trylock(&pgdat->numabalancing_migrate_lock)) {
                pgdat->numabalancing_migrate_nr_pages = 0;
-               pgdat->numabalancing_migrate_next_window = jiffies +
-                       msecs_to_jiffies(migrate_interval_millisecs);
+               do {
+                       next_window += interval;
+               } while (unlikely(time_after(jiffies, next_window)));
+
+               WRITE_ONCE(pgdat->numabalancing_migrate_next_window, next_window);
                spin_unlock(&pgdat->numabalancing_migrate_lock);
        }
        if (pgdat->numabalancing_migrate_nr_pages > ratelimit_pages) {
index a59ea70527b9bc46b4fde403a7f19b93493351fb..4e630143a0ba8549c9a63f106c7dd18b7aaa4d18 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/file.h>
 #include <linux/mm_inline.h>
 #include <linux/blk-cgroup.h>
+#include <linux/fadvise.h>
 
 #include "internal.h"
 
@@ -575,24 +576,6 @@ page_cache_async_readahead(struct address_space *mapping,
 }
 EXPORT_SYMBOL_GPL(page_cache_async_readahead);
 
-static ssize_t
-do_readahead(struct address_space *mapping, struct file *filp,
-            pgoff_t index, unsigned long nr)
-{
-       if (!mapping || !mapping->a_ops)
-               return -EINVAL;
-
-       /*
-        * Readahead doesn't make sense for DAX inodes, but we don't want it
-        * to report a failure either.  Instead, we just return success and
-        * don't do any work.
-        */
-       if (dax_mapping(mapping))
-               return 0;
-
-       return force_page_cache_readahead(mapping, filp, index, nr);
-}
-
 ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
 {
        ssize_t ret;
@@ -600,16 +583,22 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
 
        ret = -EBADF;
        f = fdget(fd);
-       if (f.file) {
-               if (f.file->f_mode & FMODE_READ) {
-                       struct address_space *mapping = f.file->f_mapping;
-                       pgoff_t start = offset >> PAGE_SHIFT;
-                       pgoff_t end = (offset + count - 1) >> PAGE_SHIFT;
-                       unsigned long len = end - start + 1;
-                       ret = do_readahead(mapping, f.file, start, len);
-               }
-               fdput(f);
-       }
+       if (!f.file || !(f.file->f_mode & FMODE_READ))
+               goto out;
+
+       /*
+        * The readahead() syscall is intended to run only on files
+        * that can execute readahead. If readahead is not possible
+        * on this file, then we must return -EINVAL.
+        */
+       ret = -EINVAL;
+       if (!f.file->f_mapping || !f.file->f_mapping->a_ops ||
+           !S_ISREG(file_inode(f.file)->i_mode))
+               goto out;
+
+       ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED);
+out:
+       fdput(f);
        return ret;
 }
 
index 0376c124b043be4d9be9f9fc233c3e03092ce428..446942677cd4b88fad61e9a869a901bc66fadc41 100644 (file)
@@ -2227,6 +2227,8 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
                        mpol_shared_policy_init(&info->policy, NULL);
                        break;
                }
+
+               lockdep_annotate_inode_mutex_key(inode);
        } else
                shmem_free_inode(sb);
        return inode;
index ea517bef7dc552a10ac6ed424ca06aa50670c303..cdc32a3b02fa0d7efc9d874b6cb6a26d82bf24c1 100644 (file)
 #endif
 #define VMACACHE_HASH(addr) ((addr >> VMACACHE_SHIFT) & VMACACHE_MASK)
 
-/*
- * Flush vma caches for threads that share a given mm.
- *
- * The operation is safe because the caller holds the mmap_sem
- * exclusively and other threads accessing the vma cache will
- * have mmap_sem held at least for read, so no extra locking
- * is required to maintain the vma cache.
- */
-void vmacache_flush_all(struct mm_struct *mm)
-{
-       struct task_struct *g, *p;
-
-       count_vm_vmacache_event(VMACACHE_FULL_FLUSHES);
-
-       /*
-        * Single threaded tasks need not iterate the entire
-        * list of process. We can avoid the flushing as well
-        * since the mm's seqnum was increased and don't have
-        * to worry about other threads' seqnum. Current's
-        * flush will occur upon the next lookup.
-        */
-       if (atomic_read(&mm->mm_users) == 1)
-               return;
-
-       rcu_read_lock();
-       for_each_process_thread(g, p) {
-               /*
-                * Only flush the vmacache pointers as the
-                * mm seqnum is already set and curr's will
-                * be set upon invalidation when the next
-                * lookup is done.
-                */
-               if (mm == p->mm)
-                       vmacache_flush(p);
-       }
-       rcu_read_unlock();
-}
-
 /*
  * This task may be accessing a foreign mm via (for example)
  * get_user_pages()->find_vma().  The vmacache is task-local and this
index 7e7d25504651d5b666f1706ff9a0743b3c62079f..c7ce2c1612259c45896bae9739a288966a28c970 100644 (file)
@@ -476,6 +476,17 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
        delta = freeable >> priority;
        delta *= 4;
        do_div(delta, shrinker->seeks);
+
+       /*
+        * Make sure we apply some minimal pressure on default priority
+        * even on small cgroups. Stale objects are not only consuming memory
+        * by themselves, but can also hold a reference to a dying cgroup,
+        * preventing it from being reclaimed. A dying cgroup with all
+        * corresponding structures like per-cpu stats and kmem caches
+        * can be really big, so it may lead to a significant waste of memory.
+        */
+       delta = max_t(unsigned long long, delta, min(freeable, batch_size));
+
        total_scan += delta;
        if (total_scan < 0) {
                pr_err("shrink_slab: %pF negative objects to delete nr=%ld\n",
index 71c20c1d40028614a19fed940a944b8cbad58776..9f481cfdf77dace2fa594585fde5079d46474c66 100644 (file)
@@ -241,7 +241,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
                 * the packet to be exactly of that size to make the link
                 * throughput estimation effective.
                 */
-               skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
+               skb_put_zero(skb, probe_len - hard_iface->bat_v.elp_skb->len);
 
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Sending unicast (probe) ELP packet on interface %s to %pM\n",
@@ -268,6 +268,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
        struct batadv_priv *bat_priv;
        struct sk_buff *skb;
        u32 elp_interval;
+       bool ret;
 
        bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
        hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
@@ -329,8 +330,11 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
                 * may sleep and that is not allowed in an rcu protected
                 * context. Therefore schedule a task for that.
                 */
-               queue_work(batadv_event_workqueue,
-                          &hardif_neigh->bat_v.metric_work);
+               ret = queue_work(batadv_event_workqueue,
+                                &hardif_neigh->bat_v.metric_work);
+
+               if (!ret)
+                       batadv_hardif_neigh_put(hardif_neigh);
        }
        rcu_read_unlock();
 
index ff9659af6b9177cdb23523d79a4bc70665b1cc4d..5f1aeeded0e3d8efe3df4f7bbf81ed57f95fc06a 100644 (file)
@@ -1772,6 +1772,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
 {
        struct batadv_bla_backbone_gw *backbone_gw;
        struct ethhdr *ethhdr;
+       bool ret;
 
        ethhdr = eth_hdr(skb);
 
@@ -1795,8 +1796,13 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
        if (unlikely(!backbone_gw))
                return true;
 
-       queue_work(batadv_event_workqueue, &backbone_gw->report_work);
-       /* backbone_gw is unreferenced in the report work function function */
+       ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
+
+       /* backbone_gw is unreferenced in the report work function function
+        * if queue_work() call was successful
+        */
+       if (!ret)
+               batadv_backbone_gw_put(backbone_gw);
 
        return true;
 }
index 8b198ee798c910b40997ed9ca867fc931c53dcc3..140c61a3f1ecfec4fe23c5ddca19e18e2e86fd56 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/kref.h>
 #include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/netdevice.h>
 #include <linux/netlink.h>
 #include <linux/rculist.h>
@@ -348,6 +349,9 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
  * @bat_priv: the bat priv with all the soft interface information
  * @orig_node: originator announcing gateway capabilities
  * @gateway: announced bandwidth information
+ *
+ * Has to be called with the appropriate locks being acquired
+ * (gw.list_lock).
  */
 static void batadv_gw_node_add(struct batadv_priv *bat_priv,
                               struct batadv_orig_node *orig_node,
@@ -355,6 +359,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
 {
        struct batadv_gw_node *gw_node;
 
+       lockdep_assert_held(&bat_priv->gw.list_lock);
+
        if (gateway->bandwidth_down == 0)
                return;
 
@@ -369,10 +375,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
        gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
        gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
 
-       spin_lock_bh(&bat_priv->gw.list_lock);
        kref_get(&gw_node->refcount);
        hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
-       spin_unlock_bh(&bat_priv->gw.list_lock);
 
        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                   "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
@@ -428,11 +432,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
 {
        struct batadv_gw_node *gw_node, *curr_gw = NULL;
 
+       spin_lock_bh(&bat_priv->gw.list_lock);
        gw_node = batadv_gw_node_get(bat_priv, orig_node);
        if (!gw_node) {
                batadv_gw_node_add(bat_priv, orig_node, gateway);
+               spin_unlock_bh(&bat_priv->gw.list_lock);
                goto out;
        }
+       spin_unlock_bh(&bat_priv->gw.list_lock);
 
        if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) &&
            gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))
index 8da3c9336111869b707dc29f6c6bd5e0258dd4dc..3ccc75ee719cf4eab27022d38754611a151805d7 100644 (file)
@@ -25,7 +25,7 @@
 #define BATADV_DRIVER_DEVICE "batman-adv"
 
 #ifndef BATADV_SOURCE_VERSION
-#define BATADV_SOURCE_VERSION "2018.2"
+#define BATADV_SOURCE_VERSION "2018.3"
 #endif
 
 /* B.A.T.M.A.N. parameters */
index c3578444f3cbe759a5385ac460ccb9d41ae1c4de..34caf129a9bf5531360f798be6a7059bad26a50f 100644 (file)
@@ -854,16 +854,27 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
        spinlock_t *lock; /* Used to lock list selected by "int in_coding" */
        struct list_head *list;
 
+       /* Select ingoing or outgoing coding node */
+       if (in_coding) {
+               lock = &orig_neigh_node->in_coding_list_lock;
+               list = &orig_neigh_node->in_coding_list;
+       } else {
+               lock = &orig_neigh_node->out_coding_list_lock;
+               list = &orig_neigh_node->out_coding_list;
+       }
+
+       spin_lock_bh(lock);
+
        /* Check if nc_node is already added */
        nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
 
        /* Node found */
        if (nc_node)
-               return nc_node;
+               goto unlock;
 
        nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
        if (!nc_node)
-               return NULL;
+               goto unlock;
 
        /* Initialize nc_node */
        INIT_LIST_HEAD(&nc_node->list);
@@ -872,22 +883,14 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
        kref_get(&orig_neigh_node->refcount);
        nc_node->orig_node = orig_neigh_node;
 
-       /* Select ingoing or outgoing coding node */
-       if (in_coding) {
-               lock = &orig_neigh_node->in_coding_list_lock;
-               list = &orig_neigh_node->in_coding_list;
-       } else {
-               lock = &orig_neigh_node->out_coding_list_lock;
-               list = &orig_neigh_node->out_coding_list;
-       }
-
        batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_node %pM -> %pM\n",
                   nc_node->addr, nc_node->orig_node->orig);
 
        /* Add nc_node to orig_node */
-       spin_lock_bh(lock);
        kref_get(&nc_node->refcount);
        list_add_tail_rcu(&nc_node->list, list);
+
+unlock:
        spin_unlock_bh(lock);
 
        return nc_node;
index 1485263a348bb50478ddc91f2bdd21dcc52db4d1..626ddca332db5f07fc79b1d0d2543b9529b85437 100644 (file)
@@ -574,15 +574,20 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
        struct batadv_softif_vlan *vlan;
        int err;
 
+       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
+
        vlan = batadv_softif_vlan_get(bat_priv, vid);
        if (vlan) {
                batadv_softif_vlan_put(vlan);
+               spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
                return -EEXIST;
        }
 
        vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
-       if (!vlan)
+       if (!vlan) {
+               spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
                return -ENOMEM;
+       }
 
        vlan->bat_priv = bat_priv;
        vlan->vid = vid;
@@ -590,17 +595,23 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
 
        atomic_set(&vlan->ap_isolation, 0);
 
+       kref_get(&vlan->refcount);
+       hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
+       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
+
+       /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the
+        * sleeping behavior of the sysfs functions and the fs_reclaim lock
+        */
        err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
        if (err) {
-               kfree(vlan);
+               /* ref for the function */
+               batadv_softif_vlan_put(vlan);
+
+               /* ref for the list */
+               batadv_softif_vlan_put(vlan);
                return err;
        }
 
-       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
-       kref_get(&vlan->refcount);
-       hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
-       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
-
        /* add a new TT local entry. This one will be marked with the NOPURGE
         * flag
         */
index f2eef43bd2ec5b798ba552ff14eedcfa734b39d6..09427fc6494a157554d8b19f3481a878a9f97bba 100644 (file)
@@ -188,7 +188,8 @@ ssize_t batadv_store_##_name(struct kobject *kobj,                  \
                                                                        \
        return __batadv_store_uint_attr(buff, count, _min, _max,        \
                                        _post_func, attr,               \
-                                       &bat_priv->_var, net_dev);      \
+                                       &bat_priv->_var, net_dev,       \
+                                       NULL);  \
 }
 
 #define BATADV_ATTR_SIF_SHOW_UINT(_name, _var)                         \
@@ -262,7 +263,9 @@ ssize_t batadv_store_##_name(struct kobject *kobj,                  \
                                                                        \
        length = __batadv_store_uint_attr(buff, count, _min, _max,      \
                                          _post_func, attr,             \
-                                         &hard_iface->_var, net_dev);  \
+                                         &hard_iface->_var,            \
+                                         hard_iface->soft_iface,       \
+                                         net_dev);                     \
                                                                        \
        batadv_hardif_put(hard_iface);                          \
        return length;                                                  \
@@ -356,10 +359,12 @@ __batadv_store_bool_attr(char *buff, size_t count,
 
 static int batadv_store_uint_attr(const char *buff, size_t count,
                                  struct net_device *net_dev,
+                                 struct net_device *slave_dev,
                                  const char *attr_name,
                                  unsigned int min, unsigned int max,
                                  atomic_t *attr)
 {
+       char ifname[IFNAMSIZ + 3] = "";
        unsigned long uint_val;
        int ret;
 
@@ -385,8 +390,11 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
        if (atomic_read(attr) == uint_val)
                return count;
 
-       batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
-                   attr_name, atomic_read(attr), uint_val);
+       if (slave_dev)
+               snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
+
+       batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
+                   attr_name, ifname, atomic_read(attr), uint_val);
 
        atomic_set(attr, uint_val);
        return count;
@@ -397,12 +405,13 @@ static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
                                        void (*post_func)(struct net_device *),
                                        const struct attribute *attr,
                                        atomic_t *attr_store,
-                                       struct net_device *net_dev)
+                                       struct net_device *net_dev,
+                                       struct net_device *slave_dev)
 {
        int ret;
 
-       ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
-                                    attr_store);
+       ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
+                                    attr->name, min, max, attr_store);
        if (post_func && ret)
                post_func(net_dev);
 
@@ -571,7 +580,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
        return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
                                        batadv_post_gw_reselect, attr,
                                        &bat_priv->gw.sel_class,
-                                       bat_priv->soft_iface);
+                                       bat_priv->soft_iface, NULL);
 }
 
 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
@@ -1090,8 +1099,9 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
        if (old_tp_override == tp_override)
                goto out;
 
-       batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
-                   "throughput_override",
+       batadv_info(hard_iface->soft_iface,
+                   "%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n",
+                   "throughput_override", net_dev->name,
                    old_tp_override / 10, old_tp_override % 10,
                    tp_override / 10, tp_override % 10);
 
index 12a2b7d21376721d15c6a31f3e794e4270d74b5c..d21624c446655d57786a1bcfa45aaf57c5ce9701 100644 (file)
@@ -1613,6 +1613,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
 {
        struct batadv_tt_orig_list_entry *orig_entry;
 
+       spin_lock_bh(&tt_global->list_lock);
+
        orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
        if (orig_entry) {
                /* refresh the ttvn: the current value could be a bogus one that
@@ -1635,11 +1637,9 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
        orig_entry->flags = flags;
        kref_init(&orig_entry->refcount);
 
-       spin_lock_bh(&tt_global->list_lock);
        kref_get(&orig_entry->refcount);
        hlist_add_head_rcu(&orig_entry->list,
                           &tt_global->orig_list);
-       spin_unlock_bh(&tt_global->list_lock);
        atomic_inc(&tt_global->orig_list_count);
 
 sync_flags:
@@ -1647,6 +1647,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
 out:
        if (orig_entry)
                batadv_tt_orig_list_entry_put(orig_entry);
+
+       spin_unlock_bh(&tt_global->list_lock);
 }
 
 /**
index a637458205d16bf838f796383d8cc15ac861801b..40e69c9346d22c09481544b8b4dec56cad88b64a 100644 (file)
@@ -529,15 +529,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
 {
        struct batadv_tvlv_handler *tvlv_handler;
 
+       spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
+
        tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
        if (tvlv_handler) {
+               spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
                batadv_tvlv_handler_put(tvlv_handler);
                return;
        }
 
        tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
-       if (!tvlv_handler)
+       if (!tvlv_handler) {
+               spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
                return;
+       }
 
        tvlv_handler->ogm_handler = optr;
        tvlv_handler->unicast_handler = uptr;
@@ -547,7 +552,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
        kref_init(&tvlv_handler->refcount);
        INIT_HLIST_NODE(&tvlv_handler->list);
 
-       spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
        kref_get(&tvlv_handler->refcount);
        hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
        spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
index ae91e2d40056b7ad12db2d934c8f76c565769ec3..3a7b0773536b8e226546ebe417463fcba5c92ba4 100644 (file)
@@ -83,6 +83,7 @@ enum {
 
 struct smp_dev {
        /* Secure Connections OOB data */
+       bool                    local_oob;
        u8                      local_pk[64];
        u8                      local_rand[16];
        bool                    debug_key;
@@ -599,6 +600,8 @@ int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
 
        memcpy(rand, smp->local_rand, 16);
 
+       smp->local_oob = true;
+
        return 0;
 }
 
@@ -1785,7 +1788,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
         * successfully received our local OOB data - therefore set the
         * flag to indicate that local OOB is in use.
         */
-       if (req->oob_flag == SMP_OOB_PRESENT)
+       if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
                set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
 
        /* SMP over BR/EDR requires special treatment */
@@ -1967,7 +1970,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
         * successfully received our local OOB data - therefore set the
         * flag to indicate that local OOB is in use.
         */
-       if (rsp->oob_flag == SMP_OOB_PRESENT)
+       if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
                set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
 
        smp->prsp[0] = SMP_CMD_PAIRING_RSP;
@@ -2697,7 +2700,13 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
         * key was set/generated.
         */
        if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
-               struct smp_dev *smp_dev = chan->data;
+               struct l2cap_chan *hchan = hdev->smp_data;
+               struct smp_dev *smp_dev;
+
+               if (!hchan || !hchan->data)
+                       return SMP_UNSPECIFIED;
+
+               smp_dev = hchan->data;
 
                tfm_ecdh = smp_dev->tfm_ecdh;
        } else {
@@ -3230,6 +3239,7 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
                return ERR_CAST(tfm_ecdh);
        }
 
+       smp->local_oob = false;
        smp->tfm_aes = tfm_aes;
        smp->tfm_cmac = tfm_cmac;
        smp->tfm_ecdh = tfm_ecdh;
index 65fc366a78a4c455a02e74bdc30c9249698eb488..8c0ed225e2801a741f81eaa6a626eb191884f0aa 100644 (file)
@@ -2592,7 +2592,7 @@ static int devlink_resource_fill(struct genl_info *info,
        if (!nlh) {
                err = devlink_dpipe_send_and_alloc_skb(&skb, info);
                if (err)
-                       goto err_skb_send_alloc;
+                       return err;
                goto send_done;
        }
        return genlmsg_reply(skb, info);
@@ -2600,7 +2600,6 @@ static int devlink_resource_fill(struct genl_info *info,
 nla_put_failure:
        err = -EMSGSIZE;
 err_resource_put:
-err_skb_send_alloc:
        nlmsg_free(skb);
        return err;
 }
index c9993c6c2fd4f492d5113d9c328c7bf3ddcfa9f3..234a0ec2e9327727e95a76f44a29e8cc93feff84 100644 (file)
@@ -2624,6 +2624,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
        case ETHTOOL_GPHYSTATS:
        case ETHTOOL_GTSO:
        case ETHTOOL_GPERMADDR:
+       case ETHTOOL_GUFO:
        case ETHTOOL_GGSO:
        case ETHTOOL_GGRO:
        case ETHTOOL_GFLAGS:
index aecdeba052d3f0ff3d4f0a33ec36891f9738052c..5e00f2b85a5681a32cd905f0c02a303c5ef209af 100644 (file)
@@ -2344,7 +2344,8 @@ BPF_CALL_4(bpf_msg_pull_data,
        if (unlikely(bytes_sg_total > copy))
                return -EINVAL;
 
-       page = alloc_pages(__GFP_NOWARN | GFP_ATOMIC, get_order(copy));
+       page = alloc_pages(__GFP_NOWARN | GFP_ATOMIC | __GFP_COMP,
+                          get_order(copy));
        if (unlikely(!page))
                return -ENOMEM;
        p = page_address(page);
index aa19d86937afabf5fb7dd29ce7c2379241281c06..91592fceeaad7225ed695aebef01fbc1fa4e284b 100644 (file)
@@ -1180,6 +1180,12 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                lladdr = neigh->ha;
        }
 
+       /* Update confirmed timestamp for neighbour entry after we
+        * received ARP packet even if it doesn't change IP to MAC binding.
+        */
+       if (new & NUD_CONNECTED)
+               neigh->confirmed = jiffies;
+
        /* If entry was valid and address is not changed,
           do not change entry state, if new one is STALE.
         */
@@ -1201,15 +1207,12 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                }
        }
 
-       /* Update timestamps only once we know we will make a change to the
+       /* Update timestamp only once we know we will make a change to the
         * neighbour entry. Otherwise we risk to move the locktime window with
         * noop updates and ignore relevant ARP updates.
         */
-       if (new != old || lladdr != neigh->ha) {
-               if (new & NUD_CONNECTED)
-                       neigh->confirmed = jiffies;
+       if (new != old || lladdr != neigh->ha)
                neigh->updated = jiffies;
-       }
 
        if (new != old) {
                neigh_del_timer(neigh);
index 57557a6a950cc9cdff959391576a03381d328c1a..3219a2932463096566ce8ff336ecdf699422dd65 100644 (file)
@@ -187,16 +187,16 @@ static void poll_napi(struct net_device *dev)
        }
 }
 
-static void netpoll_poll_dev(struct net_device *dev)
+void netpoll_poll_dev(struct net_device *dev)
 {
-       const struct net_device_ops *ops;
        struct netpoll_info *ni = rcu_dereference_bh(dev->npinfo);
+       const struct net_device_ops *ops;
 
        /* Don't do any rx activity if the dev_lock mutex is held
         * the dev_open/close paths use this to block netpoll activity
         * while changing device state
         */
-       if (down_trylock(&ni->dev_lock))
+       if (!ni || down_trylock(&ni->dev_lock))
                return;
 
        if (!netif_running(dev)) {
@@ -205,13 +205,8 @@ static void netpoll_poll_dev(struct net_device *dev)
        }
 
        ops = dev->netdev_ops;
-       if (!ops->ndo_poll_controller) {
-               up(&ni->dev_lock);
-               return;
-       }
-
-       /* Process pending work on NIC */
-       ops->ndo_poll_controller(dev);
+       if (ops->ndo_poll_controller)
+               ops->ndo_poll_controller(dev);
 
        poll_napi(dev);
 
@@ -219,6 +214,7 @@ static void netpoll_poll_dev(struct net_device *dev)
 
        zap_completion_queue();
 }
+EXPORT_SYMBOL(netpoll_poll_dev);
 
 void netpoll_poll_disable(struct net_device *dev)
 {
@@ -613,8 +609,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
        strlcpy(np->dev_name, ndev->name, IFNAMSIZ);
        INIT_WORK(&np->cleanup_work, netpoll_async_cleanup);
 
-       if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) ||
-           !ndev->netdev_ops->ndo_poll_controller) {
+       if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
                np_err(np, "%s doesn't support polling, aborting\n",
                       np->dev_name);
                err = -ENOTSUPP;
index 60c928894a7868e5f1bcec39f5204eba9e0fe82f..63ce2283a456a4aeabf3c10b681fe63195209101 100644 (file)
@@ -2810,7 +2810,7 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm)
        }
 
        if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) {
-               __dev_notify_flags(dev, old_flags, 0U);
+               __dev_notify_flags(dev, old_flags, (old_flags ^ dev->flags));
        } else {
                dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
                __dev_notify_flags(dev, old_flags, ~0U);
index c996c09d095f59c6a54ce28ff4c71bb0ac467c64..b2c807f67aba5847fa0c9f07adabbff7cf1afd22 100644 (file)
@@ -939,9 +939,6 @@ struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size)
 
        WARN_ON_ONCE(!in_task());
 
-       if (!sock_flag(sk, SOCK_ZEROCOPY))
-               return NULL;
-
        skb = sock_omalloc(sk, 0, GFP_KERNEL);
        if (!skb)
                return NULL;
index 20fda8fb8ffda40a9ec61dead5ebacdbc4c1bc4a..1fbe2f815474cd09331990d49afb140932cdd21b 100644 (file)
@@ -1377,6 +1377,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
                if (encap)
                        skb_reset_inner_headers(skb);
                skb->network_header = (u8 *)iph - skb->head;
+               skb_reset_mac_len(skb);
        } while ((skb = skb->next));
 
 out:
index 88281fbce88ce8f1062b99594665766c2a5f5b74..e7227128df2c8fd54727c234f76043133809bd1e 100644 (file)
@@ -599,6 +599,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb,
                        nextp = &fp->next;
                        fp->prev = NULL;
                        memset(&fp->rbnode, 0, sizeof(fp->rbnode));
+                       fp->sk = NULL;
                        head->data_len += fp->len;
                        head->len += fp->len;
                        if (head->ip_summed != fp->ip_summed)
index ae714aecc31c030cdce19fc5b2e92eb6ca214a16..8cce0e9ea08cb454f28b4dfdd17bb2875470a7f6 100644 (file)
@@ -178,6 +178,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
 
        if (tpi->proto == htons(ETH_P_TEB))
                itn = net_generic(net, gre_tap_net_id);
+       else if (tpi->proto == htons(ETH_P_ERSPAN) ||
+                tpi->proto == htons(ETH_P_ERSPAN2))
+               itn = net_generic(net, erspan_net_id);
        else
                itn = net_generic(net, ipgre_net_id);
 
@@ -328,6 +331,8 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
                ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
                return PACKET_RCVD;
        }
+       return PACKET_REJECT;
+
 drop:
        kfree_skb(skb);
        return PACKET_RCVD;
index c4f5602308edca064297fe8764764f65ebe84569..284a22154b4e6cb129ca7dfd127ce11e306dba19 100644 (file)
@@ -627,6 +627,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
                    const struct iphdr *tnl_params, u8 protocol)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
+       unsigned int inner_nhdr_len = 0;
        const struct iphdr *inner_iph;
        struct flowi4 fl4;
        u8     tos, ttl;
@@ -636,6 +637,14 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
        __be32 dst;
        bool connected;
 
+       /* ensure we can access the inner net header, for several users below */
+       if (skb->protocol == htons(ETH_P_IP))
+               inner_nhdr_len = sizeof(struct iphdr);
+       else if (skb->protocol == htons(ETH_P_IPV6))
+               inner_nhdr_len = sizeof(struct ipv6hdr);
+       if (unlikely(!pskb_may_pull(skb, inner_nhdr_len)))
+               goto tx_error;
+
        inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
        connected = (tunnel->parms.iph.daddr != 0);
 
index d9504adc47b3df6e3311cd5860e34deb8efe6c95..184bf2e0a1edfce0dea43ef6d06fd8c8573f71a8 100644 (file)
@@ -106,6 +106,10 @@ config NF_NAT_IPV4
 
 if NF_NAT_IPV4
 
+config NF_NAT_MASQUERADE_IPV4
+       bool
+
+if NF_TABLES
 config NFT_CHAIN_NAT_IPV4
        depends on NF_TABLES_IPV4
        tristate "IPv4 nf_tables nat chain support"
@@ -115,9 +119,6 @@ config NFT_CHAIN_NAT_IPV4
          packet transformations such as the source, destination address and
          source and destination ports.
 
-config NF_NAT_MASQUERADE_IPV4
-       bool
-
 config NFT_MASQ_IPV4
        tristate "IPv4 masquerading support for nf_tables"
        depends on NF_TABLES_IPV4
@@ -135,6 +136,7 @@ config NFT_REDIR_IPV4
        help
          This is the expression that provides IPv4 redirect support for
          nf_tables.
+endif # NF_TABLES
 
 config NF_NAT_SNMP_BASIC
        tristate "Basic SNMP-ALG support"
index b8af2fec5ad59a0ddd2590499e2c1e977646485c..10c6246396cc016b59fc3e368602684dd68566a2 100644 (file)
@@ -1185,7 +1185,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
 
        flags = msg->msg_flags;
 
-       if (flags & MSG_ZEROCOPY && size) {
+       if (flags & MSG_ZEROCOPY && size && sock_flag(sk, SOCK_ZEROCOPY)) {
                if (sk->sk_state != TCP_ESTABLISHED) {
                        err = -EINVAL;
                        goto out_err;
index 4c2dd9f863f76eb6e55202b19e1acebf4fbac887..4cf2f7bb2802ad4ae968b5a6dfb9d005ed619c76 100644 (file)
@@ -6367,8 +6367,8 @@ static bool tcp_syn_flood_action(const struct sock *sk,
        if (!queue->synflood_warned &&
            net->ipv4.sysctl_tcp_syncookies != 2 &&
            xchg(&queue->synflood_warned, 1) == 0)
-               pr_info("%s: Possible SYN flooding on port %d. %s.  Check SNMP counters.\n",
-                       proto, ntohs(tcp_hdr(skb)->dest), msg);
+               net_info_ratelimited("%s: Possible SYN flooding on port %d. %s.  Check SNMP counters.\n",
+                                    proto, ntohs(tcp_hdr(skb)->dest), msg);
 
        return want_cookie;
 }
index f4e35b2ff8b8dc3956da415cb6a29bb147e25f04..7d69dd6fa7e8c63929a27edad74fb0d6f9f3ee31 100644 (file)
@@ -2124,6 +2124,28 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
                                                         inet_compute_pseudo);
 }
 
+/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
+ * return code conversion for ip layer consumption
+ */
+static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
+                              struct udphdr *uh)
+{
+       int ret;
+
+       if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
+               skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
+                                        inet_compute_pseudo);
+
+       ret = udp_queue_rcv_skb(sk, skb);
+
+       /* a return value > 0 means to resubmit the input, but
+        * it wants the return to be -protocol, or 0
+        */
+       if (ret > 0)
+               return -ret;
+       return 0;
+}
+
 /*
  *     All we need to do is get the socket, and then do a checksum.
  */
@@ -2170,14 +2192,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                if (unlikely(sk->sk_rx_dst != dst))
                        udp_sk_rx_dst_set(sk, dst);
 
-               ret = udp_queue_rcv_skb(sk, skb);
+               ret = udp_unicast_rcv_skb(sk, skb, uh);
                sock_put(sk);
-               /* a return value > 0 means to resubmit the input, but
-                * it wants the return to be -protocol, or 0
-                */
-               if (ret > 0)
-                       return -ret;
-               return 0;
+               return ret;
        }
 
        if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
@@ -2185,22 +2202,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                                                saddr, daddr, udptable, proto);
 
        sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
-       if (sk) {
-               int ret;
-
-               if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
-                       skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
-                                                inet_compute_pseudo);
-
-               ret = udp_queue_rcv_skb(sk, skb);
-
-               /* a return value > 0 means to resubmit the input, but
-                * it wants the return to be -protocol, or 0
-                */
-               if (ret > 0)
-                       return -ret;
-               return 0;
-       }
+       if (sk)
+               return udp_unicast_rcv_skb(sk, skb, uh);
 
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                goto drop;
index d51a8c0b3372d09ad1c78b76f94b4ebaf7ca3f61..c63ccce6425fb221170b058e701c11b7ba9a497e 100644 (file)
@@ -4201,7 +4201,6 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos)
                                p++;
                                continue;
                        }
-                       state->offset++;
                        return ifa;
                }
 
@@ -4225,13 +4224,12 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
                return ifa;
        }
 
+       state->offset = 0;
        while (++state->bucket < IN6_ADDR_HSIZE) {
-               state->offset = 0;
                hlist_for_each_entry_rcu(ifa,
                                     &inet6_addr_lst[state->bucket], addr_lst) {
                        if (!net_eq(dev_net(ifa->idev->dev), net))
                                continue;
-                       state->offset++;
                        return ifa;
                }
        }
index 37ff4805b20c73fd3c404a0904985bae68f21f23..c7e495f1201105f1ac1724a7b8fd82399efcce32 100644 (file)
@@ -115,6 +115,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
                        payload_len = skb->len - nhoff - sizeof(*ipv6h);
                ipv6h->payload_len = htons(payload_len);
                skb->network_header = (u8 *)ipv6h - skb->head;
+               skb_reset_mac_len(skb);
 
                if (udpfrag) {
                        int err = ip6_find_1stfragopt(skb, &prevhdr);
index 16f200f06500758c4cae84ea16229d5dbce912cb..f9f8f554d141676a7d342f85088d12d9a6815e9d 100644 (file)
@@ -219,12 +219,10 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
                                kfree_skb(skb);
                                return -ENOBUFS;
                        }
+                       if (skb->sk)
+                               skb_set_owner_w(skb2, skb->sk);
                        consume_skb(skb);
                        skb = skb2;
-                       /* skb_set_owner_w() changes sk->sk_wmem_alloc atomically,
-                        * it is safe to call in our context (socket lock not held)
-                        */
-                       skb_set_owner_w(skb, (struct sock *)sk);
                }
                if (opt->opt_flen)
                        ipv6_push_frag_opts(skb, opt, &proto);
index 419960b0ba16370ec9c47bee16aad15d9819f349..a0b6932c3afd23c5b1b0dded8190f9a74ef274f6 100644 (file)
@@ -1234,7 +1234,7 @@ static inline int
 ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       const struct iphdr  *iph = ip_hdr(skb);
+       const struct iphdr  *iph;
        int encap_limit = -1;
        struct flowi6 fl6;
        __u8 dsfield;
@@ -1242,6 +1242,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        u8 tproto;
        int err;
 
+       /* ensure we can access the full inner ip header */
+       if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+               return -1;
+
+       iph = ip_hdr(skb);
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 
        tproto = READ_ONCE(t->parms.proto);
@@ -1306,7 +1311,7 @@ static inline int
 ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+       struct ipv6hdr *ipv6h;
        int encap_limit = -1;
        __u16 offset;
        struct flowi6 fl6;
@@ -1315,6 +1320,10 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        u8 tproto;
        int err;
 
+       if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
+               return -1;
+
+       ipv6h = ipv6_hdr(skb);
        tproto = READ_ONCE(t->parms.proto);
        if ((tproto != IPPROTO_IPV6 && tproto != 0) ||
            ip6_tnl_addr_conflict(t, ipv6h))
index 2a14d8b65924d56c79380fed6d867cf62db42e33..8f68a518d9db7a6f4d489972be3efa68315059a6 100644 (file)
@@ -445,6 +445,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev,  struct net_devic
                else if (head->ip_summed == CHECKSUM_COMPLETE)
                        head->csum = csum_add(head->csum, fp->csum);
                head->truesize += fp->truesize;
+               fp->sk = NULL;
        }
        sub_frag_mem_limit(fq->q.net, head->truesize);
 
index 18e00ce1719a3d16f5099ea2271d89916929074f..826b14de7dbbc8d1e2100820374654e5722c32b6 100644 (file)
@@ -364,11 +364,14 @@ EXPORT_SYMBOL(ip6_dst_alloc);
 
 static void ip6_dst_destroy(struct dst_entry *dst)
 {
+       struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct fib6_info *from;
        struct inet6_dev *idev;
 
-       dst_destroy_metrics_generic(dst);
+       if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
+               kfree(p);
+
        rt6_uncached_list_del(rt);
 
        idev = rt->rt6i_idev;
@@ -946,8 +949,6 @@ static void ip6_rt_init_dst_reject(struct rt6_info *rt, struct fib6_info *ort)
 
 static void ip6_rt_init_dst(struct rt6_info *rt, struct fib6_info *ort)
 {
-       rt->dst.flags |= fib6_info_dst_flags(ort);
-
        if (ort->fib6_flags & RTF_REJECT) {
                ip6_rt_init_dst_reject(rt, ort);
                return;
@@ -978,6 +979,10 @@ static void rt6_set_from(struct rt6_info *rt, struct fib6_info *from)
        rt->rt6i_flags &= ~RTF_EXPIRES;
        rcu_assign_pointer(rt->from, from);
        dst_init_metrics(&rt->dst, from->fib6_metrics->metrics, true);
+       if (from->fib6_metrics != &dst_default_metrics) {
+               rt->dst._metrics |= DST_METRICS_REFCOUNTED;
+               refcount_inc(&from->fib6_metrics->refcnt);
+       }
 }
 
 /* Caller must already hold reference to @ort */
@@ -4670,20 +4675,31 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
                         int iif, int type, u32 portid, u32 seq,
                         unsigned int flags)
 {
-       struct rtmsg *rtm;
+       struct rt6_info *rt6 = (struct rt6_info *)dst;
+       struct rt6key *rt6_dst, *rt6_src;
+       u32 *pmetrics, table, rt6_flags;
        struct nlmsghdr *nlh;
+       struct rtmsg *rtm;
        long expires = 0;
-       u32 *pmetrics;
-       u32 table;
 
        nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags);
        if (!nlh)
                return -EMSGSIZE;
 
+       if (rt6) {
+               rt6_dst = &rt6->rt6i_dst;
+               rt6_src = &rt6->rt6i_src;
+               rt6_flags = rt6->rt6i_flags;
+       } else {
+               rt6_dst = &rt->fib6_dst;
+               rt6_src = &rt->fib6_src;
+               rt6_flags = rt->fib6_flags;
+       }
+
        rtm = nlmsg_data(nlh);
        rtm->rtm_family = AF_INET6;
-       rtm->rtm_dst_len = rt->fib6_dst.plen;
-       rtm->rtm_src_len = rt->fib6_src.plen;
+       rtm->rtm_dst_len = rt6_dst->plen;
+       rtm->rtm_src_len = rt6_src->plen;
        rtm->rtm_tos = 0;
        if (rt->fib6_table)
                table = rt->fib6_table->tb6_id;
@@ -4698,7 +4714,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
        rtm->rtm_scope = RT_SCOPE_UNIVERSE;
        rtm->rtm_protocol = rt->fib6_protocol;
 
-       if (rt->fib6_flags & RTF_CACHE)
+       if (rt6_flags & RTF_CACHE)
                rtm->rtm_flags |= RTM_F_CLONED;
 
        if (dest) {
@@ -4706,7 +4722,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
                        goto nla_put_failure;
                rtm->rtm_dst_len = 128;
        } else if (rtm->rtm_dst_len)
-               if (nla_put_in6_addr(skb, RTA_DST, &rt->fib6_dst.addr))
+               if (nla_put_in6_addr(skb, RTA_DST, &rt6_dst->addr))
                        goto nla_put_failure;
 #ifdef CONFIG_IPV6_SUBTREES
        if (src) {
@@ -4714,12 +4730,12 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
                        goto nla_put_failure;
                rtm->rtm_src_len = 128;
        } else if (rtm->rtm_src_len &&
-                  nla_put_in6_addr(skb, RTA_SRC, &rt->fib6_src.addr))
+                  nla_put_in6_addr(skb, RTA_SRC, &rt6_src->addr))
                goto nla_put_failure;
 #endif
        if (iif) {
 #ifdef CONFIG_IPV6_MROUTE
-               if (ipv6_addr_is_multicast(&rt->fib6_dst.addr)) {
+               if (ipv6_addr_is_multicast(&rt6_dst->addr)) {
                        int err = ip6mr_get_route(net, skb, rtm, portid);
 
                        if (err == 0)
@@ -4754,7 +4770,14 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
        /* For multipath routes, walk the siblings list and add
         * each as a nexthop within RTA_MULTIPATH.
         */
-       if (rt->fib6_nsiblings) {
+       if (rt6) {
+               if (rt6_flags & RTF_GATEWAY &&
+                   nla_put_in6_addr(skb, RTA_GATEWAY, &rt6->rt6i_gateway))
+                       goto nla_put_failure;
+
+               if (dst->dev && nla_put_u32(skb, RTA_OIF, dst->dev->ifindex))
+                       goto nla_put_failure;
+       } else if (rt->fib6_nsiblings) {
                struct fib6_info *sibling, *next_sibling;
                struct nlattr *mp;
 
@@ -4777,7 +4800,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
                        goto nla_put_failure;
        }
 
-       if (rt->fib6_flags & RTF_EXPIRES) {
+       if (rt6_flags & RTF_EXPIRES) {
                expires = dst ? dst->expires : rt->expires;
                expires -= jiffies;
        }
@@ -4785,7 +4808,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
        if (rtnl_put_cacheinfo(skb, dst, 0, expires, dst ? dst->error : 0) < 0)
                goto nla_put_failure;
 
-       if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->fib6_flags)))
+       if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt6_flags)))
                goto nla_put_failure;
 
 
index 83f4c77c79d86eda12ec76b572c4f64546f43ae4..28c4aa5078fcb34b773875d28790e367a5c98ad6 100644 (file)
@@ -752,6 +752,28 @@ static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
        }
 }
 
+/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
+ * return code conversion for ip layer consumption
+ */
+static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
+                               struct udphdr *uh)
+{
+       int ret;
+
+       if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
+               skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
+                                        ip6_compute_pseudo);
+
+       ret = udpv6_queue_rcv_skb(sk, skb);
+
+       /* a return value > 0 means to resubmit the input, but
+        * it wants the return to be -protocol, or 0
+        */
+       if (ret > 0)
+               return -ret;
+       return 0;
+}
+
 int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                   int proto)
 {
@@ -803,13 +825,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                if (unlikely(sk->sk_rx_dst != dst))
                        udp6_sk_rx_dst_set(sk, dst);
 
-               ret = udpv6_queue_rcv_skb(sk, skb);
-               sock_put(sk);
+               if (!uh->check && !udp_sk(sk)->no_check6_rx) {
+                       sock_put(sk);
+                       goto report_csum_error;
+               }
 
-               /* a return value > 0 means to resubmit the input */
-               if (ret > 0)
-                       return ret;
-               return 0;
+               ret = udp6_unicast_rcv_skb(sk, skb, uh);
+               sock_put(sk);
+               return ret;
        }
 
        /*
@@ -822,30 +845,13 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
        /* Unicast */
        sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
        if (sk) {
-               int ret;
-
-               if (!uh->check && !udp_sk(sk)->no_check6_rx) {
-                       udp6_csum_zero_error(skb);
-                       goto csum_error;
-               }
-
-               if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
-                       skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
-                                                ip6_compute_pseudo);
-
-               ret = udpv6_queue_rcv_skb(sk, skb);
-
-               /* a return value > 0 means to resubmit the input */
-               if (ret > 0)
-                       return ret;
-
-               return 0;
+               if (!uh->check && !udp_sk(sk)->no_check6_rx)
+                       goto report_csum_error;
+               return udp6_unicast_rcv_skb(sk, skb, uh);
        }
 
-       if (!uh->check) {
-               udp6_csum_zero_error(skb);
-               goto csum_error;
-       }
+       if (!uh->check)
+               goto report_csum_error;
 
        if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
                goto discard;
@@ -866,6 +872,9 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                            ulen, skb->len,
                            daddr, ntohs(uh->dest));
        goto discard;
+
+report_csum_error:
+       udp6_csum_zero_error(skb);
 csum_error:
        __UDP6_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
 discard:
index a21d8ed0a325a5ddafd316b3fc9d972489cb8b7a..e2f16a0173a93bc876e293a68878d83d78cda7ef 100644 (file)
@@ -351,20 +351,28 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
                memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message));
 
        skb->dev = iucv->hs_dev;
-       if (!skb->dev)
-               return -ENODEV;
-       if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev))
-               return -ENETDOWN;
+       if (!skb->dev) {
+               err = -ENODEV;
+               goto err_free;
+       }
+       if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev)) {
+               err = -ENETDOWN;
+               goto err_free;
+       }
        if (skb->len > skb->dev->mtu) {
-               if (sock->sk_type == SOCK_SEQPACKET)
-                       return -EMSGSIZE;
-               else
-                       skb_trim(skb, skb->dev->mtu);
+               if (sock->sk_type == SOCK_SEQPACKET) {
+                       err = -EMSGSIZE;
+                       goto err_free;
+               }
+               skb_trim(skb, skb->dev->mtu);
        }
        skb->protocol = cpu_to_be16(ETH_P_AF_IUCV);
        nskb = skb_clone(skb, GFP_ATOMIC);
-       if (!nskb)
-               return -ENOMEM;
+       if (!nskb) {
+               err = -ENOMEM;
+               goto err_free;
+       }
+
        skb_queue_tail(&iucv->send_skb_q, nskb);
        err = dev_queue_xmit(skb);
        if (net_xmit_eval(err)) {
@@ -375,6 +383,10 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
                WARN_ON(atomic_read(&iucv->msg_recv) < 0);
        }
        return net_xmit_eval(err);
+
+err_free:
+       kfree_skb(skb);
+       return err;
 }
 
 static struct sock *__iucv_get_sock_by_name(char *nm)
@@ -1167,7 +1179,7 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
                err = afiucv_hs_send(&txmsg, sk, skb, 0);
                if (err) {
                        atomic_dec(&iucv->msg_sent);
-                       goto fail;
+                       goto out;
                }
        } else { /* Classic VM IUCV transport */
                skb_queue_tail(&iucv->send_skb_q, skb);
@@ -2155,8 +2167,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
        struct sock *sk;
        struct iucv_sock *iucv;
        struct af_iucv_trans_hdr *trans_hdr;
+       int err = NET_RX_SUCCESS;
        char nullstring[8];
-       int err = 0;
 
        if (skb->len < (ETH_HLEN + sizeof(struct af_iucv_trans_hdr))) {
                WARN_ONCE(1, "AF_IUCV too short skb, len=%d, min=%d",
@@ -2254,7 +2266,7 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
                err = afiucv_hs_callback_rx(sk, skb);
                break;
        default:
-               ;
+               kfree_skb(skb);
        }
 
        return err;
index 8f7ef167c45a75223dcb00b74174112fafdd0c34..eb502c6290c2ad1668897aedef08e1fc92e299e9 100644 (file)
@@ -1874,7 +1874,7 @@ static void iucv_pm_complete(struct device *dev)
  * Returns 0 if there are still iucv pathes defined
  *        1 if there are no iucv pathes defined
  */
-int iucv_path_table_empty(void)
+static int iucv_path_table_empty(void)
 {
        int i;
 
index 7a4de6d618b169d0f72b04386965b6e02ba27ada..8fbe6cdbe255d4d32b790baa22e1431d240f6e7f 100644 (file)
@@ -1533,10 +1533,14 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
        unsigned int flags;
 
        if (event == NETDEV_REGISTER) {
-               /* For now just support Ethernet, IPGRE, SIT and IPIP devices */
+
+               /* For now just support Ethernet, IPGRE, IP6GRE, SIT and
+                * IPIP devices
+                */
                if (dev->type == ARPHRD_ETHER ||
                    dev->type == ARPHRD_LOOPBACK ||
                    dev->type == ARPHRD_IPGRE ||
+                   dev->type == ARPHRD_IP6GRE ||
                    dev->type == ARPHRD_SIT ||
                    dev->type == ARPHRD_TUNNEL) {
                        mdev = mpls_add_dev(dev);
index 71709c104081448f3d6bc50305ad344cb815167e..f61c306de1d089358ede089f87f97c72c8927670 100644 (file)
@@ -771,13 +771,13 @@ config NETFILTER_XT_TARGET_CHECKSUM
        depends on NETFILTER_ADVANCED
        ---help---
          This option adds a `CHECKSUM' target, which can be used in the iptables mangle
-         table.
+         table to work around buggy DHCP clients in virtualized environments.
 
-         You can use this target to compute and fill in the checksum in
-         a packet that lacks a checksum.  This is particularly useful,
-         if you need to work around old applications such as dhcp clients,
-         that do not work well with checksum offloads, but don't want to disable
-         checksum offload in your device.
+         Some old DHCP clients drop packets because they are not aware
+         that the checksum would normally be offloaded to hardware and
+         thus should be considered valid.
+         This target can be used to fill in the checksum using iptables
+         when such packets are sent via a virtual network device.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
index 9f14b0df6960d167a0980cc3896e4dbc19679607..51c5d7eec0a3517518a38cce411bf7b09189c15e 100644 (file)
@@ -776,9 +776,26 @@ static const struct nf_hook_ops ipv6_conntrack_ops[] = {
 };
 #endif
 
+static int nf_ct_tcp_fixup(struct nf_conn *ct, void *_nfproto)
+{
+       u8 nfproto = (unsigned long)_nfproto;
+
+       if (nf_ct_l3num(ct) != nfproto)
+               return 0;
+
+       if (nf_ct_protonum(ct) == IPPROTO_TCP &&
+           ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED) {
+               ct->proto.tcp.seen[0].td_maxwin = 0;
+               ct->proto.tcp.seen[1].td_maxwin = 0;
+       }
+
+       return 0;
+}
+
 static int nf_ct_netns_do_get(struct net *net, u8 nfproto)
 {
        struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id);
+       bool fixup_needed = false;
        int err = 0;
 
        mutex_lock(&nf_ct_proto_mutex);
@@ -798,6 +815,8 @@ static int nf_ct_netns_do_get(struct net *net, u8 nfproto)
                                            ARRAY_SIZE(ipv4_conntrack_ops));
                if (err)
                        cnet->users4 = 0;
+               else
+                       fixup_needed = true;
                break;
 #if IS_ENABLED(CONFIG_IPV6)
        case NFPROTO_IPV6:
@@ -814,6 +833,8 @@ static int nf_ct_netns_do_get(struct net *net, u8 nfproto)
                                            ARRAY_SIZE(ipv6_conntrack_ops));
                if (err)
                        cnet->users6 = 0;
+               else
+                       fixup_needed = true;
                break;
 #endif
        default:
@@ -822,6 +843,11 @@ static int nf_ct_netns_do_get(struct net *net, u8 nfproto)
        }
  out_unlock:
        mutex_unlock(&nf_ct_proto_mutex);
+
+       if (fixup_needed)
+               nf_ct_iterate_cleanup_net(net, nf_ct_tcp_fixup,
+                                         (void *)(unsigned long)nfproto, 0, 0);
+
        return err;
 }
 
index 8c58f96b59e701422cd60303dfc6a2f3db8c1b04..f3f91ed2c21adce5dcc5e9ba06d6a843a6af39bb 100644 (file)
@@ -675,7 +675,7 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
 }
 #endif
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -697,6 +697,8 @@ static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
                        timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
                }
        }
+
+       timeouts[CTA_TIMEOUT_DCCP_UNSPEC] = timeouts[CTA_TIMEOUT_DCCP_REQUEST];
        return 0;
 }
 
@@ -726,7 +728,7 @@ dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = {
        [CTA_TIMEOUT_DCCP_CLOSING]      = { .type = NLA_U32 },
        [CTA_TIMEOUT_DCCP_TIMEWAIT]     = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
 /* template, data assigned later */
@@ -827,6 +829,11 @@ static int dccp_init_net(struct net *net, u_int16_t proto)
                dn->dccp_timeout[CT_DCCP_CLOSEREQ]      = 64 * HZ;
                dn->dccp_timeout[CT_DCCP_CLOSING]       = 64 * HZ;
                dn->dccp_timeout[CT_DCCP_TIMEWAIT]      = 2 * DCCP_MSL;
+
+               /* timeouts[0] is unused, make it same as SYN_SENT so
+                * ->timeouts[0] contains 'new' timeout, like udp or icmp.
+                */
+               dn->dccp_timeout[CT_DCCP_NONE] = dn->dccp_timeout[CT_DCCP_REQUEST];
        }
 
        return dccp_kmemdup_sysctl_table(net, pn, dn);
@@ -856,7 +863,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = {
        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = dccp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = dccp_timeout_obj_to_nlattr,
@@ -864,7 +871,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = {
                .obj_size       = sizeof(unsigned int) * CT_DCCP_MAX,
                .nla_policy     = dccp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = dccp_init_net,
        .get_net_proto          = dccp_get_net_proto,
 };
@@ -889,7 +896,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = {
        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = dccp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = dccp_timeout_obj_to_nlattr,
@@ -897,7 +904,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = {
                .obj_size       = sizeof(unsigned int) * CT_DCCP_MAX,
                .nla_policy     = dccp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = dccp_init_net,
        .get_net_proto          = dccp_get_net_proto,
 };
index ac4a0b296dcda7c7bbc51727fd0d57974813f37a..1df3244ecd07fc573538cccb83da67efaa69a5be 100644 (file)
@@ -70,7 +70,7 @@ static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
        return ret;
 }
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -113,7 +113,7 @@ static const struct nla_policy
 generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
        [CTA_TIMEOUT_GENERIC_TIMEOUT]   = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
 static struct ctl_table generic_sysctl_table[] = {
@@ -164,7 +164,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
        .pkt_to_tuple           = generic_pkt_to_tuple,
        .packet                 = generic_packet,
        .new                    = generic_new,
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = generic_timeout_nlattr_to_obj,
                .obj_to_nlattr  = generic_timeout_obj_to_nlattr,
@@ -172,7 +172,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
                .obj_size       = sizeof(unsigned int),
                .nla_policy     = generic_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = generic_init_net,
        .get_net_proto          = generic_get_net_proto,
 };
index d1632252bf5b65611e0a5afc7c87c96607fe6a71..650eb4fba2c5418951b4d22e62325726a745af22 100644 (file)
@@ -285,7 +285,7 @@ static void gre_destroy(struct nf_conn *ct)
                nf_ct_gre_keymap_destroy(master);
 }
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -334,7 +334,7 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = {
        [CTA_TIMEOUT_GRE_UNREPLIED]     = { .type = NLA_U32 },
        [CTA_TIMEOUT_GRE_REPLIED]       = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 static int gre_init_net(struct net *net, u_int16_t proto)
 {
@@ -367,7 +367,7 @@ static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
        .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
        .nla_policy      = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout    = {
                .nlattr_to_obj  = gre_timeout_nlattr_to_obj,
                .obj_to_nlattr  = gre_timeout_obj_to_nlattr,
@@ -375,7 +375,7 @@ static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
                .obj_size       = sizeof(unsigned int) * GRE_CT_MAX,
                .nla_policy     = gre_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .net_id         = &proto_gre_net_id,
        .init_net       = gre_init_net,
 };
index 036670b38282672d3760bd374d190a5df5af8393..43c7e1a217b98682a1abd5d3cdb6f63fa1febec2 100644 (file)
@@ -273,7 +273,7 @@ static unsigned int icmp_nlattr_tuple_size(void)
 }
 #endif
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -313,7 +313,7 @@ static const struct nla_policy
 icmp_timeout_nla_policy[CTA_TIMEOUT_ICMP_MAX+1] = {
        [CTA_TIMEOUT_ICMP_TIMEOUT]      = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
 static struct ctl_table icmp_sysctl_table[] = {
@@ -374,7 +374,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
        .nlattr_to_tuple        = icmp_nlattr_to_tuple,
        .nla_policy             = icmp_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = icmp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = icmp_timeout_obj_to_nlattr,
@@ -382,7 +382,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
                .obj_size       = sizeof(unsigned int),
                .nla_policy     = icmp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = icmp_init_net,
        .get_net_proto          = icmp_get_net_proto,
 };
index bed07b998a10d06593be06bcdf590f2853fbf0b2..97e40f77d678a64204cfdd660b92bb1960752305 100644 (file)
@@ -274,7 +274,7 @@ static unsigned int icmpv6_nlattr_tuple_size(void)
 }
 #endif
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -314,7 +314,7 @@ static const struct nla_policy
 icmpv6_timeout_nla_policy[CTA_TIMEOUT_ICMPV6_MAX+1] = {
        [CTA_TIMEOUT_ICMPV6_TIMEOUT]    = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
 static struct ctl_table icmpv6_sysctl_table[] = {
@@ -373,7 +373,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
        .nlattr_to_tuple        = icmpv6_nlattr_to_tuple,
        .nla_policy             = icmpv6_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = icmpv6_timeout_nlattr_to_obj,
                .obj_to_nlattr  = icmpv6_timeout_obj_to_nlattr,
@@ -381,7 +381,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
                .obj_size       = sizeof(unsigned int),
                .nla_policy     = icmpv6_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = icmpv6_init_net,
        .get_net_proto          = icmpv6_get_net_proto,
 };
index 8d1e085fc14a4a3776e8d67ca06b7cc82519fcb0..e4d738d34cd030fe5b2cd1629d436e3fa0fa4557 100644 (file)
@@ -591,7 +591,7 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
 }
 #endif
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -613,6 +613,8 @@ static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
                        timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
                }
        }
+
+       timeouts[CTA_TIMEOUT_SCTP_UNSPEC] = timeouts[CTA_TIMEOUT_SCTP_CLOSED];
        return 0;
 }
 
@@ -644,7 +646,7 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
        [CTA_TIMEOUT_SCTP_HEARTBEAT_SENT]       = { .type = NLA_U32 },
        [CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED]      = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 
 #ifdef CONFIG_SYSCTL
@@ -743,6 +745,11 @@ static int sctp_init_net(struct net *net, u_int16_t proto)
 
                for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
                        sn->timeouts[i] = sctp_timeouts[i];
+
+               /* timeouts[0] is unused, init it so ->timeouts[0] contains
+                * 'new' timeout, like udp or icmp.
+                */
+               sn->timeouts[0] = sctp_timeouts[SCTP_CONNTRACK_CLOSED];
        }
 
        return sctp_kmemdup_sysctl_table(pn, sn);
@@ -773,7 +780,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = sctp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = sctp_timeout_obj_to_nlattr,
@@ -781,7 +788,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
                .obj_size       = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
                .nla_policy     = sctp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = sctp_init_net,
        .get_net_proto          = sctp_get_net_proto,
 };
@@ -806,7 +813,8 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = {
        .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
        .nla_policy             = nf_ct_port_nla_policy,
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#endif
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = sctp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = sctp_timeout_obj_to_nlattr,
@@ -814,8 +822,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = {
                .obj_size       = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
                .nla_policy     = sctp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#endif
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = sctp_init_net,
        .get_net_proto          = sctp_get_net_proto,
 };
index d80d322b9d8ba0fcaec08a87a5e7ddcb6c533fa4..b4bdf9eda7b740dccb6501c5b0155c32d17d7e5b 100644 (file)
@@ -1279,7 +1279,7 @@ static unsigned int tcp_nlattr_tuple_size(void)
 }
 #endif
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -1301,6 +1301,7 @@ static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
                timeouts[TCP_CONNTRACK_SYN_SENT] =
                        ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT]))*HZ;
        }
+
        if (tb[CTA_TIMEOUT_TCP_SYN_RECV]) {
                timeouts[TCP_CONNTRACK_SYN_RECV] =
                        ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_RECV]))*HZ;
@@ -1341,6 +1342,8 @@ static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
                timeouts[TCP_CONNTRACK_UNACK] =
                        ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_UNACK]))*HZ;
        }
+
+       timeouts[CTA_TIMEOUT_TCP_UNSPEC] = timeouts[CTA_TIMEOUT_TCP_SYN_SENT];
        return 0;
 }
 
@@ -1391,7 +1394,7 @@ static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = {
        [CTA_TIMEOUT_TCP_RETRANS]       = { .type = NLA_U32 },
        [CTA_TIMEOUT_TCP_UNACK]         = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
 static struct ctl_table tcp_sysctl_table[] = {
@@ -1518,6 +1521,10 @@ static int tcp_init_net(struct net *net, u_int16_t proto)
                for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
                        tn->timeouts[i] = tcp_timeouts[i];
 
+               /* timeouts[0] is unused, make it same as SYN_SENT so
+                * ->timeouts[0] contains 'new' timeout, like udp or icmp.
+                */
+               tn->timeouts[0] = tcp_timeouts[TCP_CONNTRACK_SYN_SENT];
                tn->tcp_loose = nf_ct_tcp_loose;
                tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
                tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
@@ -1551,7 +1558,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 =
        .nlattr_size            = TCP_NLATTR_SIZE,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = tcp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = tcp_timeout_obj_to_nlattr,
@@ -1560,7 +1567,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 =
                                        TCP_CONNTRACK_TIMEOUT_MAX,
                .nla_policy     = tcp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = tcp_init_net,
        .get_net_proto          = tcp_get_net_proto,
 };
@@ -1586,7 +1593,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 =
        .nlattr_tuple_size      = tcp_nlattr_tuple_size,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = tcp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = tcp_timeout_obj_to_nlattr,
@@ -1595,7 +1602,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 =
                                        TCP_CONNTRACK_TIMEOUT_MAX,
                .nla_policy     = tcp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = tcp_init_net,
        .get_net_proto          = tcp_get_net_proto,
 };
index 7a1b8988a931ab15145d6371288549da51222076..3065fb8ef91b74348f95900a7b3b0cfc92970469 100644 (file)
@@ -171,7 +171,7 @@ static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
        return NF_ACCEPT;
 }
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
@@ -221,7 +221,7 @@ udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = {
        [CTA_TIMEOUT_UDP_UNREPLIED]     = { .type = NLA_U32 },
        [CTA_TIMEOUT_UDP_REPLIED]       = { .type = NLA_U32 },
 };
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
 static struct ctl_table udp_sysctl_table[] = {
@@ -292,7 +292,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
        .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = udp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = udp_timeout_obj_to_nlattr,
@@ -300,7 +300,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
                .obj_size       = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
                .nla_policy     = udp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = udp_init_net,
        .get_net_proto          = udp_get_net_proto,
 };
@@ -321,7 +321,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 =
        .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = udp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = udp_timeout_obj_to_nlattr,
@@ -329,7 +329,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 =
                .obj_size       = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
                .nla_policy     = udp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = udp_init_net,
        .get_net_proto          = udp_get_net_proto,
 };
@@ -350,7 +350,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 =
        .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = udp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = udp_timeout_obj_to_nlattr,
@@ -358,7 +358,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 =
                .obj_size       = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
                .nla_policy     = udp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = udp_init_net,
        .get_net_proto          = udp_get_net_proto,
 };
@@ -379,7 +379,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 =
        .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
        .ctnl_timeout           = {
                .nlattr_to_obj  = udp_timeout_nlattr_to_obj,
                .obj_to_nlattr  = udp_timeout_obj_to_nlattr,
@@ -387,10 +387,9 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 =
                .obj_size       = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
                .nla_policy     = udp_timeout_nla_policy,
        },
-#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
        .init_net               = udp_init_net,
        .get_net_proto          = udp_get_net_proto,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udplite6);
 #endif
-#include <net/netfilter/nf_conntrack_timeout.h>
index 1dca5683f59f1d3ae08af245ce3807e0d50bc3da..2cfb173cd0b2d8a5e99e5165edcecffcd610af33 100644 (file)
@@ -4637,6 +4637,7 @@ static int nft_flush_set(const struct nft_ctx *ctx,
        }
        set->ndeact++;
 
+       nft_set_elem_deactivate(ctx->net, set, elem);
        nft_trans_elem_set(trans) = set;
        nft_trans_elem(trans) = *elem;
        list_add_tail(&trans->list, &ctx->net->nft.commit_list);
index d46a236cdf31b612f808b33867cd5ee68e70af33..a30f8ba4b89ac427053281936ad3e70750e3a2f0 100644 (file)
@@ -489,8 +489,8 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
        return err;
 }
 
-static struct ctnl_timeout *
-ctnl_timeout_find_get(struct net *net, const char *name)
+static struct nf_ct_timeout *ctnl_timeout_find_get(struct net *net,
+                                                  const char *name)
 {
        struct ctnl_timeout *timeout, *matching = NULL;
 
@@ -509,7 +509,7 @@ ctnl_timeout_find_get(struct net *net, const char *name)
                break;
        }
 err:
-       return matching;
+       return matching ? &matching->timeout : NULL;
 }
 
 static void ctnl_timeout_put(struct nf_ct_timeout *t)
index ea4ba551abb28cb25c833dc408e23d1313b21bb4..d33094f4ec41e380c57b57b26975f263cfe6bf8f 100644 (file)
@@ -233,6 +233,7 @@ static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict)
        int err;
 
        if (verdict == NF_ACCEPT ||
+           verdict == NF_REPEAT ||
            verdict == NF_STOP) {
                rcu_read_lock();
                ct_hook = rcu_dereference(nf_ct_hook);
index 26a8baebd0722c30746edf8f4c91308efb83373a..5dd87748afa8a9185de95c439881f72d3f96e798 100644 (file)
@@ -799,7 +799,7 @@ nft_ct_timeout_parse_policy(void *timeouts,
 }
 
 struct nft_ct_timeout_obj {
-       struct nf_conn          *tmpl;
+       struct nf_ct_timeout    *timeout;
        u8                      l4proto;
 };
 
@@ -809,26 +809,42 @@ static void nft_ct_timeout_obj_eval(struct nft_object *obj,
 {
        const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
        struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
-       struct sk_buff *skb = pkt->skb;
+       struct nf_conn_timeout *timeout;
+       const unsigned int *values;
+
+       if (priv->l4proto != pkt->tprot)
+               return;
 
-       if (ct ||
-           priv->l4proto != pkt->tprot)
+       if (!ct || nf_ct_is_template(ct) || nf_ct_is_confirmed(ct))
                return;
 
-       nf_ct_set(skb, priv->tmpl, IP_CT_NEW);
+       timeout = nf_ct_timeout_find(ct);
+       if (!timeout) {
+               timeout = nf_ct_timeout_ext_add(ct, priv->timeout, GFP_ATOMIC);
+               if (!timeout) {
+                       regs->verdict.code = NF_DROP;
+                       return;
+               }
+       }
+
+       rcu_assign_pointer(timeout->timeout, priv->timeout);
+
+       /* adjust the timeout as per 'new' state. ct is unconfirmed,
+        * so the current timestamp must not be added.
+        */
+       values = nf_ct_timeout_data(timeout);
+       if (values)
+               nf_ct_refresh(ct, pkt->skb, values[0]);
 }
 
 static int nft_ct_timeout_obj_init(const struct nft_ctx *ctx,
                                   const struct nlattr * const tb[],
                                   struct nft_object *obj)
 {
-       const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;
        struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
        const struct nf_conntrack_l4proto *l4proto;
-       struct nf_conn_timeout *timeout_ext;
        struct nf_ct_timeout *timeout;
        int l3num = ctx->family;
-       struct nf_conn *tmpl;
        __u8 l4num;
        int ret;
 
@@ -863,28 +879,14 @@ static int nft_ct_timeout_obj_init(const struct nft_ctx *ctx,
 
        timeout->l3num = l3num;
        timeout->l4proto = l4proto;
-       tmpl = nf_ct_tmpl_alloc(ctx->net, zone, GFP_ATOMIC);
-       if (!tmpl) {
-               ret = -ENOMEM;
-               goto err_free_timeout;
-       }
-
-       timeout_ext = nf_ct_timeout_ext_add(tmpl, timeout, GFP_ATOMIC);
-       if (!timeout_ext) {
-               ret = -ENOMEM;
-               goto err_free_tmpl;
-       }
 
        ret = nf_ct_netns_get(ctx->net, ctx->family);
        if (ret < 0)
-               goto err_free_tmpl;
-
-       priv->tmpl = tmpl;
+               goto err_free_timeout;
 
+       priv->timeout = timeout;
        return 0;
 
-err_free_tmpl:
-       nf_ct_tmpl_free(tmpl);
 err_free_timeout:
        kfree(timeout);
 err_proto_put:
@@ -896,22 +898,19 @@ static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx,
                                       struct nft_object *obj)
 {
        struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
-       struct nf_conn_timeout *t = nf_ct_timeout_find(priv->tmpl);
-       struct nf_ct_timeout *timeout;
+       struct nf_ct_timeout *timeout = priv->timeout;
 
-       timeout = rcu_dereference_raw(t->timeout);
        nf_ct_untimeout(ctx->net, timeout);
        nf_ct_l4proto_put(timeout->l4proto);
        nf_ct_netns_put(ctx->net, ctx->family);
-       nf_ct_tmpl_free(priv->tmpl);
+       kfree(priv->timeout);
 }
 
 static int nft_ct_timeout_obj_dump(struct sk_buff *skb,
                                   struct nft_object *obj, bool reset)
 {
        const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
-       const struct nf_conn_timeout *t = nf_ct_timeout_find(priv->tmpl);
-       const struct nf_ct_timeout *timeout = rcu_dereference_raw(t->timeout);
+       const struct nf_ct_timeout *timeout = priv->timeout;
        struct nlattr *nest_params;
        int ret;
 
index 9f4151ec3e06e73460243f2b0c5c49762b37bb6d..6c7aa6a0a0d2523377f97e911cf3dcba459de752 100644 (file)
@@ -16,6 +16,9 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_CHECKSUM.h>
 
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michael S. Tsirkin <mst@redhat.com>");
 MODULE_DESCRIPTION("Xtables: checksum modification");
@@ -25,7 +28,7 @@ MODULE_ALIAS("ip6t_CHECKSUM");
 static unsigned int
 checksum_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
-       if (skb->ip_summed == CHECKSUM_PARTIAL)
+       if (skb->ip_summed == CHECKSUM_PARTIAL && !skb_is_gso(skb))
                skb_checksum_help(skb);
 
        return XT_CONTINUE;
@@ -34,6 +37,8 @@ checksum_tg(struct sk_buff *skb, const struct xt_action_param *par)
 static int checksum_tg_check(const struct xt_tgchk_param *par)
 {
        const struct xt_CHECKSUM_info *einfo = par->targinfo;
+       const struct ip6t_ip6 *i6 = par->entryinfo;
+       const struct ipt_ip *i4 = par->entryinfo;
 
        if (einfo->operation & ~XT_CHECKSUM_OP_FILL) {
                pr_info_ratelimited("unsupported CHECKSUM operation %x\n",
@@ -43,6 +48,21 @@ static int checksum_tg_check(const struct xt_tgchk_param *par)
        if (!einfo->operation)
                return -EINVAL;
 
+       switch (par->family) {
+       case NFPROTO_IPV4:
+               if (i4->proto == IPPROTO_UDP &&
+                   (i4->invflags & XT_INV_PROTO) == 0)
+                       return 0;
+               break;
+       case NFPROTO_IPV6:
+               if ((i6->flags & IP6T_F_PROTO) &&
+                   i6->proto == IPPROTO_UDP &&
+                   (i6->invflags & XT_INV_PROTO) == 0)
+                       return 0;
+               break;
+       }
+
+       pr_warn_once("CHECKSUM should be avoided.  If really needed, restrict with \"-p udp\" and only use in OUTPUT\n");
        return 0;
 }
 
index dfbdbb2fc0ed8b024122ef1c3371c1bba697d7f8..51d0c257e7a57948e1c1c033aab63614b827ca2e 100644 (file)
@@ -125,6 +125,7 @@ xt_cluster_mt(const struct sk_buff *skb, struct xt_action_param *par)
 static int xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
 {
        struct xt_cluster_match_info *info = par->matchinfo;
+       int ret;
 
        if (info->total_nodes > XT_CLUSTER_NODES_MAX) {
                pr_info_ratelimited("you have exceeded the maximum number of cluster nodes (%u > %u)\n",
@@ -135,7 +136,17 @@ static int xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
                pr_info_ratelimited("node mask cannot exceed total number of nodes\n");
                return -EDOM;
        }
-       return 0;
+
+       ret = nf_ct_netns_get(par->net, par->family);
+       if (ret < 0)
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
+       return ret;
+}
+
+static void xt_cluster_mt_destroy(const struct xt_mtdtor_param *par)
+{
+       nf_ct_netns_put(par->net, par->family);
 }
 
 static struct xt_match xt_cluster_match __read_mostly = {
@@ -144,6 +155,7 @@ static struct xt_match xt_cluster_match __read_mostly = {
        .match          = xt_cluster_mt,
        .checkentry     = xt_cluster_mt_checkentry,
        .matchsize      = sizeof(struct xt_cluster_match_info),
+       .destroy        = xt_cluster_mt_destroy,
        .me             = THIS_MODULE,
 };
 
index 9b16402f29af82a9fd594099bd199531c5d69ded..3e7d259e5d8de01148729022f55c44310f7d6ed7 100644 (file)
@@ -1057,7 +1057,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
 static void *dl_seq_start(struct seq_file *s, loff_t *pos)
        __acquires(htable->lock)
 {
-       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->file));
        unsigned int *bucket;
 
        spin_lock_bh(&htable->lock);
@@ -1074,7 +1074,7 @@ static void *dl_seq_start(struct seq_file *s, loff_t *pos)
 
 static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->file));
        unsigned int *bucket = v;
 
        *pos = ++(*bucket);
@@ -1088,7 +1088,7 @@ static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
 static void dl_seq_stop(struct seq_file *s, void *v)
        __releases(htable->lock)
 {
-       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->file));
        unsigned int *bucket = v;
 
        if (!IS_ERR(bucket))
@@ -1130,7 +1130,7 @@ static void dl_seq_print(struct dsthash_ent *ent, u_int8_t family,
 static int dl_seq_real_show_v2(struct dsthash_ent *ent, u_int8_t family,
                               struct seq_file *s)
 {
-       struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->file));
 
        spin_lock(&ent->lock);
        /* recalculate to show accurate numbers */
@@ -1145,7 +1145,7 @@ static int dl_seq_real_show_v2(struct dsthash_ent *ent, u_int8_t family,
 static int dl_seq_real_show_v1(struct dsthash_ent *ent, u_int8_t family,
                               struct seq_file *s)
 {
-       struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->file));
 
        spin_lock(&ent->lock);
        /* recalculate to show accurate numbers */
@@ -1160,7 +1160,7 @@ static int dl_seq_real_show_v1(struct dsthash_ent *ent, u_int8_t family,
 static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
                            struct seq_file *s)
 {
-       struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *ht = PDE_DATA(file_inode(s->file));
 
        spin_lock(&ent->lock);
        /* recalculate to show accurate numbers */
@@ -1174,7 +1174,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
 
 static int dl_seq_show_v2(struct seq_file *s, void *v)
 {
-       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->file));
        unsigned int *bucket = (unsigned int *)v;
        struct dsthash_ent *ent;
 
@@ -1188,7 +1188,7 @@ static int dl_seq_show_v2(struct seq_file *s, void *v)
 
 static int dl_seq_show_v1(struct seq_file *s, void *v)
 {
-       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->file));
        unsigned int *bucket = v;
        struct dsthash_ent *ent;
 
@@ -1202,7 +1202,7 @@ static int dl_seq_show_v1(struct seq_file *s, void *v)
 
 static int dl_seq_show(struct seq_file *s, void *v)
 {
-       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->private));
+       struct xt_hashlimit_htable *htable = PDE_DATA(file_inode(s->file));
        unsigned int *bucket = v;
        struct dsthash_ent *ent;
 
index c070dfc0190aa2bd84871eee50596a3d7c735636..c92894c3e40a34b34bdf533b1712fd1c1909595e 100644 (file)
@@ -781,7 +781,8 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
 {
        u32 addr_len;
 
-       if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR]) {
+       if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+           info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
                addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
                if (addr_len != sizeof(struct in_addr) &&
                    addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
index ac8030c4bcf8638f7b77873f21285c88795a62f4..19cb2e473ea607af8caa56848c9976baaf88acf4 100644 (file)
@@ -209,6 +209,11 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
                }
                create_info = (struct hci_create_pipe_resp *)skb->data;
 
+               if (create_info->pipe >= NFC_HCI_MAX_PIPES) {
+                       status = NFC_HCI_ANY_E_NOK;
+                       goto exit;
+               }
+
                /* Save the new created pipe and bind with local gate,
                 * the description for skb->data[3] is destination gate id
                 * but since we received this cmd from host controller, we
@@ -232,6 +237,11 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
                }
                delete_info = (struct hci_delete_pipe_noti *)skb->data;
 
+               if (delete_info->pipe >= NFC_HCI_MAX_PIPES) {
+                       status = NFC_HCI_ANY_E_NOK;
+                       goto exit;
+               }
+
                hdev->pipes[delete_info->pipe].gate = NFC_HCI_INVALID_GATE;
                hdev->pipes[delete_info->pipe].dest_host = NFC_HCI_INVALID_HOST;
                break;
index 3ab55784b637e3b30bd5dca1a19814943aae42e7..762d2c6788a385631a312a39625d67a1154ef596 100644 (file)
@@ -76,11 +76,13 @@ struct rds_sock *rds_find_bound(const struct in6_addr *addr, __be16 port,
        struct rds_sock *rs;
 
        __rds_create_bind_key(key, addr, port, scope_id);
-       rs = rhashtable_lookup_fast(&bind_hash_table, key, ht_parms);
+       rcu_read_lock();
+       rs = rhashtable_lookup(&bind_hash_table, key, ht_parms);
        if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD))
                rds_sock_addref(rs);
        else
                rs = NULL;
+       rcu_read_unlock();
 
        rdsdebug("returning rs %p for %pI6c:%u\n", rs, addr,
                 ntohs(port));
@@ -235,6 +237,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                goto out;
        }
 
+       sock_set_flag(sk, SOCK_RCU_FREE);
        ret = rds_add_bound(rs, binding_addr, &port, scope_id);
        if (ret)
                goto out;
index 73427ff439f90fc069ac44e53a5f8e2597a85bc6..71ff356ee7020d881b35d71747076f28530cb5e7 100644 (file)
@@ -443,7 +443,7 @@ int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted,
 int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op);
 
 /* ib_stats.c */
-DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats);
+DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_ib_statistics, rds_ib_stats);
 #define rds_ib_stats_inc(member) rds_stats_inc_which(rds_ib_stats, member)
 #define rds_ib_stats_add(member, count) \
                rds_stats_add_which(rds_ib_stats, member, count)
index 44e9c00657bc1e8572d78e8a9ca1c6a142eb9c76..6b67aa13d2dd09bc2a8fe8d6749ca570f94abe37 100644 (file)
@@ -69,7 +69,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
 
        if (!exists) {
                ret = tcf_idr_create(tn, parm->index, est, a,
-                                    &act_sample_ops, bind, false);
+                                    &act_sample_ops, bind, true);
                if (ret) {
                        tcf_idr_cleanup(tn, parm->index);
                        return ret;
index 420759153d5f4442eebab5a375714f7f89df7ea9..681f6f04e7dae38685b7abd8e4d3a313803a4517 100644 (file)
@@ -317,7 +317,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
                                                  &metadata->u.tun_info,
                                                  opts_len, extack);
                        if (ret < 0)
-                               goto err_out;
+                               goto release_tun_meta;
                }
 
                metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
@@ -333,23 +333,24 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
                                     &act_tunnel_key_ops, bind, true);
                if (ret) {
                        NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
-                       goto err_out;
+                       goto release_tun_meta;
                }
 
                ret = ACT_P_CREATED;
        } else if (!ovr) {
-               tcf_idr_release(*a, bind);
                NL_SET_ERR_MSG(extack, "TC IDR already exists");
-               return -EEXIST;
+               ret = -EEXIST;
+               goto release_tun_meta;
        }
 
        t = to_tunnel_key(*a);
 
        params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
        if (unlikely(!params_new)) {
-               tcf_idr_release(*a, bind);
                NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               exists = true;
+               goto release_tun_meta;
        }
        params_new->tcft_action = parm->t_action;
        params_new->tcft_enc_metadata = metadata;
@@ -367,6 +368,9 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 
        return ret;
 
+release_tun_meta:
+       dst_release(&metadata->dst);
+
 err_out:
        if (exists)
                tcf_idr_release(*a, bind);
@@ -408,8 +412,10 @@ static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
                    nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE,
                               opt->type) ||
                    nla_put(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA,
-                           opt->length * 4, opt + 1))
+                           opt->length * 4, opt + 1)) {
+                       nla_nest_cancel(skb, start);
                        return -EMSGSIZE;
+               }
 
                len -= sizeof(struct geneve_opt) + opt->length * 4;
                src += sizeof(struct geneve_opt) + opt->length * 4;
@@ -423,7 +429,7 @@ static int tunnel_key_opts_dump(struct sk_buff *skb,
                                const struct ip_tunnel_info *info)
 {
        struct nlattr *start;
-       int err;
+       int err = -EINVAL;
 
        if (!info->options_len)
                return 0;
@@ -435,9 +441,11 @@ static int tunnel_key_opts_dump(struct sk_buff *skb,
        if (info->key.tun_flags & TUNNEL_GENEVE_OPT) {
                err = tunnel_key_geneve_opts_dump(skb, info);
                if (err)
-                       return err;
+                       goto err_out;
        } else {
-               return -EINVAL;
+err_out:
+               nla_nest_cancel(skb, start);
+               return err;
        }
 
        nla_nest_end(skb, start);
index 1a67af8a6e8ce93bc9821804567d738b4d4547e5..0a75cb2e5e7ba2d83b063956c0ce91af25679cb1 100644 (file)
@@ -1902,6 +1902,8 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n,
                                RTM_NEWCHAIN, false);
                break;
        case RTM_DELCHAIN:
+               tfilter_notify_chain(net, skb, block, q, parent, n,
+                                    chain, RTM_DELTFILTER);
                /* Flush the chain first as the user requested chain removal. */
                tcf_chain_flush(chain);
                /* In case the chain was successfully deleted, put a reference
index 12cac85da994356ef24cf264e1fb8451f2e303dc..033696e6f74fbea97392059d243a078af925e832 100644 (file)
@@ -260,6 +260,7 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
 bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
 {
        struct dst_entry *dst = sctp_transport_dst_check(t);
+       struct sock *sk = t->asoc->base.sk;
        bool change = true;
 
        if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
@@ -271,12 +272,19 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
        pmtu = SCTP_TRUNC4(pmtu);
 
        if (dst) {
-               dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu);
+               struct sctp_pf *pf = sctp_get_pf_specific(dst->ops->family);
+               union sctp_addr addr;
+
+               pf->af->from_sk(&addr, sk);
+               pf->to_sk_daddr(&t->ipaddr, sk);
+               dst->ops->update_pmtu(dst, sk, NULL, pmtu);
+               pf->to_sk_daddr(&addr, sk);
+
                dst = sctp_transport_dst_check(t);
        }
 
        if (!dst) {
-               t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk);
+               t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
                dst = t->dst;
        }
 
index 2d8a1e15e4f95ffb9ec33d48387e0832f2166ccf..015231789ed2edf55f3cd99978496b2b5e9d0bac 100644 (file)
@@ -742,7 +742,10 @@ static void smc_connect_work(struct work_struct *work)
                smc->sk.sk_err = -rc;
 
 out:
-       smc->sk.sk_state_change(&smc->sk);
+       if (smc->sk.sk_err)
+               smc->sk.sk_state_change(&smc->sk);
+       else
+               smc->sk.sk_write_space(&smc->sk);
        kfree(smc->connect_info);
        smc->connect_info = NULL;
        release_sock(&smc->sk);
@@ -1150,9 +1153,9 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact)
 }
 
 /* listen worker: finish RDMA setup */
-static void smc_listen_rdma_finish(struct smc_sock *new_smc,
-                                  struct smc_clc_msg_accept_confirm *cclc,
-                                  int local_contact)
+static int smc_listen_rdma_finish(struct smc_sock *new_smc,
+                                 struct smc_clc_msg_accept_confirm *cclc,
+                                 int local_contact)
 {
        struct smc_link *link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK];
        int reason_code = 0;
@@ -1175,11 +1178,12 @@ static void smc_listen_rdma_finish(struct smc_sock *new_smc,
                if (reason_code)
                        goto decline;
        }
-       return;
+       return 0;
 
 decline:
        mutex_unlock(&smc_create_lgr_pending);
        smc_listen_decline(new_smc, reason_code, local_contact);
+       return reason_code;
 }
 
 /* setup for RDMA connection of server */
@@ -1276,8 +1280,10 @@ static void smc_listen_work(struct work_struct *work)
        }
 
        /* finish worker */
-       if (!ism_supported)
-               smc_listen_rdma_finish(new_smc, &cclc, local_contact);
+       if (!ism_supported) {
+               if (smc_listen_rdma_finish(new_smc, &cclc, local_contact))
+                       return;
+       }
        smc_conn_save_peer_info(new_smc, &cclc);
        mutex_unlock(&smc_create_lgr_pending);
        smc_listen_out_connected(new_smc);
@@ -1529,7 +1535,7 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
                return EPOLLNVAL;
 
        smc = smc_sk(sock->sk);
-       if ((sk->sk_state == SMC_INIT) || smc->use_fallback) {
+       if (smc->use_fallback) {
                /* delegate to CLC child sock */
                mask = smc->clcsock->ops->poll(file, smc->clcsock, wait);
                sk->sk_err = smc->clcsock->sk->sk_err;
@@ -1560,9 +1566,9 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
                                mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
                        if (sk->sk_state == SMC_APPCLOSEWAIT1)
                                mask |= EPOLLIN;
+                       if (smc->conn.urg_state == SMC_URG_VALID)
+                               mask |= EPOLLPRI;
                }
-               if (smc->conn.urg_state == SMC_URG_VALID)
-                       mask |= EPOLLPRI;
        }
 
        return mask;
index 83aba9ade060a10d3df5452b7c07648eb7759df8..52241d679cc91cd3b6ec59a4388d33b68c76f1f1 100644 (file)
@@ -446,14 +446,12 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
        vec[i++].iov_len = sizeof(trl);
        /* due to the few bytes needed for clc-handshake this cannot block */
        len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
-       if (len < sizeof(pclc)) {
-               if (len >= 0) {
-                       reason_code = -ENETUNREACH;
-                       smc->sk.sk_err = -reason_code;
-               } else {
-                       smc->sk.sk_err = smc->clcsock->sk->sk_err;
-                       reason_code = -smc->sk.sk_err;
-               }
+       if (len < 0) {
+               smc->sk.sk_err = smc->clcsock->sk->sk_err;
+               reason_code = -smc->sk.sk_err;
+       } else if (len < (int)sizeof(pclc)) {
+               reason_code = -ENETUNREACH;
+               smc->sk.sk_err = -reason_code;
        }
 
        return reason_code;
index ac961dfb1ea1b775b666be3fdc0f292545703533..ea2b87f29469610c1afaf5e043a935c24589425b 100644 (file)
@@ -100,15 +100,14 @@ static void smc_close_active_abort(struct smc_sock *smc)
        struct smc_cdc_conn_state_flags *txflags =
                &smc->conn.local_tx_ctrl.conn_state_flags;
 
-       sk->sk_err = ECONNABORTED;
-       if (smc->clcsock && smc->clcsock->sk) {
-               smc->clcsock->sk->sk_err = ECONNABORTED;
-               smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
+       if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
+               sk->sk_err = ECONNABORTED;
+               if (smc->clcsock && smc->clcsock->sk) {
+                       smc->clcsock->sk->sk_err = ECONNABORTED;
+                       smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
+               }
        }
        switch (sk->sk_state) {
-       case SMC_INIT:
-               sk->sk_state = SMC_PEERABORTWAIT;
-               break;
        case SMC_ACTIVE:
                sk->sk_state = SMC_PEERABORTWAIT;
                release_sock(sk);
@@ -143,6 +142,7 @@ static void smc_close_active_abort(struct smc_sock *smc)
        case SMC_PEERFINCLOSEWAIT:
                sock_put(sk); /* passive closing */
                break;
+       case SMC_INIT:
        case SMC_PEERABORTWAIT:
        case SMC_CLOSED:
                break;
index 01c6ce042a1cdb338d81167b1a495693a2a22154..7cb3e4f07c10f5da154c0322ef4fae54a6dc85e2 100644 (file)
@@ -461,7 +461,7 @@ static const struct genl_ops smc_pnet_ops[] = {
 };
 
 /* SMC_PNETID family definition */
-static struct genl_family smc_pnet_nl_family = {
+static struct genl_family smc_pnet_nl_family __ro_after_init = {
        .hdrsize = 0,
        .name = SMCR_GENL_FAMILY_NAME,
        .version = SMCR_GENL_FAMILY_VERSION,
index e6945e318f0285441c0095903e099cb272fa78ec..01f3f8f32d6f927fd77bac5920ab5d8339c2f6af 100644 (file)
@@ -941,7 +941,8 @@ void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
 EXPORT_SYMBOL(dlci_ioctl_set);
 
 static long sock_do_ioctl(struct net *net, struct socket *sock,
-                                unsigned int cmd, unsigned long arg)
+                         unsigned int cmd, unsigned long arg,
+                         unsigned int ifreq_size)
 {
        int err;
        void __user *argp = (void __user *)arg;
@@ -967,11 +968,11 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
        } else {
                struct ifreq ifr;
                bool need_copyout;
-               if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
+               if (copy_from_user(&ifr, argp, ifreq_size))
                        return -EFAULT;
                err = dev_ioctl(net, cmd, &ifr, &need_copyout);
                if (!err && need_copyout)
-                       if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
+                       if (copy_to_user(argp, &ifr, ifreq_size))
                                return -EFAULT;
        }
        return err;
@@ -1070,7 +1071,8 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                        err = open_related_ns(&net->ns, get_net_ns);
                        break;
                default:
-                       err = sock_do_ioctl(net, sock, cmd, arg);
+                       err = sock_do_ioctl(net, sock, cmd, arg,
+                                           sizeof(struct ifreq));
                        break;
                }
        return err;
@@ -2750,7 +2752,8 @@ static int do_siocgstamp(struct net *net, struct socket *sock,
        int err;
 
        set_fs(KERNEL_DS);
-       err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
+       err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv,
+                           sizeof(struct compat_ifreq));
        set_fs(old_fs);
        if (!err)
                err = compat_put_timeval(&ktv, up);
@@ -2766,7 +2769,8 @@ static int do_siocgstampns(struct net *net, struct socket *sock,
        int err;
 
        set_fs(KERNEL_DS);
-       err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
+       err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts,
+                           sizeof(struct compat_ifreq));
        set_fs(old_fs);
        if (!err)
                err = compat_put_timespec(&kts, up);
@@ -3072,7 +3076,8 @@ static int routing_ioctl(struct net *net, struct socket *sock,
        }
 
        set_fs(KERNEL_DS);
-       ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
+       ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r,
+                           sizeof(struct compat_ifreq));
        set_fs(old_fs);
 
 out:
@@ -3185,7 +3190,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
        case SIOCBONDSETHWADDR:
        case SIOCBONDCHANGEACTIVE:
        case SIOCGIFNAME:
-               return sock_do_ioctl(net, sock, cmd, arg);
+               return sock_do_ioctl(net, sock, cmd, arg,
+                                    sizeof(struct compat_ifreq));
        }
 
        return -ENOIOCTLCMD;
index a2f76743c73af07bdfe3ed524aebb6d5bb000dbc..6376467e78f862c25ffae531848bd7aded07609e 100644 (file)
@@ -185,6 +185,10 @@ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
                return -ENOMEM;
 
        buf->sk = msg->dst_sk;
+       if (__tipc_dump_start(&cb, msg->net)) {
+               kfree_skb(buf);
+               return -ENOMEM;
+       }
 
        do {
                int rem;
@@ -216,6 +220,7 @@ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
        err = 0;
 
 err_out:
+       tipc_dump_done(&cb);
        kfree_skb(buf);
 
        if (err == -EMSGSIZE) {
index ab7a2a7178f7167b2cac5c0f382a8bbda42bf4d5..3f03ddd0e35b2f1b6acad1c788faee1976924b3b 100644 (file)
@@ -576,6 +576,7 @@ static int tipc_release(struct socket *sock)
        sk_stop_timer(sk, &sk->sk_timer);
        tipc_sk_remove(tsk);
 
+       sock_orphan(sk);
        /* Reject any messages that accumulated in backlog queue */
        release_sock(sk);
        tipc_dest_list_purge(&tsk->cong_links);
@@ -3229,7 +3230,7 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
                                       struct netlink_callback *cb,
                                       struct tipc_sock *tsk))
 {
-       struct rhashtable_iter *iter = (void *)cb->args[0];
+       struct rhashtable_iter *iter = (void *)cb->args[4];
        struct tipc_sock *tsk;
        int err;
 
@@ -3265,8 +3266,14 @@ EXPORT_SYMBOL(tipc_nl_sk_walk);
 
 int tipc_dump_start(struct netlink_callback *cb)
 {
-       struct rhashtable_iter *iter = (void *)cb->args[0];
-       struct net *net = sock_net(cb->skb->sk);
+       return __tipc_dump_start(cb, sock_net(cb->skb->sk));
+}
+EXPORT_SYMBOL(tipc_dump_start);
+
+int __tipc_dump_start(struct netlink_callback *cb, struct net *net)
+{
+       /* tipc_nl_name_table_dump() uses cb->args[0...3]. */
+       struct rhashtable_iter *iter = (void *)cb->args[4];
        struct tipc_net *tn = tipc_net(net);
 
        if (!iter) {
@@ -3274,17 +3281,16 @@ int tipc_dump_start(struct netlink_callback *cb)
                if (!iter)
                        return -ENOMEM;
 
-               cb->args[0] = (long)iter;
+               cb->args[4] = (long)iter;
        }
 
        rhashtable_walk_enter(&tn->sk_rht, iter);
        return 0;
 }
-EXPORT_SYMBOL(tipc_dump_start);
 
 int tipc_dump_done(struct netlink_callback *cb)
 {
-       struct rhashtable_iter *hti = (void *)cb->args[0];
+       struct rhashtable_iter *hti = (void *)cb->args[4];
 
        rhashtable_walk_exit(hti);
        kfree(hti);
index d43032e26532c406bea693b923fb25572a8ad567..5e575f205afe4088f94f6f0c60f4200cc83b9b75 100644 (file)
@@ -69,5 +69,6 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
                                       struct netlink_callback *cb,
                                       struct tipc_sock *tsk));
 int tipc_dump_start(struct netlink_callback *cb);
+int __tipc_dump_start(struct netlink_callback *cb, struct net *net);
 int tipc_dump_done(struct netlink_callback *cb);
 #endif
index 292742e50bfa4b3a540cbaa3eb2b07400e7141be..961b07d4d41ca7a677b1fd0d24f490888d784e0a 100644 (file)
@@ -686,7 +686,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
                goto free_marker_record;
        }
 
-       crypto_info = &ctx->crypto_send;
+       crypto_info = &ctx->crypto_send.info;
        switch (crypto_info->cipher_type) {
        case TLS_CIPHER_AES_GCM_128:
                nonce_size = TLS_CIPHER_AES_GCM_128_IV_SIZE;
@@ -780,7 +780,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
 
        ctx->priv_ctx_tx = offload_ctx;
        rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_TX,
-                                            &ctx->crypto_send,
+                                            &ctx->crypto_send.info,
                                             tcp_sk(sk)->write_seq);
        if (rc)
                goto release_netdev;
@@ -862,7 +862,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
                goto release_ctx;
 
        rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_RX,
-                                            &ctx->crypto_recv,
+                                            &ctx->crypto_recv.info,
                                             tcp_sk(sk)->copied_seq);
        if (rc) {
                pr_err_ratelimited("%s: The netdev has refused to offload this socket\n",
index 6102169239d1343487a5a0c676384cd3ae4228e5..450a6dbc5a888421c36f71f85c31365d6138562b 100644 (file)
@@ -320,7 +320,7 @@ static struct sk_buff *tls_enc_skb(struct tls_context *tls_ctx,
                goto free_req;
 
        iv = buf;
-       memcpy(iv, tls_ctx->crypto_send_aes_gcm_128.salt,
+       memcpy(iv, tls_ctx->crypto_send.aes_gcm_128.salt,
               TLS_CIPHER_AES_GCM_128_SALT_SIZE);
        aad = buf + TLS_CIPHER_AES_GCM_128_SALT_SIZE +
              TLS_CIPHER_AES_GCM_128_IV_SIZE;
index 180b6640e5316bb89b502414c2b51c4db0269997..523622dc74f8b969113b0435b39f5d0f3d070304 100644 (file)
@@ -241,6 +241,16 @@ static void tls_write_space(struct sock *sk)
        ctx->sk_write_space(sk);
 }
 
+static void tls_ctx_free(struct tls_context *ctx)
+{
+       if (!ctx)
+               return;
+
+       memzero_explicit(&ctx->crypto_send, sizeof(ctx->crypto_send));
+       memzero_explicit(&ctx->crypto_recv, sizeof(ctx->crypto_recv));
+       kfree(ctx);
+}
+
 static void tls_sk_proto_close(struct sock *sk, long timeout)
 {
        struct tls_context *ctx = tls_get_ctx(sk);
@@ -294,7 +304,7 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
 #else
        {
 #endif
-               kfree(ctx);
+               tls_ctx_free(ctx);
                ctx = NULL;
        }
 
@@ -305,7 +315,7 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
         * for sk->sk_prot->unhash [tls_hw_unhash]
         */
        if (free_ctx)
-               kfree(ctx);
+               tls_ctx_free(ctx);
 }
 
 static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
@@ -330,7 +340,7 @@ static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
        }
 
        /* get user crypto info */
-       crypto_info = &ctx->crypto_send;
+       crypto_info = &ctx->crypto_send.info;
 
        if (!TLS_CRYPTO_INFO_READY(crypto_info)) {
                rc = -EBUSY;
@@ -417,9 +427,9 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
        }
 
        if (tx)
-               crypto_info = &ctx->crypto_send;
+               crypto_info = &ctx->crypto_send.info;
        else
-               crypto_info = &ctx->crypto_recv;
+               crypto_info = &ctx->crypto_recv.info;
 
        /* Currently we don't support set crypto info more than one time */
        if (TLS_CRYPTO_INFO_READY(crypto_info)) {
@@ -499,7 +509,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
        goto out;
 
 err_crypto_info:
-       memset(crypto_info, 0, sizeof(*crypto_info));
+       memzero_explicit(crypto_info, sizeof(union tls_crypto_context));
 out:
        return rc;
 }
index 52fbe727d7c10c7e723238ee28ce05a11a720e77..b9c6ecfbcfea722b71c7c048cf19388527e00bb7 100644 (file)
@@ -125,6 +125,9 @@ static int alloc_encrypted_sg(struct sock *sk, int len)
                         &ctx->sg_encrypted_num_elem,
                         &ctx->sg_encrypted_size, 0);
 
+       if (rc == -ENOSPC)
+               ctx->sg_encrypted_num_elem = ARRAY_SIZE(ctx->sg_encrypted_data);
+
        return rc;
 }
 
@@ -138,6 +141,9 @@ static int alloc_plaintext_sg(struct sock *sk, int len)
                         &ctx->sg_plaintext_num_elem, &ctx->sg_plaintext_size,
                         tls_ctx->pending_open_record_frags);
 
+       if (rc == -ENOSPC)
+               ctx->sg_plaintext_num_elem = ARRAY_SIZE(ctx->sg_plaintext_data);
+
        return rc;
 }
 
@@ -925,7 +931,15 @@ int tls_sw_recvmsg(struct sock *sk,
                                if (control != TLS_RECORD_TYPE_DATA)
                                        goto recv_end;
                        }
+               } else {
+                       /* MSG_PEEK right now cannot look beyond current skb
+                        * from strparser, meaning we cannot advance skb here
+                        * and thus unpause strparser since we'd loose original
+                        * one.
+                        */
+                       break;
                }
+
                /* If we have a new message from strparser, continue now. */
                if (copied >= target && !ctx->recv_pkt)
                        break;
@@ -1049,8 +1063,8 @@ static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
                goto read_failure;
        }
 
-       if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.version) ||
-           header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.version)) {
+       if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.info.version) ||
+           header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.info.version)) {
                ret = -EINVAL;
                goto read_failure;
        }
@@ -1130,7 +1144,6 @@ void tls_sw_free_resources_rx(struct sock *sk)
 
 int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
 {
-       char keyval[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
        struct tls_crypto_info *crypto_info;
        struct tls12_crypto_info_aes_gcm_128 *gcm_128_info;
        struct tls_sw_context_tx *sw_ctx_tx = NULL;
@@ -1175,12 +1188,12 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
 
        if (tx) {
                crypto_init_wait(&sw_ctx_tx->async_wait);
-               crypto_info = &ctx->crypto_send;
+               crypto_info = &ctx->crypto_send.info;
                cctx = &ctx->tx;
                aead = &sw_ctx_tx->aead_send;
        } else {
                crypto_init_wait(&sw_ctx_rx->async_wait);
-               crypto_info = &ctx->crypto_recv;
+               crypto_info = &ctx->crypto_recv.info;
                cctx = &ctx->rx;
                aead = &sw_ctx_rx->aead_recv;
        }
@@ -1259,9 +1272,7 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
 
        ctx->push_pending_record = tls_sw_push_pending_record;
 
-       memcpy(keyval, gcm_128_info->key, TLS_CIPHER_AES_GCM_128_KEY_SIZE);
-
-       rc = crypto_aead_setkey(*aead, keyval,
+       rc = crypto_aead_setkey(*aead, gcm_128_info->key,
                                TLS_CIPHER_AES_GCM_128_KEY_SIZE);
        if (rc)
                goto free_aead;
diff --git a/scripts/subarch.include b/scripts/subarch.include
new file mode 100644 (file)
index 0000000..6506828
--- /dev/null
@@ -0,0 +1,13 @@
+# SUBARCH tells the usermode build what the underlying arch is.  That is set
+# first, and if a usermode build is happening, the "ARCH=um" on the command
+# line overrides the setting of ARCH below.  If a native build is happening,
+# then ARCH is assigned, getting whatever value it gets normally, and
+# SUBARCH is subsequently ignored.
+
+SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
+                                 -e s/sun4u/sparc64/ \
+                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
+                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
+                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+                                 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
+                                 -e s/riscv.*/riscv/)
index 27d8b2688f755e974c0b168befc6c625529c3c66..d9aa521b52063501fce79062e35324a3c9046ec0 100644 (file)
@@ -57,7 +57,7 @@ config SECURITY_NETWORK
 config PAGE_TABLE_ISOLATION
        bool "Remove the kernel mapping in user mode"
        default y
-       depends on X86 && !UML
+       depends on (X86_64 || X86_PAE) && !UML
        help
          This feature reduces the number of hardware side channels by
          ensuring that the majority of kernel addresses are not mapped
index 3b602a1e27fa224e3a7628436ac6f93309a54c4a..711e89d8c4153b6123678772e83efe1092f4ae1f 100644 (file)
@@ -300,7 +300,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
        }
        dh_inputs.g_size = dlen;
 
-       dlen = dh_data_from_key(pcopy.dh_private, &dh_inputs.key);
+       dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
        if (dlen < 0) {
                ret = dlen;
                goto out2;
index 730ea91d9be886d9a16ff903ecc91f322c711e50..93676354f87f4e5c23d897c3d8cee568b6f69ac6 100644 (file)
@@ -263,6 +263,8 @@ do_registration(struct work_struct *work)
 error:
        mutex_unlock(&devices_mutex);
        snd_bebob_stream_destroy_duplex(bebob);
+       kfree(bebob->maudio_special_quirk);
+       bebob->maudio_special_quirk = NULL;
        snd_card_free(bebob->card);
        dev_info(&bebob->unit->device,
                 "Sound card registration failed: %d\n", err);
index bd55620c6a479315f6787eb26de2c73bf4913eb6..c266997ad299d93c71632bebba2c83db6cf9bc09 100644 (file)
@@ -96,17 +96,13 @@ int snd_bebob_maudio_load_firmware(struct fw_unit *unit)
        struct fw_device *device = fw_parent_device(unit);
        int err, rcode;
        u64 date;
-       __le32 cues[3] = {
-               cpu_to_le32(MAUDIO_BOOTLOADER_CUE1),
-               cpu_to_le32(MAUDIO_BOOTLOADER_CUE2),
-               cpu_to_le32(MAUDIO_BOOTLOADER_CUE3)
-       };
+       __le32 *cues;
 
        /* check date of software used to build */
        err = snd_bebob_read_block(unit, INFO_OFFSET_SW_DATE,
                                   &date, sizeof(u64));
        if (err < 0)
-               goto end;
+               return err;
        /*
         * firmware version 5058 or later has date later than "20070401", but
         * 'date' is not null-terminated.
@@ -114,20 +110,28 @@ int snd_bebob_maudio_load_firmware(struct fw_unit *unit)
        if (date < 0x3230303730343031LL) {
                dev_err(&unit->device,
                        "Use firmware version 5058 or later\n");
-               err = -ENOSYS;
-               goto end;
+               return -ENXIO;
        }
 
+       cues = kmalloc_array(3, sizeof(*cues), GFP_KERNEL);
+       if (!cues)
+               return -ENOMEM;
+
+       cues[0] = cpu_to_le32(MAUDIO_BOOTLOADER_CUE1);
+       cues[1] = cpu_to_le32(MAUDIO_BOOTLOADER_CUE2);
+       cues[2] = cpu_to_le32(MAUDIO_BOOTLOADER_CUE3);
+
        rcode = fw_run_transaction(device->card, TCODE_WRITE_BLOCK_REQUEST,
                                   device->node_id, device->generation,
                                   device->max_speed, BEBOB_ADDR_REG_REQ,
-                                  cues, sizeof(cues));
+                                  cues, 3 * sizeof(*cues));
+       kfree(cues);
        if (rcode != RCODE_COMPLETE) {
                dev_err(&unit->device,
                        "Failed to send a cue to load firmware\n");
                err = -EIO;
        }
-end:
+
        return err;
 }
 
@@ -290,10 +294,6 @@ snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814)
                bebob->midi_output_ports = 2;
        }
 end:
-       if (err < 0) {
-               kfree(params);
-               bebob->maudio_special_quirk = NULL;
-       }
        mutex_unlock(&bebob->mutex);
        return err;
 }
index 1f5e1d23f31a7132a5dfb5f3f34468b1517a89d0..ef689997d6a5b55f3d273ab4f8125fc87796cdd9 100644 (file)
@@ -49,6 +49,7 @@ static void dg00x_free(struct snd_dg00x *dg00x)
        fw_unit_put(dg00x->unit);
 
        mutex_destroy(&dg00x->mutex);
+       kfree(dg00x);
 }
 
 static void dg00x_card_free(struct snd_card *card)
index ad7a0a32557dc778e32acc6cb813cf4e56a54623..64c3cb0fb926ff8b9a51b21ec4d81cca464d3583 100644 (file)
@@ -146,6 +146,7 @@ static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
 {
        __le32 *reg;
        int i;
+       int err;
 
        reg = kcalloc(18, sizeof(__le32), GFP_KERNEL);
        if (reg == NULL)
@@ -163,9 +164,11 @@ static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
                        reg[i] = cpu_to_le32(0x00000001);
        }
 
-       return snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
-                                 FF400_FETCH_PCM_FRAMES, reg,
-                                 sizeof(__le32) * 18, 0);
+       err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
+                                FF400_FETCH_PCM_FRAMES, reg,
+                                sizeof(__le32) * 18, 0);
+       kfree(reg);
+       return err;
 }
 
 static void ff400_dump_sync_status(struct snd_ff *ff,
index 71a0613d3da040c49ef633f4877f98d8db219a99..f2d073365cf6365e5d3e5c841a7288a93c5b1ec5 100644 (file)
@@ -301,6 +301,8 @@ do_registration(struct work_struct *work)
        snd_efw_transaction_remove_instance(efw);
        snd_efw_stream_destroy_duplex(efw);
        snd_card_free(efw->card);
+       kfree(efw->resp_buf);
+       efw->resp_buf = NULL;
        dev_info(&efw->unit->device,
                 "Sound card registration failed: %d\n", err);
 }
index 1e5b2c8026355d9b788843e29990043249065b02..2ea8be6c858460dfb7c2b55fd380ca313d69c652 100644 (file)
@@ -130,6 +130,7 @@ static void oxfw_free(struct snd_oxfw *oxfw)
 
        kfree(oxfw->spec);
        mutex_destroy(&oxfw->mutex);
+       kfree(oxfw);
 }
 
 /*
@@ -207,6 +208,7 @@ static int detect_quirks(struct snd_oxfw *oxfw)
 static void do_registration(struct work_struct *work)
 {
        struct snd_oxfw *oxfw = container_of(work, struct snd_oxfw, dwork.work);
+       int i;
        int err;
 
        if (oxfw->registered)
@@ -269,7 +271,15 @@ static void do_registration(struct work_struct *work)
        snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
        if (oxfw->has_output)
                snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
+       for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; ++i) {
+               kfree(oxfw->tx_stream_formats[i]);
+               oxfw->tx_stream_formats[i] = NULL;
+               kfree(oxfw->rx_stream_formats[i]);
+               oxfw->rx_stream_formats[i] = NULL;
+       }
        snd_card_free(oxfw->card);
+       kfree(oxfw->spec);
+       oxfw->spec = NULL;
        dev_info(&oxfw->unit->device,
                 "Sound card registration failed: %d\n", err);
 }
index 44ad41fb7374070458de78e991330a744d3f0aff..d3fdc463a884e31e15518f2780c4ca080573a9de 100644 (file)
@@ -93,6 +93,7 @@ static void tscm_free(struct snd_tscm *tscm)
        fw_unit_put(tscm->unit);
 
        mutex_destroy(&tscm->mutex);
+       kfree(tscm);
 }
 
 static void tscm_card_free(struct snd_card *card)
index 560ec0986e1a56d46d9a5c7814cf4175a469249f..74244d8e2909090cfb3bfc54c57c9591332decdd 100644 (file)
@@ -40,6 +40,8 @@ static void azx_clear_corbrp(struct hdac_bus *bus)
  */
 void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
 {
+       WARN_ON_ONCE(!bus->rb.area);
+
        spin_lock_irq(&bus->reg_lock);
        /* CORB set up */
        bus->corb.addr = bus->rb.addr;
@@ -383,7 +385,7 @@ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
 EXPORT_SYMBOL_GPL(snd_hdac_bus_exit_link_reset);
 
 /* reset codec link */
-static int azx_reset(struct hdac_bus *bus, bool full_reset)
+int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
 {
        if (!full_reset)
                goto skip_reset;
@@ -408,7 +410,7 @@ static int azx_reset(struct hdac_bus *bus, bool full_reset)
  skip_reset:
        /* check to see if controller is ready */
        if (!snd_hdac_chip_readb(bus, GCTL)) {
-               dev_dbg(bus->dev, "azx_reset: controller not ready!\n");
+               dev_dbg(bus->dev, "controller not ready!\n");
                return -EBUSY;
        }
 
@@ -423,6 +425,7 @@ static int azx_reset(struct hdac_bus *bus, bool full_reset)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(snd_hdac_bus_reset_link);
 
 /* enable interrupts */
 static void azx_int_enable(struct hdac_bus *bus)
@@ -477,15 +480,17 @@ bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
                return false;
 
        /* reset controller */
-       azx_reset(bus, full_reset);
+       snd_hdac_bus_reset_link(bus, full_reset);
 
-       /* initialize interrupts */
+       /* clear interrupts */
        azx_int_clear(bus);
-       azx_int_enable(bus);
 
        /* initialize the codec command I/O */
        snd_hdac_bus_init_cmd_io(bus);
 
+       /* enable interrupts after CORB/RIRB buffers are initialized above */
+       azx_int_enable(bus);
+
        /* program the position buffer */
        if (bus->use_posbuf && bus->posbuf.addr) {
                snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr);
index 90713741c2dcac91ba658a32ec2f8580394e90fb..6ebe817801ea9a2f5e0ef3c318ce1b2fad383446 100644 (file)
@@ -2540,7 +2540,7 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un
                emu->support_tlv = 1;
                return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
        case SNDRV_EMU10K1_IOCTL_INFO:
-               info = kmalloc(sizeof(*info), GFP_KERNEL);
+               info = kzalloc(sizeof(*info), GFP_KERNEL);
                if (!info)
                        return -ENOMEM;
                snd_emu10k1_fx8010_info(emu, info);
index 1b2ce304152a65c52ce60322dbeec684965cf335..aa4c672dbaf73010aa26966173c403e6e8b0f4a7 100644 (file)
@@ -365,8 +365,10 @@ enum {
  */
 #ifdef SUPPORT_VGA_SWITCHEROO
 #define use_vga_switcheroo(chip)       ((chip)->use_vga_switcheroo)
+#define needs_eld_notify_link(chip)    ((chip)->need_eld_notify_link)
 #else
 #define use_vga_switcheroo(chip)       0
+#define needs_eld_notify_link(chip)    false
 #endif
 
 #define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
@@ -453,6 +455,7 @@ static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
 #endif
 
 static int azx_acquire_irq(struct azx *chip, int do_disconnect);
+static void set_default_power_save(struct azx *chip);
 
 /*
  * initialize the PCI registers
@@ -1201,6 +1204,10 @@ static int azx_runtime_idle(struct device *dev)
            azx_bus(chip)->codec_powered || !chip->running)
                return -EBUSY;
 
+       /* ELD notification gets broken when HD-audio bus is off */
+       if (needs_eld_notify_link(hda))
+               return -EBUSY;
+
        return 0;
 }
 
@@ -1298,6 +1305,36 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
        return true;
 }
 
+/*
+ * The discrete GPU cannot power down unless the HDA controller runtime
+ * suspends, so activate runtime PM on codecs even if power_save == 0.
+ */
+static void setup_vga_switcheroo_runtime_pm(struct azx *chip)
+{
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+       struct hda_codec *codec;
+
+       if (hda->use_vga_switcheroo && !hda->need_eld_notify_link) {
+               list_for_each_codec(codec, &chip->bus)
+                       codec->auto_runtime_pm = 1;
+               /* reset the power save setup */
+               if (chip->running)
+                       set_default_power_save(chip);
+       }
+}
+
+static void azx_vs_gpu_bound(struct pci_dev *pci,
+                            enum vga_switcheroo_client_id client_id)
+{
+       struct snd_card *card = pci_get_drvdata(pci);
+       struct azx *chip = card->private_data;
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
+       if (client_id == VGA_SWITCHEROO_DIS)
+               hda->need_eld_notify_link = 0;
+       setup_vga_switcheroo_runtime_pm(chip);
+}
+
 static void init_vga_switcheroo(struct azx *chip)
 {
        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
@@ -1306,6 +1343,7 @@ static void init_vga_switcheroo(struct azx *chip)
                dev_info(chip->card->dev,
                         "Handle vga_switcheroo audio client\n");
                hda->use_vga_switcheroo = 1;
+               hda->need_eld_notify_link = 1; /* cleared in gpu_bound op */
                chip->driver_caps |= AZX_DCAPS_PM_RUNTIME;
                pci_dev_put(p);
        }
@@ -1314,6 +1352,7 @@ static void init_vga_switcheroo(struct azx *chip)
 static const struct vga_switcheroo_client_ops azx_vs_ops = {
        .set_gpu_state = azx_vs_set_state,
        .can_switch = azx_vs_can_switch,
+       .gpu_bound = azx_vs_gpu_bound,
 };
 
 static int register_vga_switcheroo(struct azx *chip)
@@ -1339,6 +1378,7 @@ static int register_vga_switcheroo(struct azx *chip)
 #define init_vga_switcheroo(chip)              /* NOP */
 #define register_vga_switcheroo(chip)          0
 #define check_hdmi_disabled(pci)       false
+#define setup_vga_switcheroo_runtime_pm(chip)  /* NOP */
 #endif /* SUPPORT_VGA_SWITCHER */
 
 /*
@@ -1352,6 +1392,7 @@ static int azx_free(struct azx *chip)
 
        if (azx_has_pm_runtime(chip) && chip->running)
                pm_runtime_get_noresume(&pci->dev);
+       chip->running = 0;
 
        azx_del_card_list(chip);
 
@@ -2230,6 +2271,25 @@ static struct snd_pci_quirk power_save_blacklist[] = {
 };
 #endif /* CONFIG_PM */
 
+static void set_default_power_save(struct azx *chip)
+{
+       int val = power_save;
+
+#ifdef CONFIG_PM
+       if (pm_blacklist) {
+               const struct snd_pci_quirk *q;
+
+               q = snd_pci_quirk_lookup(chip->pci, power_save_blacklist);
+               if (q && val) {
+                       dev_info(chip->card->dev, "device %04x:%04x is on the power_save blacklist, forcing power_save to 0\n",
+                                q->subvendor, q->subdevice);
+                       val = 0;
+               }
+       }
+#endif /* CONFIG_PM */
+       snd_hda_set_power_save(&chip->bus, val * 1000);
+}
+
 /* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
 static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
        [AZX_DRIVER_NVIDIA] = 8,
@@ -2241,9 +2301,7 @@ static int azx_probe_continue(struct azx *chip)
        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
        struct hdac_bus *bus = azx_bus(chip);
        struct pci_dev *pci = chip->pci;
-       struct hda_codec *codec;
        int dev = chip->dev_index;
-       int val;
        int err;
 
        hda->probe_continued = 1;
@@ -2322,31 +2380,13 @@ static int azx_probe_continue(struct azx *chip)
        if (err < 0)
                goto out_free;
 
+       setup_vga_switcheroo_runtime_pm(chip);
+
        chip->running = 1;
        azx_add_card_list(chip);
 
-       val = power_save;
-#ifdef CONFIG_PM
-       if (pm_blacklist) {
-               const struct snd_pci_quirk *q;
-
-               q = snd_pci_quirk_lookup(chip->pci, power_save_blacklist);
-               if (q && val) {
-                       dev_info(chip->card->dev, "device %04x:%04x is on the power_save blacklist, forcing power_save to 0\n",
-                                q->subvendor, q->subdevice);
-                       val = 0;
-               }
-       }
-#endif /* CONFIG_PM */
-       /*
-        * The discrete GPU cannot power down unless the HDA controller runtime
-        * suspends, so activate runtime PM on codecs even if power_save == 0.
-        */
-       if (use_vga_switcheroo(hda))
-               list_for_each_codec(codec, &chip->bus)
-                       codec->auto_runtime_pm = 1;
+       set_default_power_save(chip);
 
-       snd_hda_set_power_save(&chip->bus, val * 1000);
        if (azx_has_pm_runtime(chip))
                pm_runtime_put_autosuspend(&pci->dev);
 
index e3a3d318d2e5f9fc57dbe9530a2470ab955b1765..f59719e06b91a38492957195dfda7328edeb80db 100644 (file)
@@ -37,6 +37,7 @@ struct hda_intel {
 
        /* vga_switcheroo setup */
        unsigned int use_vga_switcheroo:1;
+       unsigned int need_eld_notify_link:1;
        unsigned int vga_switcheroo_registered:1;
        unsigned int init_failed:1; /* delayed init failed */
 
index e359938e3d7e16bfd3995084be4e1b20d6b1989e..77b265bd050531f59eeddb9eaee2cd75944f5649 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/sizes.h>
 #include <linux/pm_runtime.h>
 
@@ -184,6 +185,24 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
        acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
 }
 
+static void pre_config_reset(void __iomem *acp_mmio, u16 ch_num)
+{
+       u32 dma_ctrl;
+       int ret;
+
+       /* clear the reset bit */
+       dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+       dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK;
+       acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
+       /* check the reset bit before programming configuration registers */
+       ret = readl_poll_timeout(acp_mmio + ((mmACP_DMA_CNTL_0 + ch_num) * 4),
+                                dma_ctrl,
+                                !(dma_ctrl & ACP_DMA_CNTL_0__DMAChRst_MASK),
+                                100, ACP_DMA_RESET_TIME);
+       if (ret < 0)
+               pr_err("Failed to clear reset of channel : %d\n", ch_num);
+}
+
 /*
  * Initialize the DMA descriptor information for transfer between
  * system memory <-> ACP SRAM
@@ -236,6 +255,7 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
                config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
                                              &dmadscr[i]);
        }
+       pre_config_reset(acp_mmio, ch);
        config_acp_dma_channel(acp_mmio, ch,
                               dma_dscr_idx - 1,
                               NUM_DSCRS_PER_CHANNEL,
@@ -275,6 +295,7 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
                config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
                                              &dmadscr[i]);
        }
+       pre_config_reset(acp_mmio, ch);
        /* Configure the DMA channel with the above descriptore */
        config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
                               NUM_DSCRS_PER_CHANNEL,
index 275677de669f0562b8fea2fe82c4cf07f33a90cd..407554175282fffe6b68bbfb9aaf33b3f564c0a4 100644 (file)
@@ -157,8 +157,8 @@ static const struct snd_kcontrol_new cs4265_snd_controls[] = {
        SOC_SINGLE("Validity Bit Control Switch", CS4265_SPDIF_CTL2,
                                3, 1, 0),
        SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum),
-       SOC_SINGLE("MMTLR Data Switch", 0,
-                               1, 1, 0),
+       SOC_SINGLE("MMTLR Data Switch", CS4265_SPDIF_CTL2,
+                               0, 1, 0),
        SOC_ENUM("Mono Channel Select", spdif_mono_select_enum),
        SND_SOC_BYTES("C Data Buffer", CS4265_C_DATA_BUFF, 24),
 };
index 92b7125ea16911b2de4dda0182cacef93d7cd4e2..1093f766d0d2c73fe647bac2449c7ac06d069ecd 100644 (file)
@@ -520,6 +520,7 @@ static bool max98373_volatile_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case MAX98373_R2000_SW_RESET ... MAX98373_R2009_INT_FLAG3:
+       case MAX98373_R203E_AMP_PATH_GAIN:
        case MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK:
        case MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK:
        case MAX98373_R20B6_BDE_CUR_STATE_READBACK:
@@ -729,6 +730,7 @@ static int max98373_probe(struct snd_soc_component *component)
        /* Software Reset */
        regmap_write(max98373->regmap,
                MAX98373_R2000_SW_RESET, MAX98373_SOFT_RESET);
+       usleep_range(10000, 11000);
 
        /* IV default slot configuration */
        regmap_write(max98373->regmap,
@@ -817,6 +819,7 @@ static int max98373_resume(struct device *dev)
 
        regmap_write(max98373->regmap,
                MAX98373_R2000_SW_RESET, MAX98373_SOFT_RESET);
+       usleep_range(10000, 11000);
        regcache_cache_only(max98373->regmap, false);
        regcache_sync(max98373->regmap);
        return 0;
index dca82dd6e3bfeb7cb23d3e3a478983e3c4b36b2e..32fe76c3134ab41df5e8bbb443e2e5f1b7d4a54c 100644 (file)
@@ -64,8 +64,8 @@ static const struct reg_sequence rt5514_patch[] = {
        {RT5514_ANA_CTRL_LDO10,         0x00028604},
        {RT5514_ANA_CTRL_ADCFED,        0x00000800},
        {RT5514_ASRC_IN_CTRL1,          0x00000003},
-       {RT5514_DOWNFILTER0_CTRL3,      0x10000352},
-       {RT5514_DOWNFILTER1_CTRL3,      0x10000352},
+       {RT5514_DOWNFILTER0_CTRL3,      0x10000342},
+       {RT5514_DOWNFILTER1_CTRL3,      0x10000342},
 };
 
 static const struct reg_default rt5514_reg[] = {
@@ -92,10 +92,10 @@ static const struct reg_default rt5514_reg[] = {
        {RT5514_ASRC_IN_CTRL1,          0x00000003},
        {RT5514_DOWNFILTER0_CTRL1,      0x00020c2f},
        {RT5514_DOWNFILTER0_CTRL2,      0x00020c2f},
-       {RT5514_DOWNFILTER0_CTRL3,      0x10000352},
+       {RT5514_DOWNFILTER0_CTRL3,      0x10000342},
        {RT5514_DOWNFILTER1_CTRL1,      0x00020c2f},
        {RT5514_DOWNFILTER1_CTRL2,      0x00020c2f},
-       {RT5514_DOWNFILTER1_CTRL3,      0x10000352},
+       {RT5514_DOWNFILTER1_CTRL3,      0x10000342},
        {RT5514_ANA_CTRL_LDO10,         0x00028604},
        {RT5514_ANA_CTRL_LDO18_16,      0x02000345},
        {RT5514_ANA_CTRL_ADC12,         0x0000a2a8},
index 640d400ca01359bf06c3e0f90ea1bad008a811a0..afe7d5b193133a27bd6dd8470e166d6dc0fc07b2 100644 (file)
@@ -750,8 +750,8 @@ static bool rt5682_readable_register(struct device *dev, unsigned int reg)
 }
 
 static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2250, 150, 0);
-static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
-static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0);
 static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
 
 /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
@@ -1114,7 +1114,7 @@ static const struct snd_kcontrol_new rt5682_snd_controls[] = {
 
        /* DAC Digital Volume */
        SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5682_DAC1_DIG_VOL,
-               RT5682_L_VOL_SFT, RT5682_R_VOL_SFT, 175, 0, dac_vol_tlv),
+               RT5682_L_VOL_SFT + 1, RT5682_R_VOL_SFT + 1, 86, 0, dac_vol_tlv),
 
        /* IN Boost Volume */
        SOC_SINGLE_TLV("CBJ Boost Volume", RT5682_CBJ_BST_CTRL,
@@ -1124,7 +1124,7 @@ static const struct snd_kcontrol_new rt5682_snd_controls[] = {
        SOC_DOUBLE("STO1 ADC Capture Switch", RT5682_STO1_ADC_DIG_VOL,
                RT5682_L_MUTE_SFT, RT5682_R_MUTE_SFT, 1, 1),
        SOC_DOUBLE_TLV("STO1 ADC Capture Volume", RT5682_STO1_ADC_DIG_VOL,
-               RT5682_L_VOL_SFT, RT5682_R_VOL_SFT, 127, 0, adc_vol_tlv),
+               RT5682_L_VOL_SFT + 1, RT5682_R_VOL_SFT + 1, 63, 0, adc_vol_tlv),
 
        /* ADC Boost Volume Control */
        SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5682_STO1_ADC_BOOST,
index d53680ac78e42d0bb0979afcbea8e77046d181b9..6df158669420db700af2d6e0a11707319e091290 100644 (file)
@@ -117,8 +117,7 @@ static int sigmadsp_ctrl_write(struct sigmadsp *sigmadsp,
        struct sigmadsp_control *ctrl, void *data)
 {
        /* safeload loads up to 20 bytes in a atomic operation */
-       if (ctrl->num_bytes > 4 && ctrl->num_bytes <= 20 && sigmadsp->ops &&
-           sigmadsp->ops->safeload)
+       if (ctrl->num_bytes <= 20 && sigmadsp->ops && sigmadsp->ops->safeload)
                return sigmadsp->ops->safeload(sigmadsp, ctrl->addr, data,
                        ctrl->num_bytes);
        else
index 14999b999fd31a4b25e5a06779078d1cc462ea29..0d6145549a98d62b7d91474311150fd4ba082b45 100644 (file)
@@ -424,8 +424,10 @@ static void tas6424_fault_check_work(struct work_struct *work)
               TAS6424_FAULT_PVDD_UV |
               TAS6424_FAULT_VBAT_UV;
 
-       if (reg)
+       if (!reg) {
+               tas6424->last_fault1 = reg;
                goto check_global_fault2_reg;
+       }
 
        /*
         * Only flag errors once for a given occurrence. This is needed as
@@ -461,8 +463,10 @@ static void tas6424_fault_check_work(struct work_struct *work)
               TAS6424_FAULT_OTSD_CH3 |
               TAS6424_FAULT_OTSD_CH4;
 
-       if (!reg)
+       if (!reg) {
+               tas6424->last_fault2 = reg;
                goto check_warn_reg;
+       }
 
        if ((reg & TAS6424_FAULT_OTSD) && !(tas6424->last_fault2 & TAS6424_FAULT_OTSD))
                dev_crit(dev, "experienced a global overtemp shutdown\n");
@@ -497,8 +501,10 @@ static void tas6424_fault_check_work(struct work_struct *work)
               TAS6424_WARN_VDD_OTW_CH3 |
               TAS6424_WARN_VDD_OTW_CH4;
 
-       if (!reg)
+       if (!reg) {
+               tas6424->last_warn = reg;
                goto out;
+       }
 
        if ((reg & TAS6424_WARN_VDD_UV) && !(tas6424->last_warn & TAS6424_WARN_VDD_UV))
                dev_warn(dev, "experienced a VDD under voltage condition\n");
index f27464c2c5bad53ccca78fa8ba3bd0bf3f2cfef6..79541960f45d94066af3401f115a5d091a7b552c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/acpi.h>
 
 #include "wm8804.h"
 
@@ -40,17 +41,29 @@ static const struct i2c_device_id wm8804_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id);
 
+#if defined(CONFIG_OF)
 static const struct of_device_id wm8804_of_match[] = {
        { .compatible = "wlf,wm8804", },
        { }
 };
 MODULE_DEVICE_TABLE(of, wm8804_of_match);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id wm8804_acpi_match[] = {
+       { "1AEC8804", 0 }, /* Wolfson PCI ID + part ID */
+       { "10138804", 0 }, /* Cirrus Logic PCI ID + part ID */
+       { },
+};
+MODULE_DEVICE_TABLE(acpi, wm8804_acpi_match);
+#endif
 
 static struct i2c_driver wm8804_i2c_driver = {
        .driver = {
                .name = "wm8804",
                .pm = &wm8804_pm,
-               .of_match_table = wm8804_of_match,
+               .of_match_table = of_match_ptr(wm8804_of_match),
+               .acpi_match_table = ACPI_PTR(wm8804_acpi_match),
        },
        .probe = wm8804_i2c_probe,
        .remove = wm8804_i2c_remove,
index 953d94d505864ddcefa04e78db83d96df0f19477..ade34c26ad2f3381d806ff069044d77c4186c3d8 100644 (file)
@@ -719,7 +719,7 @@ static int wm9712_probe(struct platform_device *pdev)
 
 static struct platform_driver wm9712_component_driver = {
        .driver = {
-               .name = "wm9712-component",
+               .name = "wm9712-codec",
        },
 
        .probe = wm9712_probe,
index d32844f94d74b87243e4a16d61311d2c92121dd4..b6dc524830b21a04371e79607e9b4ca1f902c108 100644 (file)
@@ -575,6 +575,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                                        BYT_RT5640_MONO_SPEAKER |
                                        BYT_RT5640_MCLK_EN),
        },
+       {       /* Linx Linx7 tablet */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LINX7"),
+               },
+               .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
+                                       BYT_RT5640_MONO_SPEAKER |
+                                       BYT_RT5640_JD_NOT_INV |
+                                       BYT_RT5640_SSP0_AIF1 |
+                                       BYT_RT5640_MCLK_EN),
+       },
        {       /* MSI S100 tablet */
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
@@ -602,6 +613,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                                        BYT_RT5640_SSP0_AIF1 |
                                        BYT_RT5640_MCLK_EN),
        },
+       {       /* Onda v975w */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+                       DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+                       /* The above are too generic, also match BIOS info */
+                       DMI_EXACT_MATCH(DMI_BIOS_VERSION, "5.6.5"),
+                       DMI_EXACT_MATCH(DMI_BIOS_DATE, "07/25/2014"),
+               },
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
+                                       BYT_RT5640_JD_SRC_JD2_IN4N |
+                                       BYT_RT5640_OVCD_TH_2000UA |
+                                       BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_DIFF_MIC |
+                                       BYT_RT5640_MCLK_EN),
+       },
        {       /* Pipo W4 */
                .matches = {
                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
index dce64948564940ea7383e0f4975de4b4ec7293ec..1d17be0f78a089e38a95ffbc3e84f0604ad6c2e3 100644 (file)
@@ -834,7 +834,7 @@ static int skl_first_init(struct hdac_bus *bus)
                return -ENXIO;
        }
 
-       skl_init_chip(bus, true);
+       snd_hdac_bus_reset_link(bus, true);
 
        snd_hdac_bus_parse_capabilities(bus);
 
index dc94c5c53788b044b183f2406df7a5d9234cc5fc..c6b51571be945e5262dbf46966caab4e1615f529 100644 (file)
@@ -960,8 +960,10 @@ static int msm_routing_probe(struct snd_soc_component *c)
 {
        int i;
 
-       for (i = 0; i < MAX_SESSIONS; i++)
+       for (i = 0; i < MAX_SESSIONS; i++) {
                routing_data->sessions[i].port_id = -1;
+               routing_data->sessions[i].fedai_id = -1;
+       }
 
        return 0;
 }
index 3a3064dda57f329a96be5ef17b1dea8251f09f72..051f96405346b2f495c94ebc409656c98634a3c8 100644 (file)
@@ -462,6 +462,11 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
                goto rsnd_adg_get_clkout_end;
 
        req_size = prop->length / sizeof(u32);
+       if (req_size > REQ_SIZE) {
+               dev_err(dev,
+                       "too many clock-frequency, use top %d\n", REQ_SIZE);
+               req_size = REQ_SIZE;
+       }
 
        of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
        req_48kHz_rate = 0;
index f8425d8b44d2b54aff876f8759e81c740cb6157a..d23c2bbff0cf4e666dcf5d3a4b26fccaf22a05ba 100644 (file)
@@ -478,7 +478,7 @@ static int rsnd_status_update(u32 *status,
                        (func_call && (mod)->ops->fn) ? #fn : "");      \
                if (func_call && (mod)->ops->fn)                        \
                        tmp = (mod)->ops->fn(mod, io, param);           \
-               if (tmp)                                                \
+               if (tmp && (tmp != -EPROBE_DEFER))                      \
                        dev_err(dev, "%s[%d] : %s error %d\n",          \
                                rsnd_mod_name(mod), rsnd_mod_id(mod),   \
                                                     #fn, tmp);         \
@@ -958,12 +958,23 @@ static void rsnd_soc_dai_shutdown(struct snd_pcm_substream *substream,
        rsnd_dai_stream_quit(io);
 }
 
+static int rsnd_soc_dai_prepare(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
+       struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
+       struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
+
+       return rsnd_dai_call(prepare, io, priv);
+}
+
 static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
        .startup        = rsnd_soc_dai_startup,
        .shutdown       = rsnd_soc_dai_shutdown,
        .trigger        = rsnd_soc_dai_trigger,
        .set_fmt        = rsnd_soc_dai_set_fmt,
        .set_tdm_slot   = rsnd_soc_set_dai_tdm_slot,
+       .prepare        = rsnd_soc_dai_prepare,
 };
 
 void rsnd_parse_connect_common(struct rsnd_dai *rdai,
@@ -1550,6 +1561,14 @@ static int rsnd_probe(struct platform_device *pdev)
                rsnd_dai_call(remove, &rdai->capture, priv);
        }
 
+       /*
+        * adg is very special mod which can't use rsnd_dai_call(remove),
+        * and it registers ADG clock on probe.
+        * It should be unregister if probe failed.
+        * Mainly it is assuming -EPROBE_DEFER case
+        */
+       rsnd_adg_remove(priv);
+
        return ret;
 }
 
index fe63ef8600d02f259743a8339ce7059ea2b1be25..d65ea7bc4dac2d2608cbcfbe3d3a4ebd915ad242 100644 (file)
@@ -241,6 +241,10 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
        /* try to get DMAEngine channel */
        chan = rsnd_dmaen_request_channel(io, mod_from, mod_to);
        if (IS_ERR_OR_NULL(chan)) {
+               /* Let's follow when -EPROBE_DEFER case */
+               if (PTR_ERR(chan) == -EPROBE_DEFER)
+                       return PTR_ERR(chan);
+
                /*
                 * DMA failed. try to PIO mode
                 * see
index 96d93330b1e1a59ebba22668ff76fb4f8a325d3d..8f7a0abfa751ed7342223e406999d0166a10307f 100644 (file)
@@ -280,6 +280,9 @@ struct rsnd_mod_ops {
        int (*nolock_stop)(struct rsnd_mod *mod,
                    struct rsnd_dai_stream *io,
                    struct rsnd_priv *priv);
+       int (*prepare)(struct rsnd_mod *mod,
+                      struct rsnd_dai_stream *io,
+                      struct rsnd_priv *priv);
 };
 
 struct rsnd_dai_stream;
@@ -309,6 +312,7 @@ struct rsnd_mod {
  * H   0: fallback
  * H   0: hw_params
  * H   0: pointer
+ * H   0: prepare
  */
 #define __rsnd_mod_shift_nolock_start  0
 #define __rsnd_mod_shift_nolock_stop   0
@@ -323,6 +327,7 @@ struct rsnd_mod {
 #define __rsnd_mod_shift_fallback      28 /* always called */
 #define __rsnd_mod_shift_hw_params     28 /* always called */
 #define __rsnd_mod_shift_pointer       28 /* always called */
+#define __rsnd_mod_shift_prepare       28 /* always called */
 
 #define __rsnd_mod_add_probe           0
 #define __rsnd_mod_add_remove          0
@@ -337,6 +342,7 @@ struct rsnd_mod {
 #define __rsnd_mod_add_fallback                0
 #define __rsnd_mod_add_hw_params       0
 #define __rsnd_mod_add_pointer         0
+#define __rsnd_mod_add_prepare         0
 
 #define __rsnd_mod_call_probe          0
 #define __rsnd_mod_call_remove         0
@@ -351,6 +357,7 @@ struct rsnd_mod {
 #define __rsnd_mod_call_pointer                0
 #define __rsnd_mod_call_nolock_start   0
 #define __rsnd_mod_call_nolock_stop    1
+#define __rsnd_mod_call_prepare                0
 
 #define rsnd_mod_to_priv(mod)  ((mod)->priv)
 #define rsnd_mod_name(mod)     ((mod)->ops->name)
index 8304e4ec9242c68eeabeca2516938990678aabc8..3f880ec66459a989306ee38303692e35d354ca37 100644 (file)
@@ -283,7 +283,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
        if (rsnd_ssi_is_multi_slave(mod, io))
                return 0;
 
-       if (ssi->usrcnt > 1) {
+       if (ssi->rate) {
                if (ssi->rate != rate) {
                        dev_err(dev, "SSI parent/child should use same rate\n");
                        return -EINVAL;
@@ -434,7 +434,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
                         struct rsnd_priv *priv)
 {
        struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
-       int ret;
 
        if (!rsnd_ssi_is_run_mods(mod, io))
                return 0;
@@ -443,10 +442,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
 
        rsnd_mod_power_on(mod);
 
-       ret = rsnd_ssi_master_clk_start(mod, io);
-       if (ret < 0)
-               return ret;
-
        rsnd_ssi_config_init(mod, io);
 
        rsnd_ssi_register_setup(mod);
@@ -852,6 +847,13 @@ static int rsnd_ssi_pio_pointer(struct rsnd_mod *mod,
        return 0;
 }
 
+static int rsnd_ssi_prepare(struct rsnd_mod *mod,
+                           struct rsnd_dai_stream *io,
+                           struct rsnd_priv *priv)
+{
+       return rsnd_ssi_master_clk_start(mod, io);
+}
+
 static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
        .name   = SSI_NAME,
        .probe  = rsnd_ssi_common_probe,
@@ -864,6 +866,7 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
        .pointer = rsnd_ssi_pio_pointer,
        .pcm_new = rsnd_ssi_pcm_new,
        .hw_params = rsnd_ssi_hw_params,
+       .prepare = rsnd_ssi_prepare,
 };
 
 static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
@@ -940,6 +943,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
        .pcm_new = rsnd_ssi_pcm_new,
        .fallback = rsnd_ssi_fallback,
        .hw_params = rsnd_ssi_hw_params,
+       .prepare = rsnd_ssi_prepare,
 };
 
 int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
index 9cfe10d8040cf8f0cea83d85d2dfb68a6b508f6d..473eefe8658e9a22af71b2f3af42f1f92cf00acd 100644 (file)
@@ -1447,7 +1447,7 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
        sink = codec_dai->playback_widget;
        source = cpu_dai->capture_widget;
        if (sink && source) {
-               ret = snd_soc_dapm_new_pcm(card, dai_link->params,
+               ret = snd_soc_dapm_new_pcm(card, rtd, dai_link->params,
                                           dai_link->num_params,
                                           source, sink);
                if (ret != 0) {
@@ -1460,7 +1460,7 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
        sink = cpu_dai->playback_widget;
        source = codec_dai->capture_widget;
        if (sink && source) {
-               ret = snd_soc_dapm_new_pcm(card, dai_link->params,
+               ret = snd_soc_dapm_new_pcm(card, rtd, dai_link->params,
                                           dai_link->num_params,
                                           source, sink);
                if (ret != 0) {
index 7e96793050c9b1a1b634d34e4e0ad9a658cf4111..461d951917c0569096eacd4274fd9eb1ade8f9c5 100644 (file)
@@ -3652,6 +3652,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
 {
        struct snd_soc_dapm_path *source_p, *sink_p;
        struct snd_soc_dai *source, *sink;
+       struct snd_soc_pcm_runtime *rtd = w->priv;
        const struct snd_soc_pcm_stream *config = w->params + w->params_select;
        struct snd_pcm_substream substream;
        struct snd_pcm_hw_params *params = NULL;
@@ -3711,6 +3712,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
                goto out;
        }
        substream.runtime = runtime;
+       substream.private_data = rtd;
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -3895,6 +3897,7 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
 }
 
 int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
+                        struct snd_soc_pcm_runtime *rtd,
                         const struct snd_soc_pcm_stream *params,
                         unsigned int num_params,
                         struct snd_soc_dapm_widget *source,
@@ -3963,6 +3966,7 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
 
        w->params = params;
        w->num_params = num_params;
+       w->priv = rtd;
 
        ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL);
        if (ret)
index 16e006f708ca0cbd44a63135bb996b8db7c3ba9e..4602464ebdfbfccd9296593ed5dd8b15f55305ff 100644 (file)
@@ -27,6 +27,7 @@
 #define __KVM_HAVE_GUEST_DEBUG
 #define __KVM_HAVE_IRQ_LINE
 #define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_VCPU_EVENTS
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 
@@ -125,6 +126,18 @@ struct kvm_sync_regs {
 struct kvm_arch_memory_slot {
 };
 
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+       struct {
+               __u8 serror_pending;
+               __u8 serror_has_esr;
+               /* Align it to 8 bytes */
+               __u8 pad[6];
+               __u64 serror_esr;
+       } exception;
+       __u32 reserved[12];
+};
+
 /* If you need to interpret the index values, here is the key: */
 #define KVM_REG_ARM_COPROC_MASK                0x000000000FFF0000
 #define KVM_REG_ARM_COPROC_SHIFT       16
index 4e76630dd6554673d71ad647c1108bb54f1bcea2..97c3478ee6e718c8ac2de4c01edee6a0dd4cd27e 100644 (file)
@@ -39,6 +39,7 @@
 #define __KVM_HAVE_GUEST_DEBUG
 #define __KVM_HAVE_IRQ_LINE
 #define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_VCPU_EVENTS
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 
@@ -154,6 +155,18 @@ struct kvm_sync_regs {
 struct kvm_arch_memory_slot {
 };
 
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+       struct {
+               __u8 serror_pending;
+               __u8 serror_has_esr;
+               /* Align it to 8 bytes */
+               __u8 pad[6];
+               __u64 serror_esr;
+       } exception;
+       __u32 reserved[12];
+};
+
 /* If you need to interpret the index values, here is the key: */
 #define KVM_REG_ARM_COPROC_MASK                0x000000000FFF0000
 #define KVM_REG_ARM_COPROC_SHIFT       16
index 4cdaa55fabfe2658e054b5aaf1455b6f0556e584..9a50f02b98946eb49df6cb5f407b1a4a04b89e6c 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * KVM s390 specific structures and definitions
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008, 2018
  *
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
@@ -225,6 +225,7 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_FPRS   (1UL << 8)
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
+#define KVM_SYNC_ETOKEN (1UL << 11)
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
 #define SDNXL (1UL << SDNXC)
@@ -258,6 +259,8 @@ struct kvm_sync_regs {
                struct {
                        __u64 reserved1[2];
                        __u64 gscb[4];
+                       __u64 etoken;
+                       __u64 etoken_extension;
                };
        };
 };
index c535c2fdea136a5e58725e72a2d867f545d393eb..86299efa804adbfc35d3338f9fe75083e6cdf5af 100644 (file)
@@ -378,4 +378,41 @@ struct kvm_sync_regs {
 #define KVM_X86_QUIRK_LINT0_REENABLED  (1 << 0)
 #define KVM_X86_QUIRK_CD_NW_CLEARED    (1 << 1)
 
+#define KVM_STATE_NESTED_GUEST_MODE    0x00000001
+#define KVM_STATE_NESTED_RUN_PENDING   0x00000002
+
+#define KVM_STATE_NESTED_SMM_GUEST_MODE        0x00000001
+#define KVM_STATE_NESTED_SMM_VMXON     0x00000002
+
+struct kvm_vmx_nested_state {
+       __u64 vmxon_pa;
+       __u64 vmcs_pa;
+
+       struct {
+               __u16 flags;
+       } smm;
+};
+
+/* for KVM_CAP_NESTED_STATE */
+struct kvm_nested_state {
+       /* KVM_STATE_* flags */
+       __u16 flags;
+
+       /* 0 for VMX, 1 for SVM.  */
+       __u16 format;
+
+       /* 128 for SVM, 128 + VMCS size for VMX.  */
+       __u32 size;
+
+       union {
+               /* VMXON, VMCS */
+               struct kvm_vmx_nested_state vmx;
+
+               /* Pad the header to 128 bytes.  */
+               __u8 pad[120];
+       };
+
+       __u8 data[0];
+};
+
 #endif /* _ASM_X86_KVM_H */
index dbf6e8bd98ba59be0519d284fdc7bf59b19f46d3..bbb2a8ef367cacd6cbd837898608d0de785c7d73 100644 (file)
@@ -286,7 +286,7 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size)
                 * Found a match; just move the remaining
                 * entries up.
                 */
-               if (i == num_records) {
+               if (i == (num_records - 1)) {
                        kvp_file_info[pool].num_records--;
                        kvp_update_file(pool);
                        return 0;
index 6b0c36a58fcbc38b67157b53efe2044bd848f137..e56997288f2b07d273f860be50a830351ad128e1 100644 (file)
@@ -30,9 +30,12 @@ struct task_struct {
        struct held_lock held_locks[MAX_LOCK_DEPTH];
        gfp_t lockdep_reclaim_gfp;
        int pid;
+       int state;
        char comm[17];
 };
 
+#define TASK_RUNNING 0
+
 extern struct task_struct *__curr(void);
 
 #define current (__curr())
diff --git a/tools/include/linux/nmi.h b/tools/include/linux/nmi.h
new file mode 100644 (file)
index 0000000..e69de29
index 664ced8cb1b041918b3c06a3df58a3940aa640e1..e907ba6f15e532b678d5aa850de09aefeaa1b79d 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: (LGPL-2.0+ OR BSD-2-Clause)
 /* Copyright (C) 2018 Netronome Systems, Inc. */
 
 #ifndef __TOOLS_LIBC_COMPAT_H
index 42990676a55e104ae85e7ea170c78c1e93427f1d..df4bedb9b01c281b7bf15048fef3063a35ede51c 100644 (file)
@@ -734,9 +734,11 @@ __SYSCALL(__NR_pkey_free,     sys_pkey_free)
 __SYSCALL(__NR_statx,     sys_statx)
 #define __NR_io_pgetevents 292
 __SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents)
+#define __NR_rseq 293
+__SYSCALL(__NR_rseq, sys_rseq)
 
 #undef __NR_syscalls
-#define __NR_syscalls 293
+#define __NR_syscalls 294
 
 /*
  * 32 bit systems traditionally used different
index 9c660e1688abe1cd6bf0e22bf709515e8a463e0d..300f336633f28ea20493570f80a73e30d87cd087 100644 (file)
@@ -687,6 +687,15 @@ struct drm_get_cap {
  */
 #define DRM_CLIENT_CAP_ASPECT_RATIO    4
 
+/**
+ * DRM_CLIENT_CAP_WRITEBACK_CONNECTORS
+ *
+ * If set to 1, the DRM core will expose special connectors to be used for
+ * writing back to memory the scene setup in the commit. Depends on client
+ * also supporting DRM_CLIENT_CAP_ATOMIC
+ */
+#define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS    5
+
 /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
 struct drm_set_client_cap {
        __u64 capability;
index cf01b68242448512416c1b1aa25f0904915aad0a..43391e2d1153adb701433d6794702b73f2d60297 100644 (file)
@@ -164,6 +164,8 @@ enum {
        IFLA_CARRIER_UP_COUNT,
        IFLA_CARRIER_DOWN_COUNT,
        IFLA_NEW_IFINDEX,
+       IFLA_MIN_MTU,
+       IFLA_MAX_MTU,
        __IFLA_MAX
 };
 
@@ -334,6 +336,7 @@ enum {
        IFLA_BRPORT_GROUP_FWD_MASK,
        IFLA_BRPORT_NEIGH_SUPPRESS,
        IFLA_BRPORT_ISOLATED,
+       IFLA_BRPORT_BACKUP_PORT,
        __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -459,6 +462,16 @@ enum {
 
 #define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
 
+/* XFRM section */
+enum {
+       IFLA_XFRM_UNSPEC,
+       IFLA_XFRM_LINK,
+       IFLA_XFRM_IF_ID,
+       __IFLA_XFRM_MAX
+};
+
+#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1)
+
 enum macsec_validation_type {
        MACSEC_VALIDATE_DISABLED = 0,
        MACSEC_VALIDATE_CHECK = 1,
@@ -920,6 +933,7 @@ enum {
        XDP_ATTACHED_DRV,
        XDP_ATTACHED_SKB,
        XDP_ATTACHED_HW,
+       XDP_ATTACHED_MULTI,
 };
 
 enum {
@@ -928,6 +942,9 @@ enum {
        IFLA_XDP_ATTACHED,
        IFLA_XDP_FLAGS,
        IFLA_XDP_PROG_ID,
+       IFLA_XDP_DRV_PROG_ID,
+       IFLA_XDP_SKB_PROG_ID,
+       IFLA_XDP_HW_PROG_ID,
        __IFLA_XDP_MAX,
 };
 
index b6270a3b38e9f3fb410e8c80d8658b2c01a8ef96..07548de5c9889f5bcd425a7273b2732003bf3c30 100644 (file)
@@ -949,6 +949,9 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_GET_MSR_FEATURES 153
 #define KVM_CAP_HYPERV_EVENTFD 154
 #define KVM_CAP_HYPERV_TLBFLUSH 155
+#define KVM_CAP_S390_HPAGE_1M 156
+#define KVM_CAP_NESTED_STATE 157
+#define KVM_CAP_ARM_INJECT_SERROR_ESR 158
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1391,6 +1394,9 @@ struct kvm_enc_region {
 /* Available with KVM_CAP_HYPERV_EVENTFD */
 #define KVM_HYPERV_EVENTFD        _IOW(KVMIO,  0xbd, struct kvm_hyperv_eventfd)
 
+/* Available with KVM_CAP_NESTED_STATE */
+#define KVM_GET_NESTED_STATE         _IOWR(KVMIO, 0xbe, struct kvm_nested_state)
+#define KVM_SET_NESTED_STATE         _IOW(KVMIO,  0xbf, struct kvm_nested_state)
 
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
index eeb787b1c53c72771c8d684154b7a87dc029a45b..f35eb72739c09e3ad0bd22e279fa4a33119c15f6 100644 (file)
@@ -144,7 +144,7 @@ enum perf_event_sample_format {
 
        PERF_SAMPLE_MAX = 1U << 20,             /* non-ABI */
 
-       __PERF_SAMPLE_CALLCHAIN_EARLY           = 1ULL << 63,
+       __PERF_SAMPLE_CALLCHAIN_EARLY           = 1ULL << 63, /* non-ABI; internal use */
 };
 
 /*
index c51f8e5cc6080c03028727cdb81343fc4cabb6e1..84c3de89696a15c1a23e7226dea456a6232e2043 100644 (file)
@@ -65,6 +65,7 @@ struct vhost_iotlb_msg {
 };
 
 #define VHOST_IOTLB_MSG 0x1
+#define VHOST_IOTLB_MSG_V2 0x2
 
 struct vhost_msg {
        int type;
@@ -74,6 +75,15 @@ struct vhost_msg {
        };
 };
 
+struct vhost_msg_v2 {
+       __u32 type;
+       __u32 reserved;
+       union {
+               struct vhost_iotlb_msg iotlb;
+               __u8 padding[64];
+       };
+};
+
 struct vhost_memory_region {
        __u64 guest_phys_addr;
        __u64 memory_size; /* bytes */
@@ -160,6 +170,14 @@ struct vhost_memory {
 #define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24,      \
                                         struct vhost_vring_state)
 
+/* Set or get vhost backend capability */
+
+/* Use message type V2 */
+#define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
+
+#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
+#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
+
 /* VHOST_NET specific defines */
 
 /* Attach virtio net ring to a raw socket, or tap device.
index 13a861135127f04e21590955de6802ea40380208..6eb9bacd1948ad810c50f2192b348c81fcb1ac99 100644 (file)
@@ -1 +1 @@
-libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o
+libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o
index 2abd0f112627607a3f6d295e688a2f31b20417e2..bdb94939fd602750f882dd0baac261f22da899a6 100644 (file)
@@ -50,6 +50,7 @@
 #include "libbpf.h"
 #include "bpf.h"
 #include "btf.h"
+#include "str_error.h"
 
 #ifndef EM_BPF
 #define EM_BPF 247
@@ -469,7 +470,7 @@ static int bpf_object__elf_init(struct bpf_object *obj)
                obj->efile.fd = open(obj->path, O_RDONLY);
                if (obj->efile.fd < 0) {
                        char errmsg[STRERR_BUFSIZE];
-                       char *cp = strerror_r(errno, errmsg, sizeof(errmsg));
+                       char *cp = str_error(errno, errmsg, sizeof(errmsg));
 
                        pr_warning("failed to open %s: %s\n", obj->path, cp);
                        return -errno;
@@ -810,8 +811,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                                                      data->d_size, name, idx);
                        if (err) {
                                char errmsg[STRERR_BUFSIZE];
-                               char *cp = strerror_r(-err, errmsg,
-                                                     sizeof(errmsg));
+                               char *cp = str_error(-err, errmsg, sizeof(errmsg));
 
                                pr_warning("failed to alloc program %s (%s): %s",
                                           name, obj->path, cp);
@@ -1140,7 +1140,7 @@ bpf_object__create_maps(struct bpf_object *obj)
 
                *pfd = bpf_create_map_xattr(&create_attr);
                if (*pfd < 0 && create_attr.btf_key_type_id) {
-                       cp = strerror_r(errno, errmsg, sizeof(errmsg));
+                       cp = str_error(errno, errmsg, sizeof(errmsg));
                        pr_warning("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n",
                                   map->name, cp, errno);
                        create_attr.btf_fd = 0;
@@ -1155,7 +1155,7 @@ bpf_object__create_maps(struct bpf_object *obj)
                        size_t j;
 
                        err = *pfd;
-                       cp = strerror_r(errno, errmsg, sizeof(errmsg));
+                       cp = str_error(errno, errmsg, sizeof(errmsg));
                        pr_warning("failed to create map (name: '%s'): %s\n",
                                   map->name, cp);
                        for (j = 0; j < i; j++)
@@ -1339,7 +1339,7 @@ load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type,
        }
 
        ret = -LIBBPF_ERRNO__LOAD;
-       cp = strerror_r(errno, errmsg, sizeof(errmsg));
+       cp = str_error(errno, errmsg, sizeof(errmsg));
        pr_warning("load bpf program failed: %s\n", cp);
 
        if (log_buf && log_buf[0] != '\0') {
@@ -1654,7 +1654,7 @@ static int check_path(const char *path)
 
        dir = dirname(dname);
        if (statfs(dir, &st_fs)) {
-               cp = strerror_r(errno, errmsg, sizeof(errmsg));
+               cp = str_error(errno, errmsg, sizeof(errmsg));
                pr_warning("failed to statfs %s: %s\n", dir, cp);
                err = -errno;
        }
@@ -1690,7 +1690,7 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
        }
 
        if (bpf_obj_pin(prog->instances.fds[instance], path)) {
-               cp = strerror_r(errno, errmsg, sizeof(errmsg));
+               cp = str_error(errno, errmsg, sizeof(errmsg));
                pr_warning("failed to pin program: %s\n", cp);
                return -errno;
        }
@@ -1708,7 +1708,7 @@ static int make_dir(const char *path)
                err = -errno;
 
        if (err) {
-               cp = strerror_r(-err, errmsg, sizeof(errmsg));
+               cp = str_error(-err, errmsg, sizeof(errmsg));
                pr_warning("failed to mkdir %s: %s\n", path, cp);
        }
        return err;
@@ -1770,7 +1770,7 @@ int bpf_map__pin(struct bpf_map *map, const char *path)
        }
 
        if (bpf_obj_pin(map->fd, path)) {
-               cp = strerror_r(errno, errmsg, sizeof(errmsg));
+               cp = str_error(errno, errmsg, sizeof(errmsg));
                pr_warning("failed to pin map: %s\n", cp);
                return -errno;
        }
diff --git a/tools/lib/bpf/str_error.c b/tools/lib/bpf/str_error.c
new file mode 100644 (file)
index 0000000..b879811
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: LGPL-2.1
+#undef _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include "str_error.h"
+
+/*
+ * Wrapper to allow for building in non-GNU systems such as Alpine Linux's musl
+ * libc, while checking strerror_r() return to avoid having to check this in
+ * all places calling it.
+ */
+char *str_error(int err, char *dst, int len)
+{
+       int ret = strerror_r(err, dst, len);
+       if (ret)
+               snprintf(dst, len, "ERROR: strerror_r(%d)=%d", err, ret);
+       return dst;
+}
diff --git a/tools/lib/bpf/str_error.h b/tools/lib/bpf/str_error.h
new file mode 100644 (file)
index 0000000..355b1db
--- /dev/null
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: LGPL-2.1
+#ifndef BPF_STR_ERROR
+#define BPF_STR_ERROR
+
+char *str_error(int err, char *dst, int len);
+#endif // BPF_STR_ERROR
index 42261a9b280e3e11721274b76503a9db1ebeac3a..ac841bc5c35bc4950f918ac304fc329e7dd1c7c2 100644 (file)
@@ -280,7 +280,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
        mv $@+ $@
 
 ifdef USE_ASCIIDOCTOR
-$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.txt
+$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : %.txt
        $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
        $(ASCIIDOC) -b manpage -d manpage \
                $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \
index b3d1b12a5081ba10a92d19c79b38c6fb4654a597..5224ade3d5afed19b93a811a162a3ae6012c7ee7 100644 (file)
@@ -777,14 +777,12 @@ endif
        $(call QUIET_INSTALL, libexec) \
                $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 ifndef NO_LIBBPF
-       $(call QUIET_INSTALL, lib) \
-               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
-       $(call QUIET_INSTALL, include/bpf) \
-               $(INSTALL) include/bpf/*.h '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
-       $(call QUIET_INSTALL, lib) \
-               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
-       $(call QUIET_INSTALL, examples/bpf) \
-               $(INSTALL) examples/bpf/*.c '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
+       $(call QUIET_INSTALL, bpf-headers) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
+               $(INSTALL) include/bpf/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
+       $(call QUIET_INSTALL, bpf-examples) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \
+               $(INSTALL) examples/bpf/*.c -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
 endif
        $(call QUIET_INSTALL, perf-archive) \
                $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
index f013b115dc860d001120233df6d912ad35c842ec..dbef716a19135fffaf2afb1adedc418a3effd420 100644 (file)
@@ -11,7 +11,8 @@ PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 
 out    := $(OUTPUT)arch/arm64/include/generated/asm
 header := $(out)/syscalls.c
-sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h
+incpath := $(srctree)/tools
+sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h
 sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
 systbl := $(sysprf)/mksyscalltbl
 
@@ -19,7 +20,7 @@ systbl := $(sysprf)/mksyscalltbl
 _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
 
 $(header): $(sysdef) $(systbl)
-       $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@
+       $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
 
 clean::
        $(call QUIET_CLEAN, arm64) $(RM) $(header)
index 52e197317d3ee22b82ced11a0b2ee4a50dd4b837..2dbb8cade048f76b4b43d88d5d9e27c09e025e0f 100755 (executable)
@@ -11,7 +11,8 @@
 
 gcc=$1
 hostcc=$2
-input=$3
+incpath=$3
+input=$4
 
 if ! test -r $input; then
        echo "Could not read input file" >&2
@@ -28,7 +29,6 @@ create_table_from_c()
 
        cat <<-_EoHEADER
                #include <stdio.h>
-               #define __ARCH_WANT_RENAMEAT
                #include "$input"
                int main(int argc, char *argv[])
                {
@@ -42,7 +42,7 @@ create_table_from_c()
        printf "%s\n" " printf(\"#define SYSCALLTBL_ARM64_MAX_ID %d\\n\", __NR_$last_sc);"
        printf "}\n"
 
-       } | $hostcc -o $create_table_exe -x c -
+       } | $hostcc -I $incpath/include/uapi -o $create_table_exe -x c -
 
        $create_table_exe
 
index 20e7d74d86cd16e86c8fd60e5839222d476f6409..10a44e946f7734b911ed00f74184f754b09d56ba 100644 (file)
@@ -22,15 +22,16 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
 
 #endif
 
-#if !defined(_CALL_ELF) || _CALL_ELF != 2
 int arch__choose_best_symbol(struct symbol *syma,
                             struct symbol *symb __maybe_unused)
 {
        char *sym = syma->name;
 
+#if !defined(_CALL_ELF) || _CALL_ELF != 2
        /* Skip over any initial dot */
        if (*sym == '.')
                sym++;
+#endif
 
        /* Avoid "SyS" kernel syscall aliases */
        if (strlen(sym) >= 3 && !strncmp(sym, "SyS", 3))
@@ -41,6 +42,7 @@ int arch__choose_best_symbol(struct symbol *syma,
        return SYMBOL_A;
 }
 
+#if !defined(_CALL_ELF) || _CALL_ELF != 2
 /* Allow matching against dot variants */
 int arch__compare_symbol_names(const char *namea, const char *nameb)
 {
index c1bd979b957be76a2ff55f45d0d4011c056e0de7..613709cfbbd03d45e2c6254c2fb5a95f7f5415b5 100644 (file)
@@ -9,6 +9,7 @@ struct test;
 int test__rdpmc(struct test *test __maybe_unused, int subtest);
 int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest);
 int test__insn_x86(struct test *test __maybe_unused, int subtest);
+int test__bp_modify(struct test *test, int subtest);
 
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
 struct thread;
index 8e2c5a38c3b90c18c2159b8f91e54500734cd9f3..586849ff83a079468abc96294077c28b68a3e0c0 100644 (file)
@@ -5,3 +5,4 @@ libperf-y += arch-tests.o
 libperf-y += rdpmc.o
 libperf-y += perf-time-to-tsc.o
 libperf-$(CONFIG_AUXTRACE) += insn-x86.o
+libperf-$(CONFIG_X86_64) += bp-modify.o
index cc1802ff54109ebccd23130fcc37f023d6e5ae9c..d47d3f8e3c8e076111d47c6ca51252552df31117 100644 (file)
@@ -23,6 +23,12 @@ struct test arch_tests[] = {
                .desc = "x86 instruction decoder - new instructions",
                .func = test__insn_x86,
        },
+#endif
+#if defined(__x86_64__)
+       {
+               .desc = "x86 bp modify",
+               .func = test__bp_modify,
+       },
 #endif
        {
                .func = NULL,
diff --git a/tools/perf/arch/x86/tests/bp-modify.c b/tools/perf/arch/x86/tests/bp-modify.c
new file mode 100644 (file)
index 0000000..f53e440
--- /dev/null
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/compiler.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/user.h>
+#include <syscall.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include <errno.h>
+#include "debug.h"
+#include "tests/tests.h"
+#include "arch-tests.h"
+
+static noinline int bp_1(void)
+{
+       pr_debug("in %s\n", __func__);
+       return 0;
+}
+
+static noinline int bp_2(void)
+{
+       pr_debug("in %s\n", __func__);
+       return 0;
+}
+
+static int spawn_child(void)
+{
+       int child = fork();
+
+       if (child == 0) {
+               /*
+                * The child sets itself for as tracee and
+                * waits in signal for parent to trace it,
+                * then it calls bp_1 and quits.
+                */
+               int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL);
+
+               if (err) {
+                       pr_debug("failed to PTRACE_TRACEME\n");
+                       exit(1);
+               }
+
+               raise(SIGCONT);
+               bp_1();
+               exit(0);
+       }
+
+       return child;
+}
+
+/*
+ * This tests creates HW breakpoint, tries to
+ * change it and checks it was properly changed.
+ */
+static int bp_modify1(void)
+{
+       pid_t child;
+       int status;
+       unsigned long rip = 0, dr7 = 1;
+
+       child = spawn_child();
+
+       waitpid(child, &status, 0);
+       if (WIFEXITED(status)) {
+               pr_debug("tracee exited prematurely 1\n");
+               return TEST_FAIL;
+       }
+
+       /*
+        * The parent does following steps:
+        *  - creates a new breakpoint (id 0) for bp_2 function
+        *  - changes that breakponit to bp_1 function
+        *  - waits for the breakpoint to hit and checks
+        *    it has proper rip of bp_1 function
+        *  - detaches the child
+        */
+       if (ptrace(PTRACE_POKEUSER, child,
+                  offsetof(struct user, u_debugreg[0]), bp_2)) {
+               pr_debug("failed to set breakpoint, 1st time: %s\n",
+                        strerror(errno));
+               goto out;
+       }
+
+       if (ptrace(PTRACE_POKEUSER, child,
+                  offsetof(struct user, u_debugreg[0]), bp_1)) {
+               pr_debug("failed to set breakpoint, 2nd time: %s\n",
+                        strerror(errno));
+               goto out;
+       }
+
+       if (ptrace(PTRACE_POKEUSER, child,
+                  offsetof(struct user, u_debugreg[7]), dr7)) {
+               pr_debug("failed to set dr7: %s\n", strerror(errno));
+               goto out;
+       }
+
+       if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
+               pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
+               goto out;
+       }
+
+       waitpid(child, &status, 0);
+       if (WIFEXITED(status)) {
+               pr_debug("tracee exited prematurely 2\n");
+               return TEST_FAIL;
+       }
+
+       rip = ptrace(PTRACE_PEEKUSER, child,
+                    offsetof(struct user_regs_struct, rip), NULL);
+       if (rip == (unsigned long) -1) {
+               pr_debug("failed to PTRACE_PEEKUSER: %s\n",
+                        strerror(errno));
+               goto out;
+       }
+
+       pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
+
+out:
+       if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
+               pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
+               return TEST_FAIL;
+       }
+
+       return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
+}
+
+/*
+ * This tests creates HW breakpoint, tries to
+ * change it to bogus value and checks the original
+ * breakpoint is hit.
+ */
+static int bp_modify2(void)
+{
+       pid_t child;
+       int status;
+       unsigned long rip = 0, dr7 = 1;
+
+       child = spawn_child();
+
+       waitpid(child, &status, 0);
+       if (WIFEXITED(status)) {
+               pr_debug("tracee exited prematurely 1\n");
+               return TEST_FAIL;
+       }
+
+       /*
+        * The parent does following steps:
+        *  - creates a new breakpoint (id 0) for bp_1 function
+        *  - tries to change that breakpoint to (-1) address
+        *  - waits for the breakpoint to hit and checks
+        *    it has proper rip of bp_1 function
+        *  - detaches the child
+        */
+       if (ptrace(PTRACE_POKEUSER, child,
+                  offsetof(struct user, u_debugreg[0]), bp_1)) {
+               pr_debug("failed to set breakpoint: %s\n",
+                        strerror(errno));
+               goto out;
+       }
+
+       if (ptrace(PTRACE_POKEUSER, child,
+                  offsetof(struct user, u_debugreg[7]), dr7)) {
+               pr_debug("failed to set dr7: %s\n", strerror(errno));
+               goto out;
+       }
+
+       if (!ptrace(PTRACE_POKEUSER, child,
+                  offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) {
+               pr_debug("failed, breakpoint set to bogus address\n");
+               goto out;
+       }
+
+       if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
+               pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
+               goto out;
+       }
+
+       waitpid(child, &status, 0);
+       if (WIFEXITED(status)) {
+               pr_debug("tracee exited prematurely 2\n");
+               return TEST_FAIL;
+       }
+
+       rip = ptrace(PTRACE_PEEKUSER, child,
+                    offsetof(struct user_regs_struct, rip), NULL);
+       if (rip == (unsigned long) -1) {
+               pr_debug("failed to PTRACE_PEEKUSER: %s\n",
+                        strerror(errno));
+               goto out;
+       }
+
+       pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
+
+out:
+       if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
+               pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
+               return TEST_FAIL;
+       }
+
+       return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
+}
+
+int test__bp_modify(struct test *test __maybe_unused,
+                   int subtest __maybe_unused)
+{
+       TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1());
+       TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2());
+
+       return 0;
+}
index 20061cf4228875bb43e34a081da7224d69531f49..28cd6a17491b2077815ce0d9bb86f741f7a2be6e 100644 (file)
@@ -246,8 +246,14 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
 
 indirect_call:
        tok = strchr(endptr, '*');
-       if (tok != NULL)
-               ops->target.addr = strtoull(tok + 1, NULL, 16);
+       if (tok != NULL) {
+               endptr++;
+
+               /* Indirect call can use a non-rip register and offset: callq  *0x8(%rbx).
+                * Do not parse such instruction.  */
+               if (strstr(endptr, "(%r") == NULL)
+                       ops->target.addr = strtoull(endptr, NULL, 16);
+       }
        goto find_target;
 }
 
@@ -276,7 +282,19 @@ bool ins__is_call(const struct ins *ins)
        return ins->ops == &call_ops || ins->ops == &s390_call_ops;
 }
 
-static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms)
+/*
+ * Prevents from matching commas in the comment section, e.g.:
+ * ffff200008446e70:       b.cs    ffff2000084470f4 <generic_exec_single+0x314>  // b.hs, b.nlast
+ */
+static inline const char *validate_comma(const char *c, struct ins_operands *ops)
+{
+       if (ops->raw_comment && c > ops->raw_comment)
+               return NULL;
+
+       return c;
+}
+
+static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
 {
        struct map *map = ms->map;
        struct symbol *sym = ms->sym;
@@ -285,6 +303,10 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
        };
        const char *c = strchr(ops->raw, ',');
        u64 start, end;
+
+       ops->raw_comment = strchr(ops->raw, arch->objdump.comment_char);
+       c = validate_comma(c, ops);
+
        /*
         * Examples of lines to parse for the _cpp_lex_token@@Base
         * function:
@@ -304,6 +326,7 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
                ops->target.addr = strtoull(c, NULL, 16);
                if (!ops->target.addr) {
                        c = strchr(c, ',');
+                       c = validate_comma(c, ops);
                        if (c++ != NULL)
                                ops->target.addr = strtoull(c, NULL, 16);
                }
@@ -361,9 +384,12 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
                return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name);
 
        c = strchr(ops->raw, ',');
+       c = validate_comma(c, ops);
+
        if (c != NULL) {
                const char *c2 = strchr(c + 1, ',');
 
+               c2 = validate_comma(c2, ops);
                /* check for 3-op insn */
                if (c2 != NULL)
                        c = c2;
index 005a5fe8a8c6bccc49ed7d6b1861952313ecb2df..5399ba2321bbb2c348e89fac2db9fed7c8d35384 100644 (file)
@@ -22,6 +22,7 @@ struct ins {
 
 struct ins_operands {
        char    *raw;
+       char    *raw_comment;
        struct {
                char    *raw;
                char    *name;
index c980bbff63536ebaba167d8ca045b65fc7060f56..1a61628a1c1262c86adff2d76c548985470d9e11 100644 (file)
@@ -251,8 +251,9 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
 {
        struct perf_evsel *evsel = zalloc(perf_evsel__object.size);
 
-       if (evsel != NULL)
-               perf_evsel__init(evsel, attr, idx);
+       if (!evsel)
+               return NULL;
+       perf_evsel__init(evsel, attr, idx);
 
        if (perf_evsel__is_bpf_output(evsel)) {
                evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
index 36d0763311efccec1adfb498cd39154266997f26..6a6929f208b4da042eeece3006f9c53740002289 100644 (file)
@@ -576,6 +576,13 @@ struct symbol *map_groups__find_symbol(struct map_groups *mg,
        return NULL;
 }
 
+static bool map__contains_symbol(struct map *map, struct symbol *sym)
+{
+       u64 ip = map->unmap_ip(map, sym->start);
+
+       return ip >= map->start && ip < map->end;
+}
+
 struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
                                         struct map **mapp)
 {
@@ -591,6 +598,10 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
 
                if (sym == NULL)
                        continue;
+               if (!map__contains_symbol(pos, sym)) {
+                       sym = NULL;
+                       continue;
+               }
                if (mapp != NULL)
                        *mapp = pos;
                goto out;
index c85d0d1a65ed72ffbdf2195004f0cd106602dde7..7b0ca7cbb7de852433a2dbd7494789096b555edd 100644 (file)
@@ -377,7 +377,7 @@ static int record_ftrace_printk(void)
 
 static int record_saved_cmdline(void)
 {
-       unsigned int size;
+       unsigned long long size;
        char *path;
        struct stat st;
        int ret, err = 0;
index 920b1d58a06899d6cecf6aea2aa30abedc95695d..e76214f8d596bc97c71390f1c82c5f75ab2fd607 100644 (file)
@@ -164,16 +164,15 @@ void parse_ftrace_printk(struct tep_handle *pevent,
 void parse_saved_cmdline(struct tep_handle *pevent,
                         char *file, unsigned int size __maybe_unused)
 {
-       char *comm;
+       char comm[17]; /* Max comm length in the kernel is 16. */
        char *line;
        char *next = NULL;
        int pid;
 
        line = strtok_r(file, "\n", &next);
        while (line) {
-               sscanf(line, "%d %ms", &pid, &comm);
-               tep_register_comm(pevent, comm, pid);
-               free(comm);
+               if (sscanf(line, "%d %16s", &pid, comm) == 2)
+                       tep_register_comm(pevent, comm, pid);
                line = strtok_r(NULL, "\n", &next);
        }
 }
index 72c25a3cb65892c4d2ae0cd13add3c3cf2423b50..d9a72547837543cb62f9754dd587afa01510d516 100644 (file)
@@ -6,7 +6,7 @@ TEST_PROGS := run.sh
 
 include ../lib.mk
 
-all:
+all: khdr
        @for DIR in $(SUBDIRS); do              \
                BUILD_TARGET=$(OUTPUT)/$$DIR;   \
                mkdir $$BUILD_TARGET  -p;       \
index e03695287f763e809bfb78637f6ff166082efc1c..88cfe88e466fb0e642b1a95e20c9f82a7e689587 100644 (file)
@@ -10,6 +10,8 @@ $(TEST_GEN_FILES): ipcsocket.c ionutils.c
 
 TEST_PROGS := ion_test.sh
 
+KSFT_KHDR_INSTALL := 1
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c
index 6f54f84144a00940a54484ec870be6ed1104f314..9b552c0fc47db8cded0fda2a53e40f9d5d42a036 100644 (file)
@@ -580,7 +580,11 @@ static void test_sockmap(int tasks, void *data)
        /* Test update without programs */
        for (i = 0; i < 6; i++) {
                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
-               if (err) {
+               if (i < 2 && !err) {
+                       printf("Allowed update sockmap '%i:%i' not in ESTABLISHED\n",
+                              i, sfd[i]);
+                       goto out_sockmap;
+               } else if (i >= 2 && err) {
                        printf("Failed noprog update sockmap '%i:%i'\n",
                               i, sfd[i]);
                        goto out_sockmap;
@@ -741,7 +745,7 @@ static void test_sockmap(int tasks, void *data)
        }
 
        /* Test map update elem afterwards fd lives in fd and map_fd */
-       for (i = 0; i < 6; i++) {
+       for (i = 2; i < 6; i++) {
                err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
                if (err) {
                        printf("Failed map_fd_rx update sockmap %i '%i:%i'\n",
@@ -845,7 +849,7 @@ static void test_sockmap(int tasks, void *data)
        }
 
        /* Delete the elems without programs */
-       for (i = 0; i < 6; i++) {
+       for (i = 2; i < 6; i++) {
                err = bpf_map_delete_elem(fd, &i);
                if (err) {
                        printf("Failed delete sockmap %i '%i:%i'\n",
index 95eb3a53c3812c61bf6d15fae51c031a75b5eb1c..adacda50a4b211e64bb40489487e9727402806a8 100644 (file)
@@ -1 +1,2 @@
 test_memcontrol
+test_core
index 1c5d2b2a583b3348b13f47b89c75d5ce504ac621..14c9fe2848062f0c2a8c37004f087d07b1d976f6 100644 (file)
@@ -89,17 +89,28 @@ int cg_read(const char *cgroup, const char *control, char *buf, size_t len)
 int cg_read_strcmp(const char *cgroup, const char *control,
                   const char *expected)
 {
-       size_t size = strlen(expected) + 1;
+       size_t size;
        char *buf;
+       int ret;
+
+       /* Handle the case of comparing against empty string */
+       if (!expected)
+               size = 32;
+       else
+               size = strlen(expected) + 1;
 
        buf = malloc(size);
        if (!buf)
                return -1;
 
-       if (cg_read(cgroup, control, buf, size))
+       if (cg_read(cgroup, control, buf, size)) {
+               free(buf);
                return -1;
+       }
 
-       return strcmp(expected, buf);
+       ret = strcmp(expected, buf);
+       free(buf);
+       return ret;
 }
 
 int cg_read_strstr(const char *cgroup, const char *control, const char *needle)
@@ -337,3 +348,24 @@ int is_swap_enabled(void)
 
        return cnt > 1;
 }
+
+int set_oom_adj_score(int pid, int score)
+{
+       char path[PATH_MAX];
+       int fd, len;
+
+       sprintf(path, "/proc/%d/oom_score_adj", pid);
+
+       fd = open(path, O_WRONLY | O_APPEND);
+       if (fd < 0)
+               return fd;
+
+       len = dprintf(fd, "%d", score);
+       if (len < 0) {
+               close(fd);
+               return len;
+       }
+
+       close(fd);
+       return 0;
+}
index 1ff6f9f1abdc07f96b4dc5b18cdb9f490ee85abb..9ac8b7958f83b26a268f54f19acb6aeeda391b75 100644 (file)
@@ -40,3 +40,4 @@ extern int get_temp_fd(void);
 extern int alloc_pagecache(int fd, size_t size);
 extern int alloc_anon(const char *cgroup, void *arg);
 extern int is_swap_enabled(void);
+extern int set_oom_adj_score(int pid, int score);
index cf0bddc9d271e369eb0a8f8afa4664c571151a18..28d321ba311b48d6f207cfdae5fc43699e2f1b81 100644 (file)
@@ -2,6 +2,7 @@
 #define _GNU_SOURCE
 
 #include <linux/limits.h>
+#include <linux/oom.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -202,6 +203,36 @@ static int alloc_pagecache_50M_noexit(const char *cgroup, void *arg)
        return 0;
 }
 
+static int alloc_anon_noexit(const char *cgroup, void *arg)
+{
+       int ppid = getppid();
+
+       if (alloc_anon(cgroup, arg))
+               return -1;
+
+       while (getppid() == ppid)
+               sleep(1);
+
+       return 0;
+}
+
+/*
+ * Wait until processes are killed asynchronously by the OOM killer
+ * If we exceed a timeout, fail.
+ */
+static int cg_test_proc_killed(const char *cgroup)
+{
+       int limit;
+
+       for (limit = 10; limit > 0; limit--) {
+               if (cg_read_strcmp(cgroup, "cgroup.procs", "") == 0)
+                       return 0;
+
+               usleep(100000);
+       }
+       return -1;
+}
+
 /*
  * First, this test creates the following hierarchy:
  * A       memory.min = 50M,  memory.max = 200M
@@ -964,6 +995,177 @@ static int test_memcg_sock(const char *root)
        return ret;
 }
 
+/*
+ * This test disables swapping and tries to allocate anonymous memory
+ * up to OOM with memory.group.oom set. Then it checks that all
+ * processes in the leaf (but not the parent) were killed.
+ */
+static int test_memcg_oom_group_leaf_events(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent, *child;
+
+       parent = cg_name(root, "memcg_test_0");
+       child = cg_name(root, "memcg_test_0/memcg_test_1");
+
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(parent, "cgroup.subtree_control", "+memory"))
+               goto cleanup;
+
+       if (cg_write(child, "memory.max", "50M"))
+               goto cleanup;
+
+       if (cg_write(child, "memory.swap.max", "0"))
+               goto cleanup;
+
+       if (cg_write(child, "memory.oom.group", "1"))
+               goto cleanup;
+
+       cg_run_nowait(parent, alloc_anon_noexit, (void *) MB(60));
+       cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
+       cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
+       if (!cg_run(child, alloc_anon, (void *)MB(100)))
+               goto cleanup;
+
+       if (cg_test_proc_killed(child))
+               goto cleanup;
+
+       if (cg_read_key_long(child, "memory.events", "oom_kill ") <= 0)
+               goto cleanup;
+
+       if (cg_read_key_long(parent, "memory.events", "oom_kill ") != 0)
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+
+       return ret;
+}
+
+/*
+ * This test disables swapping and tries to allocate anonymous memory
+ * up to OOM with memory.group.oom set. Then it checks that all
+ * processes in the parent and leaf were killed.
+ */
+static int test_memcg_oom_group_parent_events(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent, *child;
+
+       parent = cg_name(root, "memcg_test_0");
+       child = cg_name(root, "memcg_test_0/memcg_test_1");
+
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(parent, "memory.max", "80M"))
+               goto cleanup;
+
+       if (cg_write(parent, "memory.swap.max", "0"))
+               goto cleanup;
+
+       if (cg_write(parent, "memory.oom.group", "1"))
+               goto cleanup;
+
+       cg_run_nowait(parent, alloc_anon_noexit, (void *) MB(60));
+       cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
+       cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
+
+       if (!cg_run(child, alloc_anon, (void *)MB(100)))
+               goto cleanup;
+
+       if (cg_test_proc_killed(child))
+               goto cleanup;
+       if (cg_test_proc_killed(parent))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+
+       return ret;
+}
+
+/*
+ * This test disables swapping and tries to allocate anonymous memory
+ * up to OOM with memory.group.oom set. Then it checks that all
+ * processes were killed except those set with OOM_SCORE_ADJ_MIN
+ */
+static int test_memcg_oom_group_score_events(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *memcg;
+       int safe_pid;
+
+       memcg = cg_name(root, "memcg_test_0");
+
+       if (!memcg)
+               goto cleanup;
+
+       if (cg_create(memcg))
+               goto cleanup;
+
+       if (cg_write(memcg, "memory.max", "50M"))
+               goto cleanup;
+
+       if (cg_write(memcg, "memory.swap.max", "0"))
+               goto cleanup;
+
+       if (cg_write(memcg, "memory.oom.group", "1"))
+               goto cleanup;
+
+       safe_pid = cg_run_nowait(memcg, alloc_anon_noexit, (void *) MB(1));
+       if (set_oom_adj_score(safe_pid, OOM_SCORE_ADJ_MIN))
+               goto cleanup;
+
+       cg_run_nowait(memcg, alloc_anon_noexit, (void *) MB(1));
+       if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
+               goto cleanup;
+
+       if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 3)
+               goto cleanup;
+
+       if (kill(safe_pid, SIGKILL))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (memcg)
+               cg_destroy(memcg);
+       free(memcg);
+
+       return ret;
+}
+
+
 #define T(x) { x, #x }
 struct memcg_test {
        int (*fn)(const char *root);
@@ -978,6 +1180,9 @@ struct memcg_test {
        T(test_memcg_oom_events),
        T(test_memcg_swap_max),
        T(test_memcg_sock),
+       T(test_memcg_oom_group_leaf_events),
+       T(test_memcg_oom_group_parent_events),
+       T(test_memcg_oom_group_score_events),
 };
 #undef T
 
diff --git a/tools/testing/selftests/efivarfs/config b/tools/testing/selftests/efivarfs/config
new file mode 100644 (file)
index 0000000..4e151f1
--- /dev/null
@@ -0,0 +1 @@
+CONFIG_EFIVAR_FS=y
index ff8feca49746074d71b28455ff58a01a7d1b491c..ad1eeb14fda7ebf5717e7183ea83b31f6013600c 100644 (file)
@@ -18,6 +18,7 @@ TEST_GEN_FILES := \
 
 TEST_PROGS := run.sh
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_FILES): $(HEADERS)
index 1bbb47565c554cf06a95fe2a205231de75f7797e..4665cdbf1a8d4b165abb5081c408508dc56ebd78 100644 (file)
@@ -21,11 +21,8 @@ endef
 CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/
 LDLIBS += -lmount -I/usr/include/libmount
 
-$(BINARIES): ../../../gpio/gpio-utils.o ../../../../usr/include/linux/gpio.h
+$(BINARIES):| khdr
+$(BINARIES): ../../../gpio/gpio-utils.o
 
 ../../../gpio/gpio-utils.o:
        make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C ../../../gpio
-
-../../../../usr/include/linux/gpio.h:
-       make -C ../../../.. headers_install INSTALL_HDR_PATH=$(shell pwd)/../../../../usr/
-
index 15e6b75fc3a5e499fb7bcc981b6f19059406c2f6..a3edb2c8e43d0a83950d8b4535756ea0ec82eb8a 100644 (file)
@@ -19,7 +19,6 @@
 #define KSFT_FAIL  1
 #define KSFT_XFAIL 2
 #define KSFT_XPASS 3
-/* Treat skip as pass */
 #define KSFT_SKIP  4
 
 /* counters */
index 4202139d81d92c724bcb18df30b41deac28cb935..5c34752e1cff099ff884ffa0a78bb8deaa088dd6 100644 (file)
@@ -1,4 +1,5 @@
 cr4_cpuid_sync_test
+platform_info_test
 set_sregs_test
 sync_regs_test
 vmx_tsc_adjust_test
index 03b0f551bedffc7eecb6fd4452e99de1a8a4b828..ec32dad3c3f0796e8009b25633e3000efb531b8a 100644 (file)
@@ -6,7 +6,8 @@ UNAME_M := $(shell uname -m)
 LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c
 LIBKVM_x86_64 = lib/x86.c lib/vmx.c
 
-TEST_GEN_PROGS_x86_64 = set_sregs_test
+TEST_GEN_PROGS_x86_64 = platform_info_test
+TEST_GEN_PROGS_x86_64 += set_sregs_test
 TEST_GEN_PROGS_x86_64 += sync_regs_test
 TEST_GEN_PROGS_x86_64 += vmx_tsc_adjust_test
 TEST_GEN_PROGS_x86_64 += cr4_cpuid_sync_test
@@ -20,7 +21,7 @@ INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
 LINUX_TOOL_INCLUDE = $(top_srcdir)tools/include
 CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_TOOL_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -I..
-LDFLAGS += -lpthread
+LDFLAGS += -pthread
 
 # After inclusion, $(OUTPUT) is defined and
 # $(TEST_GEN_PROGS) starts with $(OUTPUT)/
@@ -37,9 +38,6 @@ $(LIBKVM_OBJ): $(OUTPUT)/%.o: %.c
 $(OUTPUT)/libkvm.a: $(LIBKVM_OBJ)
        $(AR) crs $@ $^
 
-$(LINUX_HDR_PATH):
-       make -C $(top_srcdir) headers_install
-
-all: $(STATIC_LIBS) $(LINUX_HDR_PATH)
+all: $(STATIC_LIBS)
 $(TEST_GEN_PROGS): $(STATIC_LIBS)
-$(TEST_GEN_PROGS) $(LIBKVM_OBJ): | $(LINUX_HDR_PATH)
+$(STATIC_LIBS):| khdr
index bb5a25fb82c60cbe8f7a108c81bc1c78aa2a7a20..3acf9a91704c9b9437cd42c163f6c244cb1c7d08 100644 (file)
@@ -50,6 +50,7 @@ enum vm_mem_backing_src_type {
 };
 
 int kvm_check_cap(long cap);
+int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap);
 
 struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm);
 void kvm_vm_free(struct kvm_vm *vmp);
@@ -108,6 +109,9 @@ void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid,
                          struct kvm_vcpu_events *events);
 void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid,
                          struct kvm_vcpu_events *events);
+uint64_t vcpu_get_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index);
+void vcpu_set_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index,
+       uint64_t msr_value);
 
 const char *exit_reason_str(unsigned int exit_reason);
 
index e9ba389c48dbc95390d965a8ea7d7f03da9ece44..6fd8c089cafcdea41434fadc60512b96d4a90f5d 100644 (file)
@@ -63,6 +63,29 @@ int kvm_check_cap(long cap)
        return ret;
 }
 
+/* VM Enable Capability
+ *
+ * Input Args:
+ *   vm - Virtual Machine
+ *   cap - Capability
+ *
+ * Output Args: None
+ *
+ * Return: On success, 0. On failure a TEST_ASSERT failure is produced.
+ *
+ * Enables a capability (KVM_CAP_*) on the VM.
+ */
+int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap)
+{
+       int ret;
+
+       ret = ioctl(vm->fd, KVM_ENABLE_CAP, cap);
+       TEST_ASSERT(ret == 0, "KVM_ENABLE_CAP IOCTL failed,\n"
+               "  rc: %i errno: %i", ret, errno);
+
+       return ret;
+}
+
 static void vm_open(struct kvm_vm *vm, int perm)
 {
        vm->kvm_fd = open(KVM_DEV_PATH, perm);
@@ -1220,6 +1243,72 @@ void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid,
                ret, errno);
 }
 
+/* VCPU Get MSR
+ *
+ * Input Args:
+ *   vm - Virtual Machine
+ *   vcpuid - VCPU ID
+ *   msr_index - Index of MSR
+ *
+ * Output Args: None
+ *
+ * Return: On success, value of the MSR. On failure a TEST_ASSERT is produced.
+ *
+ * Get value of MSR for VCPU.
+ */
+uint64_t vcpu_get_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index)
+{
+       struct vcpu *vcpu = vcpu_find(vm, vcpuid);
+       struct {
+               struct kvm_msrs header;
+               struct kvm_msr_entry entry;
+       } buffer = {};
+       int r;
+
+       TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
+       buffer.header.nmsrs = 1;
+       buffer.entry.index = msr_index;
+       r = ioctl(vcpu->fd, KVM_GET_MSRS, &buffer.header);
+       TEST_ASSERT(r == 1, "KVM_GET_MSRS IOCTL failed,\n"
+               "  rc: %i errno: %i", r, errno);
+
+       return buffer.entry.data;
+}
+
+/* VCPU Set MSR
+ *
+ * Input Args:
+ *   vm - Virtual Machine
+ *   vcpuid - VCPU ID
+ *   msr_index - Index of MSR
+ *   msr_value - New value of MSR
+ *
+ * Output Args: None
+ *
+ * Return: On success, nothing. On failure a TEST_ASSERT is produced.
+ *
+ * Set value of MSR for VCPU.
+ */
+void vcpu_set_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index,
+       uint64_t msr_value)
+{
+       struct vcpu *vcpu = vcpu_find(vm, vcpuid);
+       struct {
+               struct kvm_msrs header;
+               struct kvm_msr_entry entry;
+       } buffer = {};
+       int r;
+
+       TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
+       memset(&buffer, 0, sizeof(buffer));
+       buffer.header.nmsrs = 1;
+       buffer.entry.index = msr_index;
+       buffer.entry.data = msr_value;
+       r = ioctl(vcpu->fd, KVM_SET_MSRS, &buffer.header);
+       TEST_ASSERT(r == 1, "KVM_SET_MSRS IOCTL failed,\n"
+               "  rc: %i errno: %i", r, errno);
+}
+
 /* VM VCPU Args Set
  *
  * Input Args:
diff --git a/tools/testing/selftests/kvm/platform_info_test.c b/tools/testing/selftests/kvm/platform_info_test.c
new file mode 100644 (file)
index 0000000..3764e71
--- /dev/null
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test for x86 KVM_CAP_MSR_PLATFORM_INFO
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ * Verifies expected behavior of controlling guest access to
+ * MSR_PLATFORM_INFO.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "x86.h"
+
+#define VCPU_ID 0
+#define MSR_PLATFORM_INFO_MAX_TURBO_RATIO 0xff00
+
+static void guest_code(void)
+{
+       uint64_t msr_platform_info;
+
+       for (;;) {
+               msr_platform_info = rdmsr(MSR_PLATFORM_INFO);
+               GUEST_SYNC(msr_platform_info);
+               asm volatile ("inc %r11");
+       }
+}
+
+static void set_msr_platform_info_enabled(struct kvm_vm *vm, bool enable)
+{
+       struct kvm_enable_cap cap = {};
+
+       cap.cap = KVM_CAP_MSR_PLATFORM_INFO;
+       cap.flags = 0;
+       cap.args[0] = (int)enable;
+       vm_enable_cap(vm, &cap);
+}
+
+static void test_msr_platform_info_enabled(struct kvm_vm *vm)
+{
+       struct kvm_run *run = vcpu_state(vm, VCPU_ID);
+       struct guest_args args;
+
+       set_msr_platform_info_enabled(vm, true);
+       vcpu_run(vm, VCPU_ID);
+       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+                       "Exit_reason other than KVM_EXIT_IO: %u (%s),\n",
+                       run->exit_reason,
+                       exit_reason_str(run->exit_reason));
+       guest_args_read(vm, VCPU_ID, &args);
+       TEST_ASSERT(args.port == GUEST_PORT_SYNC,
+                       "Received IO from port other than PORT_HOST_SYNC: %u\n",
+                       run->io.port);
+       TEST_ASSERT((args.arg1 & MSR_PLATFORM_INFO_MAX_TURBO_RATIO) ==
+               MSR_PLATFORM_INFO_MAX_TURBO_RATIO,
+               "Expected MSR_PLATFORM_INFO to have max turbo ratio mask: %i.",
+               MSR_PLATFORM_INFO_MAX_TURBO_RATIO);
+}
+
+static void test_msr_platform_info_disabled(struct kvm_vm *vm)
+{
+       struct kvm_run *run = vcpu_state(vm, VCPU_ID);
+
+       set_msr_platform_info_enabled(vm, false);
+       vcpu_run(vm, VCPU_ID);
+       TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN,
+                       "Exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n",
+                       run->exit_reason,
+                       exit_reason_str(run->exit_reason));
+}
+
+int main(int argc, char *argv[])
+{
+       struct kvm_vm *vm;
+       struct kvm_run *state;
+       int rv;
+       uint64_t msr_platform_info;
+
+       /* Tell stdout not to buffer its content */
+       setbuf(stdout, NULL);
+
+       rv = kvm_check_cap(KVM_CAP_MSR_PLATFORM_INFO);
+       if (!rv) {
+               fprintf(stderr,
+                       "KVM_CAP_MSR_PLATFORM_INFO not supported, skip test\n");
+               exit(KSFT_SKIP);
+       }
+
+       vm = vm_create_default(VCPU_ID, 0, guest_code);
+
+       msr_platform_info = vcpu_get_msr(vm, VCPU_ID, MSR_PLATFORM_INFO);
+       vcpu_set_msr(vm, VCPU_ID, MSR_PLATFORM_INFO,
+               msr_platform_info | MSR_PLATFORM_INFO_MAX_TURBO_RATIO);
+       test_msr_platform_info_disabled(vm);
+       test_msr_platform_info_enabled(vm);
+       vcpu_set_msr(vm, VCPU_ID, MSR_PLATFORM_INFO, msr_platform_info);
+
+       kvm_vm_free(vm);
+
+       return 0;
+}
index 17ab36605a8e8933b77624843572a2d23fe846ec..0a8e75886224b371f6da30f7a01d10f652313b66 100644 (file)
@@ -16,8 +16,20 @@ TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS))
 TEST_GEN_PROGS_EXTENDED := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS_EXTENDED))
 TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
 
+top_srcdir ?= ../../../..
+include $(top_srcdir)/scripts/subarch.include
+ARCH           ?= $(SUBARCH)
+
 all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
 
+.PHONY: khdr
+khdr:
+       make ARCH=$(ARCH) -C $(top_srcdir) headers_install
+
+ifdef KSFT_KHDR_INSTALL
+$(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES):| khdr
+endif
+
 .ONESHELL:
 define RUN_TEST_PRINT_RESULT
        TEST_HDR_MSG="selftests: "`basename $$PWD`:" $$BASENAME_TEST";  \
index 2fde30191a47e6251c4fc6477548d70a394269e1..a7e8cd5bb265d86cca85e91adc69043e18a3c13a 100644 (file)
@@ -2,3 +2,4 @@ CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
 CONFIG_NOTIFIER_ERROR_INJECTION=y
 CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
+CONFIG_MEMORY_HOTREMOVE=y
index 9cca68e440a0b7107c10b1859e6fc8fb2ed2fe4f..919aa2ac00af7e601be743fac20f9e474873818e 100644 (file)
@@ -15,6 +15,7 @@ TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx
 TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
 TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls
 
+KSFT_KHDR_INSTALL := 1
 include ../lib.mk
 
 $(OUTPUT)/reuseport_bpf_numa: LDFLAGS += -lnuma
index 32a194e3e07a5a60d4c00dfdcfd25ad31ef38b6e..0ab9423d009f5b8c189dddb4a1f8f81c8a3a2101 100755 (executable)
@@ -178,8 +178,8 @@ setup() {
 
 cleanup() {
        [ ${cleanup_done} -eq 1 ] && return
-       ip netns del ${NS_A} 2 > /dev/null
-       ip netns del ${NS_B} 2 > /dev/null
+       ip netns del ${NS_A} 2> /dev/null
+       ip netns del ${NS_B} 2> /dev/null
        cleanup_done=1
 }
 
index b3ebf2646e52f3e15e7d69c648369f4c510a54b4..8fdfeafaf8c00b4b327c33e7eeac02a42979d3dc 100644 (file)
@@ -502,6 +502,55 @@ TEST_F(tls, recv_peek_multiple)
        EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
 }
 
+TEST_F(tls, recv_peek_multiple_records)
+{
+       char const *test_str = "test_read_peek_mult_recs";
+       char const *test_str_first = "test_read_peek";
+       char const *test_str_second = "_mult_recs";
+       int len;
+       char buf[64];
+
+       len = strlen(test_str_first);
+       EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
+
+       len = strlen(test_str_second) + 1;
+       EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
+
+       len = sizeof(buf);
+       memset(buf, 0, len);
+       EXPECT_NE(recv(self->cfd, buf, len, MSG_PEEK), -1);
+
+       /* MSG_PEEK can only peek into the current record. */
+       len = strlen(test_str_first) + 1;
+       EXPECT_EQ(memcmp(test_str_first, buf, len), 0);
+
+       len = sizeof(buf);
+       memset(buf, 0, len);
+       EXPECT_NE(recv(self->cfd, buf, len, 0), -1);
+
+       /* Non-MSG_PEEK will advance strparser (and therefore record)
+        * however.
+        */
+       len = strlen(test_str) + 1;
+       EXPECT_EQ(memcmp(test_str, buf, len), 0);
+
+       /* MSG_MORE will hold current record open, so later MSG_PEEK
+        * will see everything.
+        */
+       len = strlen(test_str_first);
+       EXPECT_EQ(send(self->fd, test_str_first, len, MSG_MORE), len);
+
+       len = strlen(test_str_second) + 1;
+       EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
+
+       len = sizeof(buf);
+       memset(buf, 0, len);
+       EXPECT_NE(recv(self->cfd, buf, len, MSG_PEEK), -1);
+
+       len = strlen(test_str) + 1;
+       EXPECT_EQ(memcmp(test_str, buf, len), 0);
+}
+
 TEST_F(tls, pollin)
 {
        char const *test_str = "test_poll";
index a728040edbe18e14061eda8302043f340392e27f..14cfcf006936da9dd465ae7fbd8e18b1ebb0a1bf 100644 (file)
@@ -5,6 +5,7 @@ TEST_PROGS := hwtstamp_config rxtimestamp timestamping txtimestamp
 
 all: $(TEST_PROGS)
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 clean:
index 93baacab7693c48576e4872c8d31287931b73091..d056486f49de5eacad70b4813287094e5e597927 100644 (file)
@@ -1,5 +1,6 @@
 TEST_GEN_PROGS := copy_first_unaligned alignment_handler
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c ../utils.c
index b4d7432a0ecd1b4af5fa5fe2071276172a684dc5..d40300a65b42f79ba4c48705d909906ed9115dd0 100644 (file)
@@ -4,6 +4,7 @@ TEST_GEN_FILES := exec_target
 
 CFLAGS += -O2
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c
index 1be547434a49c3feb8f7e40c03d4b5260a3b30d4..ede4d3dae7505ef31f822bac9b613aef464f6125 100644 (file)
@@ -5,6 +5,7 @@ all: $(TEST_PROGS)
 
 $(TEST_PROGS): ../harness.c ../utils.c
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 clean:
index 1cf89a34d97ca35299bf62b588b07d61ecbbb8a8..44574f3818b3d71d51a2021412ca70420b4543e2 100644 (file)
@@ -17,6 +17,7 @@ TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \
 
 EXTRA_SOURCES := validate.c ../harness.c stubs.S
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(OUTPUT)/copyuser_64_t%:      copyuser_64.S $(EXTRA_SOURCES)
index 55d7db7a616bcd7661fceeb470ecb6f153cd9eac..5df476364b4d46dd1563889bbd86864622c29ffd 100644 (file)
@@ -3,6 +3,7 @@ TEST_GEN_PROGS := dscr_default_test dscr_explicit_test dscr_user_test   \
              dscr_inherit_test dscr_inherit_exec_test dscr_sysfs_test  \
              dscr_sysfs_thread_test
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(OUTPUT)/dscr_default_test: LDLIBS += -lpthread
index 0dd3a01fdab92bc887ddc70cda06fd20c89c5154..11a10d7a2bbd9f1c93ccbf309ac5d0dc9d688f2b 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 TEST_GEN_PROGS := fpu_syscall fpu_preempt fpu_signal vmx_syscall vmx_preempt vmx_signal vsx_preempt
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c
index 8ebbe96d80a8452575fb234b6eba23a19e2c3a4e..33ced6e0ad25e07047e19699c90303ed97d157fa 100644 (file)
@@ -5,6 +5,7 @@ noarg:
 TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors
 TEST_GEN_FILES := tempfile
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c
index 6e1629bf5b09dbfb850acdb0f0c60aafdc6e3ea6..19046db995fee387a77f9fd2f2d130078c37cb71 100644 (file)
@@ -5,6 +5,7 @@ noarg:
 TEST_GEN_PROGS := count_instructions l3_bank_test per_event_excludes
 EXTRA_SOURCES := ../harness.c event.c lib.c ../utils.c
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 all: $(TEST_GEN_PROGS) ebb
index c4e64bc2e2650a2e02fac4a6f891e973a126eced..bd5dfa509272a75b97b1dbf8ac2be00c0a1ab1cc 100644 (file)
@@ -17,6 +17,7 @@ TEST_GEN_PROGS := reg_access_test event_attributes_test cycles_test   \
         lost_exception_test no_handler_test                    \
         cycles_with_mmcr2_test
 
+top_srcdir = ../../../../../..
 include ../../../lib.mk
 
 $(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c \
index 175366db7be8bc1261194ac80d009cd33e0c9c59..ea2b7bd09e369c4fb679d1baeab71e80712af186 100644 (file)
@@ -2,6 +2,7 @@ CFLAGS += -I$(CURDIR)
 
 TEST_GEN_PROGS := load_unaligned_zeropad
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c
index 28f5b781a553f4899e004e5d1450ab4b92de3407..923d531265f8c22d3adf2442e0a48fc7c1fffb5d 100644 (file)
@@ -4,6 +4,7 @@ TEST_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
               ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak ptrace-pkey core-pkey \
               perf-hwbreak
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 all: $(TEST_PROGS)
index a7cbd5082e27175822bb2d351b7ebdbf9c0e345d..1fca25c6ace067ffb7a913508b4e13059cb04770 100644 (file)
@@ -8,6 +8,7 @@ $(TEST_PROGS): ../harness.c ../utils.c signal.S
 CFLAGS += -maltivec
 signal_tm: CFLAGS += -mhtm
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 clean:
index 10b35c87a4f4e316315c977b09e2b3bc6ef2b73c..7fc0623d85c314636be8cd3d393fb6c35c643edb 100644 (file)
@@ -29,6 +29,7 @@ endif
 
 ASFLAGS = $(CFLAGS)
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): $(EXTRA_SOURCES)
index 30b8ff8fb82e7a161759bf68363e69dcbcde2304..fcd2dcb8972babf90209b699307bd086f08c5f90 100644 (file)
@@ -5,6 +5,7 @@ ASFLAGS += -O2 -Wall -g -nostdlib -m64
 
 EXTRA_CLEAN = $(OUTPUT)/*.o $(OUTPUT)/check-reversed.S
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(OUTPUT)/switch_endian_test: $(OUTPUT)/check-reversed.S
index da22ca7c38c185a5bb4df90a81fa71a9fbccc6c1..161b8846336fdb324f97833ce821babd9c139eae 100644 (file)
@@ -2,6 +2,7 @@ TEST_GEN_PROGS := ipc_unmuxed
 
 CFLAGS += -I../../../../../usr/include
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c
index c0e45d2dde25d115b73ae2e14002a8b24167abbc..9fc2cf6fbc92c9214f9978dec423c23147ca359b 100644 (file)
@@ -6,6 +6,7 @@ TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack
        tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \
        $(SIGNAL_CONTEXT_CHK_TESTS) tm-sigreturn
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c ../utils.c
index f8ced26748f84408d902cc4ce58012874c545a58..fb82068c9fda297e1c505c440d7cbe112119b581 100644 (file)
@@ -2,6 +2,7 @@ TEST_GEN_PROGS := test-vphn
 
 CFLAGS += -m64
 
+top_srcdir = ../../../../..
 include ../../lib.mk
 
 $(TEST_GEN_PROGS): ../harness.c
index 9881876d2aa0b065f0367a87ab184d41139360a3..e94b7b14bcb2608a7e5bb2694527a760cd2a93c6 100644 (file)
@@ -26,10 +26,6 @@ TEST_PROGS := run_vmtests
 
 include ../lib.mk
 
-$(OUTPUT)/userfaultfd: ../../../../usr/include/linux/kernel.h
 $(OUTPUT)/userfaultfd: LDLIBS += -lpthread
 
 $(OUTPUT)/mlock-random-test: LDLIBS += -lcap
-
-../../../../usr/include/linux/kernel.h:
-       make -C ../../../.. headers_install