]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'kvm-s390-master-4.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorRadim Krčmář <rkrcmar@redhat.com>
Tue, 4 Apr 2017 12:42:51 +0000 (14:42 +0200)
committerRadim Krčmář <rkrcmar@redhat.com>
Tue, 4 Apr 2017 12:42:51 +0000 (14:42 +0200)
From: Christian Borntraeger <borntraeger@de.ibm.com>

KVM: s390: Fix instruction-execution-protection/change-recording override

This is a fix that prevents translation exception errors
on valid page tables for the instruction-exection-protection
support. This feature was added during the 4.11 merge window.
We have to remove an old check that would trigger if the
change-recording override is not available (e.g. edat1 disabled
via cpu model).

580 files changed:
Documentation/admin-guide/kernel-parameters.txt
Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt
Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt [deleted file]
Documentation/devicetree/bindings/rng/omap_rng.txt
Documentation/extcon/intel-int3496.txt
Documentation/gcc-plugins.txt
Documentation/virtual/kvm/api.txt
MAINTAINERS
Makefile
arch/arc/boot/dts/skeleton.dtsi
arch/arc/boot/dts/skeleton_hs.dtsi
arch/arc/boot/dts/skeleton_hs_idu.dtsi
arch/arc/boot/dts/vdk_axs10x_mb.dtsi
arch/arc/include/asm/kprobes.h
arch/arc/kernel/entry-arcv2.S
arch/arc/kernel/setup.c
arch/arc/mm/cache.c
arch/arm/boot/dts/am335x-pcm-953.dtsi
arch/arm/boot/dts/am57xx-idk-common.dtsi
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/boot/dts/bcm953012k.dts
arch/arm/boot/dts/bcm958522er.dts
arch/arm/boot/dts/bcm958525er.dts
arch/arm/boot/dts/bcm958525xmc.dts
arch/arm/boot/dts/bcm958622hr.dts
arch/arm/boot/dts/bcm958623hr.dts
arch/arm/boot/dts/bcm958625hr.dts
arch/arm/boot/dts/bcm988312hr.dts
arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-a33.dtsi
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
arch/arm/configs/omap2plus_defconfig
arch/arm/mach-at91/pm.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/gpmc-nand.c [deleted file]
arch/arm/mach-omap2/gpmc-onenand.c
arch/arm/mach-omap2/omap-headsmp.S
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm64/boot/dts/broadcom/ns2.dtsi
arch/arm64/include/asm/current.h
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/arm64/kernel/kaslr.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/vdso/.gitignore
arch/c6x/kernel/ptrace.c
arch/h8300/kernel/ptrace.c
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/include/asm/bitops.h
arch/m68k/include/asm/unistd.h
arch/m68k/include/uapi/asm/unistd.h
arch/m68k/kernel/syscalltable.S
arch/metag/kernel/ptrace.c
arch/mips/kernel/ptrace.c
arch/parisc/include/asm/uaccess.h
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/process.c
arch/parisc/lib/Makefile
arch/parisc/lib/fixup.S [deleted file]
arch/parisc/lib/lusercopy.S
arch/parisc/lib/memcpy.c
arch/parisc/mm/fault.c
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/mm/init_64.c
arch/s390/include/asm/sections.h
arch/s390/kernel/vmlinux.lds.S
arch/sparc/kernel/ptrace_64.c
arch/x86/Makefile
arch/x86/Makefile_32.cpu
arch/x86/boot/compressed/error.c
arch/x86/events/core.c
arch/x86/include/asm/kvm_page_track.h
arch/x86/include/asm/timer.h
arch/x86/include/asm/uv/uv_hub.h
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/mcheck/mce_amd.c
arch/x86/kernel/ftrace.c
arch/x86/kernel/tsc.c
arch/x86/kvm/i8259.c
arch/x86/kvm/ioapic.c
arch/x86/kvm/page_track.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/memcpy_64.S
arch/x86/mm/kaslr.c
arch/x86/purgatory/Makefile
block/blk-mq.c
block/blk-stat.c
crypto/lrw.c
crypto/xts.c
drivers/acpi/Makefile
drivers/acpi/acpi_platform.c
drivers/acpi/apei/ghes.c
drivers/acpi/ioapic.c
drivers/acpi/spcr.c
drivers/auxdisplay/img-ascii-lcd.c
drivers/block/nbd.c
drivers/bluetooth/Kconfig
drivers/char/hw_random/amd-rng.c
drivers/char/hw_random/geode-rng.c
drivers/char/ppdev.c
drivers/clk/clk.c
drivers/clk/rockchip/clk-rk3036.c
drivers/clk/sunxi-ng/Kconfig
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/sunxi-ng/ccu_mp.c
drivers/clk/sunxi-ng/ccu_nkmp.c
drivers/clocksource/clkevt-probe.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpuidle/cpuidle-powernv.c
drivers/cpuidle/sysfs.c
drivers/crypto/ccp/ccp-dev-v5.c
drivers/crypto/ccp/ccp-dev.c
drivers/crypto/ccp/ccp-dev.h
drivers/crypto/ccp/ccp-dmaengine.c
drivers/dma/bcm2835-dma.c
drivers/dma/dmaengine.c
drivers/edac/Kconfig
drivers/edac/Makefile
drivers/edac/i5000_edac.c
drivers/edac/i5400_edac.c
drivers/edac/pnd2_edac.c [new file with mode: 0644]
drivers/edac/pnd2_edac.h [new file with mode: 0644]
drivers/edac/xgene_edac.c
drivers/extcon/Kconfig
drivers/extcon/extcon-intel-int3496.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/esrt.c
drivers/gpio/gpio-altera-a10sr.c
drivers/gpio/gpio-altera.c
drivers/gpio/gpio-mcp23s08.c
drivers/gpio/gpio-mockup.c
drivers/gpio/gpio-xgene.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/si_dpm.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fimc.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/exynos_drm_ipp.c
drivers/gpu/drm/exynos/exynos_drm_rotator.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/gvt/aperture_gm.c
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/debug.h
drivers/gpu/drm/i915/gvt/edid.c
drivers/gpu/drm/i915/gvt/execlist.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/gvt.h
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/mmio.h
drivers/gpu/drm/i915/gvt/opregion.c
drivers/gpu/drm/i915/gvt/render.c
drivers/gpu/drm/i915/gvt/sched_policy.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_context.h
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_shrinker.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_csr.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_gvt.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_hotplug.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/si_dpm.c
drivers/gpu/drm/vc4/vc4_crtc.c
drivers/hid/Kconfig
drivers/hid/hid-chicony.c
drivers/hid/hid-core.c
drivers/hid/hid-corsair.c
drivers/hid/hid-ids.h
drivers/hid/hid-sony.c
drivers/hid/hid-xinmo.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c
drivers/hv/channel.c
drivers/hv/channel_mgmt.c
drivers/hv/hv_fcopy.c
drivers/hv/hv_kvp.c
drivers/hv/hv_snapshot.c
drivers/hv/hv_util.c
drivers/hv/hv_utils_transport.c
drivers/hv/hv_utils_transport.h
drivers/hv/vmbus_drv.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/it87.c
drivers/hwmon/max31790.c
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/pci.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/iio/adc/ti_am335x_adc.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/magnetometer/ak8974.c
drivers/infiniband/core/cq.c
drivers/infiniband/core/device.c
drivers/infiniband/hw/i40iw/i40iw_utils.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
drivers/infiniband/sw/rdmavt/mmap.c
drivers/infiniband/sw/rxe/Kconfig
drivers/infiniband/sw/rxe/rxe_mmap.c
drivers/infiniband/sw/rxe/rxe_req.c
drivers/infiniband/sw/rxe/rxe_resp.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/misc/cm109.c
drivers/input/misc/ims-pcu.c
drivers/input/misc/yealink.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/elan_i2c_core.c
drivers/input/rmi4/rmi_f30.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/tablet/hanwang.c
drivers/input/tablet/kbtab.c
drivers/input/touchscreen/sur40.c
drivers/iommu/amd_iommu.c
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/iommu.c
drivers/irqchip/Kconfig
drivers/irqchip/irq-mips-gic.c
drivers/media/platform/coda/imx-vdoa.c
drivers/media/platform/exynos-gsc/gsc-core.c
drivers/media/platform/sti/bdisp/bdisp-v4l2.c
drivers/media/usb/dvb-usb/dvb-usb-firmware.c
drivers/memory/omap-gpmc.c
drivers/misc/cxl/pci.c
drivers/misc/mei/bus-fixup.c
drivers/misc/mei/init.c
drivers/misc/vmw_vmci/vmci_guest.c
drivers/mmc/core/block.c
drivers/mmc/core/mmc.c
drivers/mmc/host/mtk-sd.c
drivers/mmc/host/sdhci-of-arasan.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/ushc.c
drivers/net/ethernet/amd/xgbe/xgbe-common.h
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/aquantia/atlantic/aq_main.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/brocade/bna/bnad_debugfs.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/ti/Kconfig
drivers/net/ethernet/ti/Makefile
drivers/net/fjes/fjes_main.c
drivers/net/hyperv/netvsc.c
drivers/net/tun.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/vrf.c
drivers/net/wireless/ath/ath10k/hw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/marvell/mwifiex/main.c
drivers/net/wireless/marvell/mwifiex/pcie.c
drivers/nvme/host/rdma.c
drivers/nvme/target/core.c
drivers/nvme/target/loop.c
drivers/nvme/target/nvmet.h
drivers/nvme/target/rdma.c
drivers/parport/share.c
drivers/pci/host/pci-thunder-pem.c
drivers/pci/host/pcie-iproc-bcma.c
drivers/pci/host/pcie-iproc-platform.c
drivers/pci/host/pcie-iproc.h
drivers/phy/Kconfig
drivers/phy/Makefile
drivers/phy/phy-bcm-nsp-usb3.c [deleted file]
drivers/phy/phy-exynos-pcie.c
drivers/pinctrl/meson/pinctrl-meson-gxbb.c
drivers/pinctrl/pinctrl-st.c
drivers/pinctrl/qcom/pinctrl-ipq4019.c
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/pinctrl/samsung/pinctrl-samsung.c
drivers/pinctrl/ti/Kconfig
drivers/ptp/ptp_kvm.c
drivers/rapidio/devices/tsi721.c
drivers/rapidio/devices/tsi721.h
drivers/remoteproc/Kconfig
drivers/scsi/Kconfig
drivers/scsi/aacraid/commsup.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/hpsa_cmd.h
drivers/scsi/libsas/sas_ata.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/sg.c
drivers/scsi/ufs/ufshcd-pltfrm.c
drivers/scsi/ufs/ufshcd.c
drivers/thermal/cpu_cooling.c
drivers/thermal/devfreq_cooling.c
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/st-asc.c
drivers/tty/tty_ldisc.c
drivers/tty/vt/keyboard.c
drivers/usb/class/usbtmc.c
drivers/usb/core/config.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_acm.c
drivers/usb/gadget/function/f_hid.c
drivers/usb/gadget/function/f_uvc.c
drivers/usb/gadget/udc/pch_udc.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/misc/idmouse.c
drivers/usb/misc/lvstest.c
drivers/usb/misc/uss720.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_cppi41.c
drivers/usb/musb/musb_dsps.c
drivers/usb/phy/phy-isp1301.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/wusbcore/wa-hc.c
drivers/uwb/hwa-rc.c
drivers/uwb/i1480/dfu/usb.c
drivers/vfio/vfio.c
drivers/vfio/vfio_iommu_type1.c
drivers/vhost/vsock.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_pci_common.c
drivers/xen/xen-acpi-processor.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/qgroup.c
fs/btrfs/send.c
fs/crypto/crypto.c
fs/crypto/fname.c
fs/crypto/fscrypt_private.h
fs/crypto/keyinfo.c
fs/crypto/policy.c
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/move_extent.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/f2fs/debug.c
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/node.c
fs/f2fs/segment.c
fs/hugetlbfs/inode.c
fs/jbd2/journal.c
fs/jbd2/revoke.c
fs/kernfs/file.c
fs/nfs/dir.c
fs/nfs/filelayout/filelayout.c
fs/nfs/filelayout/filelayout.h
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/nfs4proc.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsproc.c
fs/nfsd/nfssvc.c
include/asm-generic/sections.h
include/asm-generic/vmlinux.lds.h
include/linux/ccp.h
include/linux/clockchips.h
include/linux/errqueue.h
include/linux/fscrypt_common.h
include/linux/gpio/consumer.h
include/linux/hwmon.h
include/linux/hyperv.h
include/linux/iio/sw_device.h
include/linux/iommu.h
include/linux/kasan.h
include/linux/kvm_host.h
include/linux/memcontrol.h
include/linux/mlx4/device.h
include/linux/mm.h
include/linux/omap-gpmc.h
include/linux/reset.h
include/linux/sched/clock.h
include/linux/usb/quirks.h
include/linux/virtio_vsock.h
include/net/af_vsock.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_tables.h
include/net/netfilter/nf_tables_ipv6.h
include/net/sctp/structs.h
include/rdma/ib_verbs.h
include/uapi/asm-generic/unistd.h
include/uapi/linux/btrfs.h
include/uapi/rdma/mlx5-abi.h
include/video/exynos5433_decon.h
init/main.c
kernel/audit.c
kernel/audit.h
kernel/auditsc.c
kernel/bpf/hashtab.c
kernel/padata.c
kernel/sched/clock.c
kernel/sched/cpufreq_schedutil.c
lib/syscall.c
lib/test_kasan.c
mm/hugetlb.c
mm/kasan/kasan.h
mm/kasan/report.c
mm/kmemleak.c
mm/migrate.c
mm/rmap.c
mm/swap_slots.c
mm/vmstat.c
mm/workingset.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bat_v.c
net/batman-adv/fragmentation.c
net/batman-adv/gateway_common.c
net/batman-adv/soft-interface.c
net/batman-adv/types.h
net/bridge/br_fdb.c
net/bridge/br_netfilter_hooks.c
net/bridge/br_private.h
net/ceph/messenger.c
net/core/netclassid_cgroup.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/fib_frontend.c
net/ipv4/ip_fragment.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
net/ipv4/netfilter/nft_masq_ipv4.c
net/ipv4/netfilter/nft_redir_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_minisocks.c
net/ipv6/netfilter/nft_masq_ipv6.c
net/ipv6/netfilter/nft_redir_ipv6.c
net/ipv6/route.c
net/ipv6/udp.c
net/mpls/af_mpls.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_nat_proto_sctp.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_ct.c
net/netfilter/nft_meta.c
net/netfilter/nft_nat.c
net/netfilter/nft_set_bitmap.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/openvswitch/flow_netlink.c
net/rxrpc/conn_event.c
net/sched/sch_dsmark.c
net/sctp/associola.c
net/sctp/output.c
net/sctp/outqueue.c
net/socket.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/tipc/subscr.c
net/unix/garbage.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/virtio_transport.c
net/vmw_vsock/virtio_transport_common.c
net/wireless/nl80211.c
net/xfrm/xfrm_user.c
scripts/Kbuild.include
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_fifo.c
sound/core/seq/seq_memory.c
sound/core/seq/seq_memory.h
sound/pci/ctxfi/cthw20k1.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/soc/atmel/atmel-classd.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/rt5665.c
sound/soc/codecs/rt5665.h
sound/soc/codecs/wm_adsp.c
sound/soc/generic/simple-card-utils.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/mediatek/Kconfig
sound/soc/sh/rcar/cmd.c
sound/soc/sh/rcar/dma.c
sound/soc/sh/rcar/ssiu.c
sound/soc/soc-core.c
sound/soc/sti/uniperif_reader.c
sound/soc/sunxi/sun8i-codec.c
sound/x86/Kconfig
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/test_maps.c
virt/kvm/eventfd.c
virt/kvm/kvm_main.c

index 2ba45caabada3e88339e88ebdfaaedbb322085c8..facc20a3f96280472396ad3f7d2e8f2dba62fecc 100644 (file)
                        kernel and module base offset ASLR (Address Space
                        Layout Randomization).
 
+       kasan_multi_shot
+                       [KNL] Enforce KASAN (Kernel Address Sanitizer) to print
+                       report on every invalid memory access. Without this
+                       parameter KASAN will print report only for the first
+                       invalid access.
+
        keepinitrd      [HW,ARM]
 
        kernelcore=     [KNL,X86,IA-64,PPC]
index 30c546900b6021d24d64e1033714d362f3152a0e..07dbb358182ccd255baf2ed1220d5df9044f9dd7 100644 (file)
@@ -45,7 +45,7 @@ The following clocks are available:
    - 1 15      SATA
    - 1 16      SATA USB
    - 1 17      Main
-   - 1 18      SD/MMC
+   - 1 18      SD/MMC/GOP
    - 1 21      Slow IO (SPI, NOR, BootROM, I2C, UART)
    - 1 22      USB3H0
    - 1 23      USB3H1
@@ -65,7 +65,7 @@ Required properties:
        "cpm-audio", "cpm-communit", "cpm-nand", "cpm-ppv2", "cpm-sdio",
        "cpm-mg-domain", "cpm-mg-core", "cpm-xor1", "cpm-xor0", "cpm-gop-dp", "none",
        "cpm-pcie_x10", "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", "cpm-sata",
-       "cpm-sata-usb", "cpm-main", "cpm-sd-mmc", "none", "none", "cpm-slow-io",
+       "cpm-sata-usb", "cpm-main", "cpm-sd-mmc-gop", "none", "none", "cpm-slow-io",
        "cpm-usb3h0", "cpm-usb3h1", "cpm-usb3dev", "cpm-eip150", "cpm-eip197";
 
 Example:
@@ -78,6 +78,6 @@ Example:
                gate-clock-output-names = "cpm-audio", "cpm-communit", "cpm-nand", "cpm-ppv2", "cpm-sdio",
                        "cpm-mg-domain", "cpm-mg-core", "cpm-xor1", "cpm-xor0", "cpm-gop-dp", "none",
                        "cpm-pcie_x10", "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", "cpm-sata",
-                       "cpm-sata-usb", "cpm-main", "cpm-sd-mmc", "none", "none", "cpm-slow-io",
+                       "cpm-sata-usb", "cpm-main", "cpm-sd-mmc-gop", "none", "none", "cpm-slow-io",
                        "cpm-usb3h0", "cpm-usb3h1", "cpm-usb3dev", "cpm-eip150", "cpm-eip197";
        };
index a78265993665a65bae524bb19606a7c16f248770..ca5204b3bc218bfe8e04a4fd5ca70482b1ab8c6b 100644 (file)
@@ -4,7 +4,6 @@ Required properties:
   - compatible: value should be one of the following
                "samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */
                "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
-               "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
                "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
                "samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
                "samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
index 18645e0228b054e1ec0a77658c78d30f3c7eed8e..5837402c3adeae526a4e6efa914fd43c64c10443 100644 (file)
@@ -11,7 +11,6 @@ Required properties:
                "samsung,s5pv210-fimd"; /* for S5PV210 SoC */
                "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */
                "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
-               "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */
                "samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */
                "samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */
 
index ea9c1c9607f61239d2d0211d0cf5a607da406fb0..520d61dad6dd7ff4f65e5e8cddbf33a63b81b009 100644 (file)
@@ -13,7 +13,7 @@ Required Properties:
        - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
                                                        before RK3288
        - "rockchip,rk3288-dw-mshc": for Rockchip RK3288
-       - "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK1108
+       - "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RV1108
        - "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036
        - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368
        - "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399
diff --git a/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt b/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt
deleted file mode 100644 (file)
index e68ae5d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-Broadcom USB3 phy binding for northstar plus SoC
-The USB3 phy is internal to the SoC and is accessed using mdio interface.
-
-Required mdio bus properties:
-- reg: Should be 0x0 for SoC internal USB3 phy
-- #address-cells: must be 1
-- #size-cells: must be 0
-
-Required USB3 PHY properties:
-- compatible: should be "brcm,nsp-usb3-phy"
-- reg: USB3 Phy address on SoC internal MDIO bus and it should be 0x10.
-- usb3-ctrl-syscon: handler of syscon node defining physical address
-  of usb3 control register.
-- #phy-cells: must be 0
-
-Required usb3 control properties:
-- compatible: should be "brcm,nsp-usb3-ctrl"
-- reg: offset and length of the control registers
-
-Example:
-
-       mdio@0 {
-               reg = <0x0>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               usb3_phy: usb-phy@10 {
-                       compatible = "brcm,nsp-usb3-phy";
-                       reg = <0x10>;
-                       usb3-ctrl-syscon = <&usb3_ctrl>;
-                       #phy-cells = <0>;
-                       status = "disabled";
-               };
-       };
-
-       usb3_ctrl: syscon@104408 {
-               compatible = "brcm,nsp-usb3-ctrl", "syscon";
-               reg = <0x104408 0x3fc>;
-       };
index 471477299ece16c931322e96fbb3c1535b1e1a43..9cf7876ab43444f604a501075ccbf6088e50f880 100644 (file)
@@ -12,7 +12,8 @@ Required properties:
 - reg : Offset and length of the register set for the module
 - interrupts : the interrupt number for the RNG module.
                Used for "ti,omap4-rng" and "inside-secure,safexcel-eip76"
-- clocks: the trng clock source
+- clocks: the trng clock source. Only mandatory for the
+  "inside-secure,safexcel-eip76" compatible.
 
 Example:
 /* AM335x */
index af0b366c25b73332a77e58b9b7247c4c387fc0d6..8155dbc7fad36a253137c230a7f074fecd0a7969 100644 (file)
@@ -20,3 +20,8 @@ Index 1: The output gpio for enabling Vbus output from the device to the otg
 Index 2: The output gpio for muxing of the data pins between the USB host and
          the USB peripheral controller, write 1 to mux to the peripheral
          controller
+
+There is a mapping between indices and GPIO connection IDs as follows
+       id      index 0
+       vbus    index 1
+       mux     index 2
index 891c694644348241925dc3e585d632222d8b0948..433eaefb4aa171ac62f3162866763a0526d7eb83 100644 (file)
@@ -18,8 +18,8 @@ because gcc versions 4.5 and 4.6 are compiled by a C compiler,
 gcc-4.7 can be compiled by a C or a C++ compiler,
 and versions 4.8+ can only be compiled by a C++ compiler.
 
-Currently the GCC plugin infrastructure supports only the x86, arm and arm64
-architectures.
+Currently the GCC plugin infrastructure supports only the x86, arm, arm64 and
+powerpc architectures.
 
 This infrastructure was ported from grsecurity [6] and PaX [7].
 
index 3c248f772ae61673e719b0c004f47d6fd7b788c1..fd106899afd1b2cf53d88d0fd2aacc85625ebe57 100644 (file)
@@ -3377,6 +3377,69 @@ struct kvm_ppc_resize_hpt {
        __u32 pad;
 };
 
+4.104 KVM_X86_GET_MCE_CAP_SUPPORTED
+
+Capability: KVM_CAP_MCE
+Architectures: x86
+Type: system ioctl
+Parameters: u64 mce_cap (out)
+Returns: 0 on success, -1 on error
+
+Returns supported MCE capabilities. The u64 mce_cap parameter
+has the same format as the MSR_IA32_MCG_CAP register. Supported
+capabilities will have the corresponding bits set.
+
+4.105 KVM_X86_SETUP_MCE
+
+Capability: KVM_CAP_MCE
+Architectures: x86
+Type: vcpu ioctl
+Parameters: u64 mcg_cap (in)
+Returns: 0 on success,
+         -EFAULT if u64 mcg_cap cannot be read,
+         -EINVAL if the requested number of banks is invalid,
+         -EINVAL if requested MCE capability is not supported.
+
+Initializes MCE support for use. The u64 mcg_cap parameter
+has the same format as the MSR_IA32_MCG_CAP register and
+specifies which capabilities should be enabled. The maximum
+supported number of error-reporting banks can be retrieved when
+checking for KVM_CAP_MCE. The supported capabilities can be
+retrieved with KVM_X86_GET_MCE_CAP_SUPPORTED.
+
+4.106 KVM_X86_SET_MCE
+
+Capability: KVM_CAP_MCE
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_x86_mce (in)
+Returns: 0 on success,
+         -EFAULT if struct kvm_x86_mce cannot be read,
+         -EINVAL if the bank number is invalid,
+         -EINVAL if VAL bit is not set in status field.
+
+Inject a machine check error (MCE) into the guest. The input
+parameter is:
+
+struct kvm_x86_mce {
+       __u64 status;
+       __u64 addr;
+       __u64 misc;
+       __u64 mcg_status;
+       __u8 bank;
+       __u8 pad1[7];
+       __u64 pad2[3];
+};
+
+If the MCE being reported is an uncorrected error, KVM will
+inject it as an MCE exception into the guest. If the guest
+MCG_STATUS register reports that an MCE is in progress, KVM
+causes an KVM_EXIT_SHUTDOWN vmexit.
+
+Otherwise, if the MCE is a corrected error, KVM will just
+store it in the corresponding bank (provided this bank is
+not holding a previously reported uncorrected error).
+
 5. The kvm_run structure
 ------------------------
 
index c776906f67a9f6795a0aef555a7fe348d07c506f..1b0a87ffffab6701691808e1ce3053bd040c5dfb 100644 (file)
@@ -3216,7 +3216,6 @@ F:        drivers/platform/chrome/
 
 CISCO VIC ETHERNET NIC DRIVER
 M:     Christian Benvenuti <benve@cisco.com>
-M:     Sujith Sankar <ssujith@cisco.com>
 M:     Govindarajulu Varadarajan <_govind@gmx.com>
 M:     Neel Patel <neepatel@cisco.com>
 S:     Supported
@@ -4776,6 +4775,12 @@ L:       linux-edac@vger.kernel.org
 S:     Maintained
 F:     drivers/edac/mpc85xx_edac.[ch]
 
+EDAC-PND2
+M:     Tony Luck <tony.luck@intel.com>
+L:     linux-edac@vger.kernel.org
+S:     Maintained
+F:     drivers/edac/pnd2_edac.[ch]
+
 EDAC-PASEMI
 M:     Egor Martovetsky <egor@pasemi.com>
 L:     linux-edac@vger.kernel.org
@@ -7774,13 +7779,6 @@ F:       include/net/mac80211.h
 F:     net/mac80211/
 F:     drivers/net/wireless/mac80211_hwsim.[ch]
 
-MACVLAN DRIVER
-M:     Patrick McHardy <kaber@trash.net>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/macvlan.c
-F:     include/linux/if_macvlan.h
-
 MAILBOX API
 M:     Jassi Brar <jassisinghbrar@gmail.com>
 L:     linux-kernel@vger.kernel.org
@@ -7853,6 +7851,8 @@ F:        drivers/net/ethernet/marvell/mvneta.*
 MARVELL MWIFIEX WIRELESS DRIVER
 M:     Amitkumar Karwar <akarwar@marvell.com>
 M:     Nishant Sarmukadam <nishants@marvell.com>
+M:     Ganapathi Bhat <gbhat@marvell.com>
+M:     Xinming Hu <huxm@marvell.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
 F:     drivers/net/wireless/marvell/mwifiex/
@@ -13383,14 +13383,6 @@ W:     https://linuxtv.org
 S:     Maintained
 F:     drivers/media/platform/vivid/*
 
-VLAN (802.1Q)
-M:     Patrick McHardy <kaber@trash.net>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/macvlan.c
-F:     include/linux/if_*vlan.h
-F:     net/8021q/
-
 VLYNQ BUS
 M:     Florian Fainelli <f.fainelli@gmail.com>
 L:     openwrt-devel@lists.openwrt.org (subscribers-only)
index b2faa93193729f43ea80d5fe83f8adf41b220b78..e11989d36c8752bfb8c0a6a4c477c009eef28b57 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 11
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc5
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
index 65808fe0a290be15ded0903ad347540d0f35a52e..2891cb266cf0b5f855e4d89bcfa8aef194bd483f 100644 (file)
@@ -26,6 +26,7 @@
                        device_type = "cpu";
                        compatible = "snps,arc770d";
                        reg = <0>;
+                       clocks = <&core_clk>;
                };
        };
 
index 2dfe8037dfbb34ac680597619ecef27319bed1a2..5e944d3e5b74f61387b1f285e6837f96f5f66127 100644 (file)
@@ -21,6 +21,7 @@
                        device_type = "cpu";
                        compatible = "snps,archs38";
                        reg = <0>;
+                       clocks = <&core_clk>;
                };
        };
 
index 4c11079f3565a3decc7f6401a92950df16565411..54b277d7dea0e4594245aa50df0a3276a85a9916 100644 (file)
 
                cpu@0 {
                        device_type = "cpu";
-                       compatible = "snps,archs38xN";
+                       compatible = "snps,archs38";
                        reg = <0>;
+                       clocks = <&core_clk>;
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "snps,archs38";
+                       reg = <1>;
+                       clocks = <&core_clk>;
+               };
+               cpu@2 {
+                       device_type = "cpu";
+                       compatible = "snps,archs38";
+                       reg = <2>;
+                       clocks = <&core_clk>;
+               };
+               cpu@3 {
+                       device_type = "cpu";
+                       compatible = "snps,archs38";
+                       reg = <3>;
+                       clocks = <&core_clk>;
                };
        };
 
index f0df59b23e21e473c6f2987593c1f7ccd9cc5958..459fc656b759aee977c560dcbbc996c6deed0cd3 100644 (file)
                        interrupts = <7>;
                        bus-width = <4>;
                };
+       };
 
-               /* Embedded Vision subsystem UIO mappings; only relevant for EV VDK */
-               uio_ev: uio@0xD0000000 {
-                       compatible = "generic-uio";
-                       reg = <0xD0000000 0x2000 0xD1000000 0x2000 0x90000000 0x10000000 0xC0000000 0x10000000>;
-                       reg-names = "ev_gsa", "ev_ctrl", "ev_shared_mem", "ev_code_mem";
-                       interrupts = <23>;
-               };
+       /*
+        * Embedded Vision subsystem UIO mappings; only relevant for EV VDK
+        *
+        * This node is intentionally put outside of MB above becase
+        * it maps areas outside of MB's 0xEz-0xFz.
+        */
+       uio_ev: uio@0xD0000000 {
+               compatible = "generic-uio";
+               reg = <0xD0000000 0x2000 0xD1000000 0x2000 0x90000000 0x10000000 0xC0000000 0x10000000>;
+               reg-names = "ev_gsa", "ev_ctrl", "ev_shared_mem", "ev_code_mem";
+               interrupt-parent = <&mb_intc>;
+               interrupts = <23>;
        };
 };
index 00bdbe167615ec2d97c7bccec66595217741cd83..2e52d18e6bc7ee3661d055c2ae6d98806478bb50 100644 (file)
@@ -54,9 +54,7 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
 void kretprobe_trampoline(void);
 void trap_is_kprobe(unsigned long address, struct pt_regs *regs);
 #else
-static void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
-{
-}
+#define trap_is_kprobe(address, regs)
 #endif /* CONFIG_KPROBES */
 
 #endif /* _ARC_KPROBES_H */
index 2585632eaa6891d511252e1aee7cce4114725533..cc558a25b8fa690d1c72afed97f80161e4167db6 100644 (file)
@@ -100,15 +100,21 @@ END(handle_interrupt)
 ;################### Non TLB Exception Handling #############################
 
 ENTRY(EV_SWI)
-       flag 1
+       ; TODO: implement this
+       EXCEPTION_PROLOGUE
+       b   ret_from_exception
 END(EV_SWI)
 
 ENTRY(EV_DivZero)
-       flag 1
+       ; TODO: implement this
+       EXCEPTION_PROLOGUE
+       b   ret_from_exception
 END(EV_DivZero)
 
 ENTRY(EV_DCError)
-       flag 1
+       ; TODO: implement this
+       EXCEPTION_PROLOGUE
+       b   ret_from_exception
 END(EV_DCError)
 
 ; ---------------------------------------------
index 3093fa898a236a1b6ae18757bbaf3f954c49dc26..fa62404ba58f77ab9fc24489b35c15132d03d720 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/root_dev.h>
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/console.h>
@@ -488,8 +489,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 {
        char *str;
        int cpu_id = ptr_to_cpu(v);
-       struct device_node *core_clk = of_find_node_by_name(NULL, "core_clk");
-       u32 freq = 0;
+       struct device *cpu_dev = get_cpu_device(cpu_id);
+       struct clk *cpu_clk;
+       unsigned long freq = 0;
 
        if (!cpu_online(cpu_id)) {
                seq_printf(m, "processor [%d]\t: Offline\n", cpu_id);
@@ -502,9 +504,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE));
 
-       of_property_read_u32(core_clk, "clock-frequency", &freq);
+       cpu_clk = clk_get(cpu_dev, NULL);
+       if (IS_ERR(cpu_clk)) {
+               seq_printf(m, "CPU speed \t: Cannot get clock for processor [%d]\n",
+                          cpu_id);
+       } else {
+               freq = clk_get_rate(cpu_clk);
+       }
        if (freq)
-               seq_printf(m, "CPU speed\t: %u.%02u Mhz\n",
+               seq_printf(m, "CPU speed\t: %lu.%02lu Mhz\n",
                           freq / 1000000, (freq / 10000) % 100);
 
        seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n",
index d408fa21a07c9937a0e2956a6e12a7895ffef684..928562967f3cd02fee4a5de34e687d442d64a4e0 100644 (file)
@@ -633,6 +633,9 @@ noinline static void slc_entire_op(const int op)
 
        write_aux_reg(ARC_REG_SLC_INVALIDATE, 1);
 
+       /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
+       read_aux_reg(r);
+
        /* Important to wait for flush to complete */
        while (read_aux_reg(r) & SLC_CTRL_BUSY);
 }
index 02981eae96b99413f28ddb76cdcc90c810c5ae37..1ec8e0d801912fbb080b7f3ff880d017f60bf320 100644 (file)
                        label = "home";
                        linux,code = <KEY_HOME>;
                        gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                button@1 {
                        label = "menu";
                        linux,code = <KEY_MENU>;
                        gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
        };
index 0d341c545b010fb810b890166eae3aa7967313ea..e5ac1d81d15c9e482ab06b41830e5230a0187e69 100644 (file)
                        /* ID & VBUS GPIOs provided in board dts */
                };
        };
+
+       tpic2810: tpic2810@60 {
+               compatible = "ti,tpic2810";
+               reg = <0x60>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
 };
 
 &mcspi3 {
                spi-max-frequency = <1000000>;
                spi-cpol;
        };
-
-       tpic2810: tpic2810@60 {
-               compatible = "ti,tpic2810";
-               reg = <0x60>;
-               gpio-controller;
-               #gpio-cells = <2>;
-       };
 };
 
 &uart3 {
index 4fbb089cf5ad3c1f96a15f504ee433ff06b724df..00de62dc0042f1445851d1cb84c2cbea3e28d25f 100644 (file)
                timer@20200 {
                        compatible = "arm,cortex-a9-global-timer";
                        reg = <0x20200 0x100>;
-                       interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
                        clocks = <&periph_clk>;
                };
 
                local-timer@20600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0x20600 0x100>;
-                       interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_PPI 13 IRQ_TYPE_EDGE_RISING>;
                        clocks = <&periph_clk>;
                };
 
index bfd923096a8c1f5487b4bed2302ee8c784c395c7..ae31a5826e918ec58fc1948df0f9998664b7064f 100644 (file)
        };
 
        memory {
-               reg = <0x00000000 0x10000000>;
+               reg = <0x80000000 0x10000000>;
        };
 };
 
 &uart0 {
-       clock-frequency = <62499840>;
+       status = "okay";
 };
 
 &uart1 {
-       clock-frequency = <62499840>;
        status = "okay";
 };
index 3f04a40eb90cc904afb27fb71603270a8d8e1bea..df05e7f568af3e36bb2aa703d39fdbec37a6cece 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index 9fd542200d3d52229e1a0651330a5ef48b2ee8a9..4a3ab19c62819fb8c57d9ccf406100b64b15c598 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index 41e7fd350fcd1bbf6c36008c5f1e1c179679ffe0..81f78435d8c76cca38cb777d86e139c7d3751151 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 31 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index 477c4860db52236fa12a70aef2235c302f4a2a45..c88b8fefcb2f13e3c9bd98321948c8988d8e428d 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index c0a499d5ba447d5503d6655541461dddb9f35317..d503fa0dde310ff7597aeb7d3bfc757bcca32291 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index f7eb5854a224486adbe98a33da6a4ae59b17a90a..cc0363b843c1a0ae777efa40a6f2e25b34cf1f4c 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index 16666324fda8b5b901af538423ad302d13b9f98d..74e15a3cd9f8efb6a65238054824ba7e22df0bc2 100644 (file)
@@ -55,6 +55,7 @@
        gpio-restart {
                compatible = "gpio-restart";
                gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
+               open-source;
                priority = <200>;
        };
 };
index 49f466fe0b1dc2eecdaca3e6638dd80a12029bcd..dcfc9759143375decd12bea87ad5e7547837f3bd 100644 (file)
        };
 };
 
-&cpu0 {
-       arm-supply = <&sw1a_reg>;
-       soc-supply = <&sw1c_reg>;
-};
-
 &fec1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet1>;
index 22332be7214032fd3ba710def036168f3f9c2b3c..528b4e9c6d3d30928d363ffc6cf1d8d2275a8ce7 100644 (file)
                };
 
                usb1: ohci@00400000 {
-                       compatible = "atmel,sama5d2-ohci", "usb-ohci";
+                       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
                        reg = <0x00400000 0x100000>;
                        interrupts = <41 IRQ_TYPE_LEVEL_HIGH 2>;
                        clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
index 82d8c477129359952b0ae499a2fdefca9393bdf4..162e1eb5373d3475fa785639223dd80750d5ca42 100644 (file)
@@ -14,6 +14,7 @@
 #include <dt-bindings/mfd/dbx500-prcmu.h>
 #include <dt-bindings/arm/ux500_pm_domains.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/ste-ab8500.h>
 #include "skeleton.dtsi"
 
 / {
                                interrupt-controller;
                                #interrupt-cells = <2>;
 
+                               ab8500_clock: clock-controller {
+                                       compatible = "stericsson,ab8500-clk";
+                                       #clock-cells = <1>;
+                               };
+
                                ab8500_gpio: ab8500-gpio {
                                        compatible = "stericsson,ab8500-gpio";
                                        gpio-controller;
 
                                ab8500-pwm {
                                        compatible = "stericsson,ab8500-pwm";
+                                       clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
+                                       clock-names = "intclk";
                                };
 
                                ab8500-debugfs {
                                        V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
                                        V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
 
+                                       clocks = <&ab8500_clock AB8500_SYSCLK_AUDIO>;
+                                       clock-names = "audioclk";
+
                                        stericsson,earpeice-cmv = <950>; /* Units in mV. */
                                };
 
                        status = "disabled";
                };
 
+               sound {
+                       compatible = "stericsson,snd-soc-mop500";
+                       stericsson,cpu-dai = <&msp1 &msp3>;
+                       stericsson,audio-codec = <&codec>;
+                       clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
+                       clock-names = "sysclk", "ulpclk", "intclk";
+               };
+
                msp0: msp@80123000 {
                        compatible = "stericsson,ux500-msp-i2s";
                        reg = <0x80123000 0x1000>;
index f37f9e10713cc878ce9ee0393aa4b0c6ad239adf..9e359e4f342e76ebd1fbfab57d1f8f427ece2cd7 100644 (file)
                        status = "okay";
                };
 
-               sound {
-                       compatible = "stericsson,snd-soc-mop500";
-
-                       stericsson,cpu-dai = <&msp1 &msp3>;
-                       stericsson,audio-codec = <&codec>;
-                       clocks = <&prcmu_clk PRCMU_SYSCLK>;
-                       clock-names = "sysclk";
-               };
-
                msp0: msp@80123000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&msp0_default_mode>;
index dd5514def6042470aabea1ee29853d6c713c2691..ade1d0d4e5f45c595f079c251c8b93dbe95742df 100644 (file)
                                     "", "", "", "", "", "", "", "";
                };
 
-               sound {
-                       compatible = "stericsson,snd-soc-mop500";
-
-                       stericsson,cpu-dai = <&msp1 &msp3>;
-                       stericsson,audio-codec = <&codec>;
-                       clocks = <&prcmu_clk PRCMU_SYSCLK>;
-                       clock-names = "sysclk";
-               };
-
                msp0: msp@80123000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&msp0_default_mode>;
index 72ec0d5ae052cda33bc05a0086cd7e34a684184c..bbf1c8cbaac6aa19a6acd946a0230220e4e11417 100644 (file)
                                        reg = <8>;
                                        label = "cpu";
                                        ethernet = <&gmac>;
-                                       phy-mode = "rgmii";
+                                       phy-mode = "rgmii-txid";
                                        fixed-link {
                                                speed = <1000>;
                                                full-duplex;
index a952cc0703cc172b3a50ab334b1eec6b44a93df8..8a3ed21cb7bcfcf4785784bcb66d10aafd2081e7 100644 (file)
                        resets = <&ccu RST_BUS_GPU>;
 
                        assigned-clocks = <&ccu CLK_GPU>;
-                       assigned-clock-rates = <408000000>;
+                       assigned-clock-rates = <384000000>;
                };
 
                gic: interrupt-controller@01c81000 {
index 18c174fef84f512c18145e795276af099d8de07b..0467fb365bfca714b5ce9021974470002139039f 100644 (file)
                simple-audio-card,mclk-fs = <512>;
                simple-audio-card,aux-devs = <&codec_analog>;
                simple-audio-card,routing =
-                       "Left DAC", "Digital Left DAC",
-                       "Right DAC", "Digital Right DAC";
+                       "Left DAC", "AIF1 Slot 0 Left",
+                       "Right DAC", "AIF1 Slot 0 Right";
                status = "disabled";
 
                simple-audio-card,cpu {
index 7097c18ff487d4851ca5d76d73e018b75aed7cb2..d6bd15898db6d6cc880fe0abb4999712450dc50e 100644 (file)
@@ -50,8 +50,6 @@
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_en_pin>;
                pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
                brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
                default-brightness-level = <8>;
 };
 
 &pio {
-       bl_en_pin: bl_en_pin@0 {
-               pins = "PH6";
-               function = "gpio_in";
-       };
-
        mmc0_cd_pin: mmc0_cd_pin@0 {
                pins = "PB4";
                function = "gpio_in";
index f2462a6bdba6e7fcfc8c04815dd763bdcd5b3069..decd388d613d7e1d65c5d194f77fb23061ed37e0 100644 (file)
@@ -188,6 +188,7 @@ CONFIG_WL12XX=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SPI=m
 CONFIG_WLCORE_SDIO=m
+CONFIG_INPUT_MOUSEDEV=m
 CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=m
 CONFIG_KEYBOARD_ATKBD=m
index 3d89b7905bd903687b481fccab7249382c2428c6..a277981f414d8dd9433569c529068f206daab81f 100644 (file)
@@ -289,6 +289,22 @@ static void at91_ddr_standby(void)
                at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
+static void sama5d3_ddr_standby(void)
+{
+       u32 lpr0;
+       u32 saved_lpr0;
+
+       saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+       lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
+       lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN;
+
+       at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
+
+       cpu_do_idle();
+
+       at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
+}
+
 /* We manage both DDRAM/SDRAM controllers, we need more than one value to
  * remember.
  */
@@ -323,7 +339,7 @@ static const struct of_device_id const ramc_ids[] __initconst = {
        { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
        { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
        { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
-       { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
+       { .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
        { /*sentinel*/ }
 };
 
index 093458b62c8dadbcc3c7cc1c3b66d84e59af3d8d..c89757abb0ae4bc82adf923a5947f2c0fbefb42c 100644 (file)
@@ -241,6 +241,3 @@ obj-$(CONFIG_MACH_OMAP2_TUSB6010)   += usb-tusb6010.o
 
 onenand-$(CONFIG_MTD_ONENAND_OMAP2)    := gpmc-onenand.o
 obj-y                                  += $(onenand-m) $(onenand-y)
-
-nand-$(CONFIG_MTD_NAND_OMAP2)          := gpmc-nand.o
-obj-y                                  += $(nand-m) $(nand-y)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
deleted file mode 100644 (file)
index f6ac027..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * gpmc-nand.c
- *
- * Copyright (C) 2009 Texas Instruments
- * Vimal Singh <vimalsingh@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/omap-gpmc.h>
-#include <linux/mtd/nand.h>
-#include <linux/platform_data/mtd-nand-omap2.h>
-
-#include <asm/mach/flash.h>
-
-#include "soc.h"
-
-/* minimum size for IO mapping */
-#define        NAND_IO_SIZE    4
-
-static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
-{
-       /* platforms which support all ECC schemes */
-       if (soc_is_am33xx() || soc_is_am43xx() || cpu_is_omap44xx() ||
-                soc_is_omap54xx() || soc_is_dra7xx())
-               return 1;
-
-       if (ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW ||
-                ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) {
-               if (cpu_is_omap24xx())
-                       return 0;
-               else if (cpu_is_omap3630() && (GET_OMAP_REVISION() == 0))
-                       return 0;
-               else
-                       return 1;
-       }
-
-       /* OMAP3xxx do not have ELM engine, so cannot support ECC schemes
-        * which require H/W based ECC error detection */
-       if ((cpu_is_omap34xx() || cpu_is_omap3630()) &&
-           ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-                (ecc_opt == OMAP_ECC_BCH8_CODE_HW)))
-               return 0;
-
-       /* legacy platforms support only HAM1 (1-bit Hamming) ECC scheme */
-       if (ecc_opt == OMAP_ECC_HAM1_CODE_HW ||
-           ecc_opt == OMAP_ECC_HAM1_CODE_SW)
-               return 1;
-       else
-               return 0;
-}
-
-/* This function will go away once the device-tree convertion is complete */
-static void gpmc_set_legacy(struct omap_nand_platform_data *gpmc_nand_data,
-                           struct gpmc_settings *s)
-{
-       /* Enable RD PIN Monitoring Reg */
-       if (gpmc_nand_data->dev_ready) {
-               s->wait_on_read = true;
-               s->wait_on_write = true;
-       }
-
-       if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
-               s->device_width = GPMC_DEVWIDTH_16BIT;
-       else
-               s->device_width = GPMC_DEVWIDTH_8BIT;
-}
-
-int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
-                  struct gpmc_timings *gpmc_t)
-{
-       int err = 0;
-       struct gpmc_settings s;
-       struct platform_device *pdev;
-       struct resource gpmc_nand_res[] = {
-               { .flags = IORESOURCE_MEM, },
-               { .flags = IORESOURCE_IRQ, },
-               { .flags = IORESOURCE_IRQ, },
-       };
-
-       BUG_ON(gpmc_nand_data->cs >= GPMC_CS_NUM);
-
-       err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
-                             (unsigned long *)&gpmc_nand_res[0].start);
-       if (err < 0) {
-               pr_err("omap2-gpmc: Cannot request GPMC CS %d, error %d\n",
-                      gpmc_nand_data->cs, err);
-               return err;
-       }
-       gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
-       gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
-       gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
-
-       memset(&s, 0, sizeof(struct gpmc_settings));
-       gpmc_set_legacy(gpmc_nand_data, &s);
-
-       s.device_nand = true;
-
-       if (gpmc_t) {
-               err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t, &s);
-               if (err < 0) {
-                       pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n",
-                              err);
-                       return err;
-               }
-       }
-
-       err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
-       if (err < 0)
-               goto out_free_cs;
-
-       err = gpmc_configure(GPMC_CONFIG_WP, 0);
-       if (err < 0)
-               goto out_free_cs;
-
-       if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
-               pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
-               err = -EINVAL;
-               goto out_free_cs;
-       }
-
-
-       pdev = platform_device_alloc("omap2-nand", gpmc_nand_data->cs);
-       if (pdev) {
-               err = platform_device_add_resources(pdev, gpmc_nand_res,
-                                                   ARRAY_SIZE(gpmc_nand_res));
-               if (!err)
-                       pdev->dev.platform_data = gpmc_nand_data;
-       } else {
-               err = -ENOMEM;
-       }
-       if (err)
-               goto out_free_pdev;
-
-       err = platform_device_add(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "Unable to register NAND device\n");
-               goto out_free_pdev;
-       }
-
-       return 0;
-
-out_free_pdev:
-       platform_device_put(pdev);
-out_free_cs:
-       gpmc_cs_free(gpmc_nand_data->cs);
-
-       return err;
-}
index 8633c703546a65c2e5b0071ffca0d5a12b664884..2944af82055847935462da4035a73b513c5795a6 100644 (file)
@@ -367,7 +367,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
        return ret;
 }
 
-void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
 {
        int err;
        struct device *dev = &gpmc_onenand_device.dev;
@@ -393,15 +393,17 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
        if (err < 0) {
                dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
                        gpmc_onenand_data->cs, err);
-               return;
+               return err;
        }
 
        gpmc_onenand_resource.end = gpmc_onenand_resource.start +
                                                        ONENAND_IO_SIZE - 1;
 
-       if (platform_device_register(&gpmc_onenand_device) < 0) {
+       err = platform_device_register(&gpmc_onenand_device);
+       if (err) {
                dev_err(dev, "Unable to register OneNAND device\n");
                gpmc_cs_free(gpmc_onenand_data->cs);
-               return;
        }
+
+       return err;
 }
index fe36ce2734d47a81f8dd5cbfdf72e9f6717df903..4c6f14cf92a82e3dbf8d7ceeb985686feb79e924 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/assembler.h>
 
 #include "omap44xx.h"
 
@@ -66,7 +67,7 @@ wait_2:       ldr     r2, =AUX_CORE_BOOT0_PA  @ read from AuxCoreBoot0
        cmp     r0, r4
        bne     wait_2
        ldr     r12, =API_HYP_ENTRY
-       adr     r0, hyp_boot
+       badr    r0, hyp_boot
        smc     #0
 hyp_boot:
        b       omap_secondary_startup
index 56f917ec8621e8d5d4a9410975ec454aa802414a..1435fee39a89ba18239291859c97f0f333ca877f 100644 (file)
@@ -2112,11 +2112,20 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
 };
 
 /* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
+       {
+               .pa_start       = OMAP34XX_SR1_BASE,
+               .pa_end         = OMAP34XX_SR1_BASE + SZ_1K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { },
+};
 
 static struct omap_hwmod_ocp_if omap34xx_l4_core__sr1 = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap34xx_sr1_hwmod,
        .clk            = "sr_l4_ick",
+       .addr           = omap3_sr1_addr_space,
        .user           = OCP_USER_MPU,
 };
 
@@ -2124,15 +2133,25 @@ static struct omap_hwmod_ocp_if omap36xx_l4_core__sr1 = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap36xx_sr1_hwmod,
        .clk            = "sr_l4_ick",
+       .addr           = omap3_sr1_addr_space,
        .user           = OCP_USER_MPU,
 };
 
 /* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = {
+       {
+               .pa_start       = OMAP34XX_SR2_BASE,
+               .pa_end         = OMAP34XX_SR2_BASE + SZ_1K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { },
+};
 
 static struct omap_hwmod_ocp_if omap34xx_l4_core__sr2 = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap34xx_sr2_hwmod,
        .clk            = "sr_l4_ick",
+       .addr           = omap3_sr2_addr_space,
        .user           = OCP_USER_MPU,
 };
 
@@ -2140,6 +2159,7 @@ static struct omap_hwmod_ocp_if omap36xx_l4_core__sr2 = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap36xx_sr2_hwmod,
        .clk            = "sr_l4_ick",
+       .addr           = omap3_sr2_addr_space,
        .user           = OCP_USER_MPU,
 };
 
@@ -3111,16 +3131,20 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = {
  * Return: 0 if device named @dev_name is not likely to be accessible,
  * or 1 if it is likely to be accessible.
  */
-static int __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus,
-                                                      const char *dev_name)
+static bool __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus,
+                                                       const char *dev_name)
 {
+       struct device_node *node;
+       bool available;
+
        if (!bus)
-               return (omap_type() == OMAP2_DEVICE_TYPE_GP) ? 1 : 0;
+               return omap_type() == OMAP2_DEVICE_TYPE_GP;
 
-       if (of_device_is_available(of_find_node_by_name(bus, dev_name)))
-               return 1;
+       node = of_get_child_by_name(bus, dev_name);
+       available = of_device_is_available(node);
+       of_node_put(node);
 
-       return 0;
+       return available;
 }
 
 int __init omap3xxx_hwmod_init(void)
@@ -3189,15 +3213,20 @@ int __init omap3xxx_hwmod_init(void)
 
        if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
                r = omap_hwmod_register_links(h_sham);
-               if (r < 0)
+               if (r < 0) {
+                       of_node_put(bus);
                        return r;
+               }
        }
 
        if (h_aes && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "aes")) {
                r = omap_hwmod_register_links(h_aes);
-               if (r < 0)
+               if (r < 0) {
+                       of_node_put(bus);
                        return r;
+               }
        }
+       of_node_put(bus);
 
        /*
         * Register hwmod links specific to certain ES levels of a
index 9f9e203c09c5ad362ae00d5038d2e52c91043f39..bcb03fc3266552e22ce855ac81677584d0937e63 100644 (file)
        pcie0: pcie@20020000 {
                compatible = "brcm,iproc-pcie";
                reg = <0 0x20020000 0 0x1000>;
+               dma-coherent;
 
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 0 0>;
        pcie4: pcie@50020000 {
                compatible = "brcm,iproc-pcie";
                reg = <0 0x50020000 0 0x1000>;
+               dma-coherent;
 
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 0 0>;
        pcie8: pcie@60c00000 {
                compatible = "brcm,iproc-pcie-paxc";
                reg = <0 0x60c00000 0 0x1000>;
+               dma-coherent;
                linux,pci-domain = <8>;
 
                bus-range = <0x0 0x1>;
                              <0x61030000 0x100>;
                        reg-names = "amac_base", "idm_base", "nicpm_base";
                        interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+                       dma-coherent;
                        phy-handle = <&gphy0>;
                        phy-mode = "rgmii";
                        status = "disabled";
                        reg = <0x612c0000 0x445>;  /* PDC FS0 regs */
                        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
                        #mbox-cells = <1>;
+                       dma-coherent;
                        brcm,rx-status-len = <32>;
                        brcm,use-bcm-hdr;
                };
                        reg = <0x612e0000 0x445>;  /* PDC FS1 regs */
                        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
                        #mbox-cells = <1>;
+                       dma-coherent;
                        brcm,rx-status-len = <32>;
                        brcm,use-bcm-hdr;
                };
                        reg = <0x61300000 0x445>;  /* PDC FS2 regs */
                        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
                        #mbox-cells = <1>;
+                       dma-coherent;
                        brcm,rx-status-len = <32>;
                        brcm,use-bcm-hdr;
                };
                        reg = <0x61320000 0x445>;  /* PDC FS3 regs */
                        interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
                        #mbox-cells = <1>;
+                       dma-coherent;
                        brcm,rx-status-len = <32>;
                        brcm,use-bcm-hdr;
                };
                sata: ahci@663f2000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
                        reg = <0x663f2000 0x1000>;
+                       dma-coherent;
                        reg-names = "ahci";
                        interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        compatible = "brcm,sdhci-iproc-cygnus";
                        reg = <0x66420000 0x100>;
                        interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>;
+                       dma-coherent;
                        bus-width = <8>;
                        clocks = <&genpll_sw BCM_NS2_GENPLL_SW_SDIO_CLK>;
                        status = "disabled";
                        compatible = "brcm,sdhci-iproc-cygnus";
                        reg = <0x66430000 0x100>;
                        interrupts = <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
+                       dma-coherent;
                        bus-width = <8>;
                        clocks = <&genpll_sw BCM_NS2_GENPLL_SW_SDIO_CLK>;
                        status = "disabled";
index 86c404171305abd290a6a85d7a5edd69c55ecd02..f6580d4afb0e0c4e242e5171ecda679d927286d2 100644 (file)
@@ -3,8 +3,6 @@
 
 #include <linux/compiler.h>
 
-#include <asm/sysreg.h>
-
 #ifndef __ASSEMBLY__
 
 struct task_struct;
index e78ac26324bd809dcd5fa2f7f45465daba8c158d..bdbeb06dc11ede112de28b09c7608b3d5b0ce23b 100644 (file)
@@ -44,7 +44,7 @@
 #define __ARM_NR_compat_cacheflush     (__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls                (__ARM_NR_COMPAT_BASE+5)
 
-#define __NR_compat_syscalls           394
+#define __NR_compat_syscalls           398
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
index b7e8ef16ff0dc62b94a042e4a0b70c9884e4cb16..c66b51aab1958816e6d137e9ae9dc0dc0378cf7f 100644 (file)
@@ -809,6 +809,14 @@ __SYSCALL(__NR_copy_file_range, sys_copy_file_range)
 __SYSCALL(__NR_preadv2, compat_sys_preadv2)
 #define __NR_pwritev2 393
 __SYSCALL(__NR_pwritev2, compat_sys_pwritev2)
+#define __NR_pkey_mprotect 394
+__SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect)
+#define __NR_pkey_alloc 395
+__SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
+#define __NR_pkey_free 396
+__SYSCALL(__NR_pkey_free, sys_pkey_free)
+#define __NR_statx 397
+__SYSCALL(__NR_statx, sys_statx)
 
 /*
  * Please add new compat syscalls above this comment and update
index 769f24ef628c1e9ffd167e0b0e634151cf36de3d..d7e90d97f5c405f2c348eaaff331df818b27906a 100644 (file)
@@ -131,11 +131,15 @@ u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
        /*
         * The kernel Image should not extend across a 1GB/32MB/512MB alignment
         * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
-        * happens, increase the KASLR offset by the size of the kernel image.
+        * happens, increase the KASLR offset by the size of the kernel image
+        * rounded up by SWAPPER_BLOCK_SIZE.
         */
        if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) !=
-           (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT))
-               offset = (offset + (u64)(_end - _text)) & mask;
+           (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) {
+               u64 kimg_sz = _end - _text;
+               offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE))
+                               & mask;
+       }
 
        if (IS_ENABLED(CONFIG_KASAN))
                /*
index ef1caae02110eef59c4abb5dd5cbb8051d9cc269..9b1036570586f95379f035b8606220144cdc7837 100644 (file)
@@ -944,7 +944,7 @@ static bool have_cpu_die(void)
 #ifdef CONFIG_HOTPLUG_CPU
        int any_cpu = raw_smp_processor_id();
 
-       if (cpu_ops[any_cpu]->cpu_die)
+       if (cpu_ops[any_cpu] && cpu_ops[any_cpu]->cpu_die)
                return true;
 #endif
        return false;
index b8cc94e9698b69f17f7d127d2663a21f64e5e2eb..f8b69d84238eb4f7743c23b425e1a4900cb9cd7f 100644 (file)
@@ -1,2 +1 @@
 vdso.lds
-vdso-offsets.h
index a27e1f02ce182d0e6805057bc9390e67df5e751c..8801dc98fd442a85cd09113ce6794040ac2e22dd 100644 (file)
@@ -70,46 +70,6 @@ static int gpr_get(struct task_struct *target,
                                   0, sizeof(*regs));
 }
 
-static int gpr_set(struct task_struct *target,
-                  const struct user_regset *regset,
-                  unsigned int pos, unsigned int count,
-                  const void *kbuf, const void __user *ubuf)
-{
-       int ret;
-       struct pt_regs *regs = task_pt_regs(target);
-
-       /* Don't copyin TSR or CSR */
-       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &regs,
-                                0, PT_TSR * sizeof(long));
-       if (ret)
-               return ret;
-
-       ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
-                                       PT_TSR * sizeof(long),
-                                       (PT_TSR + 1) * sizeof(long));
-       if (ret)
-               return ret;
-
-       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &regs,
-                                (PT_TSR + 1) * sizeof(long),
-                                PT_CSR * sizeof(long));
-       if (ret)
-               return ret;
-
-       ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
-                                       PT_CSR * sizeof(long),
-                                       (PT_CSR + 1) * sizeof(long));
-       if (ret)
-               return ret;
-
-       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &regs,
-                                (PT_CSR + 1) * sizeof(long), -1);
-       return ret;
-}
-
 enum c6x_regset {
        REGSET_GPR,
 };
@@ -121,7 +81,6 @@ static const struct user_regset c6x_regsets[] = {
                .size = sizeof(u32),
                .align = sizeof(u32),
                .get = gpr_get,
-               .set = gpr_set
        },
 };
 
index 92075544a19ac03fae02b3efc28a986b0748ec1c..0dc1c8f622bc3fda818d5703896e99be485762ea 100644 (file)
@@ -95,7 +95,8 @@ static int regs_get(struct task_struct *target,
        long *reg = (long *)&regs;
 
        /* build user regs in buffer */
-       for (r = 0; r < ARRAY_SIZE(register_offset); r++)
+       BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0);
+       for (r = 0; r < sizeof(regs) / sizeof(long); r++)
                *reg++ = h8300_get_reg(target, r);
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
@@ -113,7 +114,8 @@ static int regs_set(struct task_struct *target,
        long *reg;
 
        /* build user regs in buffer */
-       for (reg = (long *)&regs, r = 0; r < ARRAY_SIZE(register_offset); r++)
+       BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0);
+       for (reg = (long *)&regs, r = 0; r < sizeof(regs) / sizeof(long); r++)
                *reg++ = h8300_get_reg(target, r);
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
@@ -122,7 +124,7 @@ static int regs_set(struct task_struct *target,
                return ret;
 
        /* write back to pt_regs */
-       for (reg = (long *)&regs, r = 0; r < ARRAY_SIZE(register_offset); r++)
+       for (reg = (long *)&regs, r = 0; r < sizeof(regs) / sizeof(long); r++)
                h8300_put_reg(target, r, *reg++);
        return 0;
 }
index 048bf076f7df66a35fd4d11addd015e9ec285fc9..531cb9eb3319f4251bb6f4cf603b2a4bf90b7e80 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68020=y
@@ -60,6 +61,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -71,6 +73,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -101,6 +104,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -298,6 +302,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -371,6 +377,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -383,6 +390,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_A2065=y
 CONFIG_ARIADNE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -404,7 +412,6 @@ CONFIG_ZORRO8390=y
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_SMSC is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -564,6 +571,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -594,6 +603,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -605,6 +615,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -629,4 +640,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index d4de24963f5f7434e5fab612629c23149fc0389c..ca91d39555da2dad5eb6413dd1892d1a070fe172 100644 (file)
@@ -26,6 +26,7 @@ CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68020=y
@@ -58,6 +59,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -69,6 +71,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -99,6 +102,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -296,6 +300,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -353,6 +359,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -362,6 +369,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -378,7 +386,6 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -523,6 +530,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -553,6 +562,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -564,6 +574,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -588,4 +599,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index fc0fd3f871f3348233c720465d2707fd97c8d94f..23a3d8a691e2239478299856316fc9bac1261ccd 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68020=y
@@ -58,6 +59,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -69,6 +71,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -99,6 +102,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -296,6 +300,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -362,6 +368,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -372,6 +379,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_ATARILANCE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -389,7 +397,6 @@ CONFIG_NE2000=y
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 CONFIG_SMC91X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -544,6 +551,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -574,6 +583,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -585,6 +595,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -609,4 +620,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 52e984a0aa696a503f458f2dd853913a1f32a52b..95deb95140fe9273ef2f70f670182103e5f03399 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68040=y
@@ -56,6 +57,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -67,6 +69,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -97,6 +100,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -294,6 +298,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -352,6 +358,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -361,6 +368,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -377,7 +385,6 @@ CONFIG_BVME6000_NET=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -515,6 +522,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -545,6 +554,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -556,6 +566,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -580,4 +591,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index aaeed4422cc97525600537135669e9da3f865b3e..afae6958db2d777591527d1d59dc3bd686f64772 100644 (file)
@@ -26,6 +26,7 @@ CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68020=y
@@ -58,6 +59,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -69,6 +71,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -99,6 +102,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -296,6 +300,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -353,6 +359,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -363,6 +370,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_HPLANCE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -379,7 +387,6 @@ CONFIG_HPLANCE=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -525,6 +532,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -555,6 +564,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -566,6 +576,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -590,4 +601,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 3bbc9b2f0dac0fb890183d11d369655fdfd68201..b010734729a79e42b599c26919542faf4fbce31d 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68020=y
@@ -57,6 +58,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -68,6 +70,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -98,6 +101,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -298,6 +302,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -369,6 +375,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -379,6 +386,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_MACMACE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -398,7 +406,6 @@ CONFIG_MAC8390=y
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_SMSC is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -547,6 +554,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -577,6 +586,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -588,6 +598,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -612,4 +623,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 8f2c0decb2f8edd8030ffc1df2eddad2bd70a939..0e414549b235b0a04e9ed3feaa3786542c862bb3 100644 (file)
@@ -21,6 +21,7 @@ CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68020=y
@@ -67,6 +68,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -78,6 +80,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -108,6 +111,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -308,6 +312,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -402,6 +408,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -419,6 +426,7 @@ CONFIG_HPLANCE=y
 CONFIG_MVME147_NET=y
 CONFIG_SUN3LANCE=y
 CONFIG_MACMACE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -444,7 +452,6 @@ CONFIG_ZORRO8390=y
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 CONFIG_SMC91X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PLIP=m
@@ -627,6 +634,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -657,6 +666,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -668,6 +678,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -692,4 +703,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index c743dd22e96f935f553a12648991546616a47291..b2e687a0ec3d477d2f8fbb50a7387e51a60fb5bc 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68030=y
@@ -55,6 +56,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -66,6 +68,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -96,6 +99,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -293,6 +297,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -351,6 +357,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -361,6 +368,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_MVME147_NET=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -377,7 +385,6 @@ CONFIG_MVME147_NET=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -515,6 +522,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -545,6 +554,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -556,6 +566,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -580,4 +591,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 2ccaca858f0533d79d7f4c6a52bf070f333eb8ce..cbd8ee24d1bc4e2f7c4f611df7cdd95c8b147e3b 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68040=y
@@ -56,6 +57,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -67,6 +69,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -97,6 +100,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -294,6 +298,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -352,6 +358,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -361,6 +368,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -377,7 +385,6 @@ CONFIG_MVME16x_NET=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -515,6 +522,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -545,6 +554,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -556,6 +566,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -580,4 +591,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 5599f3fd5fcd44eab2e52ac460b73376be5cc052..1e82cc9443399a2cd67febf8b7f3fda0682e1990 100644 (file)
@@ -26,6 +26,7 @@ CONFIG_SUN_PARTITION=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_M68040=y
@@ -56,6 +57,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -67,6 +69,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -97,6 +100,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -294,6 +298,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -358,6 +364,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -369,6 +376,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -388,7 +396,6 @@ CONFIG_NE2000=y
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_SMSC is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PLIP=m
@@ -538,6 +545,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -568,6 +577,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -579,6 +589,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -603,4 +614,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 313bf0a562ad33496735210197879fcf86739ea2..f9e77f57a9725035d9f75a30ae4c0941c229d5d7 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_SUN3=y
@@ -53,6 +54,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -64,6 +66,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -94,6 +97,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -291,6 +295,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -349,6 +355,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -359,6 +366,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_SUN3LANCE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_EZCHIP is not set
@@ -375,7 +383,6 @@ CONFIG_SUN3_82586=y
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_SUN is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -517,6 +524,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -546,6 +555,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -557,6 +567,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -581,4 +592,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index 38b61365f769273f829980fa9cec2d9cc585e1f5..3c394fcfb36836beba293194b23b91c4ca31f2aa 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
 # CONFIG_EFI_PARTITION is not set
 CONFIG_SYSV68_PARTITION=y
 CONFIG_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_DEADLINE=m
 CONFIG_KEXEC=y
 CONFIG_BOOTINFO_PROC=y
 CONFIG_SUN3X=y
@@ -53,6 +54,7 @@ CONFIG_NET_IPVTI=m
 CONFIG_NET_FOU_IP_TUNNELS=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
@@ -64,6 +66,7 @@ CONFIG_IPV6=m
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
 CONFIG_INET6_IPCOMP=m
 CONFIG_IPV6_ILA=m
 CONFIG_IPV6_VTI=m
@@ -94,6 +97,7 @@ CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_SET_RBTREE=m
 CONFIG_NFT_SET_HASH=m
+CONFIG_NFT_SET_BITMAP=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -291,6 +295,8 @@ CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_PSAMPLE=m
+CONFIG_NET_IFE=m
 CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
@@ -349,6 +355,7 @@ CONFIG_NET_TEAM_MODE_LOADBALANCE=m
 CONFIG_MACVLAN=m
 CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
 CONFIG_GTP=m
@@ -359,6 +366,7 @@ CONFIG_VETH=m
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_SUN3LANCE=y
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -375,7 +383,6 @@ CONFIG_SUN3LANCE=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
@@ -517,6 +524,8 @@ CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_WW_MUTEX_SELFTEST=m
+CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
@@ -547,6 +556,7 @@ CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -558,6 +568,7 @@ CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -582,4 +593,5 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
index b4a9b0d5928dfb33c0c6dd5ef507305f35214fe7..dda58cfe8c22a3ec65ba074c4c0baab3c957340b 100644 (file)
@@ -148,7 +148,7 @@ static inline void bfchg_mem_change_bit(int nr, volatile unsigned long *vaddr)
 #define __change_bit(nr, vaddr)        change_bit(nr, vaddr)
 
 
-static inline int test_bit(int nr, const unsigned long *vaddr)
+static inline int test_bit(int nr, const volatile unsigned long *vaddr)
 {
        return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0;
 }
index a857d82ec5094abc30e353f25370365194a01194..aab1edd0d4bade511f2ea92230d3bd533a58ad34 100644 (file)
@@ -4,7 +4,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define NR_syscalls            379
+#define NR_syscalls            380
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
index 9fe674bf911fd2a4e61d7119f9b91ffbdddf44f5..25589f5b8669631d5cf2441d7fb405a97c5561f5 100644 (file)
 #define __NR_copy_file_range   376
 #define __NR_preadv2           377
 #define __NR_pwritev2          378
+#define __NR_statx             379
 
 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */
index d6fd6d9ced2474ab477b0becefbd5f695d256e96..8c9fcfafe0dd90ba5f67f860e7eafb351cb156ef 100644 (file)
@@ -399,3 +399,4 @@ ENTRY(sys_call_table)
        .long sys_copy_file_range
        .long sys_preadv2
        .long sys_pwritev2
+       .long sys_statx
index 5fd16ee5280c1aee8584d6fbc90d5bd74b4c1665..e615603a4b0ae95cb0731ce5e653a518763b7c92 100644 (file)
  * user_regset definitions.
  */
 
+static unsigned long user_txstatus(const struct pt_regs *regs)
+{
+       unsigned long data = (unsigned long)regs->ctx.Flags;
+
+       if (regs->ctx.SaveMask & TBICTX_CBUF_BIT)
+               data |= USER_GP_REGS_STATUS_CATCH_BIT;
+
+       return data;
+}
+
 int metag_gp_regs_copyout(const struct pt_regs *regs,
                          unsigned int pos, unsigned int count,
                          void *kbuf, void __user *ubuf)
@@ -64,9 +74,7 @@ int metag_gp_regs_copyout(const struct pt_regs *regs,
        if (ret)
                goto out;
        /* TXSTATUS */
-       data = (unsigned long)regs->ctx.Flags;
-       if (regs->ctx.SaveMask & TBICTX_CBUF_BIT)
-               data |= USER_GP_REGS_STATUS_CATCH_BIT;
+       data = user_txstatus(regs);
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  &data, 4*25, 4*26);
        if (ret)
@@ -121,6 +129,7 @@ int metag_gp_regs_copyin(struct pt_regs *regs,
        if (ret)
                goto out;
        /* TXSTATUS */
+       data = user_txstatus(regs);
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 &data, 4*25, 4*26);
        if (ret)
@@ -246,6 +255,8 @@ int metag_rp_state_copyin(struct pt_regs *regs,
        unsigned long long *ptr;
        int ret, i;
 
+       if (count < 4*13)
+               return -EINVAL;
        /* Read the entire pipeline before making any changes */
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 &rp, 0, 4*13);
@@ -305,7 +316,7 @@ static int metag_tls_set(struct task_struct *target,
                        const void *kbuf, const void __user *ubuf)
 {
        int ret;
-       void __user *tls;
+       void __user *tls = target->thread.tls_ptr;
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
        if (ret)
index 339601267265394d19e92deef167167375600e82..6931fe722a0b54dcfa5078c8686160018c1e6c64 100644 (file)
@@ -456,7 +456,8 @@ static int fpr_set(struct task_struct *target,
                                          &target->thread.fpu,
                                          0, sizeof(elf_fpregset_t));
 
-       for (i = 0; i < NUM_FPU_REGS; i++) {
+       BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
+       for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
                err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                         &fpr_val, i * sizeof(elf_fpreg_t),
                                         (i + 1) * sizeof(elf_fpreg_t));
index edfbf9d6a6dd76adae077d49d76a236d299bceda..8442727f28d2732eecb583d46bdcc88258a590dd 100644 (file)
@@ -64,6 +64,15 @@ struct exception_table_entry {
        ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \
        ".previous\n"
 
+/*
+ * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry
+ * (with lowest bit set) for which the fault handler in fixup_exception() will
+ * load -EFAULT into %r8 for a read or write fault, and zeroes the target
+ * register in case of a read fault in get_user().
+ */
+#define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\
+       ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1)
+
 /*
  * The page fault handler stores, in a per-cpu area, the following information
  * if a fixup routine is available.
@@ -91,7 +100,7 @@ struct exception_data {
 #define __get_user(x, ptr)                               \
 ({                                                       \
        register long __gu_err __asm__ ("r8") = 0;       \
-       register long __gu_val __asm__ ("r9") = 0;       \
+       register long __gu_val;                          \
                                                         \
        load_sr2();                                      \
        switch (sizeof(*(ptr))) {                        \
@@ -107,22 +116,23 @@ struct exception_data {
 })
 
 #define __get_user_asm(ldx, ptr)                        \
-       __asm__("\n1:\t" ldx "\t0(%%sr2,%2),%0\n\t"     \
-               ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_1)\
+       __asm__("1: " ldx " 0(%%sr2,%2),%0\n"           \
+               "9:\n"                                  \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
                : "=r"(__gu_val), "=r"(__gu_err)        \
-               : "r"(ptr), "1"(__gu_err)               \
-               : "r1");
+               : "r"(ptr), "1"(__gu_err));
 
 #if !defined(CONFIG_64BIT)
 
 #define __get_user_asm64(ptr)                          \
-       __asm__("\n1:\tldw 0(%%sr2,%2),%0"              \
-               "\n2:\tldw 4(%%sr2,%2),%R0\n\t"         \
-               ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_2)\
-               ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_get_user_skip_1)\
+       __asm__("   copy %%r0,%R0\n"                    \
+               "1: ldw 0(%%sr2,%2),%0\n"               \
+               "2: ldw 4(%%sr2,%2),%R0\n"              \
+               "9:\n"                                  \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
                : "=r"(__gu_val), "=r"(__gu_err)        \
-               : "r"(ptr), "1"(__gu_err)               \
-               : "r1");
+               : "r"(ptr), "1"(__gu_err));
 
 #endif /* !defined(CONFIG_64BIT) */
 
@@ -148,32 +158,31 @@ struct exception_data {
  * The "__put_user/kernel_asm()" macros tell gcc they read from memory
  * instead of writing. This is because they do not write to any memory
  * gcc knows about, so there are no aliasing issues. These macros must
- * also be aware that "fixup_put_user_skip_[12]" are executed in the
- * context of the fault, and any registers used there must be listed
- * as clobbers. In this case only "r1" is used by the current routines.
- * r8/r9 are already listed as err/val.
+ * also be aware that fixups are executed in the context of the fault,
+ * and any registers used there must be listed as clobbers.
+ * r8 is already listed as err.
  */
 
 #define __put_user_asm(stx, x, ptr)                         \
        __asm__ __volatile__ (                              \
-               "\n1:\t" stx "\t%2,0(%%sr2,%1)\n\t"         \
-               ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_1)\
+               "1: " stx " %2,0(%%sr2,%1)\n"               \
+               "9:\n"                                      \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b)     \
                : "=r"(__pu_err)                            \
-               : "r"(ptr), "r"(x), "0"(__pu_err)           \
-               : "r1")
+               : "r"(ptr), "r"(x), "0"(__pu_err))
 
 
 #if !defined(CONFIG_64BIT)
 
 #define __put_user_asm64(__val, ptr) do {                  \
        __asm__ __volatile__ (                              \
-               "\n1:\tstw %2,0(%%sr2,%1)"                  \
-               "\n2:\tstw %R2,4(%%sr2,%1)\n\t"             \
-               ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_2)\
-               ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_put_user_skip_1)\
+               "1: stw %2,0(%%sr2,%1)\n"                   \
+               "2: stw %R2,4(%%sr2,%1)\n"                  \
+               "9:\n"                                      \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b)     \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b)     \
                : "=r"(__pu_err)                            \
-               : "r"(ptr), "r"(__val), "0"(__pu_err) \
-               : "r1");                                    \
+               : "r"(ptr), "r"(__val), "0"(__pu_err));     \
 } while (0)
 
 #endif /* !defined(CONFIG_64BIT) */
index 7484b3d11e0dbf83e58de4b64b08079b4a346bd7..c6d6272a934f03823b655cf07b38e7bbc01ca12e 100644 (file)
@@ -47,16 +47,6 @@ EXPORT_SYMBOL(__cmpxchg_u64);
 EXPORT_SYMBOL(lclear_user);
 EXPORT_SYMBOL(lstrnlen_user);
 
-/* Global fixups - defined as int to avoid creation of function pointers */
-extern int fixup_get_user_skip_1;
-extern int fixup_get_user_skip_2;
-extern int fixup_put_user_skip_1;
-extern int fixup_put_user_skip_2;
-EXPORT_SYMBOL(fixup_get_user_skip_1);
-EXPORT_SYMBOL(fixup_get_user_skip_2);
-EXPORT_SYMBOL(fixup_put_user_skip_1);
-EXPORT_SYMBOL(fixup_put_user_skip_2);
-
 #ifndef CONFIG_64BIT
 /* Needed so insmod can set dp value */
 extern int $global$;
index b76f503eee4a83c14d7f8156f339952e521a26ed..4516a5b53f38ef651c038e4231effa00fd6db19d 100644 (file)
@@ -143,6 +143,8 @@ void machine_power_off(void)
        printk(KERN_EMERG "System shut down completed.\n"
               "Please power this system off now.");
 
+       /* prevent soft lockup/stalled CPU messages for endless loop. */
+       rcu_sysrq_start();
        for (;;);
 }
 
index 8fa92b8d839abb98efb59bb4ac7689a40aeaf602..f2dac4d73b1b309cb2fbc28b744f948be8a35d11 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for parisc-specific library files
 #
 
-lib-y  := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \
+lib-y  := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \
           ucmpdi2.o delay.o
 
 obj-y  := iomap.o
diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S
deleted file mode 100644 (file)
index a5b72f2..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Linux/PA-RISC Project (http://www.parisc-linux.org/)
- *
- *  Copyright (C) 2004  Randolph Chung <tausq@debian.org>
- *
- *    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, or (at your option)
- *    any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * Fixup routines for kernel exception handling.
- */
-#include <asm/asm-offsets.h>
-#include <asm/assembly.h>
-#include <asm/errno.h>
-#include <linux/linkage.h>
-
-#ifdef CONFIG_SMP
-       .macro  get_fault_ip t1 t2
-       loadgp
-       addil LT%__per_cpu_offset,%r27
-       LDREG RT%__per_cpu_offset(%r1),\t1
-       /* t2 = smp_processor_id() */
-       mfctl 30,\t2
-       ldw TI_CPU(\t2),\t2
-#ifdef CONFIG_64BIT
-       extrd,u \t2,63,32,\t2
-#endif
-       /* t2 = &__per_cpu_offset[smp_processor_id()]; */
-       LDREGX \t2(\t1),\t2 
-       addil LT%exception_data,%r27
-       LDREG RT%exception_data(%r1),\t1
-       /* t1 = this_cpu_ptr(&exception_data) */
-       add,l \t1,\t2,\t1
-       /* %r27 = t1->fault_gp - restore gp */
-       LDREG EXCDATA_GP(\t1), %r27
-       /* t1 = t1->fault_ip */
-       LDREG EXCDATA_IP(\t1), \t1
-       .endm
-#else
-       .macro  get_fault_ip t1 t2
-       loadgp
-       /* t1 = this_cpu_ptr(&exception_data) */
-       addil LT%exception_data,%r27
-       LDREG RT%exception_data(%r1),\t2
-       /* %r27 = t2->fault_gp - restore gp */
-       LDREG EXCDATA_GP(\t2), %r27
-       /* t1 = t2->fault_ip */
-       LDREG EXCDATA_IP(\t2), \t1
-       .endm
-#endif
-
-       .level LEVEL
-
-       .text
-       .section .fixup, "ax"
-
-       /* get_user() fixups, store -EFAULT in r8, and 0 in r9 */
-ENTRY_CFI(fixup_get_user_skip_1)
-       get_fault_ip %r1,%r8
-       ldo 4(%r1), %r1
-       ldi -EFAULT, %r8
-       bv %r0(%r1)
-       copy %r0, %r9
-ENDPROC_CFI(fixup_get_user_skip_1)
-
-ENTRY_CFI(fixup_get_user_skip_2)
-       get_fault_ip %r1,%r8
-       ldo 8(%r1), %r1
-       ldi -EFAULT, %r8
-       bv %r0(%r1)
-       copy %r0, %r9
-ENDPROC_CFI(fixup_get_user_skip_2)
-
-       /* put_user() fixups, store -EFAULT in r8 */
-ENTRY_CFI(fixup_put_user_skip_1)
-       get_fault_ip %r1,%r8
-       ldo 4(%r1), %r1
-       bv %r0(%r1)
-       ldi -EFAULT, %r8
-ENDPROC_CFI(fixup_put_user_skip_1)
-
-ENTRY_CFI(fixup_put_user_skip_2)
-       get_fault_ip %r1,%r8
-       ldo 8(%r1), %r1
-       bv %r0(%r1)
-       ldi -EFAULT, %r8
-ENDPROC_CFI(fixup_put_user_skip_2)
-
index 56845de6b5dfc9ba21aec0b4840ffec6fb41fac5..f01188c044ee83e41ba52162544464781056f262 100644 (file)
@@ -5,6 +5,8 @@
  *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
  *    Copyright (C) 2001 Matthieu Delahaye <delahaym at esiee.fr>
  *    Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2017 Helge Deller <deller@gmx.de>
+ *    Copyright (C) 2017 John David Anglin <dave.anglin@bell.net>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
@@ -132,4 +134,320 @@ ENDPROC_CFI(lstrnlen_user)
 
        .procend
 
+
+
+/*
+ * unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
+ *
+ * Inputs:
+ * - sr1 already contains space of source region
+ * - sr2 already contains space of destination region
+ *
+ * Returns:
+ * - number of bytes that could not be copied.
+ *   On success, this will be zero.
+ *
+ * This code is based on a C-implementation of a copy routine written by
+ * Randolph Chung, which in turn was derived from the glibc.
+ *
+ * Several strategies are tried to try to get the best performance for various
+ * conditions. In the optimal case, we copy by loops that copy 32- or 16-bytes
+ * at a time using general registers.  Unaligned copies are handled either by
+ * aligning the destination and then using shift-and-write method, or in a few
+ * cases by falling back to a byte-at-a-time copy.
+ *
+ * Testing with various alignments and buffer sizes shows that this code is
+ * often >10x faster than a simple byte-at-a-time copy, even for strangely
+ * aligned operands. It is interesting to note that the glibc version of memcpy
+ * (written in C) is actually quite fast already. This routine is able to beat
+ * it by 30-40% for aligned copies because of the loop unrolling, but in some
+ * cases the glibc version is still slightly faster. This lends more
+ * credibility that gcc can generate very good code as long as we are careful.
+ *
+ * Possible optimizations:
+ * - add cache prefetching
+ * - try not to use the post-increment address modifiers; they may create
+ *   additional interlocks. Assumption is that those were only efficient on old
+ *   machines (pre PA8000 processors)
+ */
+
+       dst = arg0
+       src = arg1
+       len = arg2
+       end = arg3
+       t1  = r19
+       t2  = r20
+       t3  = r21
+       t4  = r22
+       srcspc = sr1
+       dstspc = sr2
+
+       t0 = r1
+       a1 = t1
+       a2 = t2
+       a3 = t3
+       a0 = t4
+
+       save_src = ret0
+       save_dst = ret1
+       save_len = r31
+
+ENTRY_CFI(pa_memcpy)
+       .proc
+       .callinfo NO_CALLS
+       .entry
+
+       /* Last destination address */
+       add     dst,len,end
+
+       /* short copy with less than 16 bytes? */
+       cmpib,>>=,n 15,len,.Lbyte_loop
+
+       /* same alignment? */
+       xor     src,dst,t0
+       extru   t0,31,2,t1
+       cmpib,<>,n  0,t1,.Lunaligned_copy
+
+#ifdef CONFIG_64BIT
+       /* only do 64-bit copies if we can get aligned. */
+       extru   t0,31,3,t1
+       cmpib,<>,n  0,t1,.Lalign_loop32
+
+       /* loop until we are 64-bit aligned */
+.Lalign_loop64:
+       extru   dst,31,3,t1
+       cmpib,=,n       0,t1,.Lcopy_loop_16
+20:    ldb,ma  1(srcspc,src),t1
+21:    stb,ma  t1,1(dstspc,dst)
+       b       .Lalign_loop64
+       ldo     -1(len),len
+
+       ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
+
+       ldi     31,t0
+.Lcopy_loop_16:
+       cmpb,COND(>>=),n t0,len,.Lword_loop
+
+10:    ldd     0(srcspc,src),t1
+11:    ldd     8(srcspc,src),t2
+       ldo     16(src),src
+12:    std,ma  t1,8(dstspc,dst)
+13:    std,ma  t2,8(dstspc,dst)
+14:    ldd     0(srcspc,src),t1
+15:    ldd     8(srcspc,src),t2
+       ldo     16(src),src
+16:    std,ma  t1,8(dstspc,dst)
+17:    std,ma  t2,8(dstspc,dst)
+
+       ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(11b,.Lcopy16_fault)
+       ASM_EXCEPTIONTABLE_ENTRY(12b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(13b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(14b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(15b,.Lcopy16_fault)
+       ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
+
+       b       .Lcopy_loop_16
+       ldo     -32(len),len
+
+.Lword_loop:
+       cmpib,COND(>>=),n 3,len,.Lbyte_loop
+20:    ldw,ma  4(srcspc,src),t1
+21:    stw,ma  t1,4(dstspc,dst)
+       b       .Lword_loop
+       ldo     -4(len),len
+
+       ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
+
+#endif /* CONFIG_64BIT */
+
+       /* loop until we are 32-bit aligned */
+.Lalign_loop32:
+       extru   dst,31,2,t1
+       cmpib,=,n       0,t1,.Lcopy_loop_4
+20:    ldb,ma  1(srcspc,src),t1
+21:    stb,ma  t1,1(dstspc,dst)
+       b       .Lalign_loop32
+       ldo     -1(len),len
+
+       ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
+
+
+.Lcopy_loop_4:
+       cmpib,COND(>>=),n 15,len,.Lbyte_loop
+
+10:    ldw     0(srcspc,src),t1
+11:    ldw     4(srcspc,src),t2
+12:    stw,ma  t1,4(dstspc,dst)
+13:    stw,ma  t2,4(dstspc,dst)
+14:    ldw     8(srcspc,src),t1
+15:    ldw     12(srcspc,src),t2
+       ldo     16(src),src
+16:    stw,ma  t1,4(dstspc,dst)
+17:    stw,ma  t2,4(dstspc,dst)
+
+       ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(11b,.Lcopy8_fault)
+       ASM_EXCEPTIONTABLE_ENTRY(12b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(13b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(14b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(15b,.Lcopy8_fault)
+       ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
+
+       b       .Lcopy_loop_4
+       ldo     -16(len),len
+
+.Lbyte_loop:
+       cmpclr,COND(<>) len,%r0,%r0
+       b,n     .Lcopy_done
+20:    ldb     0(srcspc,src),t1
+       ldo     1(src),src
+21:    stb,ma  t1,1(dstspc,dst)
+       b       .Lbyte_loop
+       ldo     -1(len),len
+
+       ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
+
+.Lcopy_done:
+       bv      %r0(%r2)
+       sub     end,dst,ret0
+
+
+       /* src and dst are not aligned the same way. */
+       /* need to go the hard way */
+.Lunaligned_copy:
+       /* align until dst is 32bit-word-aligned */
+       extru   dst,31,2,t1
+       cmpib,COND(=),n 0,t1,.Lcopy_dstaligned
+20:    ldb     0(srcspc,src),t1
+       ldo     1(src),src
+21:    stb,ma  t1,1(dstspc,dst)
+       b       .Lunaligned_copy
+       ldo     -1(len),len
+
+       ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
+       ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
+
+.Lcopy_dstaligned:
+
+       /* store src, dst and len in safe place */
+       copy    src,save_src
+       copy    dst,save_dst
+       copy    len,save_len
+
+       /* len now needs give number of words to copy */
+       SHRREG  len,2,len
+
+       /*
+        * Copy from a not-aligned src to an aligned dst using shifts.
+        * Handles 4 words per loop.
+        */
+
+       depw,z src,28,2,t0
+       subi 32,t0,t0
+       mtsar t0
+       extru len,31,2,t0
+       cmpib,= 2,t0,.Lcase2
+       /* Make src aligned by rounding it down.  */
+       depi 0,31,2,src
+
+       cmpiclr,<> 3,t0,%r0
+       b,n .Lcase3
+       cmpiclr,<> 1,t0,%r0
+       b,n .Lcase1
+.Lcase0:
+       cmpb,= %r0,len,.Lcda_finish
+       nop
+
+1:     ldw,ma 4(srcspc,src), a3
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+1:     ldw,ma 4(srcspc,src), a0
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       b,n .Ldo3
+.Lcase1:
+1:     ldw,ma 4(srcspc,src), a2
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+1:     ldw,ma 4(srcspc,src), a3
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       ldo -1(len),len
+       cmpb,=,n %r0,len,.Ldo0
+.Ldo4:
+1:     ldw,ma 4(srcspc,src), a0
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       shrpw a2, a3, %sar, t0
+1:     stw,ma t0, 4(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
+.Ldo3:
+1:     ldw,ma 4(srcspc,src), a1
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       shrpw a3, a0, %sar, t0
+1:     stw,ma t0, 4(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
+.Ldo2:
+1:     ldw,ma 4(srcspc,src), a2
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       shrpw a0, a1, %sar, t0
+1:     stw,ma t0, 4(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
+.Ldo1:
+1:     ldw,ma 4(srcspc,src), a3
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       shrpw a1, a2, %sar, t0
+1:     stw,ma t0, 4(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
+       ldo -4(len),len
+       cmpb,<> %r0,len,.Ldo4
+       nop
+.Ldo0:
+       shrpw a2, a3, %sar, t0
+1:     stw,ma t0, 4(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
+
+.Lcda_rdfault:
+.Lcda_finish:
+       /* calculate new src, dst and len and jump to byte-copy loop */
+       sub     dst,save_dst,t0
+       add     save_src,t0,src
+       b       .Lbyte_loop
+       sub     save_len,t0,len
+
+.Lcase3:
+1:     ldw,ma 4(srcspc,src), a0
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+1:     ldw,ma 4(srcspc,src), a1
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       b .Ldo2
+       ldo 1(len),len
+.Lcase2:
+1:     ldw,ma 4(srcspc,src), a1
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+1:     ldw,ma 4(srcspc,src), a2
+       ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
+       b .Ldo1
+       ldo 2(len),len
+
+
+       /* fault exception fixup handlers: */
+#ifdef CONFIG_64BIT
+.Lcopy16_fault:
+10:    b       .Lcopy_done
+       std,ma  t1,8(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
+#endif
+
+.Lcopy8_fault:
+10:    b       .Lcopy_done
+       stw,ma  t1,4(dstspc,dst)
+       ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
+
+       .exit
+ENDPROC_CFI(pa_memcpy)
+       .procend
+
        .end
index f82ff10ed974117a59f8713eba4281350feb44aa..b3d47ec1d80a241db8781518026d5a95e26ddb24 100644 (file)
@@ -2,7 +2,7 @@
  *    Optimized memory copy routines.
  *
  *    Copyright (C) 2004 Randolph Chung <tausq@debian.org>
- *    Copyright (C) 2013 Helge Deller <deller@gmx.de>
+ *    Copyright (C) 2013-2017 Helge Deller <deller@gmx.de>
  *
  *    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
  *    Portions derived from the GNU C Library
  *    Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
  *
- * Several strategies are tried to try to get the best performance for various
- * conditions. In the optimal case, we copy 64-bytes in an unrolled loop using 
- * fp regs. This is followed by loops that copy 32- or 16-bytes at a time using
- * general registers.  Unaligned copies are handled either by aligning the 
- * destination and then using shift-and-write method, or in a few cases by 
- * falling back to a byte-at-a-time copy.
- *
- * I chose to implement this in C because it is easier to maintain and debug,
- * and in my experiments it appears that the C code generated by gcc (3.3/3.4
- * at the time of writing) is fairly optimal. Unfortunately some of the 
- * semantics of the copy routine (exception handling) is difficult to express
- * in C, so we have to play some tricks to get it to work.
- *
- * All the loads and stores are done via explicit asm() code in order to use
- * the right space registers. 
- * 
- * Testing with various alignments and buffer sizes shows that this code is 
- * often >10x faster than a simple byte-at-a-time copy, even for strangely
- * aligned operands. It is interesting to note that the glibc version
- * of memcpy (written in C) is actually quite fast already. This routine is 
- * able to beat it by 30-40% for aligned copies because of the loop unrolling, 
- * but in some cases the glibc version is still slightly faster. This lends 
- * more credibility that gcc can generate very good code as long as we are 
- * careful.
- *
- * TODO:
- * - cache prefetching needs more experimentation to get optimal settings
- * - try not to use the post-increment address modifiers; they create additional
- *   interlocks
- * - replace byte-copy loops with stybs sequences
  */
 
-#ifdef __KERNEL__
 #include <linux/module.h>
 #include <linux/compiler.h>
 #include <linux/uaccess.h>
-#define s_space "%%sr1"
-#define d_space "%%sr2"
-#else
-#include "memcpy.h"
-#define s_space "%%sr0"
-#define d_space "%%sr0"
-#define pa_memcpy new2_copy
-#endif
 
 DECLARE_PER_CPU(struct exception_data, exception_data);
 
-#define preserve_branch(label) do {                                    \
-       volatile int dummy = 0;                                         \
-       /* The following branch is never taken, it's just here to  */   \
-       /* prevent gcc from optimizing away our exception code. */      \
-       if (unlikely(dummy != dummy))                                   \
-               goto label;                                             \
-} while (0)
-
 #define get_user_space() (segment_eq(get_fs(), KERNEL_DS) ? 0 : mfsp(3))
 #define get_kernel_space() (0)
 
-#define MERGE(w0, sh_1, w1, sh_2)  ({                                  \
-       unsigned int _r;                                                \
-       asm volatile (                                                  \
-       "mtsar %3\n"                                                    \
-       "shrpw %1, %2, %%sar, %0\n"                                     \
-       : "=r"(_r)                                                      \
-       : "r"(w0), "r"(w1), "r"(sh_2)                                   \
-       );                                                              \
-       _r;                                                             \
-})
-#define THRESHOLD      16
-
-#ifdef DEBUG_MEMCPY
-#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __func__ ); printk(KERN_DEBUG fmt, ##args ); } while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-#define def_load_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e)    \
-       __asm__ __volatile__ (                          \
-       "1:\t" #_insn ",ma " #_sz "(" _s ",%1), %0\n\t" \
-       ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
-       : _tt(_t), "+r"(_a)                             \
-       :                                               \
-       : "r8")
-
-#define def_store_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e)   \
-       __asm__ __volatile__ (                          \
-       "1:\t" #_insn ",ma %1, " #_sz "(" _s ",%0)\n\t" \
-       ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
-       : "+r"(_a)                                      \
-       : _tt(_t)                                       \
-       : "r8")
-
-#define ldbma(_s, _a, _t, _e) def_load_ai_insn(ldbs,1,"=r",_s,_a,_t,_e)
-#define stbma(_s, _t, _a, _e) def_store_ai_insn(stbs,1,"r",_s,_a,_t,_e)
-#define ldwma(_s, _a, _t, _e) def_load_ai_insn(ldw,4,"=r",_s,_a,_t,_e)
-#define stwma(_s, _t, _a, _e) def_store_ai_insn(stw,4,"r",_s,_a,_t,_e)
-#define flddma(_s, _a, _t, _e) def_load_ai_insn(fldd,8,"=f",_s,_a,_t,_e)
-#define fstdma(_s, _t, _a, _e) def_store_ai_insn(fstd,8,"f",_s,_a,_t,_e)
-
-#define def_load_insn(_insn,_tt,_s,_o,_a,_t,_e)        \
-       __asm__ __volatile__ (                          \
-       "1:\t" #_insn " " #_o "(" _s ",%1), %0\n\t"     \
-       ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
-       : _tt(_t)                                       \
-       : "r"(_a)                                       \
-       : "r8")
-
-#define def_store_insn(_insn,_tt,_s,_t,_o,_a,_e)       \
-       __asm__ __volatile__ (                          \
-       "1:\t" #_insn " %0, " #_o "(" _s ",%1)\n\t"     \
-       ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
-       :                                               \
-       : _tt(_t), "r"(_a)                              \
-       : "r8")
-
-#define ldw(_s,_o,_a,_t,_e)    def_load_insn(ldw,"=r",_s,_o,_a,_t,_e)
-#define stw(_s,_t,_o,_a,_e)    def_store_insn(stw,"r",_s,_t,_o,_a,_e)
-
-#ifdef  CONFIG_PREFETCH
-static inline void prefetch_src(const void *addr)
-{
-       __asm__("ldw 0(" s_space ",%0), %%r0" : : "r" (addr));
-}
-
-static inline void prefetch_dst(const void *addr)
-{
-       __asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr));
-}
-#else
-#define prefetch_src(addr) do { } while(0)
-#define prefetch_dst(addr) do { } while(0)
-#endif
-
-#define PA_MEMCPY_OK           0
-#define PA_MEMCPY_LOAD_ERROR   1
-#define PA_MEMCPY_STORE_ERROR  2
-
-/* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words
- * per loop.  This code is derived from glibc. 
- */
-static noinline unsigned long copy_dstaligned(unsigned long dst,
-                                       unsigned long src, unsigned long len)
-{
-       /* gcc complains that a2 and a3 may be uninitialized, but actually
-        * they cannot be.  Initialize a2/a3 to shut gcc up.
-        */
-       register unsigned int a0, a1, a2 = 0, a3 = 0;
-       int sh_1, sh_2;
-
-       /* prefetch_src((const void *)src); */
-
-       /* Calculate how to shift a word read at the memory operation
-          aligned srcp to make it aligned for copy.  */
-       sh_1 = 8 * (src % sizeof(unsigned int));
-       sh_2 = 8 * sizeof(unsigned int) - sh_1;
-
-       /* Make src aligned by rounding it down.  */
-       src &= -sizeof(unsigned int);
-
-       switch (len % 4)
-       {
-               case 2:
-                       /* a1 = ((unsigned int *) src)[0];
-                          a2 = ((unsigned int *) src)[1]; */
-                       ldw(s_space, 0, src, a1, cda_ldw_exc);
-                       ldw(s_space, 4, src, a2, cda_ldw_exc);
-                       src -= 1 * sizeof(unsigned int);
-                       dst -= 3 * sizeof(unsigned int);
-                       len += 2;
-                       goto do1;
-               case 3:
-                       /* a0 = ((unsigned int *) src)[0];
-                          a1 = ((unsigned int *) src)[1]; */
-                       ldw(s_space, 0, src, a0, cda_ldw_exc);
-                       ldw(s_space, 4, src, a1, cda_ldw_exc);
-                       src -= 0 * sizeof(unsigned int);
-                       dst -= 2 * sizeof(unsigned int);
-                       len += 1;
-                       goto do2;
-               case 0:
-                       if (len == 0)
-                               return PA_MEMCPY_OK;
-                       /* a3 = ((unsigned int *) src)[0];
-                          a0 = ((unsigned int *) src)[1]; */
-                       ldw(s_space, 0, src, a3, cda_ldw_exc);
-                       ldw(s_space, 4, src, a0, cda_ldw_exc);
-                       src -=-1 * sizeof(unsigned int);
-                       dst -= 1 * sizeof(unsigned int);
-                       len += 0;
-                       goto do3;
-               case 1:
-                       /* a2 = ((unsigned int *) src)[0];
-                          a3 = ((unsigned int *) src)[1]; */
-                       ldw(s_space, 0, src, a2, cda_ldw_exc);
-                       ldw(s_space, 4, src, a3, cda_ldw_exc);
-                       src -=-2 * sizeof(unsigned int);
-                       dst -= 0 * sizeof(unsigned int);
-                       len -= 1;
-                       if (len == 0)
-                               goto do0;
-                       goto do4;                       /* No-op.  */
-       }
-
-       do
-       {
-               /* prefetch_src((const void *)(src + 4 * sizeof(unsigned int))); */
-do4:
-               /* a0 = ((unsigned int *) src)[0]; */
-               ldw(s_space, 0, src, a0, cda_ldw_exc);
-               /* ((unsigned int *) dst)[0] = MERGE (a2, sh_1, a3, sh_2); */
-               stw(d_space, MERGE (a2, sh_1, a3, sh_2), 0, dst, cda_stw_exc);
-do3:
-               /* a1 = ((unsigned int *) src)[1]; */
-               ldw(s_space, 4, src, a1, cda_ldw_exc);
-               /* ((unsigned int *) dst)[1] = MERGE (a3, sh_1, a0, sh_2); */
-               stw(d_space, MERGE (a3, sh_1, a0, sh_2), 4, dst, cda_stw_exc);
-do2:
-               /* a2 = ((unsigned int *) src)[2]; */
-               ldw(s_space, 8, src, a2, cda_ldw_exc);
-               /* ((unsigned int *) dst)[2] = MERGE (a0, sh_1, a1, sh_2); */
-               stw(d_space, MERGE (a0, sh_1, a1, sh_2), 8, dst, cda_stw_exc);
-do1:
-               /* a3 = ((unsigned int *) src)[3]; */
-               ldw(s_space, 12, src, a3, cda_ldw_exc);
-               /* ((unsigned int *) dst)[3] = MERGE (a1, sh_1, a2, sh_2); */
-               stw(d_space, MERGE (a1, sh_1, a2, sh_2), 12, dst, cda_stw_exc);
-
-               src += 4 * sizeof(unsigned int);
-               dst += 4 * sizeof(unsigned int);
-               len -= 4;
-       }
-       while (len != 0);
-
-do0:
-       /* ((unsigned int *) dst)[0] = MERGE (a2, sh_1, a3, sh_2); */
-       stw(d_space, MERGE (a2, sh_1, a3, sh_2), 0, dst, cda_stw_exc);
-
-       preserve_branch(handle_load_error);
-       preserve_branch(handle_store_error);
-
-       return PA_MEMCPY_OK;
-
-handle_load_error:
-       __asm__ __volatile__ ("cda_ldw_exc:\n");
-       return PA_MEMCPY_LOAD_ERROR;
-
-handle_store_error:
-       __asm__ __volatile__ ("cda_stw_exc:\n");
-       return PA_MEMCPY_STORE_ERROR;
-}
-
-
-/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR.
- * In case of an access fault the faulty address can be read from the per_cpu
- * exception data struct. */
-static noinline unsigned long pa_memcpy_internal(void *dstp, const void *srcp,
-                                       unsigned long len)
-{
-       register unsigned long src, dst, t1, t2, t3;
-       register unsigned char *pcs, *pcd;
-       register unsigned int *pws, *pwd;
-       register double *pds, *pdd;
-       unsigned long ret;
-
-       src = (unsigned long)srcp;
-       dst = (unsigned long)dstp;
-       pcs = (unsigned char *)srcp;
-       pcd = (unsigned char *)dstp;
-
-       /* prefetch_src((const void *)srcp); */
-
-       if (len < THRESHOLD)
-               goto byte_copy;
-
-       /* Check alignment */
-       t1 = (src ^ dst);
-       if (unlikely(t1 & (sizeof(double)-1)))
-               goto unaligned_copy;
-
-       /* src and dst have same alignment. */
-
-       /* Copy bytes till we are double-aligned. */
-       t2 = src & (sizeof(double) - 1);
-       if (unlikely(t2 != 0)) {
-               t2 = sizeof(double) - t2;
-               while (t2 && len) {
-                       /* *pcd++ = *pcs++; */
-                       ldbma(s_space, pcs, t3, pmc_load_exc);
-                       len--;
-                       stbma(d_space, t3, pcd, pmc_store_exc);
-                       t2--;
-               }
-       }
-
-       pds = (double *)pcs;
-       pdd = (double *)pcd;
-
-#if 0
-       /* Copy 8 doubles at a time */
-       while (len >= 8*sizeof(double)) {
-               register double r1, r2, r3, r4, r5, r6, r7, r8;
-               /* prefetch_src((char *)pds + L1_CACHE_BYTES); */
-               flddma(s_space, pds, r1, pmc_load_exc);
-               flddma(s_space, pds, r2, pmc_load_exc);
-               flddma(s_space, pds, r3, pmc_load_exc);
-               flddma(s_space, pds, r4, pmc_load_exc);
-               fstdma(d_space, r1, pdd, pmc_store_exc);
-               fstdma(d_space, r2, pdd, pmc_store_exc);
-               fstdma(d_space, r3, pdd, pmc_store_exc);
-               fstdma(d_space, r4, pdd, pmc_store_exc);
-
-#if 0
-               if (L1_CACHE_BYTES <= 32)
-                       prefetch_src((char *)pds + L1_CACHE_BYTES);
-#endif
-               flddma(s_space, pds, r5, pmc_load_exc);
-               flddma(s_space, pds, r6, pmc_load_exc);
-               flddma(s_space, pds, r7, pmc_load_exc);
-               flddma(s_space, pds, r8, pmc_load_exc);
-               fstdma(d_space, r5, pdd, pmc_store_exc);
-               fstdma(d_space, r6, pdd, pmc_store_exc);
-               fstdma(d_space, r7, pdd, pmc_store_exc);
-               fstdma(d_space, r8, pdd, pmc_store_exc);
-               len -= 8*sizeof(double);
-       }
-#endif
-
-       pws = (unsigned int *)pds;
-       pwd = (unsigned int *)pdd;
-
-word_copy:
-       while (len >= 8*sizeof(unsigned int)) {
-               register unsigned int r1,r2,r3,r4,r5,r6,r7,r8;
-               /* prefetch_src((char *)pws + L1_CACHE_BYTES); */
-               ldwma(s_space, pws, r1, pmc_load_exc);
-               ldwma(s_space, pws, r2, pmc_load_exc);
-               ldwma(s_space, pws, r3, pmc_load_exc);
-               ldwma(s_space, pws, r4, pmc_load_exc);
-               stwma(d_space, r1, pwd, pmc_store_exc);
-               stwma(d_space, r2, pwd, pmc_store_exc);
-               stwma(d_space, r3, pwd, pmc_store_exc);
-               stwma(d_space, r4, pwd, pmc_store_exc);
-
-               ldwma(s_space, pws, r5, pmc_load_exc);
-               ldwma(s_space, pws, r6, pmc_load_exc);
-               ldwma(s_space, pws, r7, pmc_load_exc);
-               ldwma(s_space, pws, r8, pmc_load_exc);
-               stwma(d_space, r5, pwd, pmc_store_exc);
-               stwma(d_space, r6, pwd, pmc_store_exc);
-               stwma(d_space, r7, pwd, pmc_store_exc);
-               stwma(d_space, r8, pwd, pmc_store_exc);
-               len -= 8*sizeof(unsigned int);
-       }
-
-       while (len >= 4*sizeof(unsigned int)) {
-               register unsigned int r1,r2,r3,r4;
-               ldwma(s_space, pws, r1, pmc_load_exc);
-               ldwma(s_space, pws, r2, pmc_load_exc);
-               ldwma(s_space, pws, r3, pmc_load_exc);
-               ldwma(s_space, pws, r4, pmc_load_exc);
-               stwma(d_space, r1, pwd, pmc_store_exc);
-               stwma(d_space, r2, pwd, pmc_store_exc);
-               stwma(d_space, r3, pwd, pmc_store_exc);
-               stwma(d_space, r4, pwd, pmc_store_exc);
-               len -= 4*sizeof(unsigned int);
-       }
-
-       pcs = (unsigned char *)pws;
-       pcd = (unsigned char *)pwd;
-
-byte_copy:
-       while (len) {
-               /* *pcd++ = *pcs++; */
-               ldbma(s_space, pcs, t3, pmc_load_exc);
-               stbma(d_space, t3, pcd, pmc_store_exc);
-               len--;
-       }
-
-       return PA_MEMCPY_OK;
-
-unaligned_copy:
-       /* possibly we are aligned on a word, but not on a double... */
-       if (likely((t1 & (sizeof(unsigned int)-1)) == 0)) {
-               t2 = src & (sizeof(unsigned int) - 1);
-
-               if (unlikely(t2 != 0)) {
-                       t2 = sizeof(unsigned int) - t2;
-                       while (t2) {
-                               /* *pcd++ = *pcs++; */
-                               ldbma(s_space, pcs, t3, pmc_load_exc);
-                               stbma(d_space, t3, pcd, pmc_store_exc);
-                               len--;
-                               t2--;
-                       }
-               }
-
-               pws = (unsigned int *)pcs;
-               pwd = (unsigned int *)pcd;
-               goto word_copy;
-       }
-
-       /* Align the destination.  */
-       if (unlikely((dst & (sizeof(unsigned int) - 1)) != 0)) {
-               t2 = sizeof(unsigned int) - (dst & (sizeof(unsigned int) - 1));
-               while (t2) {
-                       /* *pcd++ = *pcs++; */
-                       ldbma(s_space, pcs, t3, pmc_load_exc);
-                       stbma(d_space, t3, pcd, pmc_store_exc);
-                       len--;
-                       t2--;
-               }
-               dst = (unsigned long)pcd;
-               src = (unsigned long)pcs;
-       }
-
-       ret = copy_dstaligned(dst, src, len / sizeof(unsigned int));
-       if (ret)
-               return ret;
-
-       pcs += (len & -sizeof(unsigned int));
-       pcd += (len & -sizeof(unsigned int));
-       len %= sizeof(unsigned int);
-
-       preserve_branch(handle_load_error);
-       preserve_branch(handle_store_error);
-
-       goto byte_copy;
-
-handle_load_error:
-       __asm__ __volatile__ ("pmc_load_exc:\n");
-       return PA_MEMCPY_LOAD_ERROR;
-
-handle_store_error:
-       __asm__ __volatile__ ("pmc_store_exc:\n");
-       return PA_MEMCPY_STORE_ERROR;
-}
-
-
 /* Returns 0 for success, otherwise, returns number of bytes not transferred. */
-static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
-{
-       unsigned long ret, fault_addr, reference;
-       struct exception_data *d;
-
-       ret = pa_memcpy_internal(dstp, srcp, len);
-       if (likely(ret == PA_MEMCPY_OK))
-               return 0;
-
-       /* if a load or store fault occured we can get the faulty addr */
-       d = this_cpu_ptr(&exception_data);
-       fault_addr = d->fault_addr;
-
-       /* error in load or store? */
-       if (ret == PA_MEMCPY_LOAD_ERROR)
-               reference = (unsigned long) srcp;
-       else
-               reference = (unsigned long) dstp;
+extern unsigned long pa_memcpy(void *dst, const void *src,
+                               unsigned long len);
 
-       DPRINTF("pa_memcpy: fault type = %lu, len=%lu fault_addr=%lu ref=%lu\n",
-               ret, len, fault_addr, reference);
-
-       if (fault_addr >= reference)
-               return len - (fault_addr - reference);
-       else
-               return len;
-}
-
-#ifdef __KERNEL__
 unsigned long __copy_to_user(void __user *dst, const void *src,
                             unsigned long len)
 {
@@ -537,5 +84,3 @@ long probe_kernel_read(void *dst, const void *src, size_t size)
 
        return __probe_kernel_read(dst, src, size);
 }
-
-#endif
index deab89a8915a108a3fd98bef581605b59c094ab8..32ec22146141e56f9436bfbdfaccf0256820a552 100644 (file)
@@ -150,6 +150,23 @@ int fixup_exception(struct pt_regs *regs)
                d->fault_space = regs->isr;
                d->fault_addr = regs->ior;
 
+               /*
+                * Fix up get_user() and put_user().
+                * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant
+                * bit in the relative address of the fixup routine to indicate
+                * that %r8 should be loaded with -EFAULT to report a userspace
+                * access error.
+                */
+               if (fix->fixup & 1) {
+                       regs->gr[8] = -EFAULT;
+
+                       /* zero target register for get_user() */
+                       if (parisc_acctyp(0, regs->iir) == VM_READ) {
+                               int treg = regs->iir & 0x1f;
+                               regs->gr[treg] = 0;
+                       }
+               }
+
                regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup;
                regs->iaoq[0] &= ~3;
                /*
index 995728736677071512b5eb40f04bff0045bd2bbb..6fd08219248db7485a6d5c8227dee83664d29b38 100644 (file)
@@ -449,9 +449,23 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 _GLOBAL(pnv_wakeup_tb_loss)
        ld      r1,PACAR1(r13)
        /*
-        * Before entering any idle state, the NVGPRs are saved in the stack
-        * and they are restored before switching to the process context. Hence
-        * until they are restored, they are free to be used.
+        * Before entering any idle state, the NVGPRs are saved in the stack.
+        * If there was a state loss, or PACA_NAPSTATELOST was set, then the
+        * NVGPRs are restored. If we are here, it is likely that state is lost,
+        * but not guaranteed -- neither ISA207 nor ISA300 tests to reach
+        * here are the same as the test to restore NVGPRS:
+        * PACA_THREAD_IDLE_STATE test for ISA207, PSSCR test for ISA300,
+        * and SRR1 test for restoring NVGPRs.
+        *
+        * We are about to clobber NVGPRs now, so set NAPSTATELOST to
+        * guarantee they will always be restored. This might be tightened
+        * with careful reading of specs (particularly for ISA300) but this
+        * is already a slow wakeup path and it's simpler to be safe.
+        */
+       li      r0,1
+       stb     r0,PACA_NAPSTATELOST(r13)
+
+       /*
         *
         * Save SRR1 and LR in NVGPRs as they might be clobbered in
         * opal_call() (called in CHECK_HMI_INTERRUPT). SRR1 is required
index 9be992083d2a7f7103d6ef9a251e95a207d41dd0..c22f207aa6564ba93df40ecc03713de04cb20f99 100644 (file)
@@ -397,8 +397,7 @@ static void early_check_vec5(void)
 void __init mmu_early_init_devtree(void)
 {
        /* Disable radix mode based on kernel command line. */
-       /* We don't yet have the machinery to do radix as a guest. */
-       if (disable_radix || !(mfmsr() & MSR_HV))
+       if (disable_radix)
                cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
 
        /*
index 5ce29fe100baaa0ee0dcaa987901691fb76e4044..fbd9116eb17bf2c73d80952af2108eecdf4db1ed 100644 (file)
@@ -4,6 +4,5 @@
 #include <asm-generic/sections.h>
 
 extern char _eshared[], _ehead[];
-extern char __start_ro_after_init[], __end_ro_after_init[];
 
 #endif
index 5ccf953962518294e2fc0d1b6e6b633e589f223b..72307f108c40387fd718e9ca1e07ee5cb6ef9cb8 100644 (file)
@@ -63,11 +63,9 @@ SECTIONS
 
        . = ALIGN(PAGE_SIZE);
        __start_ro_after_init = .;
-       __start_data_ro_after_init = .;
        .data..ro_after_init : {
                 *(.data..ro_after_init)
        }
-       __end_data_ro_after_init = .;
        EXCEPTION_TABLE(16)
        . = ALIGN(PAGE_SIZE);
        __end_ro_after_init = .;
index df9e731a76f51b923098501ac11ae3b0303c923a..fc5124ccdb53c7abc43e381ba098c453892a7640 100644 (file)
@@ -351,7 +351,7 @@ static int genregs64_set(struct task_struct *target,
        }
 
        if (!ret) {
-               unsigned long y;
+               unsigned long y = regs->y;
 
                ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                         &y,
index 2d449337a36051183c8468f469a8816e6c1e9e7c..a94a4d10f2dfa426d3746cfc9e528d8c91b7e824 100644 (file)
@@ -120,10 +120,6 @@ else
         # -funit-at-a-time shrinks the kernel .text considerably
         # unfortunately it makes reading oopses harder.
         KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
-
-        # this works around some issues with generating unwind tables in older gccs
-        # newer gccs do it by default
-        KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args)
 endif
 
 ifdef CONFIG_X86_X32
@@ -147,6 +143,37 @@ ifeq ($(CONFIG_KMEMCHECK),y)
        KBUILD_CFLAGS += $(call cc-option,-fno-builtin-memcpy)
 endif
 
+#
+# If the function graph tracer is used with mcount instead of fentry,
+# '-maccumulate-outgoing-args' is needed to prevent a GCC bug
+# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42109)
+#
+ifdef CONFIG_FUNCTION_GRAPH_TRACER
+  ifndef CONFIG_HAVE_FENTRY
+       ACCUMULATE_OUTGOING_ARGS := 1
+  else
+    ifeq ($(call cc-option-yn, -mfentry), n)
+       ACCUMULATE_OUTGOING_ARGS := 1
+    endif
+  endif
+endif
+
+#
+# Jump labels need '-maccumulate-outgoing-args' for gcc < 4.5.2 to prevent a
+# GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46226).  There's no way
+# to test for this bug at compile-time because the test case needs to execute,
+# which is a no-go for cross compilers.  So check the GCC version instead.
+#
+ifdef CONFIG_JUMP_LABEL
+  ifneq ($(ACCUMULATE_OUTGOING_ARGS), 1)
+       ACCUMULATE_OUTGOING_ARGS = $(call cc-if-fullversion, -lt, 040502, 1)
+  endif
+endif
+
+ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
+       KBUILD_CFLAGS += -maccumulate-outgoing-args
+endif
+
 # Stackpointer is addressed different for 32 bit and 64 bit x86
 sp-$(CONFIG_X86_32) := esp
 sp-$(CONFIG_X86_64) := rsp
index 6647ed49c66c9789b7e0d37286653021a6fc7d4c..a45eb15b7cf290a176d287c1255b9f9412495831 100644 (file)
@@ -45,24 +45,6 @@ cflags-$(CONFIG_MGEODE_LX)   += $(call cc-option,-march=geode,-march=pentium-mmx)
 # cpu entries
 cflags-$(CONFIG_X86_GENERIC)   += $(call tune,generic,$(call tune,i686))
 
-# Work around the pentium-mmx code generator madness of gcc4.4.x which
-# does stack alignment by generating horrible code _before_ the mcount
-# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph
-# tracer assumptions. For i686, generic, core2 this is set by the
-# compiler anyway
-ifeq ($(CONFIG_FUNCTION_GRAPH_TRACER), y)
-ADD_ACCUMULATE_OUTGOING_ARGS := y
-endif
-
-# Work around to a bug with asm goto with first implementations of it
-# in gcc causing gcc to mess up the push and pop of the stack in some
-# uses of asm goto.
-ifeq ($(CONFIG_JUMP_LABEL), y)
-ADD_ACCUMULATE_OUTGOING_ARGS := y
-endif
-
-cflags-$(ADD_ACCUMULATE_OUTGOING_ARGS) += $(call cc-option,-maccumulate-outgoing-args)
-
 # Bug fix for binutils: this option is required in order to keep
 # binutils from generating NOPL instructions against our will.
 ifneq ($(CONFIG_X86_P6_NOP),y)
index 6248740b68b5a0c71bddf6eb29e4c6898902d471..31922023de49281d44f7fe893099935a594f5456 100644 (file)
@@ -4,6 +4,7 @@
  * memcpy() and memmove() are defined for the compressed boot environment.
  */
 #include "misc.h"
+#include "error.h"
 
 void warn(char *m)
 {
index 2aa1ad194db21a541f65c30b65fe20f2806fdff3..580b60f5ac83cea46a75a11185c8ef0a8c2da516 100644 (file)
@@ -2256,6 +2256,7 @@ void arch_perf_update_userpage(struct perf_event *event,
                               struct perf_event_mmap_page *userpg, u64 now)
 {
        struct cyc2ns_data *data;
+       u64 offset;
 
        userpg->cap_user_time = 0;
        userpg->cap_user_time_zero = 0;
@@ -2263,11 +2264,13 @@ void arch_perf_update_userpage(struct perf_event *event,
                !!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED);
        userpg->pmc_width = x86_pmu.cntval_bits;
 
-       if (!sched_clock_stable())
+       if (!using_native_sched_clock() || !sched_clock_stable())
                return;
 
        data = cyc2ns_read_begin();
 
+       offset = data->cyc2ns_offset + __sched_clock_offset;
+
        /*
         * Internal timekeeping for enabled/running/stopped times
         * is always in the local_clock domain.
@@ -2275,7 +2278,7 @@ void arch_perf_update_userpage(struct perf_event *event,
        userpg->cap_user_time = 1;
        userpg->time_mult = data->cyc2ns_mul;
        userpg->time_shift = data->cyc2ns_shift;
-       userpg->time_offset = data->cyc2ns_offset - now;
+       userpg->time_offset = offset - now;
 
        /*
         * cap_user_time_zero doesn't make sense when we're using a different
@@ -2283,7 +2286,7 @@ void arch_perf_update_userpage(struct perf_event *event,
         */
        if (!event->attr.use_clockid) {
                userpg->cap_user_time_zero = 1;
-               userpg->time_zero = data->cyc2ns_offset;
+               userpg->time_zero = offset;
        }
 
        cyc2ns_read_end(data);
index d74747b031ecd2e20dcf437944195a37e7c6bb3b..c4eda791f877b6c67808546ce072da07b9bb8002 100644 (file)
@@ -46,6 +46,7 @@ struct kvm_page_track_notifier_node {
 };
 
 void kvm_page_track_init(struct kvm *kvm);
+void kvm_page_track_cleanup(struct kvm *kvm);
 
 void kvm_page_track_free_memslot(struct kvm_memory_slot *free,
                                 struct kvm_memory_slot *dont);
index a04eabd43d06621dfadb38d01869f2f22adce783..27e9f9d769b892ef27fa3cf13cb95a7c9563b559 100644 (file)
@@ -12,6 +12,8 @@ extern int recalibrate_cpu_khz(void);
 
 extern int no_timer_check;
 
+extern bool using_native_sched_clock(void);
+
 /*
  * We use the full linear equation: f(x) = a + b*x, in order to allow
  * a continuous function in the face of dynamic freq changes.
index 72e8300b1e8a6a96eef10a918abb5b3b020014aa..9cffb44a3cf5dfedb122c7b31c2f690177e68604 100644 (file)
@@ -485,15 +485,17 @@ static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr)
 
        if (paddr < uv_hub_info->lowmem_remap_top)
                paddr |= uv_hub_info->lowmem_remap_base;
-       paddr |= uv_hub_info->gnode_upper;
-       if (m_val)
+
+       if (m_val) {
+               paddr |= uv_hub_info->gnode_upper;
                paddr = ((paddr << uv_hub_info->m_shift)
                                                >> uv_hub_info->m_shift) |
                        ((paddr >> uv_hub_info->m_val)
                                                << uv_hub_info->n_lshift);
-       else
+       } else {
                paddr |= uv_soc_phys_ram_to_nasid(paddr)
                                                << uv_hub_info->gpa_shift;
+       }
        return paddr;
 }
 
index e9f8f8cdd57085db85dee8247b67150250308a42..86f20cc0a65e2240b2eb5a05fa77af3e866b40d6 100644 (file)
@@ -1105,7 +1105,8 @@ void __init uv_init_hub_info(struct uv_hub_info_s *hi)
        node_id.v               = uv_read_local_mmr(UVH_NODE_ID);
        uv_cpuid.gnode_shift    = max_t(unsigned int, uv_cpuid.gnode_shift, mn.n_val);
        hi->gnode_extra         = (node_id.s.node_id & ~((1 << uv_cpuid.gnode_shift) - 1)) >> 1;
-       hi->gnode_upper         = (unsigned long)hi->gnode_extra << mn.m_val;
+       if (mn.m_val)
+               hi->gnode_upper = (u64)hi->gnode_extra << mn.m_val;
 
        if (uv_gp_table) {
                hi->global_mmr_base     = uv_gp_table->mmr_base;
index 524cc5780a779630d3203d834b0a508097340c67..6e4a047e4b684b0feeeeba851b850c9baebb552f 100644 (file)
@@ -60,7 +60,7 @@ static const char * const th_names[] = {
        "load_store",
        "insn_fetch",
        "combined_unit",
-       "",
+       "decode_unit",
        "northbridge",
        "execution_unit",
 };
index 8f3d9cf26ff9f70ce6b93af12c3a0ff65785d5fa..cbd73eb4217026f1ef39e913cceb04d5c1af4e3a 100644 (file)
 #include <asm/ftrace.h>
 #include <asm/nops.h>
 
+#if defined(CONFIG_FUNCTION_GRAPH_TRACER) && \
+       !defined(CC_USING_FENTRY) && \
+       !defined(CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE)
+# error The following combination is not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER && CONFIG_CC_OPTIMIZE_FOR_SIZE
+#endif
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 int ftrace_arch_code_modify_prepare(void)
index c73a7f9e881aa25852cd4a1aa58950ee9bd79149..714dfba6a1e713fb6b5f4268c318f913bb266628 100644 (file)
@@ -328,7 +328,7 @@ unsigned long long sched_clock(void)
        return paravirt_sched_clock();
 }
 
-static inline bool using_native_sched_clock(void)
+bool using_native_sched_clock(void)
 {
        return pv_time_ops.sched_clock == native_sched_clock;
 }
@@ -336,7 +336,7 @@ static inline bool using_native_sched_clock(void)
 unsigned long long
 sched_clock(void) __attribute__((alias("native_sched_clock")));
 
-static inline bool using_native_sched_clock(void) { return true; }
+bool using_native_sched_clock(void) { return true; }
 #endif
 
 int check_tsc_unstable(void)
index 73ea24d4f119c8dce2a0d3e5bfc24ef3d7562d3a..047b17a26269610b9cc083899cafaa6ca236eb5b 100644 (file)
@@ -657,6 +657,9 @@ void kvm_pic_destroy(struct kvm *kvm)
 {
        struct kvm_pic *vpic = kvm->arch.vpic;
 
+       if (!vpic)
+               return;
+
        kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
        kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
        kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
index 6e219e5c07d27c5dc41786953b1114b1e475e346..289270a6aecbb478ea14cc786c72fcfdf5058350 100644 (file)
@@ -635,6 +635,9 @@ void kvm_ioapic_destroy(struct kvm *kvm)
 {
        struct kvm_ioapic *ioapic = kvm->arch.vioapic;
 
+       if (!ioapic)
+               return;
+
        cancel_delayed_work_sync(&ioapic->eoi_inject);
        kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
        kvm->arch.vioapic = NULL;
index 37942e419c32e599a4ba05d3b75a77680f0065d9..60168cdd05463e2e18c993e20dfdeed7986808ce 100644 (file)
@@ -160,6 +160,14 @@ bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn,
        return !!ACCESS_ONCE(slot->arch.gfn_track[mode][index]);
 }
 
+void kvm_page_track_cleanup(struct kvm *kvm)
+{
+       struct kvm_page_track_notifier_head *head;
+
+       head = &kvm->arch.track_notifier_head;
+       cleanup_srcu_struct(&head->track_srcu);
+}
+
 void kvm_page_track_init(struct kvm *kvm)
 {
        struct kvm_page_track_notifier_head *head;
index d1efe2c62b3f8d0db7392970cdfd8e018dd3ac06..5fba70646c327941d231ab6dfa459e8a8536a115 100644 (file)
@@ -1379,6 +1379,9 @@ static void avic_vm_destroy(struct kvm *kvm)
        unsigned long flags;
        struct kvm_arch *vm_data = &kvm->arch;
 
+       if (!avic)
+               return;
+
        avic_free_vm_id(vm_data->avic_vm_id);
 
        if (vm_data->avic_logical_id_table_page)
index 98e82ee1e6996671f912a152dec5367baea45b80..2ee00dbbbd5188ccd51324085d51b0de679666bb 100644 (file)
@@ -1239,6 +1239,11 @@ static inline bool cpu_has_vmx_invvpid_global(void)
        return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
 }
 
+static inline bool cpu_has_vmx_invvpid(void)
+{
+       return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
+}
+
 static inline bool cpu_has_vmx_ept(void)
 {
        return vmcs_config.cpu_based_2nd_exec_ctrl &
@@ -2753,7 +2758,6 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
                SECONDARY_EXEC_RDTSCP |
                SECONDARY_EXEC_DESC |
                SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
-               SECONDARY_EXEC_ENABLE_VPID |
                SECONDARY_EXEC_APIC_REGISTER_VIRT |
                SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
                SECONDARY_EXEC_WBINVD_EXITING |
@@ -2781,10 +2785,12 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
         * though it is treated as global context.  The alternative is
         * not failing the single-context invvpid, and it is worse.
         */
-       if (enable_vpid)
+       if (enable_vpid) {
+               vmx->nested.nested_vmx_secondary_ctls_high |=
+                       SECONDARY_EXEC_ENABLE_VPID;
                vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
                        VMX_VPID_EXTENT_SUPPORTED_MASK;
-       else
+       else
                vmx->nested.nested_vmx_vpid_caps = 0;
 
        if (enable_unrestricted_guest)
@@ -4024,6 +4030,12 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
        __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid);
 }
 
+static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu)
+{
+       if (enable_ept)
+               vmx_flush_tlb(vcpu);
+}
+
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
 {
        ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
@@ -6517,8 +6529,10 @@ static __init int hardware_setup(void)
        if (boot_cpu_has(X86_FEATURE_NX))
                kvm_enable_efer_bits(EFER_NX);
 
-       if (!cpu_has_vmx_vpid())
+       if (!cpu_has_vmx_vpid() || !cpu_has_vmx_invvpid() ||
+               !(cpu_has_vmx_invvpid_single() || cpu_has_vmx_invvpid_global()))
                enable_vpid = 0;
+
        if (!cpu_has_vmx_shadow_vmcs())
                enable_shadow_vmcs = 0;
        if (enable_shadow_vmcs)
@@ -8501,7 +8515,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
            && kvm_vmx_exit_handlers[exit_reason])
                return kvm_vmx_exit_handlers[exit_reason](vcpu);
        else {
-               WARN_ONCE(1, "vmx: unexpected exit reason 0x%x\n", exit_reason);
+               vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n",
+                               exit_reason);
                kvm_queue_exception(vcpu, UD_VECTOR);
                return 1;
        }
@@ -8547,6 +8562,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
        } else {
                sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
                sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+               vmx_flush_tlb_ept_only(vcpu);
        }
        vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control);
 
@@ -8572,8 +8588,10 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa)
         */
        if (!is_guest_mode(vcpu) ||
            !nested_cpu_has2(get_vmcs12(&vmx->vcpu),
-                            SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
+                            SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
                vmcs_write64(APIC_ACCESS_ADDR, hpa);
+               vmx_flush_tlb_ept_only(vcpu);
+       }
 }
 
 static void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
@@ -9974,7 +9992,6 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        u32 exec_control;
-       bool nested_ept_enabled = false;
 
        vmcs_write16(GUEST_ES_SELECTOR, vmcs12->guest_es_selector);
        vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector);
@@ -10121,8 +10138,6 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                                vmcs12->guest_intr_status);
                }
 
-               nested_ept_enabled = (exec_control & SECONDARY_EXEC_ENABLE_EPT) != 0;
-
                /*
                 * Write an illegal value to APIC_ACCESS_ADDR. Later,
                 * nested_get_vmcs12_pages will either fix it up or
@@ -10255,6 +10270,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
        if (nested_cpu_has_ept(vmcs12)) {
                kvm_mmu_unload(vcpu);
                nested_ept_init_mmu_context(vcpu);
+       } else if (nested_cpu_has2(vmcs12,
+                                  SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
+               vmx_flush_tlb_ept_only(vcpu);
        }
 
        /*
@@ -10282,12 +10300,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
        vmx_set_efer(vcpu, vcpu->arch.efer);
 
        /* Shadow page tables on either EPT or shadow page tables. */
-       if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_ept_enabled,
+       if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12),
                                entry_failure_code))
                return 1;
 
-       kvm_mmu_reset_context(vcpu);
-
        if (!enable_ept)
                vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested;
 
@@ -11056,6 +11072,10 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
                vmx->nested.change_vmcs01_virtual_x2apic_mode = false;
                vmx_set_virtual_x2apic_mode(vcpu,
                                vcpu->arch.apic_base & X2APIC_ENABLE);
+       } else if (!nested_cpu_has_ept(vmcs12) &&
+                  nested_cpu_has2(vmcs12,
+                                  SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
+               vmx_flush_tlb_ept_only(vcpu);
        }
 
        /* This is needed for same reason as it was needed in prepare_vmcs02 */
index 1faf620a6fdc206705a03357d3a8ec5814b2c790..ccbd45ecd41a3fa5c850cf924cccbb2723aecc92 100644 (file)
@@ -8153,11 +8153,12 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
        if (kvm_x86_ops->vm_destroy)
                kvm_x86_ops->vm_destroy(kvm);
        kvm_iommu_unmap_guest(kvm);
-       kfree(kvm->arch.vpic);
-       kfree(kvm->arch.vioapic);
+       kvm_pic_destroy(kvm);
+       kvm_ioapic_destroy(kvm);
        kvm_free_vcpus(kvm);
        kvfree(rcu_dereference_check(kvm->arch.apic_map, 1));
        kvm_mmu_uninit_vm(kvm);
+       kvm_page_track_cleanup(kvm);
 }
 
 void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
@@ -8566,11 +8567,11 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
 {
        struct x86_exception fault;
 
-       trace_kvm_async_pf_ready(work->arch.token, work->gva);
        if (work->wakeup_all)
                work->arch.token = ~0; /* broadcast wakeup */
        else
                kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
+       trace_kvm_async_pf_ready(work->arch.token, work->gva);
 
        if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) &&
            !apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) {
index 779782f5832476582becc24e5a0f0f5b10ea0b53..9a53a06e5a3efcb62f9563a6161fd98bbc22d617 100644 (file)
@@ -290,7 +290,7 @@ EXPORT_SYMBOL_GPL(memcpy_mcsafe_unrolled)
        _ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail)
        _ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail)
        _ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail)
-       _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
+       _ASM_EXTABLE_FAULT(.L_cache_w2, .L_memcpy_mcsafe_fail)
        _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
        _ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail)
        _ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail)
index 887e57182716828b7f4f4946fe7145d106ec5bea..aed206475aa7c04892443646efa6e88a9e5f4d24 100644 (file)
@@ -48,7 +48,7 @@ static const unsigned long vaddr_start = __PAGE_OFFSET_BASE;
 #if defined(CONFIG_X86_ESPFIX64)
 static const unsigned long vaddr_end = ESPFIX_BASE_ADDR;
 #elif defined(CONFIG_EFI)
-static const unsigned long vaddr_end = EFI_VA_START;
+static const unsigned long vaddr_end = EFI_VA_END;
 #else
 static const unsigned long vaddr_end = __START_KERNEL_map;
 #endif
@@ -105,7 +105,7 @@ void __init kernel_randomize_memory(void)
         */
        BUILD_BUG_ON(vaddr_start >= vaddr_end);
        BUILD_BUG_ON(IS_ENABLED(CONFIG_X86_ESPFIX64) &&
-                    vaddr_end >= EFI_VA_START);
+                    vaddr_end >= EFI_VA_END);
        BUILD_BUG_ON((IS_ENABLED(CONFIG_X86_ESPFIX64) ||
                      IS_ENABLED(CONFIG_EFI)) &&
                     vaddr_end >= __START_KERNEL_map);
index 555b9fa0ad43cbd4148b2fb268692d4b2de167c4..7dbdb780264df9258d98829f8a11496cd58bb7ab 100644 (file)
@@ -8,6 +8,7 @@ PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib
 targets += purgatory.ro
 
+KASAN_SANITIZE := n
 KCOV_INSTRUMENT := n
 
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
index a4546f060e80933423638f1399ab1922db8331a9..6b6e7bc041dbf3c4699ca9bfa8e36c58a8f119d0 100644 (file)
@@ -697,17 +697,8 @@ static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
 {
        struct blk_mq_timeout_data *data = priv;
 
-       if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) {
-               /*
-                * If a request wasn't started before the queue was
-                * marked dying, kill it here or it'll go unnoticed.
-                */
-               if (unlikely(blk_queue_dying(rq->q))) {
-                       rq->errors = -EIO;
-                       blk_mq_end_request(rq, rq->errors);
-               }
+       if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags))
                return;
-       }
 
        if (time_after_eq(jiffies, rq->deadline)) {
                if (!blk_mark_rq_complete(rq))
@@ -978,7 +969,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
        struct request *rq;
        LIST_HEAD(driver_list);
        struct list_head *dptr;
-       int queued, ret = BLK_MQ_RQ_QUEUE_OK;
+       int errors, queued, ret = BLK_MQ_RQ_QUEUE_OK;
 
        /*
         * Start off with dptr being NULL, so we start the first request
@@ -989,7 +980,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
        /*
         * Now process all the entries, sending them to the driver.
         */
-       queued = 0;
+       errors = queued = 0;
        while (!list_empty(list)) {
                struct blk_mq_queue_data bd;
 
@@ -1046,6 +1037,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
                default:
                        pr_err("blk-mq: bad return on queue: %d\n", ret);
                case BLK_MQ_RQ_QUEUE_ERROR:
+                       errors++;
                        rq->errors = -EIO;
                        blk_mq_end_request(rq, rq->errors);
                        break;
@@ -1097,7 +1089,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
                        blk_mq_run_hw_queue(hctx, true);
        }
 
-       return queued != 0;
+       return (queued + errors) != 0;
 }
 
 static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
index 9b43efb8933fb9a0f352922029b86903e5b7c8e7..186fcb981e9b1d9696e3e000b0fde7b86e1a9663 100644 (file)
@@ -30,11 +30,11 @@ static void blk_stat_flush_batch(struct blk_rq_stat *stat)
 
 static void blk_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src)
 {
+       blk_stat_flush_batch(src);
+
        if (!src->nr_samples)
                return;
 
-       blk_stat_flush_batch(src);
-
        dst->min = min(dst->min, src->min);
        dst->max = max(dst->max, src->max);
 
index ecd8474018e3bde6d16d44c66da6844b6c78ad26..3ea095adafd9af0067f695c4c70e2af702f70923 100644 (file)
@@ -286,8 +286,11 @@ static int init_crypt(struct skcipher_request *req, crypto_completion_t done)
 
        subreq->cryptlen = LRW_BUFFER_SIZE;
        if (req->cryptlen > LRW_BUFFER_SIZE) {
-               subreq->cryptlen = min(req->cryptlen, (unsigned)PAGE_SIZE);
-               rctx->ext = kmalloc(subreq->cryptlen, gfp);
+               unsigned int n = min(req->cryptlen, (unsigned int)PAGE_SIZE);
+
+               rctx->ext = kmalloc(n, gfp);
+               if (rctx->ext)
+                       subreq->cryptlen = n;
        }
 
        rctx->src = req->src;
index baeb34dd8582ebd11473ebb8e2ed5eadd7d2f71b..c976bfac29da526844f6a5578fea1455945c26f3 100644 (file)
@@ -230,8 +230,11 @@ static int init_crypt(struct skcipher_request *req, crypto_completion_t done)
 
        subreq->cryptlen = XTS_BUFFER_SIZE;
        if (req->cryptlen > XTS_BUFFER_SIZE) {
-               subreq->cryptlen = min(req->cryptlen, (unsigned)PAGE_SIZE);
-               rctx->ext = kmalloc(subreq->cryptlen, gfp);
+               unsigned int n = min(req->cryptlen, (unsigned int)PAGE_SIZE);
+
+               rctx->ext = kmalloc(n, gfp);
+               if (rctx->ext)
+                       subreq->cryptlen = n;
        }
 
        rctx->src = req->src;
index a391bbc48105ae6cf3504775c60b00b4dcd5705e..d94f92f88ca1c9afb7e04b4f96901f9518a4a2c1 100644 (file)
@@ -2,7 +2,6 @@
 # Makefile for the Linux ACPI interpreter
 #
 
-ccflags-y                      := -Os
 ccflags-$(CONFIG_ACPI_DEBUG)   += -DACPI_DEBUG_OUTPUT
 
 #
index b4c1a6a51da482a953051959279fc9d39cd29d49..03250e1f11039b99e6a25e1650b9d67c3cee41c9 100644 (file)
 ACPI_MODULE_NAME("platform");
 
 static const struct acpi_device_id forbidden_id_list[] = {
-       {"PNP0000", 0}, /* PIC */
-       {"PNP0100", 0}, /* Timer */
-       {"PNP0200", 0}, /* AT DMA Controller */
+       {"PNP0000",  0},        /* PIC */
+       {"PNP0100",  0},        /* Timer */
+       {"PNP0200",  0},        /* AT DMA Controller */
+       {"ACPI0009", 0},        /* IOxAPIC */
+       {"ACPI000A", 0},        /* IOAPIC */
        {"", 0},
 };
 
index b192b42a835105a68038ce13d568fad7154497c4..79b3c9c5a3bc9497ea7e9ef5e26fced8b55617b2 100644 (file)
@@ -1073,6 +1073,7 @@ static int ghes_remove(struct platform_device *ghes_dev)
                if (list_empty(&ghes_sci))
                        unregister_acpi_hed_notifier(&ghes_notifier_sci);
                mutex_unlock(&ghes_list_mutex);
+               synchronize_rcu();
                break;
        case ACPI_HEST_NOTIFY_NMI:
                ghes_nmi_remove(ghes);
index 1120dfd625b8a18a81030c7b6a4276769594879c..7e4fbf9a53a3ccd19488b2eb17de2d1be7dfe4de 100644 (file)
@@ -45,6 +45,12 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, void *data)
        struct resource *res = data;
        struct resource_win win;
 
+       /*
+        * We might assign this to 'res' later, make sure all pointers are
+        * cleared before the resource is added to the global list
+        */
+       memset(&win, 0, sizeof(win));
+
        res->flags = 0;
        if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
                return AE_OK;
index 01c94669a2b0ad91976daf9f3c7ef3338b48e965..3afa8c1fa12702c251d5d3654e2026ba0ebfcd62 100644 (file)
@@ -30,7 +30,7 @@ static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
                return true;
 
        if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
-                       h->oem_revision == 0)
+                       h->oem_revision == 1)
                return true;
 
        return false;
index bf43b5d2aafcafb2b0bc32652cacac6750c5bff9..83f1439e57fd8cb5d40e0a9d435a8a7fe62939c4 100644 (file)
@@ -218,6 +218,7 @@ static const struct of_device_id img_ascii_lcd_matches[] = {
        { .compatible = "img,boston-lcd", .data = &boston_config },
        { .compatible = "mti,malta-lcd", .data = &malta_config },
        { .compatible = "mti,sead3-lcd", .data = &sead3_config },
+       { /* sentinel */ }
 };
 
 /**
index 7e4287bc19e52991a82cf218906fe7384112921b..d8a23561b4cb4b720065ccf1bd97714a07395c73 100644 (file)
@@ -47,6 +47,8 @@ static DEFINE_MUTEX(nbd_index_mutex);
 struct nbd_sock {
        struct socket *sock;
        struct mutex tx_lock;
+       struct request *pending;
+       int sent;
 };
 
 #define NBD_TIMEDOUT                   0
@@ -124,7 +126,8 @@ static const char *nbdcmd_to_ascii(int cmd)
 
 static int nbd_size_clear(struct nbd_device *nbd, struct block_device *bdev)
 {
-       bd_set_size(bdev, 0);
+       if (bdev->bd_openers <= 1)
+               bd_set_size(bdev, 0);
        set_capacity(nbd->disk, 0);
        kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
 
@@ -190,7 +193,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
 
        dev_err(nbd_to_dev(nbd), "Connection timed out, shutting down connection\n");
        set_bit(NBD_TIMEDOUT, &nbd->runtime_flags);
-       req->errors++;
+       req->errors = -EIO;
 
        mutex_lock(&nbd->config_lock);
        sock_shutdown(nbd);
@@ -202,7 +205,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
  *  Send or receive packet.
  */
 static int sock_xmit(struct nbd_device *nbd, int index, int send,
-                    struct iov_iter *iter, int msg_flags)
+                    struct iov_iter *iter, int msg_flags, int *sent)
 {
        struct socket *sock = nbd->socks[index]->sock;
        int result;
@@ -237,6 +240,8 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
                                result = -EPIPE; /* short read */
                        break;
                }
+               if (sent)
+                       *sent += result;
        } while (msg_data_left(&msg));
 
        tsk_restore_flags(current, pflags, PF_MEMALLOC);
@@ -248,6 +253,7 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
 static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 {
        struct request *req = blk_mq_rq_from_pdu(cmd);
+       struct nbd_sock *nsock = nbd->socks[index];
        int result;
        struct nbd_request request = {.magic = htonl(NBD_REQUEST_MAGIC)};
        struct kvec iov = {.iov_base = &request, .iov_len = sizeof(request)};
@@ -256,6 +262,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
        struct bio *bio;
        u32 type;
        u32 tag = blk_mq_unique_tag(req);
+       int sent = nsock->sent, skip = 0;
 
        iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request));
 
@@ -283,6 +290,17 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
                return -EIO;
        }
 
+       /* We did a partial send previously, and we at least sent the whole
+        * request struct, so just go and send the rest of the pages in the
+        * request.
+        */
+       if (sent) {
+               if (sent >= sizeof(request)) {
+                       skip = sent - sizeof(request);
+                       goto send_pages;
+               }
+               iov_iter_advance(&from, sent);
+       }
        request.type = htonl(type);
        if (type != NBD_CMD_FLUSH) {
                request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
@@ -294,15 +312,27 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
                cmd, nbdcmd_to_ascii(type),
                (unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
        result = sock_xmit(nbd, index, 1, &from,
-                       (type == NBD_CMD_WRITE) ? MSG_MORE : 0);
+                       (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent);
        if (result <= 0) {
+               if (result == -ERESTARTSYS) {
+                       /* If we havne't sent anything we can just return BUSY,
+                        * however if we have sent something we need to make
+                        * sure we only allow this req to be sent until we are
+                        * completely done.
+                        */
+                       if (sent) {
+                               nsock->pending = req;
+                               nsock->sent = sent;
+                       }
+                       return BLK_MQ_RQ_QUEUE_BUSY;
+               }
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                        "Send control failed (result %d)\n", result);
                return -EIO;
        }
-
+send_pages:
        if (type != NBD_CMD_WRITE)
-               return 0;
+               goto out;
 
        bio = req->bio;
        while (bio) {
@@ -318,8 +348,25 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
                                cmd, bvec.bv_len);
                        iov_iter_bvec(&from, ITER_BVEC | WRITE,
                                      &bvec, 1, bvec.bv_len);
-                       result = sock_xmit(nbd, index, 1, &from, flags);
+                       if (skip) {
+                               if (skip >= iov_iter_count(&from)) {
+                                       skip -= iov_iter_count(&from);
+                                       continue;
+                               }
+                               iov_iter_advance(&from, skip);
+                               skip = 0;
+                       }
+                       result = sock_xmit(nbd, index, 1, &from, flags, &sent);
                        if (result <= 0) {
+                               if (result == -ERESTARTSYS) {
+                                       /* We've already sent the header, we
+                                        * have no choice but to set pending and
+                                        * return BUSY.
+                                        */
+                                       nsock->pending = req;
+                                       nsock->sent = sent;
+                                       return BLK_MQ_RQ_QUEUE_BUSY;
+                               }
                                dev_err(disk_to_dev(nbd->disk),
                                        "Send data failed (result %d)\n",
                                        result);
@@ -336,6 +383,9 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
                }
                bio = next;
        }
+out:
+       nsock->pending = NULL;
+       nsock->sent = 0;
        return 0;
 }
 
@@ -353,7 +403,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
 
        reply.magic = 0;
        iov_iter_kvec(&to, READ | ITER_KVEC, &iov, 1, sizeof(reply));
-       result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL);
+       result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
        if (result <= 0) {
                if (!test_bit(NBD_DISCONNECTED, &nbd->runtime_flags) &&
                    !test_bit(NBD_DISCONNECT_REQUESTED, &nbd->runtime_flags))
@@ -383,7 +433,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
        if (ntohl(reply.error)) {
                dev_err(disk_to_dev(nbd->disk), "Other side returned error (%d)\n",
                        ntohl(reply.error));
-               req->errors++;
+               req->errors = -EIO;
                return cmd;
        }
 
@@ -395,11 +445,11 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
                rq_for_each_segment(bvec, req, iter) {
                        iov_iter_bvec(&to, ITER_BVEC | READ,
                                      &bvec, 1, bvec.bv_len);
-                       result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL);
+                       result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
                        if (result <= 0) {
                                dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
                                        result);
-                               req->errors++;
+                               req->errors = -EIO;
                                return cmd;
                        }
                        dev_dbg(nbd_to_dev(nbd), "request %p: got %d bytes data\n",
@@ -469,7 +519,7 @@ static void nbd_clear_req(struct request *req, void *data, bool reserved)
        if (!blk_mq_request_started(req))
                return;
        cmd = blk_mq_rq_to_pdu(req);
-       req->errors++;
+       req->errors = -EIO;
        nbd_end_request(cmd);
 }
 
@@ -482,22 +532,23 @@ static void nbd_clear_que(struct nbd_device *nbd)
 }
 
 
-static void nbd_handle_cmd(struct nbd_cmd *cmd, int index)
+static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
 {
        struct request *req = blk_mq_rq_from_pdu(cmd);
        struct nbd_device *nbd = cmd->nbd;
        struct nbd_sock *nsock;
+       int ret;
 
        if (index >= nbd->num_connections) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Attempted send on invalid socket\n");
-               goto error_out;
+               return -EINVAL;
        }
 
        if (test_bit(NBD_DISCONNECTED, &nbd->runtime_flags)) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Attempted send on closed socket\n");
-               goto error_out;
+               return -EINVAL;
        }
 
        req->errors = 0;
@@ -508,29 +559,30 @@ static void nbd_handle_cmd(struct nbd_cmd *cmd, int index)
                mutex_unlock(&nsock->tx_lock);
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Attempted send on closed socket\n");
-               goto error_out;
+               return -EINVAL;
        }
 
-       if (nbd_send_cmd(nbd, cmd, index) != 0) {
-               dev_err_ratelimited(disk_to_dev(nbd->disk),
-                                   "Request send failed\n");
-               req->errors++;
-               nbd_end_request(cmd);
+       /* Handle the case that we have a pending request that was partially
+        * transmitted that _has_ to be serviced first.  We need to call requeue
+        * here so that it gets put _after_ the request that is already on the
+        * dispatch list.
+        */
+       if (unlikely(nsock->pending && nsock->pending != req)) {
+               blk_mq_requeue_request(req, true);
+               ret = 0;
+               goto out;
        }
-
+       ret = nbd_send_cmd(nbd, cmd, index);
+out:
        mutex_unlock(&nsock->tx_lock);
-
-       return;
-
-error_out:
-       req->errors++;
-       nbd_end_request(cmd);
+       return ret;
 }
 
 static int nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
                        const struct blk_mq_queue_data *bd)
 {
        struct nbd_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
+       int ret;
 
        /*
         * Since we look at the bio's to send the request over the network we
@@ -543,10 +595,20 @@ static int nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
         */
        init_completion(&cmd->send_complete);
        blk_mq_start_request(bd->rq);
-       nbd_handle_cmd(cmd, hctx->queue_num);
+
+       /* We can be called directly from the user space process, which means we
+        * could possibly have signals pending so our sendmsg will fail.  In
+        * this case we need to return that we are busy, otherwise error out as
+        * appropriate.
+        */
+       ret = nbd_handle_cmd(cmd, hctx->queue_num);
+       if (ret < 0)
+               ret = BLK_MQ_RQ_QUEUE_ERROR;
+       if (!ret)
+               ret = BLK_MQ_RQ_QUEUE_OK;
        complete(&cmd->send_complete);
 
-       return BLK_MQ_RQ_QUEUE_OK;
+       return ret;
 }
 
 static int nbd_add_socket(struct nbd_device *nbd, struct block_device *bdev,
@@ -581,6 +643,8 @@ static int nbd_add_socket(struct nbd_device *nbd, struct block_device *bdev,
 
        mutex_init(&nsock->tx_lock);
        nsock->sock = sock;
+       nsock->pending = NULL;
+       nsock->sent = 0;
        socks[nbd->num_connections++] = nsock;
 
        if (max_part)
@@ -602,6 +666,8 @@ static void nbd_reset(struct nbd_device *nbd)
 
 static void nbd_bdev_reset(struct block_device *bdev)
 {
+       if (bdev->bd_openers > 1)
+               return;
        set_device_ro(bdev, false);
        bdev->bd_inode->i_size = 0;
        if (max_part > 0) {
@@ -634,7 +700,7 @@ static void send_disconnects(struct nbd_device *nbd)
 
        for (i = 0; i < nbd->num_connections; i++) {
                iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request));
-               ret = sock_xmit(nbd, i, 1, &from, 0);
+               ret = sock_xmit(nbd, i, 1, &from, 0, NULL);
                if (ret <= 0)
                        dev_err(disk_to_dev(nbd->disk),
                                "Send disconnect failed %d\n", ret);
@@ -665,7 +731,8 @@ static int nbd_clear_sock(struct nbd_device *nbd, struct block_device *bdev)
 {
        sock_shutdown(nbd);
        nbd_clear_que(nbd);
-       kill_bdev(bdev);
+
+       __invalidate_device(bdev, true);
        nbd_bdev_reset(bdev);
        /*
         * We want to give the run thread a chance to wait for everybody
@@ -781,7 +848,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
                nbd_size_set(nbd, bdev, nbd->blksize, arg);
                return 0;
        case NBD_SET_TIMEOUT:
-               nbd->tag_set.timeout = arg * HZ;
+               if (arg) {
+                       nbd->tag_set.timeout = arg * HZ;
+                       blk_queue_rq_timeout(nbd->disk->queue, arg * HZ);
+               }
                return 0;
 
        case NBD_SET_FLAGS:
index c2c14a12713b56038c8c21deae2212550d24422b..08e054507d0bcd7fc59f5d14d0927ba6ca35291f 100644 (file)
@@ -344,7 +344,8 @@ config BT_WILINK
 
 config BT_QCOMSMD
        tristate "Qualcomm SMD based HCI support"
-       depends on (QCOM_SMD && QCOM_WCNSS_CTRL) || COMPILE_TEST
+       depends on QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n)
+       depends on QCOM_WCNSS_CTRL || (COMPILE_TEST && QCOM_WCNSS_CTRL=n)
        select BT_QCA
        help
          Qualcomm SMD based HCI driver.
index 4a99ac756f0815a890665f1433b1038a98069be9..9959c762da2f8ec1f5cb0fde48021598f3deecfd 100644 (file)
@@ -55,6 +55,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
 struct amd768_priv {
        void __iomem *iobase;
        struct pci_dev *pcidev;
+       u32 pmbase;
 };
 
 static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
@@ -148,33 +149,58 @@ found:
        if (pmbase == 0)
                return -EIO;
 
-       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       if (!devm_request_region(&pdev->dev, pmbase + PMBASE_OFFSET,
-                               PMBASE_SIZE, DRV_NAME)) {
+       if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) {
                dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
                        pmbase + 0xF0);
-               return -EBUSY;
+               err = -EBUSY;
+               goto out;
        }
 
-       priv->iobase = devm_ioport_map(&pdev->dev, pmbase + PMBASE_OFFSET,
-                       PMBASE_SIZE);
+       priv->iobase = ioport_map(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
        if (!priv->iobase) {
                pr_err(DRV_NAME "Cannot map ioport\n");
-               return -ENOMEM;
+               err = -EINVAL;
+               goto err_iomap;
        }
 
        amd_rng.priv = (unsigned long)priv;
+       priv->pmbase = pmbase;
        priv->pcidev = pdev;
 
        pr_info(DRV_NAME " detected\n");
-       return devm_hwrng_register(&pdev->dev, &amd_rng);
+       err = hwrng_register(&amd_rng);
+       if (err) {
+               pr_err(DRV_NAME " registering failed (%d)\n", err);
+               goto err_hwrng;
+       }
+       return 0;
+
+err_hwrng:
+       ioport_unmap(priv->iobase);
+err_iomap:
+       release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+out:
+       kfree(priv);
+       return err;
 }
 
 static void __exit mod_exit(void)
 {
+       struct amd768_priv *priv;
+
+       priv = (struct amd768_priv *)amd_rng.priv;
+
+       hwrng_unregister(&amd_rng);
+
+       ioport_unmap(priv->iobase);
+
+       release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+
+       kfree(priv);
 }
 
 module_init(mod_init);
index e7a2459420291b6b931b285fe2b9be22cdd3e897..e1d421a36a138d6a5e30b16bf62208846b5372ab 100644 (file)
@@ -31,6 +31,9 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 
+
+#define PFX    KBUILD_MODNAME ": "
+
 #define GEODE_RNG_DATA_REG   0x50
 #define GEODE_RNG_STATUS_REG 0x54
 
@@ -82,6 +85,7 @@ static struct hwrng geode_rng = {
 
 static int __init mod_init(void)
 {
+       int err = -ENODEV;
        struct pci_dev *pdev = NULL;
        const struct pci_device_id *ent;
        void __iomem *mem;
@@ -89,27 +93,43 @@ static int __init mod_init(void)
 
        for_each_pci_dev(pdev) {
                ent = pci_match_id(pci_tbl, pdev);
-               if (ent) {
-                       rng_base = pci_resource_start(pdev, 0);
-                       if (rng_base == 0)
-                               return -ENODEV;
-
-                       mem = devm_ioremap(&pdev->dev, rng_base, 0x58);
-                       if (!mem)
-                               return -ENOMEM;
-                       geode_rng.priv = (unsigned long)mem;
-
-                       pr_info("AMD Geode RNG detected\n");
-                       return devm_hwrng_register(&pdev->dev, &geode_rng);
-               }
+               if (ent)
+                       goto found;
        }
-
        /* Device not found. */
-       return -ENODEV;
+       goto out;
+
+found:
+       rng_base = pci_resource_start(pdev, 0);
+       if (rng_base == 0)
+               goto out;
+       err = -ENOMEM;
+       mem = ioremap(rng_base, 0x58);
+       if (!mem)
+               goto out;
+       geode_rng.priv = (unsigned long)mem;
+
+       pr_info("AMD Geode RNG detected\n");
+       err = hwrng_register(&geode_rng);
+       if (err) {
+               pr_err(PFX "RNG registering failed (%d)\n",
+                      err);
+               goto err_unmap;
+       }
+out:
+       return err;
+
+err_unmap:
+       iounmap(mem);
+       goto out;
 }
 
 static void __exit mod_exit(void)
 {
+       void __iomem *mem = (void __iomem *)geode_rng.priv;
+
+       hwrng_unregister(&geode_rng);
+       iounmap(mem);
 }
 
 module_init(mod_init);
index 2a558c706581b21864d45ac701213beb301e8899..3e73bcdf9e658d378963bee83bfeda2e76659c40 100644 (file)
@@ -84,11 +84,14 @@ struct pp_struct {
        struct ieee1284_info state;
        struct ieee1284_info saved_state;
        long default_inactivity;
+       int index;
 };
 
 /* should we use PARDEVICE_MAX here? */
 static struct device *devices[PARPORT_MAX];
 
+static DEFINE_IDA(ida_index);
+
 /* pp_struct.flags bitfields */
 #define PP_CLAIMED    (1<<0)
 #define PP_EXCL       (1<<1)
@@ -290,7 +293,7 @@ static int register_device(int minor, struct pp_struct *pp)
        struct pardevice *pdev = NULL;
        char *name;
        struct pardev_cb ppdev_cb;
-       int rc = 0;
+       int rc = 0, index;
 
        name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor);
        if (name == NULL)
@@ -303,20 +306,23 @@ static int register_device(int minor, struct pp_struct *pp)
                goto err;
        }
 
+       index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL);
        memset(&ppdev_cb, 0, sizeof(ppdev_cb));
        ppdev_cb.irq_func = pp_irq;
        ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
        ppdev_cb.private = pp;
-       pdev = parport_register_dev_model(port, name, &ppdev_cb, minor);
+       pdev = parport_register_dev_model(port, name, &ppdev_cb, index);
        parport_put_port(port);
 
        if (!pdev) {
                pr_warn("%s: failed to register device!\n", name);
                rc = -ENXIO;
+               ida_simple_remove(&ida_index, index);
                goto err;
        }
 
        pp->pdev = pdev;
+       pp->index = index;
        dev_dbg(&pdev->dev, "registered pardevice\n");
 err:
        kfree(name);
@@ -755,6 +761,7 @@ static int pp_release(struct inode *inode, struct file *file)
 
        if (pp->pdev) {
                parport_unregister_device(pp->pdev);
+               ida_simple_remove(&ida_index, pp->index);
                pp->pdev = NULL;
                pr_debug(CHRDEV "%x: unregistered pardevice\n", minor);
        }
index 0fb39fe217d17ae1bb681912764b2506007f5f42..67201f67a14af7b07aec557308a7fb39d1432157 100644 (file)
@@ -2502,7 +2502,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
 
        clk->core = hw->core;
        clk->dev_id = dev_id;
-       clk->con_id = con_id;
+       clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
        clk->max_rate = ULONG_MAX;
 
        clk_prepare_lock();
@@ -2518,6 +2518,7 @@ void __clk_free_clk(struct clk *clk)
        hlist_del(&clk->clks_node);
        clk_prepare_unlock();
 
+       kfree_const(clk->con_id);
        kfree(clk);
 }
 
index 924f560dcf80e8a5681fba4c670524b2b20b01ee..00d4150e33c37434c056ba27867db908d6117bdf 100644 (file)
@@ -127,7 +127,7 @@ PNAME(mux_ddrphy_p)         = { "dpll_ddr", "gpll_ddr" };
 PNAME(mux_pll_src_3plls_p)     = { "apll", "dpll", "gpll" };
 PNAME(mux_timer_p)             = { "xin24m", "pclk_peri_src" };
 
-PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p)    = { "apll", "dpll", "gpll" "usb480m" };
+PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p)    = { "apll", "dpll", "gpll", "usb480m" };
 
 PNAME(mux_mmc_src_p)   = { "apll", "dpll", "gpll", "xin24m" };
 PNAME(mux_i2s_pre_p)   = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
@@ -450,6 +450,13 @@ static void __init rk3036_clk_init(struct device_node *np)
                return;
        }
 
+       /*
+        * Make uart_pll_clk a child of the gpll, as all other sources are
+        * not that usable / stable.
+        */
+       writel_relaxed(HIWORD_UPDATE(0x2, 0x3, 10),
+                      reg_base + RK2928_CLKSEL_CON(13));
+
        ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
        if (IS_ERR(ctx)) {
                pr_err("%s: rockchip clk init failed\n", __func__);
index 695bbf9ef428f98f5348d100a6af2525f04afb59..72109d2cf41b29da83dd88dbdb0e820364c893dd 100644 (file)
@@ -80,6 +80,7 @@ config SUN6I_A31_CCU
        select SUNXI_CCU_DIV
        select SUNXI_CCU_NK
        select SUNXI_CCU_NKM
+       select SUNXI_CCU_NKMP
        select SUNXI_CCU_NM
        select SUNXI_CCU_MP
        select SUNXI_CCU_PHASE
index e3c084cc6da55e77f24bf058038bda710fd792d0..f54114c607df76edeb77c70e0f7c97656e67634c 100644 (file)
@@ -566,7 +566,7 @@ static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
                             0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
 
 /* Fixed Factor clocks */
-static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 1, 2, 0);
+static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0);
 
 /* We hardcode the divider to 4 for now */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
index 4c9a920ff4ab7c351d59333d131d039f5e36f40a..89e68d29bf456ab3d682f7d2ba7d35ad4a21bb58 100644 (file)
@@ -608,7 +608,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
                                 0x150, 0, 4, 24, 2, BIT(31),
                                 CLK_SET_RATE_PARENT);
 
-static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(31), 0);
+static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
 
 static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
 
index 22c2ca7a2a221c1f25456e6e2548d381fbc23adf..b583f186a804df669e974f811e6bef91c4aaa877 100644 (file)
@@ -85,6 +85,10 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
        unsigned int m, p;
        u32 reg;
 
+       /* Adjust parent_rate according to pre-dividers */
+       ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux,
+                                               -1, &parent_rate);
+
        reg = readl(cmp->common.base + cmp->common.reg);
 
        m = reg >> cmp->m.shift;
@@ -117,6 +121,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
        unsigned int m, p;
        u32 reg;
 
+       /* Adjust parent_rate according to pre-dividers */
+       ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux,
+                                               -1, &parent_rate);
+
        max_m = cmp->m.max ?: 1 << cmp->m.width;
        max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
 
index a2b40a0001577d2579aa563341d1d890797f4b7f..488055ed944f2b9dff8ca1baa5059ea22879328b 100644 (file)
@@ -107,7 +107,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
        p = reg >> nkmp->p.shift;
        p &= (1 << nkmp->p.width) - 1;
 
-       return parent_rate * n * k >> p / m;
+       return (parent_rate * n * k >> p) / m;
 }
 
 static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
index 8c30fec86094df926b8fa23bd162d44051894006..eb89b502acbdfdb5f343a34fde38afc1aa55683b 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <linux/init.h>
 #include <linux/of.h>
-#include <linux/clockchip.h>
+#include <linux/clockchips.h>
 
 extern struct of_device_id __clkevt_of_table[];
 
index b8ff617d449d928f97e2c4785639c07166135627..bc96d423781aa8a300725f8fbe0a052be12cd4b5 100644 (file)
@@ -918,11 +918,19 @@ static struct kobj_type ktype_cpufreq = {
        .release        = cpufreq_sysfs_release,
 };
 
-static int add_cpu_dev_symlink(struct cpufreq_policy *policy,
-                              struct device *dev)
+static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu)
 {
+       struct device *dev = get_cpu_device(cpu);
+
+       if (!dev)
+               return;
+
+       if (cpumask_test_and_set_cpu(cpu, policy->real_cpus))
+               return;
+
        dev_dbg(dev, "%s: Adding symlink\n", __func__);
-       return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
+       if (sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"))
+               dev_err(dev, "cpufreq symlink creation failed\n");
 }
 
 static void remove_cpu_dev_symlink(struct cpufreq_policy *policy,
@@ -1180,10 +1188,13 @@ static int cpufreq_online(unsigned int cpu)
                policy->user_policy.min = policy->min;
                policy->user_policy.max = policy->max;
 
-               write_lock_irqsave(&cpufreq_driver_lock, flags);
-               for_each_cpu(j, policy->related_cpus)
+               for_each_cpu(j, policy->related_cpus) {
                        per_cpu(cpufreq_cpu_data, j) = policy;
-               write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+                       add_cpu_dev_symlink(policy, j);
+               }
+       } else {
+               policy->min = policy->user_policy.min;
+               policy->max = policy->user_policy.max;
        }
 
        if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
@@ -1272,13 +1283,15 @@ out_exit_policy:
 
        if (cpufreq_driver->exit)
                cpufreq_driver->exit(policy);
+
+       for_each_cpu(j, policy->real_cpus)
+               remove_cpu_dev_symlink(policy, get_cpu_device(j));
+
 out_free_policy:
        cpufreq_policy_free(policy);
        return ret;
 }
 
-static int cpufreq_offline(unsigned int cpu);
-
 /**
  * cpufreq_add_dev - the cpufreq interface for a CPU device.
  * @dev: CPU device.
@@ -1300,16 +1313,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
 
        /* Create sysfs link on CPU registration */
        policy = per_cpu(cpufreq_cpu_data, cpu);
-       if (!policy || cpumask_test_and_set_cpu(cpu, policy->real_cpus))
-               return 0;
+       if (policy)
+               add_cpu_dev_symlink(policy, cpu);
 
-       ret = add_cpu_dev_symlink(policy, dev);
-       if (ret) {
-               cpumask_clear_cpu(cpu, policy->real_cpus);
-               cpufreq_offline(cpu);
-       }
-
-       return ret;
+       return 0;
 }
 
 static int cpufreq_offline(unsigned int cpu)
index 08e134ffba68e28656374fc55fab95345050cf8c..283491f742d3d78659696bd58c48fc5a3bd7a370 100644 (file)
@@ -364,9 +364,7 @@ static bool driver_registered __read_mostly;
 static bool acpi_ppc;
 #endif
 
-static struct perf_limits performance_limits;
-static struct perf_limits powersave_limits;
-static struct perf_limits *limits;
+static struct perf_limits global;
 
 static void intel_pstate_init_limits(struct perf_limits *limits)
 {
@@ -377,14 +375,6 @@ static void intel_pstate_init_limits(struct perf_limits *limits)
        limits->max_sysfs_pct = 100;
 }
 
-static void intel_pstate_set_performance_limits(struct perf_limits *limits)
-{
-       intel_pstate_init_limits(limits);
-       limits->min_perf_pct = 100;
-       limits->min_perf = int_ext_tofp(1);
-       limits->min_sysfs_pct = 100;
-}
-
 static DEFINE_MUTEX(intel_pstate_driver_lock);
 static DEFINE_MUTEX(intel_pstate_limits_lock);
 
@@ -507,7 +497,7 @@ static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
         * correct max turbo frequency based on the turbo state.
         * Also need to convert to MHz as _PSS freq is in MHz.
         */
-       if (!limits->turbo_disabled)
+       if (!global.turbo_disabled)
                cpu->acpi_perf_data.states[0].core_frequency =
                                        policy->cpuinfo.max_freq / 1000;
        cpu->valid_pss_table = true;
@@ -626,7 +616,7 @@ static inline void update_turbo_state(void)
 
        cpu = all_cpu_data[0];
        rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
-       limits->turbo_disabled =
+       global.turbo_disabled =
                (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ||
                 cpu->pstate.max_pstate == cpu->pstate.turbo_pstate);
 }
@@ -851,7 +841,7 @@ static struct freq_attr *hwp_cpufreq_attrs[] = {
 static void intel_pstate_hwp_set(struct cpufreq_policy *policy)
 {
        int min, hw_min, max, hw_max, cpu;
-       struct perf_limits *perf_limits = limits;
+       struct perf_limits *perf_limits = &global;
        u64 value, cap;
 
        for_each_cpu(cpu, policy->cpus) {
@@ -863,19 +853,22 @@ static void intel_pstate_hwp_set(struct cpufreq_policy *policy)
 
                rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
                hw_min = HWP_LOWEST_PERF(cap);
-               if (limits->no_turbo)
+               if (global.no_turbo)
                        hw_max = HWP_GUARANTEED_PERF(cap);
                else
                        hw_max = HWP_HIGHEST_PERF(cap);
 
-               min = fp_ext_toint(hw_max * perf_limits->min_perf);
+               max = fp_ext_toint(hw_max * perf_limits->max_perf);
+               if (cpu_data->policy == CPUFREQ_POLICY_PERFORMANCE)
+                       min = max;
+               else
+                       min = fp_ext_toint(hw_max * perf_limits->min_perf);
 
                rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
 
                value &= ~HWP_MIN_PERF(~0L);
                value |= HWP_MIN_PERF(min);
 
-               max = fp_ext_toint(hw_max * perf_limits->max_perf);
                value &= ~HWP_MAX_PERF(~0L);
                value |= HWP_MAX_PERF(max);
 
@@ -968,20 +961,11 @@ static int intel_pstate_resume(struct cpufreq_policy *policy)
 }
 
 static void intel_pstate_update_policies(void)
-       __releases(&intel_pstate_limits_lock)
-       __acquires(&intel_pstate_limits_lock)
 {
-       struct perf_limits *saved_limits = limits;
        int cpu;
 
-       mutex_unlock(&intel_pstate_limits_lock);
-
        for_each_possible_cpu(cpu)
                cpufreq_update_policy(cpu);
-
-       mutex_lock(&intel_pstate_limits_lock);
-
-       limits = saved_limits;
 }
 
 /************************** debugfs begin ************************/
@@ -1060,7 +1044,7 @@ static void intel_pstate_debug_hide_params(void)
        static ssize_t show_##file_name                                 \
        (struct kobject *kobj, struct attribute *attr, char *buf)       \
        {                                                               \
-               return sprintf(buf, "%u\n", limits->object);            \
+               return sprintf(buf, "%u\n", global.object);             \
        }
 
 static ssize_t intel_pstate_show_status(char *buf);
@@ -1151,10 +1135,10 @@ static ssize_t show_no_turbo(struct kobject *kobj,
        }
 
        update_turbo_state();
-       if (limits->turbo_disabled)
-               ret = sprintf(buf, "%u\n", limits->turbo_disabled);
+       if (global.turbo_disabled)
+               ret = sprintf(buf, "%u\n", global.turbo_disabled);
        else
-               ret = sprintf(buf, "%u\n", limits->no_turbo);
+               ret = sprintf(buf, "%u\n", global.no_turbo);
 
        mutex_unlock(&intel_pstate_driver_lock);
 
@@ -1181,19 +1165,19 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
        mutex_lock(&intel_pstate_limits_lock);
 
        update_turbo_state();
-       if (limits->turbo_disabled) {
+       if (global.turbo_disabled) {
                pr_warn("Turbo disabled by BIOS or unavailable on processor\n");
                mutex_unlock(&intel_pstate_limits_lock);
                mutex_unlock(&intel_pstate_driver_lock);
                return -EPERM;
        }
 
-       limits->no_turbo = clamp_t(int, input, 0, 1);
-
-       intel_pstate_update_policies();
+       global.no_turbo = clamp_t(int, input, 0, 1);
 
        mutex_unlock(&intel_pstate_limits_lock);
 
+       intel_pstate_update_policies();
+
        mutex_unlock(&intel_pstate_driver_lock);
 
        return count;
@@ -1218,19 +1202,16 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
 
        mutex_lock(&intel_pstate_limits_lock);
 
-       limits->max_sysfs_pct = clamp_t(int, input, 0 , 100);
-       limits->max_perf_pct = min(limits->max_policy_pct,
-                                  limits->max_sysfs_pct);
-       limits->max_perf_pct = max(limits->min_policy_pct,
-                                  limits->max_perf_pct);
-       limits->max_perf_pct = max(limits->min_perf_pct,
-                                  limits->max_perf_pct);
-       limits->max_perf = percent_ext_fp(limits->max_perf_pct);
-
-       intel_pstate_update_policies();
+       global.max_sysfs_pct = clamp_t(int, input, 0 , 100);
+       global.max_perf_pct = min(global.max_policy_pct, global.max_sysfs_pct);
+       global.max_perf_pct = max(global.min_policy_pct, global.max_perf_pct);
+       global.max_perf_pct = max(global.min_perf_pct, global.max_perf_pct);
+       global.max_perf = percent_ext_fp(global.max_perf_pct);
 
        mutex_unlock(&intel_pstate_limits_lock);
 
+       intel_pstate_update_policies();
+
        mutex_unlock(&intel_pstate_driver_lock);
 
        return count;
@@ -1255,19 +1236,16 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
 
        mutex_lock(&intel_pstate_limits_lock);
 
-       limits->min_sysfs_pct = clamp_t(int, input, 0 , 100);
-       limits->min_perf_pct = max(limits->min_policy_pct,
-                                  limits->min_sysfs_pct);
-       limits->min_perf_pct = min(limits->max_policy_pct,
-                                  limits->min_perf_pct);
-       limits->min_perf_pct = min(limits->max_perf_pct,
-                                  limits->min_perf_pct);
-       limits->min_perf = percent_ext_fp(limits->min_perf_pct);
-
-       intel_pstate_update_policies();
+       global.min_sysfs_pct = clamp_t(int, input, 0 , 100);
+       global.min_perf_pct = max(global.min_policy_pct, global.min_sysfs_pct);
+       global.min_perf_pct = min(global.max_policy_pct, global.min_perf_pct);
+       global.min_perf_pct = min(global.max_perf_pct, global.min_perf_pct);
+       global.min_perf = percent_ext_fp(global.min_perf_pct);
 
        mutex_unlock(&intel_pstate_limits_lock);
 
+       intel_pstate_update_policies();
+
        mutex_unlock(&intel_pstate_driver_lock);
 
        return count;
@@ -1387,7 +1365,7 @@ static u64 atom_get_val(struct cpudata *cpudata, int pstate)
        u32 vid;
 
        val = (u64)pstate << 8;
-       if (limits->no_turbo && !limits->turbo_disabled)
+       if (global.no_turbo && !global.turbo_disabled)
                val |= (u64)1 << 32;
 
        vid_fp = cpudata->vid.min + mul_fp(
@@ -1557,7 +1535,7 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate)
        u64 val;
 
        val = (u64)pstate << 8;
-       if (limits->no_turbo && !limits->turbo_disabled)
+       if (global.no_turbo && !global.turbo_disabled)
                val |= (u64)1 << 32;
 
        return val;
@@ -1683,9 +1661,9 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
        int max_perf = cpu->pstate.turbo_pstate;
        int max_perf_adj;
        int min_perf;
-       struct perf_limits *perf_limits = limits;
+       struct perf_limits *perf_limits = &global;
 
-       if (limits->no_turbo || limits->turbo_disabled)
+       if (global.no_turbo || global.turbo_disabled)
                max_perf = cpu->pstate.max_pstate;
 
        if (per_cpu_limits)
@@ -1820,7 +1798,7 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
 
        sample->busy_scaled = busy_frac * 100;
 
-       target = limits->no_turbo || limits->turbo_disabled ?
+       target = global.no_turbo || global.turbo_disabled ?
                        cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
        target += target >> 2;
        target = mul_fp(target, busy_frac);
@@ -2116,7 +2094,7 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
 static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 {
        struct cpudata *cpu;
-       struct perf_limits *perf_limits = NULL;
+       struct perf_limits *perf_limits = &global;
 
        if (!policy->cpuinfo.max_freq)
                return -ENODEV;
@@ -2139,21 +2117,6 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 
        mutex_lock(&intel_pstate_limits_lock);
 
-       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-               pr_debug("set performance\n");
-               if (!perf_limits) {
-                       limits = &performance_limits;
-                       perf_limits = limits;
-               }
-       } else {
-               pr_debug("set powersave\n");
-               if (!perf_limits) {
-                       limits = &powersave_limits;
-                       perf_limits = limits;
-               }
-
-       }
-
        intel_pstate_update_perf_limits(policy, perf_limits);
 
        if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
@@ -2177,16 +2140,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
 {
        struct cpudata *cpu = all_cpu_data[policy->cpu];
-       struct perf_limits *perf_limits;
-
-       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
-               perf_limits = &performance_limits;
-       else
-               perf_limits = &powersave_limits;
 
        update_turbo_state();
-       policy->cpuinfo.max_freq = perf_limits->turbo_disabled ||
-                                       perf_limits->no_turbo ?
+       policy->cpuinfo.max_freq = global.turbo_disabled || global.no_turbo ?
                                        cpu->pstate.max_freq :
                                        cpu->pstate.turbo_freq;
 
@@ -2201,9 +2157,9 @@ static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
                unsigned int max_freq, min_freq;
 
                max_freq = policy->cpuinfo.max_freq *
-                                       perf_limits->max_sysfs_pct / 100;
+                                       global.max_sysfs_pct / 100;
                min_freq = policy->cpuinfo.max_freq *
-                                       perf_limits->min_sysfs_pct / 100;
+                                       global.min_sysfs_pct / 100;
                cpufreq_verify_within_limits(policy, min_freq, max_freq);
        }
 
@@ -2255,7 +2211,7 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
        /* cpuinfo and default policy values */
        policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling;
        update_turbo_state();
-       policy->cpuinfo.max_freq = limits->turbo_disabled ?
+       policy->cpuinfo.max_freq = global.turbo_disabled ?
                        cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
        policy->cpuinfo.max_freq *= cpu->pstate.scaling;
 
@@ -2275,7 +2231,7 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
                return ret;
 
        policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-       if (limits->min_perf_pct == 100 && limits->max_perf_pct == 100)
+       if (IS_ENABLED(CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE))
                policy->policy = CPUFREQ_POLICY_PERFORMANCE;
        else
                policy->policy = CPUFREQ_POLICY_POWERSAVE;
@@ -2301,7 +2257,7 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
        struct cpudata *cpu = all_cpu_data[policy->cpu];
 
        update_turbo_state();
-       policy->cpuinfo.max_freq = limits->turbo_disabled ?
+       policy->cpuinfo.max_freq = global.no_turbo || global.turbo_disabled ?
                        cpu->pstate.max_freq : cpu->pstate.turbo_freq;
 
        cpufreq_verify_within_cpu_limits(policy);
@@ -2309,26 +2265,6 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
        return 0;
 }
 
-static unsigned int intel_cpufreq_turbo_update(struct cpudata *cpu,
-                                              struct cpufreq_policy *policy,
-                                              unsigned int target_freq)
-{
-       unsigned int max_freq;
-
-       update_turbo_state();
-
-       max_freq = limits->no_turbo || limits->turbo_disabled ?
-                       cpu->pstate.max_freq : cpu->pstate.turbo_freq;
-       policy->cpuinfo.max_freq = max_freq;
-       if (policy->max > max_freq)
-               policy->max = max_freq;
-
-       if (target_freq > max_freq)
-               target_freq = max_freq;
-
-       return target_freq;
-}
-
 static int intel_cpufreq_target(struct cpufreq_policy *policy,
                                unsigned int target_freq,
                                unsigned int relation)
@@ -2337,8 +2273,10 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
        struct cpufreq_freqs freqs;
        int target_pstate;
 
+       update_turbo_state();
+
        freqs.old = policy->cur;
-       freqs.new = intel_cpufreq_turbo_update(cpu, policy, target_freq);
+       freqs.new = target_freq;
 
        cpufreq_freq_transition_begin(policy, &freqs);
        switch (relation) {
@@ -2370,7 +2308,8 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
        struct cpudata *cpu = all_cpu_data[policy->cpu];
        int target_pstate;
 
-       target_freq = intel_cpufreq_turbo_update(cpu, policy, target_freq);
+       update_turbo_state();
+
        target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling);
        target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
        intel_pstate_update_pstate(cpu, target_pstate);
@@ -2425,13 +2364,7 @@ static int intel_pstate_register_driver(void)
 {
        int ret;
 
-       intel_pstate_init_limits(&powersave_limits);
-       intel_pstate_set_performance_limits(&performance_limits);
-       if (IS_ENABLED(CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE) &&
-           intel_pstate_driver == &intel_pstate)
-               limits = &performance_limits;
-       else
-               limits = &powersave_limits;
+       intel_pstate_init_limits(&global);
 
        ret = cpufreq_register_driver(intel_pstate_driver);
        if (ret) {
index 370593006f5f76db29a0433912966cb49820346d..cda8f62d555b57700daded5a5214c8e88ffca4ee 100644 (file)
@@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void)
                drv->state_count += 1;
        }
 
+       /*
+        * On the PowerNV platform cpu_present may be less than cpu_possible in
+        * cases when firmware detects the CPU, but it is not available to the
+        * OS.  If CONFIG_HOTPLUG_CPU=n, then such CPUs are not hotplugable at
+        * run time and hence cpu_devices are not created for those CPUs by the
+        * generic topology_init().
+        *
+        * drv->cpumask defaults to cpu_possible_mask in
+        * __cpuidle_driver_init().  This breaks cpuidle on PowerNV where
+        * cpu_devices are not created for CPUs in cpu_possible_mask that
+        * cannot be hot-added later at run time.
+        *
+        * Trying cpuidle_register_device() on a CPU without a cpu_device is
+        * incorrect, so pass a correct CPU mask to the generic cpuidle driver.
+        */
+
+       drv->cpumask = (struct cpumask *)cpu_present_mask;
+
        return 0;
 }
 
index c5adc8c9ac43afeffb0f7ca842f730df76ef8eb1..ae948b1da93a379b12d16aaf98be5df6ac762da4 100644 (file)
@@ -615,6 +615,18 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev)
        struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
        int error;
 
+       /*
+        * Return if cpu_device is not setup for this CPU.
+        *
+        * This could happen if the arch did not set up cpu_device
+        * since this CPU is not in cpu_present mask and the
+        * driver did not send a correct CPU mask during registration.
+        * Without this check we would end up passing bogus
+        * value for &cpu_dev->kobj in kobject_init_and_add()
+        */
+       if (!cpu_dev)
+               return -ENODEV;
+
        kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
        if (!kdev)
                return -ENOMEM;
index 41cc853f8569cfd4825806028331ed5d98f005c0..fc08b4ed69d936f2866d5c9fef19450b852f900c 100644 (file)
@@ -1015,6 +1015,7 @@ const struct ccp_vdata ccpv5a = {
 
 const struct ccp_vdata ccpv5b = {
        .version = CCP_VERSION(5, 0),
+       .dma_chan_attr = DMA_PRIVATE,
        .setup = ccp5other_config,
        .perform = &ccp5_actions,
        .bar = 2,
index 511ab042b5e7939b008045129de0c9e268f2db46..92d1c6959f08b8943f513a9ed5fd8525c2d6b702 100644 (file)
@@ -283,11 +283,14 @@ EXPORT_SYMBOL_GPL(ccp_version);
  */
 int ccp_enqueue_cmd(struct ccp_cmd *cmd)
 {
-       struct ccp_device *ccp = ccp_get_device();
+       struct ccp_device *ccp;
        unsigned long flags;
        unsigned int i;
        int ret;
 
+       /* Some commands might need to be sent to a specific device */
+       ccp = cmd->ccp ? cmd->ccp : ccp_get_device();
+
        if (!ccp)
                return -ENODEV;
 
index 2b5c01fade05a526d5e78241eab38ec16e790aa6..aa36f3f81860560a442687518f78a0e752a9c11b 100644 (file)
 
 /* ------------------------ General CCP Defines ------------------------ */
 
+#define        CCP_DMA_DFLT                    0x0
+#define        CCP_DMA_PRIV                    0x1
+#define        CCP_DMA_PUB                     0x2
+
 #define CCP_DMAPOOL_MAX_SIZE           64
 #define CCP_DMAPOOL_ALIGN              BIT(5)
 
@@ -636,6 +640,7 @@ struct ccp_actions {
 /* Structure to hold CCP version-specific values */
 struct ccp_vdata {
        const unsigned int version;
+       const unsigned int dma_chan_attr;
        void (*setup)(struct ccp_device *);
        const struct ccp_actions *perform;
        const unsigned int bar;
index e5d9278f40197427e913993fe9249d405585fe87..e00be01fbf5a036fcd8a9f09234b581998b7b75f 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/dmaengine.h>
 #include <linux/spinlock.h>
        (mask == 0) ? 64 : fls64(mask); \
 })
 
+/* The CCP as a DMA provider can be configured for public or private
+ * channels. Default is specified in the vdata for the device (PCI ID).
+ * This module parameter will override for all channels on all devices:
+ *   dma_chan_attr = 0x2 to force all channels public
+ *                 = 0x1 to force all channels private
+ *                 = 0x0 to defer to the vdata setting
+ *                 = any other value: warning, revert to 0x0
+ */
+static unsigned int dma_chan_attr = CCP_DMA_DFLT;
+module_param(dma_chan_attr, uint, 0444);
+MODULE_PARM_DESC(dma_chan_attr, "Set DMA channel visibility: 0 (default) = device defaults, 1 = make private, 2 = make public");
+
+unsigned int ccp_get_dma_chan_attr(struct ccp_device *ccp)
+{
+       switch (dma_chan_attr) {
+       case CCP_DMA_DFLT:
+               return ccp->vdata->dma_chan_attr;
+
+       case CCP_DMA_PRIV:
+               return DMA_PRIVATE;
+
+       case CCP_DMA_PUB:
+               return 0;
+
+       default:
+               dev_info_once(ccp->dev, "Invalid value for dma_chan_attr: %d\n",
+                             dma_chan_attr);
+               return ccp->vdata->dma_chan_attr;
+       }
+}
+
 static void ccp_free_cmd_resources(struct ccp_device *ccp,
                                   struct list_head *list)
 {
@@ -390,6 +422,7 @@ static struct ccp_dma_desc *ccp_create_desc(struct dma_chan *dma_chan,
                        goto err;
 
                ccp_cmd = &cmd->ccp_cmd;
+               ccp_cmd->ccp = chan->ccp;
                ccp_pt = &ccp_cmd->u.passthru_nomap;
                ccp_cmd->flags = CCP_CMD_MAY_BACKLOG;
                ccp_cmd->flags |= CCP_CMD_PASSTHRU_NO_DMA_MAP;
@@ -674,6 +707,15 @@ int ccp_dmaengine_register(struct ccp_device *ccp)
        dma_cap_set(DMA_SG, dma_dev->cap_mask);
        dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask);
 
+       /* The DMA channels for this device can be set to public or private,
+        * and overridden by the module parameter dma_chan_attr.
+        * Default: according to the value in vdata (dma_chan_attr=0)
+        * dma_chan_attr=0x1: all channels private (override vdata)
+        * dma_chan_attr=0x2: all channels public (override vdata)
+        */
+       if (ccp_get_dma_chan_attr(ccp) == DMA_PRIVATE)
+               dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask);
+
        INIT_LIST_HEAD(&dma_dev->channels);
        for (i = 0; i < ccp->cmd_q_count; i++) {
                chan = ccp->ccp_dma_chan + i;
index e18dc596cf2447fa9ef7e41b62d9396e29043426..6204cc32d09c5096df8aec304c3c37b3bcb6be44 100644 (file)
@@ -251,8 +251,11 @@ static void bcm2835_dma_create_cb_set_length(
         */
 
        /* have we filled in period_length yet? */
-       if (*total_len + control_block->length < period_len)
+       if (*total_len + control_block->length < period_len) {
+               /* update number of bytes in this period so far */
+               *total_len += control_block->length;
                return;
+       }
 
        /* calculate the length that remains to reach period_length */
        control_block->length = period_len - *total_len;
index 24e0221fd66d1ff58eead62ee9f4a865eb87da03..d9118ec23025417eb6732542d653ac989cee05e1 100644 (file)
@@ -1108,12 +1108,14 @@ static struct dmaengine_unmap_pool *__get_unmap_pool(int nr)
        switch (order) {
        case 0 ... 1:
                return &unmap_pool[0];
+#if IS_ENABLED(CONFIG_DMA_ENGINE_RAID)
        case 2 ... 4:
                return &unmap_pool[1];
        case 5 ... 7:
                return &unmap_pool[2];
        case 8:
                return &unmap_pool[3];
+#endif
        default:
                BUG();
                return NULL;
index 82d85cce81f815b9b8bf70352e3bdeeece2d7d41..4773f286723414fec52bde6d8396bab8bfece386 100644 (file)
@@ -43,6 +43,7 @@ config EDAC_LEGACY_SYSFS
 
 config EDAC_DEBUG
        bool "Debugging"
+       select DEBUG_FS
        help
          This turns on debugging information for the entire EDAC subsystem.
          You do so by inserting edac_module with "edac_debug_level=x." Valid
@@ -259,6 +260,15 @@ config EDAC_SKX
          Support for error detection and correction the Intel
          Skylake server Integrated Memory Controllers.
 
+config EDAC_PND2
+       tristate "Intel Pondicherry2"
+       depends on EDAC_MM_EDAC && PCI && X86_64 && X86_MCE_INTEL
+       help
+         Support for error detection and correction on the Intel
+         Pondicherry2 Integrated Memory Controller. This SoC IP is
+         first used on the Apollo Lake platform and Denverton
+         micro-server but may appear on others in the future.
+
 config EDAC_MPC85XX
        tristate "Freescale MPC83xx / MPC85xx"
        depends on EDAC_MM_EDAC && FSL_SOC
index 88e472e8b9a918e36e65b4385c9c412f92c7cea3..587107e909967d56056df688624474bca4da3cac 100644 (file)
@@ -32,6 +32,7 @@ obj-$(CONFIG_EDAC_I7300)              += i7300_edac.o
 obj-$(CONFIG_EDAC_I7CORE)              += i7core_edac.o
 obj-$(CONFIG_EDAC_SBRIDGE)             += sb_edac.o
 obj-$(CONFIG_EDAC_SKX)                 += skx_edac.o
+obj-$(CONFIG_EDAC_PND2)                        += pnd2_edac.o
 obj-$(CONFIG_EDAC_E7XXX)               += e7xxx_edac.o
 obj-$(CONFIG_EDAC_E752X)               += e752x_edac.o
 obj-$(CONFIG_EDAC_I82443BXGX)          += i82443bxgx_edac.o
index 1670d27bcac82d51cbb3de30d75e261100ddb83e..f683919981b06730090c2a11b98d45a5c0713944 100644 (file)
@@ -1293,7 +1293,7 @@ static int i5000_init_csrows(struct mem_ctl_info *mci)
                        dimm->mtype = MEM_FB_DDR2;
 
                        /* ask what device type on this row */
-                       if (MTR_DRAM_WIDTH(mtr))
+                       if (MTR_DRAM_WIDTH(mtr) == 8)
                                dimm->dtype = DEV_X8;
                        else
                                dimm->dtype = DEV_X4;
index abf6ef22e220602f48559504ec18e77c5115de5b..37a9ba71da449bab30c12438325ecc419d9fa3e8 100644 (file)
@@ -1207,13 +1207,14 @@ static int i5400_init_dimms(struct mem_ctl_info *mci)
 
                        dimm->nr_pages = size_mb << 8;
                        dimm->grain = 8;
-                       dimm->dtype = MTR_DRAM_WIDTH(mtr) ? DEV_X8 : DEV_X4;
+                       dimm->dtype = MTR_DRAM_WIDTH(mtr) == 8 ?
+                                     DEV_X8 : DEV_X4;
                        dimm->mtype = MEM_FB_DDR2;
                        /*
                         * The eccc mechanism is SDDC (aka SECC), with
                         * is similar to Chipkill.
                         */
-                       dimm->edac_mode = MTR_DRAM_WIDTH(mtr) ?
+                       dimm->edac_mode = MTR_DRAM_WIDTH(mtr) == 8 ?
                                          EDAC_S8ECD8ED : EDAC_S4ECD4ED;
                        ndimms++;
                }
diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c
new file mode 100644 (file)
index 0000000..928e0db
--- /dev/null
@@ -0,0 +1,1546 @@
+/*
+ * Driver for Pondicherry2 memory controller.
+ *
+ * Copyright (c) 2016, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * [Derived from sb_edac.c]
+ *
+ * Translation of system physical addresses to DIMM addresses
+ * is a two stage process:
+ *
+ * First the Pondicherry 2 memory controller handles slice and channel interleaving
+ * in "sys2pmi()". This is (almost) completley common between platforms.
+ *
+ * Then a platform specific dunit (DIMM unit) completes the process to provide DIMM,
+ * rank, bank, row and column using the appropriate "dunit_ops" functions/parameters.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/edac.h>
+#include <linux/mmzone.h>
+#include <linux/smp.h>
+#include <linux/bitmap.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+#include <asm/processor.h>
+#include <asm/mce.h>
+
+#include "edac_mc.h"
+#include "edac_module.h"
+#include "pnd2_edac.h"
+
+#define APL_NUM_CHANNELS       4
+#define DNV_NUM_CHANNELS       2
+#define DNV_MAX_DIMMS          2 /* Max DIMMs per channel */
+
+enum type {
+       APL,
+       DNV, /* All requests go to PMI CH0 on each slice (CH1 disabled) */
+};
+
+struct dram_addr {
+       int chan;
+       int dimm;
+       int rank;
+       int bank;
+       int row;
+       int col;
+};
+
+struct pnd2_pvt {
+       int dimm_geom[APL_NUM_CHANNELS];
+       u64 tolm, tohm;
+};
+
+/*
+ * System address space is divided into multiple regions with
+ * different interleave rules in each. The as0/as1 regions
+ * have no interleaving at all. The as2 region is interleaved
+ * between two channels. The mot region is magic and may overlap
+ * other regions, with its interleave rules taking precedence.
+ * Addresses not in any of these regions are interleaved across
+ * all four channels.
+ */
+static struct region {
+       u64     base;
+       u64     limit;
+       u8      enabled;
+} mot, as0, as1, as2;
+
+static struct dunit_ops {
+       char *name;
+       enum type type;
+       int pmiaddr_shift;
+       int pmiidx_shift;
+       int channels;
+       int dimms_per_channel;
+       int (*rd_reg)(int port, int off, int op, void *data, size_t sz, char *name);
+       int (*get_registers)(void);
+       int (*check_ecc)(void);
+       void (*mk_region)(char *name, struct region *rp, void *asym);
+       void (*get_dimm_config)(struct mem_ctl_info *mci);
+       int (*pmi2mem)(struct mem_ctl_info *mci, u64 pmiaddr, u32 pmiidx,
+                                  struct dram_addr *daddr, char *msg);
+} *ops;
+
+static struct mem_ctl_info *pnd2_mci;
+
+#define PND2_MSG_SIZE  256
+
+/* Debug macros */
+#define pnd2_printk(level, fmt, arg...)                        \
+       edac_printk(level, "pnd2", fmt, ##arg)
+
+#define pnd2_mc_printk(mci, level, fmt, arg...)        \
+       edac_mc_chipset_printk(mci, level, "pnd2", fmt, ##arg)
+
+#define MOT_CHAN_INTLV_BIT_1SLC_2CH 12
+#define MOT_CHAN_INTLV_BIT_2SLC_2CH 13
+#define SELECTOR_DISABLED (-1)
+#define _4GB (1ul << 32)
+
+#define PMI_ADDRESS_WIDTH      31
+#define PND_MAX_PHYS_BIT       39
+
+#define APL_ASYMSHIFT          28
+#define DNV_ASYMSHIFT          31
+#define CH_HASH_MASK_LSB       6
+#define SLICE_HASH_MASK_LSB    6
+#define MOT_SLC_INTLV_BIT      12
+#define LOG2_PMI_ADDR_GRANULARITY      5
+#define MOT_SHIFT      24
+
+#define GET_BITFIELD(v, lo, hi)        (((v) & GENMASK_ULL(hi, lo)) >> (lo))
+#define U64_LSHIFT(val, s)     ((u64)(val) << (s))
+
+#ifdef CONFIG_X86_INTEL_SBI_APL
+#include "linux/platform_data/sbi_apl.h"
+int sbi_send(int port, int off, int op, u32 *data)
+{
+       struct sbi_apl_message sbi_arg;
+       int ret, read = 0;
+
+       memset(&sbi_arg, 0, sizeof(sbi_arg));
+
+       if (op == 0 || op == 4 || op == 6)
+               read = 1;
+       else
+               sbi_arg.data = *data;
+
+       sbi_arg.opcode = op;
+       sbi_arg.port_address = port;
+       sbi_arg.register_offset = off;
+       ret = sbi_apl_commit(&sbi_arg);
+       if (ret || sbi_arg.status)
+               edac_dbg(2, "sbi_send status=%d ret=%d data=%x\n",
+                                sbi_arg.status, ret, sbi_arg.data);
+
+       if (ret == 0)
+               ret = sbi_arg.status;
+
+       if (ret == 0 && read)
+               *data = sbi_arg.data;
+
+       return ret;
+}
+#else
+int sbi_send(int port, int off, int op, u32 *data)
+{
+       return -EUNATCH;
+}
+#endif
+
+static int apl_rd_reg(int port, int off, int op, void *data, size_t sz, char *name)
+{
+       int     ret = 0;
+
+       edac_dbg(2, "Read %s port=%x off=%x op=%x\n", name, port, off, op);
+       switch (sz) {
+       case 8:
+               ret = sbi_send(port, off + 4, op, (u32 *)(data + 4));
+       case 4:
+               ret = sbi_send(port, off, op, (u32 *)data);
+               pnd2_printk(KERN_DEBUG, "%s=%x%08x ret=%d\n", name,
+                                       sz == 8 ? *((u32 *)(data + 4)) : 0, *((u32 *)data), ret);
+               break;
+       }
+
+       return ret;
+}
+
+static u64 get_mem_ctrl_hub_base_addr(void)
+{
+       struct b_cr_mchbar_lo_pci lo;
+       struct b_cr_mchbar_hi_pci hi;
+       struct pci_dev *pdev;
+
+       pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x1980, NULL);
+       if (pdev) {
+               pci_read_config_dword(pdev, 0x48, (u32 *)&lo);
+               pci_read_config_dword(pdev, 0x4c, (u32 *)&hi);
+               pci_dev_put(pdev);
+       } else {
+               return 0;
+       }
+
+       if (!lo.enable) {
+               edac_dbg(2, "MMIO via memory controller hub base address is disabled!\n");
+               return 0;
+       }
+
+       return U64_LSHIFT(hi.base, 32) | U64_LSHIFT(lo.base, 15);
+}
+
+static u64 get_sideband_reg_base_addr(void)
+{
+       struct pci_dev *pdev;
+       u32 hi, lo;
+
+       pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x19dd, NULL);
+       if (pdev) {
+               pci_read_config_dword(pdev, 0x10, &lo);
+               pci_read_config_dword(pdev, 0x14, &hi);
+               pci_dev_put(pdev);
+               return (U64_LSHIFT(hi, 32) | U64_LSHIFT(lo, 0));
+       } else {
+               return 0xfd000000;
+       }
+}
+
+static int dnv_rd_reg(int port, int off, int op, void *data, size_t sz, char *name)
+{
+       struct pci_dev *pdev;
+       char *base;
+       u64 addr;
+
+       if (op == 4) {
+               pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x1980, NULL);
+               if (!pdev)
+                       return -ENODEV;
+
+               pci_read_config_dword(pdev, off, data);
+               pci_dev_put(pdev);
+       } else {
+               /* MMIO via memory controller hub base address */
+               if (op == 0 && port == 0x4c) {
+                       addr = get_mem_ctrl_hub_base_addr();
+                       if (!addr)
+                               return -ENODEV;
+               } else {
+                       /* MMIO via sideband register base address */
+                       addr = get_sideband_reg_base_addr();
+                       if (!addr)
+                               return -ENODEV;
+                       addr += (port << 16);
+               }
+
+               base = ioremap((resource_size_t)addr, 0x10000);
+               if (!base)
+                       return -ENODEV;
+
+               if (sz == 8)
+                       *(u32 *)(data + 4) = *(u32 *)(base + off + 4);
+               *(u32 *)data = *(u32 *)(base + off);
+
+               iounmap(base);
+       }
+
+       edac_dbg(2, "Read %s=%.8x_%.8x\n", name,
+                       (sz == 8) ? *(u32 *)(data + 4) : 0, *(u32 *)data);
+
+       return 0;
+}
+
+#define RD_REGP(regp, regname, port)   \
+       ops->rd_reg(port,                                       \
+               regname##_offset,                               \
+               regname##_r_opcode,                             \
+               regp, sizeof(struct regname),   \
+               #regname)
+
+#define RD_REG(regp, regname)                  \
+       ops->rd_reg(regname ## _port,           \
+               regname##_offset,                               \
+               regname##_r_opcode,                             \
+               regp, sizeof(struct regname),   \
+               #regname)
+
+static u64 top_lm, top_hm;
+static bool two_slices;
+static bool two_channels; /* Both PMI channels in one slice enabled */
+
+static u8 sym_chan_mask;
+static u8 asym_chan_mask;
+static u8 chan_mask;
+
+static int slice_selector = -1;
+static int chan_selector = -1;
+static u64 slice_hash_mask;
+static u64 chan_hash_mask;
+
+static void mk_region(char *name, struct region *rp, u64 base, u64 limit)
+{
+       rp->enabled = 1;
+       rp->base = base;
+       rp->limit = limit;
+       edac_dbg(2, "Region:%s [%llx, %llx]\n", name, base, limit);
+}
+
+static void mk_region_mask(char *name, struct region *rp, u64 base, u64 mask)
+{
+       if (mask == 0) {
+               pr_info(FW_BUG "MOT mask cannot be zero\n");
+               return;
+       }
+       if (mask != GENMASK_ULL(PND_MAX_PHYS_BIT, __ffs(mask))) {
+               pr_info(FW_BUG "MOT mask not power of two\n");
+               return;
+       }
+       if (base & ~mask) {
+               pr_info(FW_BUG "MOT region base/mask alignment error\n");
+               return;
+       }
+       rp->base = base;
+       rp->limit = (base | ~mask) & GENMASK_ULL(PND_MAX_PHYS_BIT, 0);
+       rp->enabled = 1;
+       edac_dbg(2, "Region:%s [%llx, %llx]\n", name, base, rp->limit);
+}
+
+static bool in_region(struct region *rp, u64 addr)
+{
+       if (!rp->enabled)
+               return false;
+
+       return rp->base <= addr && addr <= rp->limit;
+}
+
+static int gen_sym_mask(struct b_cr_slice_channel_hash *p)
+{
+       int mask = 0;
+
+       if (!p->slice_0_mem_disabled)
+               mask |= p->sym_slice0_channel_enabled;
+
+       if (!p->slice_1_disabled)
+               mask |= p->sym_slice1_channel_enabled << 2;
+
+       if (p->ch_1_disabled || p->enable_pmi_dual_data_mode)
+               mask &= 0x5;
+
+       return mask;
+}
+
+static int gen_asym_mask(struct b_cr_slice_channel_hash *p,
+                        struct b_cr_asym_mem_region0_mchbar *as0,
+                        struct b_cr_asym_mem_region1_mchbar *as1,
+                        struct b_cr_asym_2way_mem_region_mchbar *as2way)
+{
+       const int intlv[] = { 0x5, 0xA, 0x3, 0xC };
+       int mask = 0;
+
+       if (as2way->asym_2way_interleave_enable)
+               mask = intlv[as2way->asym_2way_intlv_mode];
+       if (as0->slice0_asym_enable)
+               mask |= (1 << as0->slice0_asym_channel_select);
+       if (as1->slice1_asym_enable)
+               mask |= (4 << as1->slice1_asym_channel_select);
+       if (p->slice_0_mem_disabled)
+               mask &= 0xc;
+       if (p->slice_1_disabled)
+               mask &= 0x3;
+       if (p->ch_1_disabled || p->enable_pmi_dual_data_mode)
+               mask &= 0x5;
+
+       return mask;
+}
+
+static struct b_cr_tolud_pci tolud;
+static struct b_cr_touud_lo_pci touud_lo;
+static struct b_cr_touud_hi_pci touud_hi;
+static struct b_cr_asym_mem_region0_mchbar asym0;
+static struct b_cr_asym_mem_region1_mchbar asym1;
+static struct b_cr_asym_2way_mem_region_mchbar asym_2way;
+static struct b_cr_mot_out_base_mchbar mot_base;
+static struct b_cr_mot_out_mask_mchbar mot_mask;
+static struct b_cr_slice_channel_hash chash;
+
+/* Apollo Lake dunit */
+/*
+ * Validated on board with just two DIMMs in the [0] and [2] positions
+ * in this array. Other port number matches documentation, but caution
+ * advised.
+ */
+static const int apl_dports[APL_NUM_CHANNELS] = { 0x18, 0x10, 0x11, 0x19 };
+static struct d_cr_drp0 drp0[APL_NUM_CHANNELS];
+
+/* Denverton dunit */
+static const int dnv_dports[DNV_NUM_CHANNELS] = { 0x10, 0x12 };
+static struct d_cr_dsch dsch;
+static struct d_cr_ecc_ctrl ecc_ctrl[DNV_NUM_CHANNELS];
+static struct d_cr_drp drp[DNV_NUM_CHANNELS];
+static struct d_cr_dmap dmap[DNV_NUM_CHANNELS];
+static struct d_cr_dmap1 dmap1[DNV_NUM_CHANNELS];
+static struct d_cr_dmap2 dmap2[DNV_NUM_CHANNELS];
+static struct d_cr_dmap3 dmap3[DNV_NUM_CHANNELS];
+static struct d_cr_dmap4 dmap4[DNV_NUM_CHANNELS];
+static struct d_cr_dmap5 dmap5[DNV_NUM_CHANNELS];
+
+static void apl_mk_region(char *name, struct region *rp, void *asym)
+{
+       struct b_cr_asym_mem_region0_mchbar *a = asym;
+
+       mk_region(name, rp,
+                         U64_LSHIFT(a->slice0_asym_base, APL_ASYMSHIFT),
+                         U64_LSHIFT(a->slice0_asym_limit, APL_ASYMSHIFT) +
+                         GENMASK_ULL(APL_ASYMSHIFT - 1, 0));
+}
+
+static void dnv_mk_region(char *name, struct region *rp, void *asym)
+{
+       struct b_cr_asym_mem_region_denverton *a = asym;
+
+       mk_region(name, rp,
+                         U64_LSHIFT(a->slice_asym_base, DNV_ASYMSHIFT),
+                         U64_LSHIFT(a->slice_asym_limit, DNV_ASYMSHIFT) +
+                         GENMASK_ULL(DNV_ASYMSHIFT - 1, 0));
+}
+
+static int apl_get_registers(void)
+{
+       int i;
+
+       if (RD_REG(&asym_2way, b_cr_asym_2way_mem_region_mchbar))
+               return -ENODEV;
+
+       for (i = 0; i < APL_NUM_CHANNELS; i++)
+               if (RD_REGP(&drp0[i], d_cr_drp0, apl_dports[i]))
+                       return -ENODEV;
+
+       return 0;
+}
+
+static int dnv_get_registers(void)
+{
+       int i;
+
+       if (RD_REG(&dsch, d_cr_dsch))
+               return -ENODEV;
+
+       for (i = 0; i < DNV_NUM_CHANNELS; i++)
+               if (RD_REGP(&ecc_ctrl[i], d_cr_ecc_ctrl, dnv_dports[i]) ||
+                       RD_REGP(&drp[i], d_cr_drp, dnv_dports[i]) ||
+                       RD_REGP(&dmap[i], d_cr_dmap, dnv_dports[i]) ||
+                       RD_REGP(&dmap1[i], d_cr_dmap1, dnv_dports[i]) ||
+                       RD_REGP(&dmap2[i], d_cr_dmap2, dnv_dports[i]) ||
+                       RD_REGP(&dmap3[i], d_cr_dmap3, dnv_dports[i]) ||
+                       RD_REGP(&dmap4[i], d_cr_dmap4, dnv_dports[i]) ||
+                       RD_REGP(&dmap5[i], d_cr_dmap5, dnv_dports[i]))
+                       return -ENODEV;
+
+       return 0;
+}
+
+/*
+ * Read all the h/w config registers once here (they don't
+ * change at run time. Figure out which address ranges have
+ * which interleave characteristics.
+ */
+static int get_registers(void)
+{
+       const int intlv[] = { 10, 11, 12, 12 };
+
+       if (RD_REG(&tolud, b_cr_tolud_pci) ||
+               RD_REG(&touud_lo, b_cr_touud_lo_pci) ||
+               RD_REG(&touud_hi, b_cr_touud_hi_pci) ||
+               RD_REG(&asym0, b_cr_asym_mem_region0_mchbar) ||
+               RD_REG(&asym1, b_cr_asym_mem_region1_mchbar) ||
+               RD_REG(&mot_base, b_cr_mot_out_base_mchbar) ||
+               RD_REG(&mot_mask, b_cr_mot_out_mask_mchbar) ||
+               RD_REG(&chash, b_cr_slice_channel_hash))
+               return -ENODEV;
+
+       if (ops->get_registers())
+               return -ENODEV;
+
+       if (ops->type == DNV) {
+               /* PMI channel idx (always 0) for asymmetric region */
+               asym0.slice0_asym_channel_select = 0;
+               asym1.slice1_asym_channel_select = 0;
+               /* PMI channel bitmap (always 1) for symmetric region */
+               chash.sym_slice0_channel_enabled = 0x1;
+               chash.sym_slice1_channel_enabled = 0x1;
+       }
+
+       if (asym0.slice0_asym_enable)
+               ops->mk_region("as0", &as0, &asym0);
+
+       if (asym1.slice1_asym_enable)
+               ops->mk_region("as1", &as1, &asym1);
+
+       if (asym_2way.asym_2way_interleave_enable) {
+               mk_region("as2way", &as2,
+                                 U64_LSHIFT(asym_2way.asym_2way_base, APL_ASYMSHIFT),
+                                 U64_LSHIFT(asym_2way.asym_2way_limit, APL_ASYMSHIFT) +
+                                 GENMASK_ULL(APL_ASYMSHIFT - 1, 0));
+       }
+
+       if (mot_base.imr_en) {
+               mk_region_mask("mot", &mot,
+                                          U64_LSHIFT(mot_base.mot_out_base, MOT_SHIFT),
+                                          U64_LSHIFT(mot_mask.mot_out_mask, MOT_SHIFT));
+       }
+
+       top_lm = U64_LSHIFT(tolud.tolud, 20);
+       top_hm = U64_LSHIFT(touud_hi.touud, 32) | U64_LSHIFT(touud_lo.touud, 20);
+
+       two_slices = !chash.slice_1_disabled &&
+                                !chash.slice_0_mem_disabled &&
+                                (chash.sym_slice0_channel_enabled != 0) &&
+                                (chash.sym_slice1_channel_enabled != 0);
+       two_channels = !chash.ch_1_disabled &&
+                                !chash.enable_pmi_dual_data_mode &&
+                                ((chash.sym_slice0_channel_enabled == 3) ||
+                                (chash.sym_slice1_channel_enabled == 3));
+
+       sym_chan_mask = gen_sym_mask(&chash);
+       asym_chan_mask = gen_asym_mask(&chash, &asym0, &asym1, &asym_2way);
+       chan_mask = sym_chan_mask | asym_chan_mask;
+
+       if (two_slices && !two_channels) {
+               if (chash.hvm_mode)
+                       slice_selector = 29;
+               else
+                       slice_selector = intlv[chash.interleave_mode];
+       } else if (!two_slices && two_channels) {
+               if (chash.hvm_mode)
+                       chan_selector = 29;
+               else
+                       chan_selector = intlv[chash.interleave_mode];
+       } else if (two_slices && two_channels) {
+               if (chash.hvm_mode) {
+                       slice_selector = 29;
+                       chan_selector = 30;
+               } else {
+                       slice_selector = intlv[chash.interleave_mode];
+                       chan_selector = intlv[chash.interleave_mode] + 1;
+               }
+       }
+
+       if (two_slices) {
+               if (!chash.hvm_mode)
+                       slice_hash_mask = chash.slice_hash_mask << SLICE_HASH_MASK_LSB;
+               if (!two_channels)
+                       slice_hash_mask |= BIT_ULL(slice_selector);
+       }
+
+       if (two_channels) {
+               if (!chash.hvm_mode)
+                       chan_hash_mask = chash.ch_hash_mask << CH_HASH_MASK_LSB;
+               if (!two_slices)
+                       chan_hash_mask |= BIT_ULL(chan_selector);
+       }
+
+       return 0;
+}
+
+/* Get a contiguous memory address (remove the MMIO gap) */
+static u64 remove_mmio_gap(u64 sys)
+{
+       return (sys < _4GB) ? sys : sys - (_4GB - top_lm);
+}
+
+/* Squeeze out one address bit, shift upper part down to fill gap */
+static void remove_addr_bit(u64 *addr, int bitidx)
+{
+       u64     mask;
+
+       if (bitidx == -1)
+               return;
+
+       mask = (1ull << bitidx) - 1;
+       *addr = ((*addr >> 1) & ~mask) | (*addr & mask);
+}
+
+/* XOR all the bits from addr specified in mask */
+static int hash_by_mask(u64 addr, u64 mask)
+{
+       u64 result = addr & mask;
+
+       result = (result >> 32) ^ result;
+       result = (result >> 16) ^ result;
+       result = (result >> 8) ^ result;
+       result = (result >> 4) ^ result;
+       result = (result >> 2) ^ result;
+       result = (result >> 1) ^ result;
+
+       return (int)result & 1;
+}
+
+/*
+ * First stage decode. Take the system address and figure out which
+ * second stage will deal with it based on interleave modes.
+ */
+static int sys2pmi(const u64 addr, u32 *pmiidx, u64 *pmiaddr, char *msg)
+{
+       u64 contig_addr, contig_base, contig_offset, contig_base_adj;
+       int mot_intlv_bit = two_slices ? MOT_CHAN_INTLV_BIT_2SLC_2CH :
+                                               MOT_CHAN_INTLV_BIT_1SLC_2CH;
+       int slice_intlv_bit_rm = SELECTOR_DISABLED;
+       int chan_intlv_bit_rm = SELECTOR_DISABLED;
+       /* Determine if address is in the MOT region. */
+       bool mot_hit = in_region(&mot, addr);
+       /* Calculate the number of symmetric regions enabled. */
+       int sym_channels = hweight8(sym_chan_mask);
+
+       /*
+        * The amount we need to shift the asym base can be determined by the
+        * number of enabled symmetric channels.
+        * NOTE: This can only work because symmetric memory is not supposed
+        * to do a 3-way interleave.
+        */
+       int sym_chan_shift = sym_channels >> 1;
+
+       /* Give up if address is out of range, or in MMIO gap */
+       if (addr >= (1ul << PND_MAX_PHYS_BIT) ||
+          (addr >= top_lm && addr < _4GB) || addr >= top_hm) {
+               snprintf(msg, PND2_MSG_SIZE, "Error address 0x%llx is not DRAM", addr);
+               return -EINVAL;
+       }
+
+       /* Get a contiguous memory address (remove the MMIO gap) */
+       contig_addr = remove_mmio_gap(addr);
+
+       if (in_region(&as0, addr)) {
+               *pmiidx = asym0.slice0_asym_channel_select;
+
+               contig_base = remove_mmio_gap(as0.base);
+               contig_offset = contig_addr - contig_base;
+               contig_base_adj = (contig_base >> sym_chan_shift) *
+                                                 ((chash.sym_slice0_channel_enabled >> (*pmiidx & 1)) & 1);
+               contig_addr = contig_offset + ((sym_channels > 0) ? contig_base_adj : 0ull);
+       } else if (in_region(&as1, addr)) {
+               *pmiidx = 2u + asym1.slice1_asym_channel_select;
+
+               contig_base = remove_mmio_gap(as1.base);
+               contig_offset = contig_addr - contig_base;
+               contig_base_adj = (contig_base >> sym_chan_shift) *
+                                                 ((chash.sym_slice1_channel_enabled >> (*pmiidx & 1)) & 1);
+               contig_addr = contig_offset + ((sym_channels > 0) ? contig_base_adj : 0ull);
+       } else if (in_region(&as2, addr) && (asym_2way.asym_2way_intlv_mode == 0x3ul)) {
+               bool channel1;
+
+               mot_intlv_bit = MOT_CHAN_INTLV_BIT_1SLC_2CH;
+               *pmiidx = (asym_2way.asym_2way_intlv_mode & 1) << 1;
+               channel1 = mot_hit ? ((bool)((addr >> mot_intlv_bit) & 1)) :
+                       hash_by_mask(contig_addr, chan_hash_mask);
+               *pmiidx |= (u32)channel1;
+
+               contig_base = remove_mmio_gap(as2.base);
+               chan_intlv_bit_rm = mot_hit ? mot_intlv_bit : chan_selector;
+               contig_offset = contig_addr - contig_base;
+               remove_addr_bit(&contig_offset, chan_intlv_bit_rm);
+               contig_addr = (contig_base >> sym_chan_shift) + contig_offset;
+       } else {
+               /* Otherwise we're in normal, boring symmetric mode. */
+               *pmiidx = 0u;
+
+               if (two_slices) {
+                       bool slice1;
+
+                       if (mot_hit) {
+                               slice_intlv_bit_rm = MOT_SLC_INTLV_BIT;
+                               slice1 = (addr >> MOT_SLC_INTLV_BIT) & 1;
+                       } else {
+                               slice_intlv_bit_rm = slice_selector;
+                               slice1 = hash_by_mask(addr, slice_hash_mask);
+                       }
+
+                       *pmiidx = (u32)slice1 << 1;
+               }
+
+               if (two_channels) {
+                       bool channel1;
+
+                       mot_intlv_bit = two_slices ? MOT_CHAN_INTLV_BIT_2SLC_2CH :
+                                                       MOT_CHAN_INTLV_BIT_1SLC_2CH;
+
+                       if (mot_hit) {
+                               chan_intlv_bit_rm = mot_intlv_bit;
+                               channel1 = (addr >> mot_intlv_bit) & 1;
+                       } else {
+                               chan_intlv_bit_rm = chan_selector;
+                               channel1 = hash_by_mask(contig_addr, chan_hash_mask);
+                       }
+
+                       *pmiidx |= (u32)channel1;
+               }
+       }
+
+       /* Remove the chan_selector bit first */
+       remove_addr_bit(&contig_addr, chan_intlv_bit_rm);
+       /* Remove the slice bit (we remove it second because it must be lower */
+       remove_addr_bit(&contig_addr, slice_intlv_bit_rm);
+       *pmiaddr = contig_addr;
+
+       return 0;
+}
+
+/* Translate PMI address to memory (rank, row, bank, column) */
+#define C(n) (0x10 | (n))      /* column */
+#define B(n) (0x20 | (n))      /* bank */
+#define R(n) (0x40 | (n))      /* row */
+#define RS   (0x80)                    /* rank */
+
+/* addrdec values */
+#define AMAP_1KB       0
+#define AMAP_2KB       1
+#define AMAP_4KB       2
+#define AMAP_RSVD      3
+
+/* dden values */
+#define DEN_4Gb                0
+#define DEN_8Gb                2
+
+/* dwid values */
+#define X8             0
+#define X16            1
+
+static struct dimm_geometry {
+       u8      addrdec;
+       u8      dden;
+       u8      dwid;
+       u8      rowbits, colbits;
+       u16     bits[PMI_ADDRESS_WIDTH];
+} dimms[] = {
+       {
+               .addrdec = AMAP_1KB, .dden = DEN_4Gb, .dwid = X16,
+               .rowbits = 15, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  B(0),  B(1),  B(2),  R(0),
+                       R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),  R(9),
+                       R(10), C(7),  C(8),  C(9),  R(11), RS,    R(12), R(13), R(14),
+                       0,     0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_1KB, .dden = DEN_4Gb, .dwid = X8,
+               .rowbits = 16, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  B(0),  B(1),  B(2),  R(0),
+                       R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),  R(9),
+                       R(10), C(7),  C(8),  C(9),  R(11), RS,    R(12), R(13), R(14),
+                       R(15), 0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_1KB, .dden = DEN_8Gb, .dwid = X16,
+               .rowbits = 16, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  B(0),  B(1),  B(2),  R(0),
+                       R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),  R(9),
+                       R(10), C(7),  C(8),  C(9),  R(11), RS,    R(12), R(13), R(14),
+                       R(15), 0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_1KB, .dden = DEN_8Gb, .dwid = X8,
+               .rowbits = 16, .colbits = 11,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  B(0),  B(1),  B(2),  R(0),
+                       R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),  R(9),
+                       R(10), C(7),  C(8),  C(9),  R(11), RS,    C(11), R(12), R(13),
+                       R(14), R(15), 0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_2KB, .dden = DEN_4Gb, .dwid = X16,
+               .rowbits = 15, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  B(0),  B(1),  B(2),
+                       R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),
+                       R(9),  R(10), C(8),  C(9),  R(11), RS,    R(12), R(13), R(14),
+                       0,     0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_2KB, .dden = DEN_4Gb, .dwid = X8,
+               .rowbits = 16, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  B(0),  B(1),  B(2),
+                       R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),
+                       R(9),  R(10), C(8),  C(9),  R(11), RS,    R(12), R(13), R(14),
+                       R(15), 0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_2KB, .dden = DEN_8Gb, .dwid = X16,
+               .rowbits = 16, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  B(0),  B(1),  B(2),
+                       R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),
+                       R(9),  R(10), C(8),  C(9),  R(11), RS,    R(12), R(13), R(14),
+                       R(15), 0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_2KB, .dden = DEN_8Gb, .dwid = X8,
+               .rowbits = 16, .colbits = 11,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  B(0),  B(1),  B(2),
+                       R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),  R(8),
+                       R(9),  R(10), C(8),  C(9),  R(11), RS,    C(11), R(12), R(13),
+                       R(14), R(15), 0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_4KB, .dden = DEN_4Gb, .dwid = X16,
+               .rowbits = 15, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  C(8),  B(0),  B(1),
+                       B(2),  R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
+                       R(8),  R(9),  R(10), C(9),  R(11), RS,    R(12), R(13), R(14),
+                       0,     0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_4KB, .dden = DEN_4Gb, .dwid = X8,
+               .rowbits = 16, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  C(8),  B(0),  B(1),
+                       B(2),  R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
+                       R(8),  R(9),  R(10), C(9),  R(11), RS,    R(12), R(13), R(14),
+                       R(15), 0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_4KB, .dden = DEN_8Gb, .dwid = X16,
+               .rowbits = 16, .colbits = 10,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  C(8),  B(0),  B(1),
+                       B(2),  R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
+                       R(8),  R(9),  R(10), C(9),  R(11), RS,    R(12), R(13), R(14),
+                       R(15), 0,     0,     0
+               }
+       },
+       {
+               .addrdec = AMAP_4KB, .dden = DEN_8Gb, .dwid = X8,
+               .rowbits = 16, .colbits = 11,
+               .bits = {
+                       C(2),  C(3),  C(4),  C(5),  C(6),  C(7),  C(8),  B(0),  B(1),
+                       B(2),  R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
+                       R(8),  R(9),  R(10), C(9),  R(11), RS,    C(11), R(12), R(13),
+                       R(14), R(15), 0,     0
+               }
+       }
+};
+
+static int bank_hash(u64 pmiaddr, int idx, int shft)
+{
+       int bhash = 0;
+
+       switch (idx) {
+       case 0:
+               bhash ^= ((pmiaddr >> (12 + shft)) ^ (pmiaddr >> (9 + shft))) & 1;
+               break;
+       case 1:
+               bhash ^= (((pmiaddr >> (10 + shft)) ^ (pmiaddr >> (8 + shft))) & 1) << 1;
+               bhash ^= ((pmiaddr >> 22) & 1) << 1;
+               break;
+       case 2:
+               bhash ^= (((pmiaddr >> (13 + shft)) ^ (pmiaddr >> (11 + shft))) & 1) << 2;
+               break;
+       }
+
+       return bhash;
+}
+
+static int rank_hash(u64 pmiaddr)
+{
+       return ((pmiaddr >> 16) ^ (pmiaddr >> 10)) & 1;
+}
+
+/* Second stage decode. Compute rank, bank, row & column. */
+static int apl_pmi2mem(struct mem_ctl_info *mci, u64 pmiaddr, u32 pmiidx,
+                      struct dram_addr *daddr, char *msg)
+{
+       struct d_cr_drp0 *cr_drp0 = &drp0[pmiidx];
+       struct pnd2_pvt *pvt = mci->pvt_info;
+       int g = pvt->dimm_geom[pmiidx];
+       struct dimm_geometry *d = &dimms[g];
+       int column = 0, bank = 0, row = 0, rank = 0;
+       int i, idx, type, skiprs = 0;
+
+       for (i = 0; i < PMI_ADDRESS_WIDTH; i++) {
+               int     bit = (pmiaddr >> i) & 1;
+
+               if (i + skiprs >= PMI_ADDRESS_WIDTH) {
+                       snprintf(msg, PND2_MSG_SIZE, "Bad dimm_geometry[] table\n");
+                       return -EINVAL;
+               }
+
+               type = d->bits[i + skiprs] & ~0xf;
+               idx = d->bits[i + skiprs] & 0xf;
+
+               /*
+                * On single rank DIMMs ignore the rank select bit
+                * and shift remainder of "bits[]" down one place.
+                */
+               if (type == RS && (cr_drp0->rken0 + cr_drp0->rken1) == 1) {
+                       skiprs = 1;
+                       type = d->bits[i + skiprs] & ~0xf;
+                       idx = d->bits[i + skiprs] & 0xf;
+               }
+
+               switch (type) {
+               case C(0):
+                       column |= (bit << idx);
+                       break;
+               case B(0):
+                       bank |= (bit << idx);
+                       if (cr_drp0->bahen)
+                               bank ^= bank_hash(pmiaddr, idx, d->addrdec);
+                       break;
+               case R(0):
+                       row |= (bit << idx);
+                       break;
+               case RS:
+                       rank = bit;
+                       if (cr_drp0->rsien)
+                               rank ^= rank_hash(pmiaddr);
+                       break;
+               default:
+                       if (bit) {
+                               snprintf(msg, PND2_MSG_SIZE, "Bad translation\n");
+                               return -EINVAL;
+                       }
+                       goto done;
+               }
+       }
+
+done:
+       daddr->col = column;
+       daddr->bank = bank;
+       daddr->row = row;
+       daddr->rank = rank;
+       daddr->dimm = 0;
+
+       return 0;
+}
+
+/* Pluck bit "in" from pmiaddr and return value shifted to bit "out" */
+#define dnv_get_bit(pmi, in, out) ((int)(((pmi) >> (in)) & 1u) << (out))
+
+static int dnv_pmi2mem(struct mem_ctl_info *mci, u64 pmiaddr, u32 pmiidx,
+                                          struct dram_addr *daddr, char *msg)
+{
+       /* Rank 0 or 1 */
+       daddr->rank = dnv_get_bit(pmiaddr, dmap[pmiidx].rs0 + 13, 0);
+       /* Rank 2 or 3 */
+       daddr->rank |= dnv_get_bit(pmiaddr, dmap[pmiidx].rs1 + 13, 1);
+
+       /*
+        * Normally ranks 0,1 are DIMM0, and 2,3 are DIMM1, but we
+        * flip them if DIMM1 is larger than DIMM0.
+        */
+       daddr->dimm = (daddr->rank >= 2) ^ drp[pmiidx].dimmflip;
+
+       daddr->bank = dnv_get_bit(pmiaddr, dmap[pmiidx].ba0 + 6, 0);
+       daddr->bank |= dnv_get_bit(pmiaddr, dmap[pmiidx].ba1 + 6, 1);
+       daddr->bank |= dnv_get_bit(pmiaddr, dmap[pmiidx].bg0 + 6, 2);
+       if (dsch.ddr4en)
+               daddr->bank |= dnv_get_bit(pmiaddr, dmap[pmiidx].bg1 + 6, 3);
+       if (dmap1[pmiidx].bxor) {
+               if (dsch.ddr4en) {
+                       daddr->bank ^= dnv_get_bit(pmiaddr, dmap3[pmiidx].row6 + 6, 0);
+                       daddr->bank ^= dnv_get_bit(pmiaddr, dmap3[pmiidx].row7 + 6, 1);
+                       if (dsch.chan_width == 0)
+                               /* 64/72 bit dram channel width */
+                               daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca3 + 6, 2);
+                       else
+                               /* 32/40 bit dram channel width */
+                               daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca4 + 6, 2);
+                       daddr->bank ^= dnv_get_bit(pmiaddr, dmap2[pmiidx].row2 + 6, 3);
+               } else {
+                       daddr->bank ^= dnv_get_bit(pmiaddr, dmap2[pmiidx].row2 + 6, 0);
+                       daddr->bank ^= dnv_get_bit(pmiaddr, dmap3[pmiidx].row6 + 6, 1);
+                       if (dsch.chan_width == 0)
+                               daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca3 + 6, 2);
+                       else
+                               daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca4 + 6, 2);
+               }
+       }
+
+       daddr->row = dnv_get_bit(pmiaddr, dmap2[pmiidx].row0 + 6, 0);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row1 + 6, 1);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row2 + 6, 2);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row3 + 6, 3);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row4 + 6, 4);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row5 + 6, 5);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row6 + 6, 6);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row7 + 6, 7);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row8 + 6, 8);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row9 + 6, 9);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row10 + 6, 10);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row11 + 6, 11);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row12 + 6, 12);
+       daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row13 + 6, 13);
+       if (dmap4[pmiidx].row14 != 31)
+               daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row14 + 6, 14);
+       if (dmap4[pmiidx].row15 != 31)
+               daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row15 + 6, 15);
+       if (dmap4[pmiidx].row16 != 31)
+               daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row16 + 6, 16);
+       if (dmap4[pmiidx].row17 != 31)
+               daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row17 + 6, 17);
+
+       daddr->col = dnv_get_bit(pmiaddr, dmap5[pmiidx].ca3 + 6, 3);
+       daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca4 + 6, 4);
+       daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca5 + 6, 5);
+       daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca6 + 6, 6);
+       daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca7 + 6, 7);
+       daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca8 + 6, 8);
+       daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca9 + 6, 9);
+       if (!dsch.ddr4en && dmap1[pmiidx].ca11 != 0x3f)
+               daddr->col |= dnv_get_bit(pmiaddr, dmap1[pmiidx].ca11 + 13, 11);
+
+       return 0;
+}
+
+static int check_channel(int ch)
+{
+       if (drp0[ch].dramtype != 0) {
+               pnd2_printk(KERN_INFO, "Unsupported DIMM in channel %d\n", ch);
+               return 1;
+       } else if (drp0[ch].eccen == 0) {
+               pnd2_printk(KERN_INFO, "ECC disabled on channel %d\n", ch);
+               return 1;
+       }
+       return 0;
+}
+
+static int apl_check_ecc_active(void)
+{
+       int     i, ret = 0;
+
+       /* Check dramtype and ECC mode for each present DIMM */
+       for (i = 0; i < APL_NUM_CHANNELS; i++)
+               if (chan_mask & BIT(i))
+                       ret += check_channel(i);
+       return ret ? -EINVAL : 0;
+}
+
+#define DIMMS_PRESENT(d) ((d)->rken0 + (d)->rken1 + (d)->rken2 + (d)->rken3)
+
+static int check_unit(int ch)
+{
+       struct d_cr_drp *d = &drp[ch];
+
+       if (DIMMS_PRESENT(d) && !ecc_ctrl[ch].eccen) {
+               pnd2_printk(KERN_INFO, "ECC disabled on channel %d\n", ch);
+               return 1;
+       }
+       return 0;
+}
+
+static int dnv_check_ecc_active(void)
+{
+       int     i, ret = 0;
+
+       for (i = 0; i < DNV_NUM_CHANNELS; i++)
+               ret += check_unit(i);
+       return ret ? -EINVAL : 0;
+}
+
+static int get_memory_error_data(struct mem_ctl_info *mci, u64 addr,
+                                                                struct dram_addr *daddr, char *msg)
+{
+       u64     pmiaddr;
+       u32     pmiidx;
+       int     ret;
+
+       ret = sys2pmi(addr, &pmiidx, &pmiaddr, msg);
+       if (ret)
+               return ret;
+
+       pmiaddr >>= ops->pmiaddr_shift;
+       /* pmi channel idx to dimm channel idx */
+       pmiidx >>= ops->pmiidx_shift;
+       daddr->chan = pmiidx;
+
+       ret = ops->pmi2mem(mci, pmiaddr, pmiidx, daddr, msg);
+       if (ret)
+               return ret;
+
+       edac_dbg(0, "SysAddr=%llx PmiAddr=%llx Channel=%d DIMM=%d Rank=%d Bank=%d Row=%d Column=%d\n",
+                        addr, pmiaddr, daddr->chan, daddr->dimm, daddr->rank, daddr->bank, daddr->row, daddr->col);
+
+       return 0;
+}
+
+static void pnd2_mce_output_error(struct mem_ctl_info *mci, const struct mce *m,
+                                 struct dram_addr *daddr)
+{
+       enum hw_event_mc_err_type tp_event;
+       char *optype, msg[PND2_MSG_SIZE];
+       bool ripv = m->mcgstatus & MCG_STATUS_RIPV;
+       bool overflow = m->status & MCI_STATUS_OVER;
+       bool uc_err = m->status & MCI_STATUS_UC;
+       bool recov = m->status & MCI_STATUS_S;
+       u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52);
+       u32 mscod = GET_BITFIELD(m->status, 16, 31);
+       u32 errcode = GET_BITFIELD(m->status, 0, 15);
+       u32 optypenum = GET_BITFIELD(m->status, 4, 6);
+       int rc;
+
+       tp_event = uc_err ? (ripv ? HW_EVENT_ERR_FATAL : HW_EVENT_ERR_UNCORRECTED) :
+                                                HW_EVENT_ERR_CORRECTED;
+
+       /*
+        * According with Table 15-9 of the Intel Architecture spec vol 3A,
+        * memory errors should fit in this mask:
+        *      000f 0000 1mmm cccc (binary)
+        * where:
+        *      f = Correction Report Filtering Bit. If 1, subsequent errors
+        *          won't be shown
+        *      mmm = error type
+        *      cccc = channel
+        * If the mask doesn't match, report an error to the parsing logic
+        */
+       if (!((errcode & 0xef80) == 0x80)) {
+               optype = "Can't parse: it is not a mem";
+       } else {
+               switch (optypenum) {
+               case 0:
+                       optype = "generic undef request error";
+                       break;
+               case 1:
+                       optype = "memory read error";
+                       break;
+               case 2:
+                       optype = "memory write error";
+                       break;
+               case 3:
+                       optype = "addr/cmd error";
+                       break;
+               case 4:
+                       optype = "memory scrubbing error";
+                       break;
+               default:
+                       optype = "reserved";
+                       break;
+               }
+       }
+
+       /* Only decode errors with an valid address (ADDRV) */
+       if (!(m->status & MCI_STATUS_ADDRV))
+               return;
+
+       rc = get_memory_error_data(mci, m->addr, daddr, msg);
+       if (rc)
+               goto address_error;
+
+       snprintf(msg, sizeof(msg),
+                "%s%s err_code:%04x:%04x channel:%d DIMM:%d rank:%d row:%d bank:%d col:%d",
+                overflow ? " OVERFLOW" : "", (uc_err && recov) ? " recoverable" : "", mscod,
+                errcode, daddr->chan, daddr->dimm, daddr->rank, daddr->row, daddr->bank, daddr->col);
+
+       edac_dbg(0, "%s\n", msg);
+
+       /* Call the helper to output message */
+       edac_mc_handle_error(tp_event, mci, core_err_cnt, m->addr >> PAGE_SHIFT,
+                                                m->addr & ~PAGE_MASK, 0, daddr->chan, daddr->dimm, -1, optype, msg);
+
+       return;
+
+address_error:
+       edac_mc_handle_error(tp_event, mci, core_err_cnt, 0, 0, 0, -1, -1, -1, msg, "");
+}
+
+static void apl_get_dimm_config(struct mem_ctl_info *mci)
+{
+       struct pnd2_pvt *pvt = mci->pvt_info;
+       struct dimm_info *dimm;
+       struct d_cr_drp0 *d;
+       u64     capacity;
+       int     i, g;
+
+       for (i = 0; i < APL_NUM_CHANNELS; i++) {
+               if (!(chan_mask & BIT(i)))
+                       continue;
+
+               dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, 0, 0);
+               if (!dimm) {
+                       edac_dbg(0, "No allocated DIMM for channel %d\n", i);
+                       continue;
+               }
+
+               d = &drp0[i];
+               for (g = 0; g < ARRAY_SIZE(dimms); g++)
+                       if (dimms[g].addrdec == d->addrdec &&
+                           dimms[g].dden == d->dden &&
+                           dimms[g].dwid == d->dwid)
+                               break;
+
+               if (g == ARRAY_SIZE(dimms)) {
+                       edac_dbg(0, "Channel %d: unrecognized DIMM\n", i);
+                       continue;
+               }
+
+               pvt->dimm_geom[i] = g;
+               capacity = (d->rken0 + d->rken1) * 8 * (1ul << dimms[g].rowbits) *
+                                  (1ul << dimms[g].colbits);
+               edac_dbg(0, "Channel %d: %lld MByte DIMM\n", i, capacity >> (20 - 3));
+               dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3));
+               dimm->grain = 32;
+               dimm->dtype = (d->dwid == 0) ? DEV_X8 : DEV_X16;
+               dimm->mtype = MEM_DDR3;
+               dimm->edac_mode = EDAC_SECDED;
+               snprintf(dimm->label, sizeof(dimm->label), "Slice#%d_Chan#%d", i / 2, i % 2);
+       }
+}
+
+static const int dnv_dtypes[] = {
+       DEV_X8, DEV_X4, DEV_X16, DEV_UNKNOWN
+};
+
+static void dnv_get_dimm_config(struct mem_ctl_info *mci)
+{
+       int     i, j, ranks_of_dimm[DNV_MAX_DIMMS], banks, rowbits, colbits, memtype;
+       struct dimm_info *dimm;
+       struct d_cr_drp *d;
+       u64     capacity;
+
+       if (dsch.ddr4en) {
+               memtype = MEM_DDR4;
+               banks = 16;
+               colbits = 10;
+       } else {
+               memtype = MEM_DDR3;
+               banks = 8;
+       }
+
+       for (i = 0; i < DNV_NUM_CHANNELS; i++) {
+               if (dmap4[i].row14 == 31)
+                       rowbits = 14;
+               else if (dmap4[i].row15 == 31)
+                       rowbits = 15;
+               else if (dmap4[i].row16 == 31)
+                       rowbits = 16;
+               else if (dmap4[i].row17 == 31)
+                       rowbits = 17;
+               else
+                       rowbits = 18;
+
+               if (memtype == MEM_DDR3) {
+                       if (dmap1[i].ca11 != 0x3f)
+                               colbits = 12;
+                       else
+                               colbits = 10;
+               }
+
+               d = &drp[i];
+               /* DIMM0 is present if rank0 and/or rank1 is enabled */
+               ranks_of_dimm[0] = d->rken0 + d->rken1;
+               /* DIMM1 is present if rank2 and/or rank3 is enabled */
+               ranks_of_dimm[1] = d->rken2 + d->rken3;
+
+               for (j = 0; j < DNV_MAX_DIMMS; j++) {
+                       if (!ranks_of_dimm[j])
+                               continue;
+
+                       dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0);
+                       if (!dimm) {
+                               edac_dbg(0, "No allocated DIMM for channel %d DIMM %d\n", i, j);
+                               continue;
+                       }
+
+                       capacity = ranks_of_dimm[j] * banks * (1ul << rowbits) * (1ul << colbits);
+                       edac_dbg(0, "Channel %d DIMM %d: %lld MByte DIMM\n", i, j, capacity >> (20 - 3));
+                       dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3));
+                       dimm->grain = 32;
+                       dimm->dtype = dnv_dtypes[j ? d->dimmdwid0 : d->dimmdwid1];
+                       dimm->mtype = memtype;
+                       dimm->edac_mode = EDAC_SECDED;
+                       snprintf(dimm->label, sizeof(dimm->label), "Chan#%d_DIMM#%d", i, j);
+               }
+       }
+}
+
+static int pnd2_register_mci(struct mem_ctl_info **ppmci)
+{
+       struct edac_mc_layer layers[2];
+       struct mem_ctl_info *mci;
+       struct pnd2_pvt *pvt;
+       int rc;
+
+       rc = ops->check_ecc();
+       if (rc < 0)
+               return rc;
+
+       /* Allocate a new MC control structure */
+       layers[0].type = EDAC_MC_LAYER_CHANNEL;
+       layers[0].size = ops->channels;
+       layers[0].is_virt_csrow = false;
+       layers[1].type = EDAC_MC_LAYER_SLOT;
+       layers[1].size = ops->dimms_per_channel;
+       layers[1].is_virt_csrow = true;
+       mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(*pvt));
+       if (!mci)
+               return -ENOMEM;
+
+       pvt = mci->pvt_info;
+       memset(pvt, 0, sizeof(*pvt));
+
+       mci->mod_name = "pnd2_edac.c";
+       mci->dev_name = ops->name;
+       mci->ctl_name = "Pondicherry2";
+
+       /* Get dimm basic config and the memory layout */
+       ops->get_dimm_config(mci);
+
+       if (edac_mc_add_mc(mci)) {
+               edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
+               edac_mc_free(mci);
+               return -EINVAL;
+       }
+
+       *ppmci = mci;
+
+       return 0;
+}
+
+static void pnd2_unregister_mci(struct mem_ctl_info *mci)
+{
+       if (unlikely(!mci || !mci->pvt_info)) {
+               pnd2_printk(KERN_ERR, "Couldn't find mci handler\n");
+               return;
+       }
+
+       /* Remove MC sysfs nodes */
+       edac_mc_del_mc(NULL);
+       edac_dbg(1, "%s: free mci struct\n", mci->ctl_name);
+       edac_mc_free(mci);
+}
+
+/*
+ * Callback function registered with core kernel mce code.
+ * Called once for each logged error.
+ */
+static int pnd2_mce_check_error(struct notifier_block *nb, unsigned long val, void *data)
+{
+       struct mce *mce = (struct mce *)data;
+       struct mem_ctl_info *mci;
+       struct dram_addr daddr;
+       char *type;
+
+       if (get_edac_report_status() == EDAC_REPORTING_DISABLED)
+               return NOTIFY_DONE;
+
+       mci = pnd2_mci;
+       if (!mci)
+               return NOTIFY_DONE;
+
+       /*
+        * Just let mcelog handle it if the error is
+        * outside the memory controller. A memory error
+        * is indicated by bit 7 = 1 and bits = 8-11,13-15 = 0.
+        * bit 12 has an special meaning.
+        */
+       if ((mce->status & 0xefff) >> 7 != 1)
+               return NOTIFY_DONE;
+
+       if (mce->mcgstatus & MCG_STATUS_MCIP)
+               type = "Exception";
+       else
+               type = "Event";
+
+       pnd2_mc_printk(mci, KERN_INFO, "HANDLING MCE MEMORY ERROR\n");
+       pnd2_mc_printk(mci, KERN_INFO, "CPU %u: Machine Check %s: %llx Bank %u: %llx\n",
+                                  mce->extcpu, type, mce->mcgstatus, mce->bank, mce->status);
+       pnd2_mc_printk(mci, KERN_INFO, "TSC %llx ", mce->tsc);
+       pnd2_mc_printk(mci, KERN_INFO, "ADDR %llx ", mce->addr);
+       pnd2_mc_printk(mci, KERN_INFO, "MISC %llx ", mce->misc);
+       pnd2_mc_printk(mci, KERN_INFO, "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
+                                  mce->cpuvendor, mce->cpuid, mce->time, mce->socketid, mce->apicid);
+
+       pnd2_mce_output_error(mci, mce, &daddr);
+
+       /* Advice mcelog that the error were handled */
+       return NOTIFY_STOP;
+}
+
+static struct notifier_block pnd2_mce_dec = {
+       .notifier_call  = pnd2_mce_check_error,
+};
+
+#ifdef CONFIG_EDAC_DEBUG
+/*
+ * Write an address to this file to exercise the address decode
+ * logic in this driver.
+ */
+static u64 pnd2_fake_addr;
+#define PND2_BLOB_SIZE 1024
+static char pnd2_result[PND2_BLOB_SIZE];
+static struct dentry *pnd2_test;
+static struct debugfs_blob_wrapper pnd2_blob = {
+       .data = pnd2_result,
+       .size = 0
+};
+
+static int debugfs_u64_set(void *data, u64 val)
+{
+       struct dram_addr daddr;
+       struct mce m;
+
+       *(u64 *)data = val;
+       m.mcgstatus = 0;
+       /* ADDRV + MemRd + Unknown channel */
+       m.status = MCI_STATUS_ADDRV + 0x9f;
+       m.addr = val;
+       pnd2_mce_output_error(pnd2_mci, &m, &daddr);
+       snprintf(pnd2_blob.data, PND2_BLOB_SIZE,
+                        "SysAddr=%llx Channel=%d DIMM=%d Rank=%d Bank=%d Row=%d Column=%d\n",
+                        m.addr, daddr.chan, daddr.dimm, daddr.rank, daddr.bank, daddr.row, daddr.col);
+       pnd2_blob.size = strlen(pnd2_blob.data);
+
+       return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n");
+
+static void setup_pnd2_debug(void)
+{
+       pnd2_test = edac_debugfs_create_dir("pnd2_test");
+       edac_debugfs_create_file("pnd2_debug_addr", 0200, pnd2_test,
+                                                        &pnd2_fake_addr, &fops_u64_wo);
+       debugfs_create_blob("pnd2_debug_results", 0400, pnd2_test, &pnd2_blob);
+}
+
+static void teardown_pnd2_debug(void)
+{
+       debugfs_remove_recursive(pnd2_test);
+}
+#else
+static void setup_pnd2_debug(void)     {}
+static void teardown_pnd2_debug(void)  {}
+#endif /* CONFIG_EDAC_DEBUG */
+
+
+static int pnd2_probe(void)
+{
+       int rc;
+
+       edac_dbg(2, "\n");
+       rc = get_registers();
+       if (rc)
+               return rc;
+
+       return pnd2_register_mci(&pnd2_mci);
+}
+
+static void pnd2_remove(void)
+{
+       edac_dbg(0, "\n");
+       pnd2_unregister_mci(pnd2_mci);
+}
+
+static struct dunit_ops apl_ops = {
+               .name                   = "pnd2/apl",
+               .type                   = APL,
+               .pmiaddr_shift          = LOG2_PMI_ADDR_GRANULARITY,
+               .pmiidx_shift           = 0,
+               .channels               = APL_NUM_CHANNELS,
+               .dimms_per_channel      = 1,
+               .rd_reg                 = apl_rd_reg,
+               .get_registers          = apl_get_registers,
+               .check_ecc              = apl_check_ecc_active,
+               .mk_region              = apl_mk_region,
+               .get_dimm_config        = apl_get_dimm_config,
+               .pmi2mem                = apl_pmi2mem,
+};
+
+static struct dunit_ops dnv_ops = {
+               .name                   = "pnd2/dnv",
+               .type                   = DNV,
+               .pmiaddr_shift          = 0,
+               .pmiidx_shift           = 1,
+               .channels               = DNV_NUM_CHANNELS,
+               .dimms_per_channel      = 2,
+               .rd_reg                 = dnv_rd_reg,
+               .get_registers          = dnv_get_registers,
+               .check_ecc              = dnv_check_ecc_active,
+               .mk_region              = dnv_mk_region,
+               .get_dimm_config        = dnv_get_dimm_config,
+               .pmi2mem                = dnv_pmi2mem,
+};
+
+static const struct x86_cpu_id pnd2_cpuids[] = {
+       { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT, 0, (kernel_ulong_t)&apl_ops },
+       { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_DENVERTON, 0, (kernel_ulong_t)&dnv_ops },
+       { }
+};
+MODULE_DEVICE_TABLE(x86cpu, pnd2_cpuids);
+
+static int __init pnd2_init(void)
+{
+       const struct x86_cpu_id *id;
+       int rc;
+
+       edac_dbg(2, "\n");
+
+       id = x86_match_cpu(pnd2_cpuids);
+       if (!id)
+               return -ENODEV;
+
+       ops = (struct dunit_ops *)id->driver_data;
+
+       /* Ensure that the OPSTATE is set correctly for POLL or NMI */
+       opstate_init();
+
+       rc = pnd2_probe();
+       if (rc < 0) {
+               pnd2_printk(KERN_ERR, "Failed to register device with error %d.\n", rc);
+               return rc;
+       }
+
+       if (!pnd2_mci)
+               return -ENODEV;
+
+       mce_register_decode_chain(&pnd2_mce_dec);
+       setup_pnd2_debug();
+
+       return 0;
+}
+
+static void __exit pnd2_exit(void)
+{
+       edac_dbg(2, "\n");
+       teardown_pnd2_debug();
+       mce_unregister_decode_chain(&pnd2_mce_dec);
+       pnd2_remove();
+}
+
+module_init(pnd2_init);
+module_exit(pnd2_exit);
+
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Tony Luck");
+MODULE_DESCRIPTION("MC Driver for Intel SoC using Pondicherry memory controller");
diff --git a/drivers/edac/pnd2_edac.h b/drivers/edac/pnd2_edac.h
new file mode 100644 (file)
index 0000000..61b6e79
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Register bitfield descriptions for Pondicherry2 memory controller.
+ *
+ * Copyright (c) 2016, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _PND2_REGS_H
+#define _PND2_REGS_H
+
+struct b_cr_touud_lo_pci {
+       u32     lock : 1;
+       u32     reserved_1 : 19;
+       u32     touud : 12;
+};
+
+#define b_cr_touud_lo_pci_port 0x4c
+#define b_cr_touud_lo_pci_offset 0xa8
+#define b_cr_touud_lo_pci_r_opcode 0x04
+
+struct b_cr_touud_hi_pci {
+       u32     touud : 7;
+       u32     reserved_0 : 25;
+};
+
+#define b_cr_touud_hi_pci_port 0x4c
+#define b_cr_touud_hi_pci_offset 0xac
+#define b_cr_touud_hi_pci_r_opcode 0x04
+
+struct b_cr_tolud_pci {
+       u32     lock : 1;
+       u32     reserved_0 : 19;
+       u32     tolud : 12;
+};
+
+#define b_cr_tolud_pci_port 0x4c
+#define b_cr_tolud_pci_offset 0xbc
+#define b_cr_tolud_pci_r_opcode 0x04
+
+struct b_cr_mchbar_lo_pci {
+       u32 enable : 1;
+       u32 pad_3_1 : 3;
+       u32 pad_14_4: 11;
+       u32 base: 17;
+};
+
+struct b_cr_mchbar_hi_pci {
+       u32 base : 7;
+       u32 pad_31_7 : 25;
+};
+
+/* Symmetric region */
+struct b_cr_slice_channel_hash {
+       u64     slice_1_disabled : 1;
+       u64     hvm_mode : 1;
+       u64     interleave_mode : 2;
+       u64     slice_0_mem_disabled : 1;
+       u64     reserved_0 : 1;
+       u64     slice_hash_mask : 14;
+       u64     reserved_1 : 11;
+       u64     enable_pmi_dual_data_mode : 1;
+       u64     ch_1_disabled : 1;
+       u64     reserved_2 : 1;
+       u64     sym_slice0_channel_enabled : 2;
+       u64     sym_slice1_channel_enabled : 2;
+       u64     ch_hash_mask : 14;
+       u64     reserved_3 : 11;
+       u64     lock : 1;
+};
+
+#define b_cr_slice_channel_hash_port 0x4c
+#define b_cr_slice_channel_hash_offset 0x4c58
+#define b_cr_slice_channel_hash_r_opcode 0x06
+
+struct b_cr_mot_out_base_mchbar {
+       u32     reserved_0 : 14;
+       u32     mot_out_base : 15;
+       u32     reserved_1 : 1;
+       u32     tr_en : 1;
+       u32     imr_en : 1;
+};
+
+#define b_cr_mot_out_base_mchbar_port 0x4c
+#define b_cr_mot_out_base_mchbar_offset 0x6af0
+#define b_cr_mot_out_base_mchbar_r_opcode 0x00
+
+struct b_cr_mot_out_mask_mchbar {
+       u32     reserved_0 : 14;
+       u32     mot_out_mask : 15;
+       u32     reserved_1 : 1;
+       u32     ia_iwb_en : 1;
+       u32     gt_iwb_en : 1;
+};
+
+#define b_cr_mot_out_mask_mchbar_port 0x4c
+#define b_cr_mot_out_mask_mchbar_offset 0x6af4
+#define b_cr_mot_out_mask_mchbar_r_opcode 0x00
+
+struct b_cr_asym_mem_region0_mchbar {
+       u32     pad : 4;
+       u32     slice0_asym_base : 11;
+       u32     pad_18_15 : 4;
+       u32     slice0_asym_limit : 11;
+       u32     slice0_asym_channel_select : 1;
+       u32     slice0_asym_enable : 1;
+};
+
+#define b_cr_asym_mem_region0_mchbar_port 0x4c
+#define b_cr_asym_mem_region0_mchbar_offset 0x6e40
+#define b_cr_asym_mem_region0_mchbar_r_opcode 0x00
+
+struct b_cr_asym_mem_region1_mchbar {
+       u32     pad : 4;
+       u32     slice1_asym_base : 11;
+       u32     pad_18_15 : 4;
+       u32     slice1_asym_limit : 11;
+       u32     slice1_asym_channel_select : 1;
+       u32     slice1_asym_enable : 1;
+};
+
+#define b_cr_asym_mem_region1_mchbar_port 0x4c
+#define b_cr_asym_mem_region1_mchbar_offset 0x6e44
+#define b_cr_asym_mem_region1_mchbar_r_opcode 0x00
+
+/* Some bit fields moved in above two structs on Denverton */
+struct b_cr_asym_mem_region_denverton {
+       u32     pad : 4;
+       u32     slice_asym_base : 8;
+       u32     pad_19_12 : 8;
+       u32     slice_asym_limit : 8;
+       u32     pad_28_30 : 3;
+       u32     slice_asym_enable : 1;
+};
+
+struct b_cr_asym_2way_mem_region_mchbar {
+       u32     pad : 2;
+       u32     asym_2way_intlv_mode : 2;
+       u32     asym_2way_base : 11;
+       u32     pad_16_15 : 2;
+       u32     asym_2way_limit : 11;
+       u32     pad_30_28 : 3;
+       u32     asym_2way_interleave_enable : 1;
+};
+
+#define b_cr_asym_2way_mem_region_mchbar_port 0x4c
+#define b_cr_asym_2way_mem_region_mchbar_offset 0x6e50
+#define b_cr_asym_2way_mem_region_mchbar_r_opcode 0x00
+
+/* Apollo Lake d-unit */
+
+struct d_cr_drp0 {
+       u32     rken0 : 1;
+       u32     rken1 : 1;
+       u32     ddmen : 1;
+       u32     rsvd3 : 1;
+       u32     dwid : 2;
+       u32     dden : 3;
+       u32     rsvd13_9 : 5;
+       u32     rsien : 1;
+       u32     bahen : 1;
+       u32     rsvd18_16 : 3;
+       u32     caswizzle : 2;
+       u32     eccen : 1;
+       u32     dramtype : 3;
+       u32     blmode : 3;
+       u32     addrdec : 2;
+       u32     dramdevice_pr : 2;
+};
+
+#define d_cr_drp0_offset 0x1400
+#define d_cr_drp0_r_opcode 0x00
+
+/* Denverton d-unit */
+
+struct d_cr_dsch {
+       u32     ch0en : 1;
+       u32     ch1en : 1;
+       u32     ddr4en : 1;
+       u32     coldwake : 1;
+       u32     newbypdis : 1;
+       u32     chan_width : 1;
+       u32     rsvd6_6 : 1;
+       u32     ooodis : 1;
+       u32     rsvd18_8 : 11;
+       u32     ic : 1;
+       u32     rsvd31_20 : 12;
+};
+
+#define d_cr_dsch_port 0x16
+#define d_cr_dsch_offset 0x0
+#define d_cr_dsch_r_opcode 0x0
+
+struct d_cr_ecc_ctrl {
+       u32     eccen : 1;
+       u32     rsvd31_1 : 31;
+};
+
+#define d_cr_ecc_ctrl_offset 0x180
+#define d_cr_ecc_ctrl_r_opcode 0x0
+
+struct d_cr_drp {
+       u32     rken0 : 1;
+       u32     rken1 : 1;
+       u32     rken2 : 1;
+       u32     rken3 : 1;
+       u32     dimmdwid0 : 2;
+       u32     dimmdden0 : 2;
+       u32     dimmdwid1 : 2;
+       u32     dimmdden1 : 2;
+       u32     rsvd15_12 : 4;
+       u32     dimmflip : 1;
+       u32     rsvd31_17 : 15;
+};
+
+#define d_cr_drp_offset 0x158
+#define d_cr_drp_r_opcode 0x0
+
+struct d_cr_dmap {
+       u32     ba0 : 5;
+       u32     ba1 : 5;
+       u32     bg0 : 5; /* if ddr3, ba2 = bg0 */
+       u32     bg1 : 5; /* if ddr3, ba3 = bg1 */
+       u32     rs0 : 5;
+       u32     rs1 : 5;
+       u32     rsvd : 2;
+};
+
+#define d_cr_dmap_offset 0x174
+#define d_cr_dmap_r_opcode 0x0
+
+struct d_cr_dmap1 {
+       u32     ca11 : 6;
+       u32     bxor : 1;
+       u32     rsvd : 25;
+};
+
+#define d_cr_dmap1_offset 0xb4
+#define d_cr_dmap1_r_opcode 0x0
+
+struct d_cr_dmap2 {
+       u32     row0 : 5;
+       u32     row1 : 5;
+       u32     row2 : 5;
+       u32     row3 : 5;
+       u32     row4 : 5;
+       u32     row5 : 5;
+       u32     rsvd : 2;
+};
+
+#define d_cr_dmap2_offset 0x148
+#define d_cr_dmap2_r_opcode 0x0
+
+struct d_cr_dmap3 {
+       u32     row6 : 5;
+       u32     row7 : 5;
+       u32     row8 : 5;
+       u32     row9 : 5;
+       u32     row10 : 5;
+       u32     row11 : 5;
+       u32     rsvd : 2;
+};
+
+#define d_cr_dmap3_offset 0x14c
+#define d_cr_dmap3_r_opcode 0x0
+
+struct d_cr_dmap4 {
+       u32     row12 : 5;
+       u32     row13 : 5;
+       u32     row14 : 5;
+       u32     row15 : 5;
+       u32     row16 : 5;
+       u32     row17 : 5;
+       u32     rsvd : 2;
+};
+
+#define d_cr_dmap4_offset 0x150
+#define d_cr_dmap4_r_opcode 0x0
+
+struct d_cr_dmap5 {
+       u32     ca3 : 4;
+       u32     ca4 : 4;
+       u32     ca5 : 4;
+       u32     ca6 : 4;
+       u32     ca7 : 4;
+       u32     ca8 : 4;
+       u32     ca9 : 4;
+       u32     rsvd : 4;
+};
+
+#define d_cr_dmap5_offset 0x154
+#define d_cr_dmap5_r_opcode 0x0
+
+#endif /* _PND2_REGS_H */
index 6c270d9d304a8eafb7464f576fdff119cb4cf27a..669246056812e8d361040fb4ce6f098574460768 100644 (file)
@@ -1596,7 +1596,7 @@ static void xgene_edac_pa_report(struct edac_device_ctl_info *edac_dev)
        reg = readl(ctx->dev_csr + IOBPATRANSERRINTSTS);
        if (!reg)
                goto chk_iob_axi0;
-       dev_err(edac_dev->dev, "IOB procesing agent (PA) transaction error\n");
+       dev_err(edac_dev->dev, "IOB processing agent (PA) transaction error\n");
        if (reg & IOBPA_RDATA_CORRUPT_MASK)
                dev_err(edac_dev->dev, "IOB PA read data RAM error\n");
        if (reg & IOBPA_M_RDATA_CORRUPT_MASK)
index 96bbae579c0b01cfdc3798e8fdb03948cb391280..fc09c76248b41630c8e849db0d8bf6826fb0e9aa 100644 (file)
@@ -44,7 +44,7 @@ config EXTCON_GPIO
 
 config EXTCON_INTEL_INT3496
        tristate "Intel INT3496 ACPI device extcon driver"
-       depends on GPIOLIB && ACPI
+       depends on GPIOLIB && ACPI && (X86 || COMPILE_TEST)
        help
          Say Y here to enable extcon support for USB OTG ports controlled by
          an Intel INT3496 ACPI device.
index a3131b036de6810281854730c429a17117e6832d..9d17984bbbd49a810ac749f06013c282a006c46f 100644 (file)
@@ -45,6 +45,17 @@ static const unsigned int int3496_cable[] = {
        EXTCON_NONE,
 };
 
+static const struct acpi_gpio_params id_gpios = { INT3496_GPIO_USB_ID, 0, false };
+static const struct acpi_gpio_params vbus_gpios = { INT3496_GPIO_VBUS_EN, 0, false };
+static const struct acpi_gpio_params mux_gpios = { INT3496_GPIO_USB_MUX, 0, false };
+
+static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = {
+       { "id-gpios", &id_gpios, 1 },
+       { "vbus-gpios", &vbus_gpios, 1 },
+       { "mux-gpios", &mux_gpios, 1 },
+       { },
+};
+
 static void int3496_do_usb_id(struct work_struct *work)
 {
        struct int3496_data *data =
@@ -83,6 +94,13 @@ static int int3496_probe(struct platform_device *pdev)
        struct int3496_data *data;
        int ret;
 
+       ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
+                                       acpi_int3496_default_gpios);
+       if (ret) {
+               dev_err(dev, "can't add GPIO ACPI mapping\n");
+               return ret;
+       }
+
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -90,30 +108,27 @@ static int int3496_probe(struct platform_device *pdev)
        data->dev = dev;
        INIT_DELAYED_WORK(&data->work, int3496_do_usb_id);
 
-       data->gpio_usb_id = devm_gpiod_get_index(dev, "id",
-                                               INT3496_GPIO_USB_ID,
-                                               GPIOD_IN);
+       data->gpio_usb_id = devm_gpiod_get(dev, "id", GPIOD_IN);
        if (IS_ERR(data->gpio_usb_id)) {
                ret = PTR_ERR(data->gpio_usb_id);
                dev_err(dev, "can't request USB ID GPIO: %d\n", ret);
                return ret;
+       } else if (gpiod_get_direction(data->gpio_usb_id) != GPIOF_DIR_IN) {
+               dev_warn(dev, FW_BUG "USB ID GPIO not in input mode, fixing\n");
+               gpiod_direction_input(data->gpio_usb_id);
        }
 
        data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id);
-       if (data->usb_id_irq <= 0) {
+       if (data->usb_id_irq < 0) {
                dev_err(dev, "can't get USB ID IRQ: %d\n", data->usb_id_irq);
-               return -EINVAL;
+               return data->usb_id_irq;
        }
 
-       data->gpio_vbus_en = devm_gpiod_get_index(dev, "vbus en",
-                                                INT3496_GPIO_VBUS_EN,
-                                                GPIOD_ASIS);
+       data->gpio_vbus_en = devm_gpiod_get(dev, "vbus", GPIOD_ASIS);
        if (IS_ERR(data->gpio_vbus_en))
                dev_info(dev, "can't request VBUS EN GPIO\n");
 
-       data->gpio_usb_mux = devm_gpiod_get_index(dev, "usb mux",
-                                                INT3496_GPIO_USB_MUX,
-                                                GPIOD_ASIS);
+       data->gpio_usb_mux = devm_gpiod_get(dev, "mux", GPIOD_ASIS);
        if (IS_ERR(data->gpio_usb_mux))
                dev_info(dev, "can't request USB MUX GPIO\n");
 
@@ -154,6 +169,8 @@ static int int3496_remove(struct platform_device *pdev)
        devm_free_irq(&pdev->dev, data->usb_id_irq, data);
        cancel_delayed_work_sync(&data->work);
 
+       acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
+
        return 0;
 }
 
index e7d404059b7316a5c5668f609ceb5957fdcdd97d..b372aad3b449c39a85daa7d8df1a417741a83a73 100644 (file)
@@ -389,7 +389,6 @@ int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
                        return 0;
                }
        }
-       pr_err_once("requested map not found.\n");
        return -ENOENT;
 }
 
index 08b026864d4e7d5f00b76cbd95b7398c6db943f8..8554d7aec31c640b6e845ec6502fb2d538408fae 100644 (file)
@@ -254,7 +254,7 @@ void __init efi_esrt_init(void)
 
        rc = efi_mem_desc_lookup(efi.esrt, &md);
        if (rc < 0) {
-               pr_err("ESRT header is not in the memory map.\n");
+               pr_warn("ESRT header is not in the memory map.\n");
                return;
        }
 
index 9e1a138fed53372a56dd1b7d2982ec198f46b3f1..16a8951b2beda389368c858848beb2edaf06949f 100644 (file)
@@ -96,7 +96,7 @@ static int altr_a10sr_gpio_probe(struct platform_device *pdev)
        gpio->regmap = a10sr->regmap;
 
        gpio->gp = altr_a10sr_gc;
-
+       gpio->gp.parent = pdev->dev.parent;
        gpio->gp.of_node = pdev->dev.of_node;
 
        ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
index 5bddbd507ca9f105aa18cfe5f43b673b676d551d..3fe6a21e05a5718d8769bf2dd505cb5968f41207 100644 (file)
@@ -90,21 +90,18 @@ static int altera_gpio_irq_set_type(struct irq_data *d,
 
        altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
 
-       if (type == IRQ_TYPE_NONE)
+       if (type == IRQ_TYPE_NONE) {
+               irq_set_handler_locked(d, handle_bad_irq);
                return 0;
-       if (type == IRQ_TYPE_LEVEL_HIGH &&
-               altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH)
-               return 0;
-       if (type == IRQ_TYPE_EDGE_RISING &&
-               altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_RISING)
-               return 0;
-       if (type == IRQ_TYPE_EDGE_FALLING &&
-               altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_FALLING)
-               return 0;
-       if (type == IRQ_TYPE_EDGE_BOTH &&
-               altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_BOTH)
+       }
+       if (type == altera_gc->interrupt_trigger) {
+               if (type == IRQ_TYPE_LEVEL_HIGH)
+                       irq_set_handler_locked(d, handle_level_irq);
+               else
+                       irq_set_handler_locked(d, handle_simple_irq);
                return 0;
-
+       }
+       irq_set_handler_locked(d, handle_bad_irq);
        return -EINVAL;
 }
 
@@ -230,7 +227,6 @@ static void altera_gpio_irq_edge_handler(struct irq_desc *desc)
        chained_irq_exit(chip, desc);
 }
 
-
 static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc)
 {
        struct altera_gpio_chip *altera_gc;
@@ -310,7 +306,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
        altera_gc->interrupt_trigger = reg;
 
        ret = gpiochip_irqchip_add(&altera_gc->mmchip.gc, &altera_irq_chip, 0,
-               handle_simple_irq, IRQ_TYPE_NONE);
+               handle_bad_irq, IRQ_TYPE_NONE);
 
        if (ret) {
                dev_err(&pdev->dev, "could not add irqchip\n");
index bdb692345428ccc99c8f22bd3b460f25b41e3156..2a57d024481db8c354badd976843f83a365c72a9 100644 (file)
@@ -270,8 +270,10 @@ mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
 static irqreturn_t mcp23s08_irq(int irq, void *data)
 {
        struct mcp23s08 *mcp = data;
-       int intcap, intf, i;
+       int intcap, intf, i, gpio, gpio_orig, intcap_mask;
        unsigned int child_irq;
+       bool intf_set, intcap_changed, gpio_bit_changed,
+               defval_changed, gpio_set;
 
        mutex_lock(&mcp->lock);
        if (mcp_read(mcp, MCP_INTF, &intf) < 0) {
@@ -287,14 +289,67 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
        }
 
        mcp->cache[MCP_INTCAP] = intcap;
+
+       /* This clears the interrupt(configurable on S18) */
+       if (mcp_read(mcp, MCP_GPIO, &gpio) < 0) {
+               mutex_unlock(&mcp->lock);
+               return IRQ_HANDLED;
+       }
+       gpio_orig = mcp->cache[MCP_GPIO];
+       mcp->cache[MCP_GPIO] = gpio;
        mutex_unlock(&mcp->lock);
 
+       if (mcp->cache[MCP_INTF] == 0) {
+               /* There is no interrupt pending */
+               return IRQ_HANDLED;
+       }
+
+       dev_dbg(mcp->chip.parent,
+               "intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n",
+               intcap, intf, gpio_orig, gpio);
 
        for (i = 0; i < mcp->chip.ngpio; i++) {
-               if ((BIT(i) & mcp->cache[MCP_INTF]) &&
-                   ((BIT(i) & intcap & mcp->irq_rise) ||
-                    (mcp->irq_fall & ~intcap & BIT(i)) ||
-                    (BIT(i) & mcp->cache[MCP_INTCON]))) {
+               /* We must check all of the inputs on the chip,
+                * otherwise we may not notice a change on >=2 pins.
+                *
+                * On at least the mcp23s17, INTCAP is only updated
+                * one byte at a time(INTCAPA and INTCAPB are
+                * not written to at the same time - only on a per-bank
+                * basis).
+                *
+                * INTF only contains the single bit that caused the
+                * interrupt per-bank.  On the mcp23s17, there is
+                * INTFA and INTFB.  If two pins are changed on the A
+                * side at the same time, INTF will only have one bit
+                * set.  If one pin on the A side and one pin on the B
+                * side are changed at the same time, INTF will have
+                * two bits set.  Thus, INTF can't be the only check
+                * to see if the input has changed.
+                */
+
+               intf_set = BIT(i) & mcp->cache[MCP_INTF];
+               if (i < 8 && intf_set)
+                       intcap_mask = 0x00FF;
+               else if (i >= 8 && intf_set)
+                       intcap_mask = 0xFF00;
+               else
+                       intcap_mask = 0x00;
+
+               intcap_changed = (intcap_mask &
+                       (BIT(i) & mcp->cache[MCP_INTCAP])) !=
+                       (intcap_mask & (BIT(i) & gpio_orig));
+               gpio_set = BIT(i) & mcp->cache[MCP_GPIO];
+               gpio_bit_changed = (BIT(i) & gpio_orig) !=
+                       (BIT(i) & mcp->cache[MCP_GPIO]);
+               defval_changed = (BIT(i) & mcp->cache[MCP_INTCON]) &&
+                       ((BIT(i) & mcp->cache[MCP_GPIO]) !=
+                       (BIT(i) & mcp->cache[MCP_DEFVAL]));
+
+               if (((gpio_bit_changed || intcap_changed) &&
+                       (BIT(i) & mcp->irq_rise) && gpio_set) ||
+                   ((gpio_bit_changed || intcap_changed) &&
+                       (BIT(i) & mcp->irq_fall) && !gpio_set) ||
+                   defval_changed) {
                        child_irq = irq_find_mapping(mcp->chip.irqdomain, i);
                        handle_nested_irq(child_irq);
                }
index 06dac72cb69c0c1c6e9005c748a613985dea111b..d993386892138757b67be09b4df8a822e39e4017 100644 (file)
@@ -197,7 +197,7 @@ static ssize_t gpio_mockup_event_write(struct file *file,
        struct seq_file *sfile;
        struct gpio_desc *desc;
        struct gpio_chip *gc;
-       int status, val;
+       int val;
        char buf;
 
        sfile = file->private_data;
@@ -206,9 +206,8 @@ static ssize_t gpio_mockup_event_write(struct file *file,
        chip = priv->chip;
        gc = &chip->gc;
 
-       status = copy_from_user(&buf, usr_buf, 1);
-       if (status)
-               return status;
+       if (copy_from_user(&buf, usr_buf, 1))
+               return -EFAULT;
 
        if (buf == '0')
                val = 0;
index 40a8881c2ce882bc1eef7eb59fff492afa6f378b..f1c6ec17b90a8352ecaf2e350aa8309a317925d8 100644 (file)
@@ -42,9 +42,7 @@ struct xgene_gpio {
        struct gpio_chip        chip;
        void __iomem            *base;
        spinlock_t              lock;
-#ifdef CONFIG_PM
        u32                     set_dr_val[XGENE_MAX_GPIO_BANKS];
-#endif
 };
 
 static int xgene_gpio_get(struct gpio_chip *gc, unsigned int offset)
@@ -138,8 +136,7 @@ static int xgene_gpio_dir_out(struct gpio_chip *gc,
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int xgene_gpio_suspend(struct device *dev)
+static __maybe_unused int xgene_gpio_suspend(struct device *dev)
 {
        struct xgene_gpio *gpio = dev_get_drvdata(dev);
        unsigned long bank_offset;
@@ -152,7 +149,7 @@ static int xgene_gpio_suspend(struct device *dev)
        return 0;
 }
 
-static int xgene_gpio_resume(struct device *dev)
+static __maybe_unused int xgene_gpio_resume(struct device *dev)
 {
        struct xgene_gpio *gpio = dev_get_drvdata(dev);
        unsigned long bank_offset;
@@ -166,10 +163,6 @@ static int xgene_gpio_resume(struct device *dev)
 }
 
 static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume);
-#define XGENE_GPIO_PM_OPS      (&xgene_gpio_pm)
-#else
-#define XGENE_GPIO_PM_OPS      NULL
-#endif
 
 static int xgene_gpio_probe(struct platform_device *pdev)
 {
@@ -241,7 +234,7 @@ static struct platform_driver xgene_gpio_driver = {
                .name = "xgene-gpio",
                .of_match_table = xgene_gpio_of_match,
                .acpi_match_table = ACPI_PTR(xgene_gpio_acpi_match),
-               .pm     = XGENE_GPIO_PM_OPS,
+               .pm     = &xgene_gpio_pm,
        },
        .probe = xgene_gpio_probe,
 };
index a3a105ec99e2d797978c79355f6ea67d4d4df5b4..de0cf3315484c997877b30a65a15e7e1af3b87a4 100644 (file)
@@ -475,7 +475,7 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)
        int r;
 
        if (adev->wb.wb_obj == NULL) {
-               r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * 4,
+               r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t),
                                            PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
                                            &adev->wb.wb_obj, &adev->wb.gpu_addr,
                                            (void **)&adev->wb.wb);
@@ -488,7 +488,7 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)
                memset(&adev->wb.used, 0, sizeof(adev->wb.used));
 
                /* clear wb memory */
-               memset((char *)adev->wb.wb, 0, AMDGPU_GPU_PAGE_SIZE);
+               memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t));
        }
 
        return 0;
index f7adbace428a49ea77a47bf3d3590ec136b0d1fe..b76cd699eb0d7357d79d68f9da4fd9bd02f3e132 100644 (file)
@@ -421,6 +421,7 @@ static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x6985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
        {0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
        {0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
+       {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
        {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
 
        {0, 0, 0}
index 33b504bafb8824727f3ba60fe2b103608ffe61c0..c5dec210d5299995c72ea79f95c05415306f034f 100644 (file)
@@ -3465,9 +3465,13 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
                        max_sclk = 75000;
                }
        } else if (adev->asic_type == CHIP_OLAND) {
-               if ((adev->pdev->device == 0x6604) &&
-                   (adev->pdev->subsystem_vendor == 0x1028) &&
-                   (adev->pdev->subsystem_device == 0x066F)) {
+               if ((adev->pdev->revision == 0xC7) ||
+                   (adev->pdev->revision == 0x80) ||
+                   (adev->pdev->revision == 0x81) ||
+                   (adev->pdev->revision == 0x83) ||
+                   (adev->pdev->revision == 0x87) ||
+                   (adev->pdev->device == 0x6604) ||
+                   (adev->pdev->device == 0x6605)) {
                        max_sclk = 75000;
                }
        }
index f6d4d9700734e6d48792e90d47c7bfe4081116a1..324a688b3f3013e9020ce2b9f0f76083ad91f890 100644 (file)
@@ -1260,9 +1260,9 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
         * to KMS, hence fail if different settings are requested.
         */
        if (var->bits_per_pixel != fb->format->cpp[0] * 8 ||
-           var->xres != fb->width || var->yres != fb->height ||
-           var->xres_virtual != fb->width || var->yres_virtual != fb->height) {
-               DRM_DEBUG("fb userspace requested width/height/bpp different than current fb "
+           var->xres > fb->width || var->yres > fb->height ||
+           var->xres_virtual > fb->width || var->yres_virtual > fb->height) {
+               DRM_DEBUG("fb requested width/height/bpp can't fit in current fb "
                          "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n",
                          var->xres, var->yres, var->bits_per_pixel,
                          var->xres_virtual, var->yres_virtual,
index 130d7d517a19a180ca7f2e744131aeabc554564b..da48819ff2e6550c0a7d6206569d85e8a880c0c5 100644 (file)
@@ -1311,6 +1311,8 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
                goto out_pm_put;
        }
 
+       mutex_lock(&gpu->lock);
+
        fence = etnaviv_gpu_fence_alloc(gpu);
        if (!fence) {
                event_free(gpu, event);
@@ -1318,8 +1320,6 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
                goto out_pm_put;
        }
 
-       mutex_lock(&gpu->lock);
-
        gpu->event[event].fence = fence;
        submit->fence = fence->seqno;
        gpu->active_fence = submit->fence;
index 0fd6f7a18364a69ba67cb000674593fc94041e19..c0e8d3302292c9c9329ca4795b4d9ffb3465a178 100644 (file)
@@ -68,6 +68,8 @@ struct decon_context {
        unsigned long                   flags;
        unsigned long                   out_type;
        int                             first_win;
+       spinlock_t                      vblank_lock;
+       u32                             frame_id;
 };
 
 static const uint32_t decon_formats[] = {
@@ -103,7 +105,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
                if (ctx->out_type & IFTYPE_I80)
                        val |= VIDINTCON0_FRAMEDONE;
                else
-                       val |= VIDINTCON0_INTFRMEN;
+                       val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
 
                writel(val, ctx->addr + DECON_VIDINTCON0);
        }
@@ -122,14 +124,56 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
                writel(0, ctx->addr + DECON_VIDINTCON0);
 }
 
+/* return number of starts/ends of frame transmissions since reset */
+static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
+{
+       u32 frm, pfrm, status, cnt = 2;
+
+       /* To get consistent result repeat read until frame id is stable.
+        * Usually the loop will be executed once, in rare cases when the loop
+        * is executed at frame change time 2nd pass will be needed.
+        */
+       frm = readl(ctx->addr + DECON_CRFMID);
+       do {
+               status = readl(ctx->addr + DECON_VIDCON1);
+               pfrm = frm;
+               frm = readl(ctx->addr + DECON_CRFMID);
+       } while (frm != pfrm && --cnt);
+
+       /* CRFMID is incremented on BPORCH in case of I80 and on VSYNC in case
+        * of RGB, it should be taken into account.
+        */
+       if (!frm)
+               return 0;
+
+       switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) {
+       case VIDCON1_VSTATUS_VS:
+               if (!(ctx->out_type & IFTYPE_I80))
+                       --frm;
+               break;
+       case VIDCON1_VSTATUS_BP:
+               --frm;
+               break;
+       case VIDCON1_I80_ACTIVE:
+       case VIDCON1_VSTATUS_AC:
+               if (end)
+                       --frm;
+               break;
+       default:
+               break;
+       }
+
+       return frm;
+}
+
 static void decon_setup_trigger(struct decon_context *ctx)
 {
        if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
                return;
 
        if (!(ctx->out_type & I80_HW_TRG)) {
-               writel(TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN
-                      TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN,
+               writel(TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
+                      TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN,
                       ctx->addr + DECON_TRIGCON);
                return;
        }
@@ -365,11 +409,14 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
 static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
 {
        struct decon_context *ctx = crtc->ctx;
+       unsigned long flags;
        int i;
 
        if (test_bit(BIT_SUSPENDED, &ctx->flags))
                return;
 
+       spin_lock_irqsave(&ctx->vblank_lock, flags);
+
        for (i = ctx->first_win; i < WINDOWS_NR; i++)
                decon_shadow_protect_win(ctx, i, false);
 
@@ -378,11 +425,18 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
 
        if (ctx->out_type & IFTYPE_I80)
                set_bit(BIT_WIN_UPDATED, &ctx->flags);
+
+       ctx->frame_id = decon_get_frame_count(ctx, true);
+
+       exynos_crtc_handle_event(crtc);
+
+       spin_unlock_irqrestore(&ctx->vblank_lock, flags);
 }
 
 static void decon_swreset(struct decon_context *ctx)
 {
        unsigned int tries;
+       unsigned long flags;
 
        writel(0, ctx->addr + DECON_VIDCON0);
        for (tries = 2000; tries; --tries) {
@@ -400,6 +454,10 @@ static void decon_swreset(struct decon_context *ctx)
 
        WARN(tries == 0, "failed to software reset DECON\n");
 
+       spin_lock_irqsave(&ctx->vblank_lock, flags);
+       ctx->frame_id = 0;
+       spin_unlock_irqrestore(&ctx->vblank_lock, flags);
+
        if (!(ctx->out_type & IFTYPE_HDMI))
                return;
 
@@ -578,6 +636,24 @@ static const struct component_ops decon_component_ops = {
        .unbind = decon_unbind,
 };
 
+static void decon_handle_vblank(struct decon_context *ctx)
+{
+       u32 frm;
+
+       spin_lock(&ctx->vblank_lock);
+
+       frm = decon_get_frame_count(ctx, true);
+
+       if (frm != ctx->frame_id) {
+               /* handle only if incremented, take care of wrap-around */
+               if ((s32)(frm - ctx->frame_id) > 0)
+                       drm_crtc_handle_vblank(&ctx->crtc->base);
+               ctx->frame_id = frm;
+       }
+
+       spin_unlock(&ctx->vblank_lock);
+}
+
 static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 {
        struct decon_context *ctx = dev_id;
@@ -598,7 +674,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
                            (VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F))
                                return IRQ_HANDLED;
                }
-               drm_crtc_handle_vblank(&ctx->crtc->base);
+               decon_handle_vblank(ctx);
        }
 
 out:
@@ -671,6 +747,7 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
        __set_bit(BIT_SUSPENDED, &ctx->flags);
        ctx->dev = dev;
        ctx->out_type = (unsigned long)of_device_get_match_data(dev);
+       spin_lock_init(&ctx->vblank_lock);
 
        if (ctx->out_type & IFTYPE_HDMI) {
                ctx->first_win = 1;
@@ -678,7 +755,7 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
                ctx->out_type |= IFTYPE_I80;
        }
 
-       if (ctx->out_type | I80_HW_TRG) {
+       if (ctx->out_type & I80_HW_TRG) {
                ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
                                                        "samsung,disp-sysreg");
                if (IS_ERR(ctx->sysreg)) {
index f9ab19e205e243d931412257064455582747e92a..48811806fa2727c540e5f5e9d0ffb1700dc08c4f 100644 (file)
@@ -526,6 +526,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
 
        for (i = 0; i < WINDOWS_NR; i++)
                decon_shadow_protect_win(ctx, i, false);
+       exynos_crtc_handle_event(crtc);
 }
 
 static void decon_init(struct decon_context *ctx)
index 5367b6664fe37d6ea1825eac48e620a7c6d902e7..c65f4509932c56f18f869f81b293d707ce2e47d7 100644 (file)
@@ -85,16 +85,28 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
                                     struct drm_crtc_state *old_crtc_state)
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-       struct drm_pending_vblank_event *event;
-       unsigned long flags;
 
        if (exynos_crtc->ops->atomic_flush)
                exynos_crtc->ops->atomic_flush(exynos_crtc);
+}
+
+static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
+       .enable         = exynos_drm_crtc_enable,
+       .disable        = exynos_drm_crtc_disable,
+       .mode_set_nofb  = exynos_drm_crtc_mode_set_nofb,
+       .atomic_check   = exynos_crtc_atomic_check,
+       .atomic_begin   = exynos_crtc_atomic_begin,
+       .atomic_flush   = exynos_crtc_atomic_flush,
+};
+
+void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
+{
+       struct drm_crtc *crtc = &exynos_crtc->base;
+       struct drm_pending_vblank_event *event = crtc->state->event;
+       unsigned long flags;
 
-       event = crtc->state->event;
        if (event) {
                crtc->state->event = NULL;
-
                spin_lock_irqsave(&crtc->dev->event_lock, flags);
                if (drm_crtc_vblank_get(crtc) == 0)
                        drm_crtc_arm_vblank_event(crtc, event);
@@ -105,15 +117,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
 
 }
 
-static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
-       .enable         = exynos_drm_crtc_enable,
-       .disable        = exynos_drm_crtc_disable,
-       .mode_set_nofb  = exynos_drm_crtc_mode_set_nofb,
-       .atomic_check   = exynos_crtc_atomic_check,
-       .atomic_begin   = exynos_crtc_atomic_begin,
-       .atomic_flush   = exynos_crtc_atomic_flush,
-};
-
 static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
index 6a581a8af4650fcf5f07ea3fa84c6b1dd5e81ad4..abd5d6ceac0c2fa0500650a139876d20ca9d3ea8 100644 (file)
@@ -40,4 +40,6 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
  */
 void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
 
+void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc);
+
 #endif
index 812e2ec0761d0b2b6ad17c71c99a37995e09ca51..d7ef26370e67c59fa2825a8be9303ab4f5b0c708 100644 (file)
@@ -86,7 +86,7 @@
 #define DSIM_SYNC_INFORM               (1 << 27)
 #define DSIM_EOT_DISABLE               (1 << 28)
 #define DSIM_MFLUSH_VS                 (1 << 29)
-/* This flag is valid only for exynos3250/3472/4415/5260/5430 */
+/* This flag is valid only for exynos3250/3472/5260/5430 */
 #define DSIM_CLKLANE_STOP              (1 << 30)
 
 /* DSIM_ESCMODE */
@@ -473,17 +473,6 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
        .reg_values = reg_values,
 };
 
-static const struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
-       .reg_ofs = exynos_reg_ofs,
-       .plltmr_reg = 0x58,
-       .has_clklane_stop = 1,
-       .num_clks = 2,
-       .max_freq = 1000,
-       .wait_for_reset = 1,
-       .num_bits_resol = 11,
-       .reg_values = reg_values,
-};
-
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
        .reg_ofs = exynos_reg_ofs,
        .plltmr_reg = 0x58,
@@ -521,8 +510,6 @@ static const struct of_device_id exynos_dsi_of_match[] = {
          .data = &exynos3_dsi_driver_data },
        { .compatible = "samsung,exynos4210-mipi-dsi",
          .data = &exynos4_dsi_driver_data },
-       { .compatible = "samsung,exynos4415-mipi-dsi",
-         .data = &exynos4415_dsi_driver_data },
        { .compatible = "samsung,exynos5410-mipi-dsi",
          .data = &exynos5_dsi_driver_data },
        { .compatible = "samsung,exynos5422-mipi-dsi",
@@ -979,7 +966,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
        bool first = !xfer->tx_done;
        u32 reg;
 
-       dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",
+       dev_dbg(dev, "< xfer %pK: tx len %u, done %u, rx len %u, done %u\n",
                xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);
 
        if (length > DSI_TX_FIFO_SIZE)
@@ -1177,7 +1164,7 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
        spin_unlock_irqrestore(&dsi->transfer_lock, flags);
 
        dev_dbg(dsi->dev,
-               "> xfer %p, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",
+               "> xfer %pK, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",
                xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,
                xfer->rx_done);
 
@@ -1348,9 +1335,12 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
        int te_gpio_irq;
 
        dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);
+       if (dsi->te_gpio == -ENOENT)
+               return 0;
+
        if (!gpio_is_valid(dsi->te_gpio)) {
-               dev_err(dsi->dev, "no te-gpios specified\n");
                ret = dsi->te_gpio;
+               dev_err(dsi->dev, "cannot get te-gpios, %d\n", ret);
                goto out;
        }
 
index 95871577015d8a5389cdae3a0c87413af7f0448f..5b18b5c5fdf255f262d68fc6fc7103f8d4d06910 100644 (file)
@@ -1695,7 +1695,7 @@ static int fimc_probe(struct platform_device *pdev)
                goto err_put_clk;
        }
 
-       DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
+       DRM_DEBUG_KMS("id[%d]ippdrv[%pK]\n", ctx->id, ippdrv);
 
        spin_lock_init(&ctx->lock);
        platform_set_drvdata(pdev, ctx);
index a9fa444c6053c0c8d048598198938d7fa2647cce..3f04d72c448d386fc9f646e1033c8528406b107e 100644 (file)
 #define TRIGCON                                0x1A4
 #define TRGMODE_ENABLE                 (1 << 0)
 #define SWTRGCMD_ENABLE                        (1 << 1)
-/* Exynos3250, 3472, 4415, 5260 5410, 5420 and 5422 only supported. */
+/* Exynos3250, 3472, 5260 5410, 5420 and 5422 only supported. */
 #define HWTRGEN_ENABLE                 (1 << 3)
 #define HWTRGMASK_ENABLE               (1 << 4)
-/* Exynos3250, 3472, 4415, 5260, 5420 and 5422 only supported. */
+/* Exynos3250, 3472, 5260, 5420 and 5422 only supported. */
 #define HWTRIGEN_PER_ENABLE            (1 << 31)
 
 /* display mode change control register except exynos4 */
@@ -138,18 +138,6 @@ static struct fimd_driver_data exynos4_fimd_driver_data = {
        .has_vtsel = 1,
 };
 
-static struct fimd_driver_data exynos4415_fimd_driver_data = {
-       .timing_base = 0x20000,
-       .lcdblk_offset = 0x210,
-       .lcdblk_vt_shift = 10,
-       .lcdblk_bypass_shift = 1,
-       .trg_type = I80_HW_TRG,
-       .has_shadowcon = 1,
-       .has_vidoutcon = 1,
-       .has_vtsel = 1,
-       .has_trigger_per_te = 1,
-};
-
 static struct fimd_driver_data exynos5_fimd_driver_data = {
        .timing_base = 0x20000,
        .lcdblk_offset = 0x214,
@@ -210,8 +198,6 @@ static const struct of_device_id fimd_driver_dt_match[] = {
          .data = &exynos3_fimd_driver_data },
        { .compatible = "samsung,exynos4210-fimd",
          .data = &exynos4_fimd_driver_data },
-       { .compatible = "samsung,exynos4415-fimd",
-         .data = &exynos4415_fimd_driver_data },
        { .compatible = "samsung,exynos5250-fimd",
          .data = &exynos5_fimd_driver_data },
        { .compatible = "samsung,exynos5420-fimd",
@@ -257,7 +243,7 @@ static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
                        val |= VIDINTCON0_INT_FRAME;
 
                        val &= ~VIDINTCON0_FRAMESEL0_MASK;
-                       val |= VIDINTCON0_FRAMESEL0_VSYNC;
+                       val |= VIDINTCON0_FRAMESEL0_FRONTPORCH;
                        val &= ~VIDINTCON0_FRAMESEL1_MASK;
                        val |= VIDINTCON0_FRAMESEL1_NONE;
                }
@@ -723,6 +709,8 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc)
 
        for (i = 0; i < WINDOWS_NR; i++)
                fimd_shadow_protect_win(ctx, i, false);
+
+       exynos_crtc_handle_event(crtc);
 }
 
 static void fimd_update_plane(struct exynos_drm_crtc *crtc,
index 4c28f7ffcc4dd1a0593e5c37bb878f6481f1ed70..55a1579d11b3d7c1ce604eeba2988de78de61e0b 100644 (file)
@@ -218,7 +218,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
                return ERR_PTR(ret);
        }
 
-       DRM_DEBUG_KMS("created file object = %p\n", obj->filp);
+       DRM_DEBUG_KMS("created file object = %pK\n", obj->filp);
 
        return exynos_gem;
 }
index bef57987759d2c8d2da9451a80c02b7b1c370b7f..0506b2b17ac1c45a1bea639cb37ed90075be3677 100644 (file)
@@ -1723,7 +1723,7 @@ static int gsc_probe(struct platform_device *pdev)
                return ret;
        }
 
-       DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
+       DRM_DEBUG_KMS("id[%d]ippdrv[%pK]\n", ctx->id, ippdrv);
 
        mutex_init(&ctx->lock);
        platform_set_drvdata(pdev, ctx);
index 9c84ee76f18adc0ab1b8dcc3f406a4021346ece8..3edda18cc2d2d61b7010b57817aeecababe1d4c5 100644 (file)
@@ -208,7 +208,7 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id)
         * e.g PAUSE state, queue buf, command control.
         */
        list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
-               DRM_DEBUG_KMS("count[%d]ippdrv[%p]\n", count++, ippdrv);
+               DRM_DEBUG_KMS("count[%d]ippdrv[%pK]\n", count++, ippdrv);
 
                mutex_lock(&ippdrv->cmd_lock);
                list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
@@ -388,7 +388,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
        }
        property->prop_id = ret;
 
-       DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[%p]\n",
+       DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[%pK]\n",
                property->prop_id, property->cmd, ippdrv);
 
        /* stored property information and ippdrv in private data */
@@ -518,7 +518,7 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
 {
        int i;
 
-       DRM_DEBUG_KMS("node[%p]\n", m_node);
+       DRM_DEBUG_KMS("node[%pK]\n", m_node);
 
        if (!m_node) {
                DRM_ERROR("invalid dequeue node.\n");
@@ -562,7 +562,7 @@ static struct drm_exynos_ipp_mem_node
        m_node->buf_id = qbuf->buf_id;
        INIT_LIST_HEAD(&m_node->list);
 
-       DRM_DEBUG_KMS("m_node[%p]ops_id[%d]\n", m_node, qbuf->ops_id);
+       DRM_DEBUG_KMS("m_node[%pK]ops_id[%d]\n", m_node, qbuf->ops_id);
        DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id);
 
        for_each_ipp_planar(i) {
@@ -659,7 +659,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
 
        mutex_lock(&c_node->event_lock);
        list_for_each_entry_safe(e, te, &c_node->event_list, base.link) {
-               DRM_DEBUG_KMS("count[%d]e[%p]\n", count++, e);
+               DRM_DEBUG_KMS("count[%d]e[%pK]\n", count++, e);
 
                /*
                 * qbuf == NULL condition means all event deletion.
@@ -750,7 +750,7 @@ static struct drm_exynos_ipp_mem_node
 
        /* find memory node from memory list */
        list_for_each_entry(m_node, head, list) {
-               DRM_DEBUG_KMS("count[%d]m_node[%p]\n", count++, m_node);
+               DRM_DEBUG_KMS("count[%d]m_node[%pK]\n", count++, m_node);
 
                /* compare buffer id */
                if (m_node->buf_id == qbuf->buf_id)
@@ -767,7 +767,7 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
        struct exynos_drm_ipp_ops *ops = NULL;
        int ret = 0;
 
-       DRM_DEBUG_KMS("node[%p]\n", m_node);
+       DRM_DEBUG_KMS("node[%pK]\n", m_node);
 
        if (!m_node) {
                DRM_ERROR("invalid queue node.\n");
@@ -1232,7 +1232,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
                        m_node = list_first_entry(head,
                                struct drm_exynos_ipp_mem_node, list);
 
-                       DRM_DEBUG_KMS("m_node[%p]\n", m_node);
+                       DRM_DEBUG_KMS("m_node[%pK]\n", m_node);
 
                        ret = ipp_set_mem_node(ippdrv, c_node, m_node);
                        if (ret) {
@@ -1601,7 +1601,7 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
                }
                ippdrv->prop_list.ipp_id = ret;
 
-               DRM_DEBUG_KMS("count[%d]ippdrv[%p]ipp_id[%d]\n",
+               DRM_DEBUG_KMS("count[%d]ippdrv[%pK]ipp_id[%d]\n",
                        count++, ippdrv, ret);
 
                /* store parent device for node */
@@ -1659,7 +1659,7 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
 
        file_priv->ipp_dev = dev;
 
-       DRM_DEBUG_KMS("done priv[%p]\n", dev);
+       DRM_DEBUG_KMS("done priv[%pK]\n", dev);
 
        return 0;
 }
@@ -1676,7 +1676,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
                mutex_lock(&ippdrv->cmd_lock);
                list_for_each_entry_safe(c_node, tc_node,
                        &ippdrv->cmd_list, list) {
-                       DRM_DEBUG_KMS("count[%d]ippdrv[%p]\n",
+                       DRM_DEBUG_KMS("count[%d]ippdrv[%pK]\n",
                                count++, ippdrv);
 
                        if (c_node->filp == file) {
index 6591e406084c164d30c1945aa2f6d7ce559c67fd..79282a820ecce104a59c828beac7be68b65a21ee 100644 (file)
@@ -748,7 +748,7 @@ static int rotator_probe(struct platform_device *pdev)
                goto err_ippdrv_register;
        }
 
-       DRM_DEBUG_KMS("ippdrv[%p]\n", ippdrv);
+       DRM_DEBUG_KMS("ippdrv[%pK]\n", ippdrv);
 
        platform_set_drvdata(pdev, rot);
 
index 57fe514d5c5bf9adc9f423d9f46a51e25aedfa46..5d9a62a87eec75f574ea0e696f31059d5802fa7d 100644 (file)
@@ -170,6 +170,7 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
        .enable_vblank = vidi_enable_vblank,
        .disable_vblank = vidi_disable_vblank,
        .update_plane = vidi_update_plane,
+       .atomic_flush = exynos_crtc_handle_event,
 };
 
 static void vidi_fake_vblank_timer(unsigned long arg)
index 72143ac1052526ffc03332c5b6b211ae7bf30216..25edb635a197621871d583e26b3d31d3717a82fa 100644 (file)
@@ -1012,6 +1012,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
                return;
 
        mixer_vsync_set_update(mixer_ctx, true);
+       exynos_crtc_handle_event(crtc);
 }
 
 static void mixer_enable(struct exynos_drm_crtc *crtc)
index 3b6caaca975135d6b8d595393ffc372bc14107bc..325618d969feedf035196c9e3d211affe2fd82f6 100644 (file)
@@ -242,7 +242,7 @@ static int alloc_resource(struct intel_vgpu *vgpu,
        const char *item;
 
        if (!param->low_gm_sz || !param->high_gm_sz || !param->fence_sz) {
-               gvt_err("Invalid vGPU creation params\n");
+               gvt_vgpu_err("Invalid vGPU creation params\n");
                return -EINVAL;
        }
 
@@ -285,9 +285,9 @@ static int alloc_resource(struct intel_vgpu *vgpu,
        return 0;
 
 no_enough_resource:
-       gvt_err("vgpu%d: fail to allocate resource %s\n", vgpu->id, item);
-       gvt_err("vgpu%d: request %luMB avail %luMB max %luMB taken %luMB\n",
-               vgpu->id, BYTES_TO_MB(request), BYTES_TO_MB(avail),
+       gvt_vgpu_err("fail to allocate resource %s\n", item);
+       gvt_vgpu_err("request %luMB avail %luMB max %luMB taken %luMB\n",
+               BYTES_TO_MB(request), BYTES_TO_MB(avail),
                BYTES_TO_MB(max), BYTES_TO_MB(taken));
        return -ENOSPC;
 }
index 7ae6e2b241c829efdfddfa7f826c182e0078aae5..2b92cc8a7d1aa551778917ed038bc6aa7961ce3e 100644 (file)
@@ -817,6 +817,25 @@ static bool is_shadowed_mmio(unsigned int offset)
        return ret;
 }
 
+static inline bool is_force_nonpriv_mmio(unsigned int offset)
+{
+       return (offset >= 0x24d0 && offset < 0x2500);
+}
+
+static int force_nonpriv_reg_handler(struct parser_exec_state *s,
+                                    unsigned int offset, unsigned int index)
+{
+       struct intel_gvt *gvt = s->vgpu->gvt;
+       unsigned int data = cmd_val(s, index + 1);
+
+       if (!intel_gvt_in_force_nonpriv_whitelist(gvt, data)) {
+               gvt_err("Unexpected forcenonpriv 0x%x LRI write, value=0x%x\n",
+                       offset, data);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int cmd_reg_handler(struct parser_exec_state *s,
        unsigned int offset, unsigned int index, char *cmd)
 {
@@ -824,23 +843,26 @@ static int cmd_reg_handler(struct parser_exec_state *s,
        struct intel_gvt *gvt = vgpu->gvt;
 
        if (offset + 4 > gvt->device_info.mmio_size) {
-               gvt_err("%s access to (%x) outside of MMIO range\n",
+               gvt_vgpu_err("%s access to (%x) outside of MMIO range\n",
                                cmd, offset);
                return -EINVAL;
        }
 
        if (!intel_gvt_mmio_is_cmd_access(gvt, offset)) {
-               gvt_err("vgpu%d: %s access to non-render register (%x)\n",
-                               s->vgpu->id, cmd, offset);
+               gvt_vgpu_err("%s access to non-render register (%x)\n",
+                               cmd, offset);
                return 0;
        }
 
        if (is_shadowed_mmio(offset)) {
-               gvt_err("vgpu%d: found access of shadowed MMIO %x\n",
-                               s->vgpu->id, offset);
+               gvt_vgpu_err("found access of shadowed MMIO %x\n", offset);
                return 0;
        }
 
+       if (is_force_nonpriv_mmio(offset) &&
+           force_nonpriv_reg_handler(s, offset, index))
+               return -EINVAL;
+
        if (offset == i915_mmio_reg_offset(DERRMR) ||
                offset == i915_mmio_reg_offset(FORCEWAKE_MT)) {
                /* Writing to HW VGT_PVINFO_PAGE offset will be discarded */
@@ -1008,7 +1030,7 @@ static int cmd_handler_pipe_control(struct parser_exec_state *s)
                        ret = cmd_reg_handler(s, 0x2358, 1, "pipe_ctrl");
                else if (post_sync == 1) {
                        /* check ggtt*/
-                       if ((cmd_val(s, 2) & (1 << 2))) {
+                       if ((cmd_val(s, 1) & PIPE_CONTROL_GLOBAL_GTT_IVB)) {
                                gma = cmd_val(s, 2) & GENMASK(31, 3);
                                if (gmadr_bytes == 8)
                                        gma |= (cmd_gma_hi(s, 3)) << 32;
@@ -1129,6 +1151,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s,
                struct mi_display_flip_command_info *info)
 {
        struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
+       struct intel_vgpu *vgpu = s->vgpu;
        u32 dword0 = cmd_val(s, 0);
        u32 dword1 = cmd_val(s, 1);
        u32 dword2 = cmd_val(s, 2);
@@ -1167,7 +1190,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s,
                break;
 
        default:
-               gvt_err("unknown plane code %d\n", plane);
+               gvt_vgpu_err("unknown plane code %d\n", plane);
                return -EINVAL;
        }
 
@@ -1274,25 +1297,26 @@ static int update_plane_mmio_from_mi_display_flip(
 static int cmd_handler_mi_display_flip(struct parser_exec_state *s)
 {
        struct mi_display_flip_command_info info;
+       struct intel_vgpu *vgpu = s->vgpu;
        int ret;
        int i;
        int len = cmd_length(s);
 
        ret = decode_mi_display_flip(s, &info);
        if (ret) {
-               gvt_err("fail to decode MI display flip command\n");
+               gvt_vgpu_err("fail to decode MI display flip command\n");
                return ret;
        }
 
        ret = check_mi_display_flip(s, &info);
        if (ret) {
-               gvt_err("invalid MI display flip command\n");
+               gvt_vgpu_err("invalid MI display flip command\n");
                return ret;
        }
 
        ret = update_plane_mmio_from_mi_display_flip(s, &info);
        if (ret) {
-               gvt_err("fail to update plane mmio\n");
+               gvt_vgpu_err("fail to update plane mmio\n");
                return ret;
        }
 
@@ -1350,7 +1374,8 @@ static inline int cmd_address_audit(struct parser_exec_state *s,
        int ret;
 
        if (op_size > max_surface_size) {
-               gvt_err("command address audit fail name %s\n", s->info->name);
+               gvt_vgpu_err("command address audit fail name %s\n",
+                       s->info->name);
                return -EINVAL;
        }
 
@@ -1367,7 +1392,7 @@ static inline int cmd_address_audit(struct parser_exec_state *s,
        }
        return 0;
 err:
-       gvt_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
+       gvt_vgpu_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
                        s->info->name, guest_gma, op_size);
 
        pr_err("cmd dump: ");
@@ -1412,8 +1437,10 @@ static int cmd_handler_mi_store_data_imm(struct parser_exec_state *s)
 
 static inline int unexpected_cmd(struct parser_exec_state *s)
 {
-       gvt_err("vgpu%d: Unexpected %s in command buffer!\n",
-                       s->vgpu->id, s->info->name);
+       struct intel_vgpu *vgpu = s->vgpu;
+
+       gvt_vgpu_err("Unexpected %s in command buffer!\n", s->info->name);
+
        return -EINVAL;
 }
 
@@ -1516,7 +1543,7 @@ static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm,
        while (gma != end_gma) {
                gpa = intel_vgpu_gma_to_gpa(mm, gma);
                if (gpa == INTEL_GVT_INVALID_ADDR) {
-                       gvt_err("invalid gma address: %lx\n", gma);
+                       gvt_vgpu_err("invalid gma address: %lx\n", gma);
                        return -EFAULT;
                }
 
@@ -1557,6 +1584,7 @@ static uint32_t find_bb_size(struct parser_exec_state *s)
        uint32_t bb_size = 0;
        uint32_t cmd_len = 0;
        bool met_bb_end = false;
+       struct intel_vgpu *vgpu = s->vgpu;
        u32 cmd;
 
        /* get the start gm address of the batch buffer */
@@ -1565,7 +1593,7 @@ static uint32_t find_bb_size(struct parser_exec_state *s)
 
        info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id);
        if (info == NULL) {
-               gvt_err("unknown cmd 0x%x, opcode=0x%x\n",
+               gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n",
                                cmd, get_opcode(cmd, s->ring_id));
                return -EINVAL;
        }
@@ -1574,7 +1602,7 @@ static uint32_t find_bb_size(struct parser_exec_state *s)
                                gma, gma + 4, &cmd);
                info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id);
                if (info == NULL) {
-                       gvt_err("unknown cmd 0x%x, opcode=0x%x\n",
+                       gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n",
                                cmd, get_opcode(cmd, s->ring_id));
                        return -EINVAL;
                }
@@ -1599,6 +1627,7 @@ static uint32_t find_bb_size(struct parser_exec_state *s)
 static int perform_bb_shadow(struct parser_exec_state *s)
 {
        struct intel_shadow_bb_entry *entry_obj;
+       struct intel_vgpu *vgpu = s->vgpu;
        unsigned long gma = 0;
        uint32_t bb_size;
        void *dst = NULL;
@@ -1633,7 +1662,7 @@ static int perform_bb_shadow(struct parser_exec_state *s)
 
        ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false);
        if (ret) {
-               gvt_err("failed to set shadow batch to CPU\n");
+               gvt_vgpu_err("failed to set shadow batch to CPU\n");
                goto unmap_src;
        }
 
@@ -1645,7 +1674,7 @@ static int perform_bb_shadow(struct parser_exec_state *s)
                              gma, gma + bb_size,
                              dst);
        if (ret) {
-               gvt_err("fail to copy guest ring buffer\n");
+               gvt_vgpu_err("fail to copy guest ring buffer\n");
                goto unmap_src;
        }
 
@@ -1676,15 +1705,16 @@ static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s)
 {
        bool second_level;
        int ret = 0;
+       struct intel_vgpu *vgpu = s->vgpu;
 
        if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
-               gvt_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n");
+               gvt_vgpu_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n");
                return -EINVAL;
        }
 
        second_level = BATCH_BUFFER_2ND_LEVEL_BIT(cmd_val(s, 0)) == 1;
        if (second_level && (s->buf_type != BATCH_BUFFER_INSTRUCTION)) {
-               gvt_err("Jumping to 2nd level BB from RB is not allowed\n");
+               gvt_vgpu_err("Jumping to 2nd level BB from RB is not allowed\n");
                return -EINVAL;
        }
 
@@ -1702,7 +1732,7 @@ static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s)
        if (batch_buffer_needs_scan(s)) {
                ret = perform_bb_shadow(s);
                if (ret < 0)
-                       gvt_err("invalid shadow batch buffer\n");
+                       gvt_vgpu_err("invalid shadow batch buffer\n");
        } else {
                /* emulate a batch buffer end to do return right */
                ret = cmd_handler_mi_batch_buffer_end(s);
@@ -2429,6 +2459,7 @@ static int cmd_parser_exec(struct parser_exec_state *s)
        int ret = 0;
        cycles_t t0, t1, t2;
        struct parser_exec_state s_before_advance_custom;
+       struct intel_vgpu *vgpu = s->vgpu;
 
        t0 = get_cycles();
 
@@ -2436,7 +2467,7 @@ static int cmd_parser_exec(struct parser_exec_state *s)
 
        info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id);
        if (info == NULL) {
-               gvt_err("unknown cmd 0x%x, opcode=0x%x\n",
+               gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n",
                                cmd, get_opcode(cmd, s->ring_id));
                return -EINVAL;
        }
@@ -2452,7 +2483,7 @@ static int cmd_parser_exec(struct parser_exec_state *s)
        if (info->handler) {
                ret = info->handler(s);
                if (ret < 0) {
-                       gvt_err("%s handler error\n", info->name);
+                       gvt_vgpu_err("%s handler error\n", info->name);
                        return ret;
                }
        }
@@ -2463,7 +2494,7 @@ static int cmd_parser_exec(struct parser_exec_state *s)
        if (!(info->flag & F_IP_ADVANCE_CUSTOM)) {
                ret = cmd_advance_default(s);
                if (ret) {
-                       gvt_err("%s IP advance error\n", info->name);
+                       gvt_vgpu_err("%s IP advance error\n", info->name);
                        return ret;
                }
        }
@@ -2486,6 +2517,7 @@ static int command_scan(struct parser_exec_state *s,
 
        unsigned long gma_head, gma_tail, gma_bottom;
        int ret = 0;
+       struct intel_vgpu *vgpu = s->vgpu;
 
        gma_head = rb_start + rb_head;
        gma_tail = rb_start + rb_tail;
@@ -2497,7 +2529,7 @@ static int command_scan(struct parser_exec_state *s,
                if (s->buf_type == RING_BUFFER_INSTRUCTION) {
                        if (!(s->ip_gma >= rb_start) ||
                                !(s->ip_gma < gma_bottom)) {
-                               gvt_err("ip_gma %lx out of ring scope."
+                               gvt_vgpu_err("ip_gma %lx out of ring scope."
                                        "(base:0x%lx, bottom: 0x%lx)\n",
                                        s->ip_gma, rb_start,
                                        gma_bottom);
@@ -2505,7 +2537,7 @@ static int command_scan(struct parser_exec_state *s,
                                return -EINVAL;
                        }
                        if (gma_out_of_range(s->ip_gma, gma_head, gma_tail)) {
-                               gvt_err("ip_gma %lx out of range."
+                               gvt_vgpu_err("ip_gma %lx out of range."
                                        "base 0x%lx head 0x%lx tail 0x%lx\n",
                                        s->ip_gma, rb_start,
                                        rb_head, rb_tail);
@@ -2515,7 +2547,7 @@ static int command_scan(struct parser_exec_state *s,
                }
                ret = cmd_parser_exec(s);
                if (ret) {
-                       gvt_err("cmd parser error\n");
+                       gvt_vgpu_err("cmd parser error\n");
                        parser_exec_state_dump(s);
                        break;
                }
@@ -2639,7 +2671,7 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
                                gma_head, gma_top,
                                workload->shadow_ring_buffer_va);
                if (ret) {
-                       gvt_err("fail to copy guest ring buffer\n");
+                       gvt_vgpu_err("fail to copy guest ring buffer\n");
                        return ret;
                }
                copy_len = gma_top - gma_head;
@@ -2651,7 +2683,7 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
                        gma_head, gma_tail,
                        workload->shadow_ring_buffer_va + copy_len);
        if (ret) {
-               gvt_err("fail to copy guest ring buffer\n");
+               gvt_vgpu_err("fail to copy guest ring buffer\n");
                return ret;
        }
        ring->tail += workload->rb_len;
@@ -2662,16 +2694,17 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
 int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
 {
        int ret;
+       struct intel_vgpu *vgpu = workload->vgpu;
 
        ret = shadow_workload_ring_buffer(workload);
        if (ret) {
-               gvt_err("fail to shadow workload ring_buffer\n");
+               gvt_vgpu_err("fail to shadow workload ring_buffer\n");
                return ret;
        }
 
        ret = scan_workload(workload);
        if (ret) {
-               gvt_err("scan workload error\n");
+               gvt_vgpu_err("scan workload error\n");
                return ret;
        }
        return 0;
@@ -2681,6 +2714,7 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 {
        int ctx_size = wa_ctx->indirect_ctx.size;
        unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
+       struct intel_vgpu *vgpu = wa_ctx->workload->vgpu;
        struct drm_i915_gem_object *obj;
        int ret = 0;
        void *map;
@@ -2694,14 +2728,14 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
        /* get the va of the shadow batch buffer */
        map = i915_gem_object_pin_map(obj, I915_MAP_WB);
        if (IS_ERR(map)) {
-               gvt_err("failed to vmap shadow indirect ctx\n");
+               gvt_vgpu_err("failed to vmap shadow indirect ctx\n");
                ret = PTR_ERR(map);
                goto put_obj;
        }
 
        ret = i915_gem_object_set_to_cpu_domain(obj, false);
        if (ret) {
-               gvt_err("failed to set shadow indirect ctx to CPU\n");
+               gvt_vgpu_err("failed to set shadow indirect ctx to CPU\n");
                goto unmap_src;
        }
 
@@ -2710,7 +2744,7 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
                                guest_gma, guest_gma + ctx_size,
                                map);
        if (ret) {
-               gvt_err("fail to copy guest indirect ctx\n");
+               gvt_vgpu_err("fail to copy guest indirect ctx\n");
                goto unmap_src;
        }
 
@@ -2744,13 +2778,14 @@ static int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 {
        int ret;
+       struct intel_vgpu *vgpu = wa_ctx->workload->vgpu;
 
        if (wa_ctx->indirect_ctx.size == 0)
                return 0;
 
        ret = shadow_indirect_ctx(wa_ctx);
        if (ret) {
-               gvt_err("fail to shadow indirect ctx\n");
+               gvt_vgpu_err("fail to shadow indirect ctx\n");
                return ret;
        }
 
@@ -2758,7 +2793,7 @@ int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 
        ret = scan_wa_ctx(wa_ctx);
        if (ret) {
-               gvt_err("scan wa ctx error\n");
+               gvt_vgpu_err("scan wa ctx error\n");
                return ret;
        }
 
index 68cba7bd980af8cb9a855ef3ff4a4c446947ebaf..b0cff4dc2684792271a5e648c889dbb5a4d04ac5 100644 (file)
 #define gvt_err(fmt, args...) \
        DRM_ERROR("gvt: "fmt, ##args)
 
+#define gvt_vgpu_err(fmt, args...)                                     \
+do {                                                                   \
+       if (IS_ERR_OR_NULL(vgpu))                                       \
+               DRM_DEBUG_DRIVER("gvt: "fmt, ##args);                   \
+       else                                                            \
+               DRM_DEBUG_DRIVER("gvt: vgpu %d: "fmt, vgpu->id, ##args);\
+} while (0)
+
 #define gvt_dbg_core(fmt, args...) \
        DRM_DEBUG_DRIVER("gvt: core: "fmt, ##args)
 
index bda85dff7b2a998d68d1485479c9687eab206600..42cd09ec63fa7c41b69d684f8cf382a04f15b2ab 100644 (file)
@@ -52,16 +52,16 @@ static unsigned char edid_get_byte(struct intel_vgpu *vgpu)
        unsigned char chr = 0;
 
        if (edid->state == I2C_NOT_SPECIFIED || !edid->slave_selected) {
-               gvt_err("Driver tries to read EDID without proper sequence!\n");
+               gvt_vgpu_err("Driver tries to read EDID without proper sequence!\n");
                return 0;
        }
        if (edid->current_edid_read >= EDID_SIZE) {
-               gvt_err("edid_get_byte() exceeds the size of EDID!\n");
+               gvt_vgpu_err("edid_get_byte() exceeds the size of EDID!\n");
                return 0;
        }
 
        if (!edid->edid_available) {
-               gvt_err("Reading EDID but EDID is not available!\n");
+               gvt_vgpu_err("Reading EDID but EDID is not available!\n");
                return 0;
        }
 
@@ -72,7 +72,7 @@ static unsigned char edid_get_byte(struct intel_vgpu *vgpu)
                chr = edid_data->edid_block[edid->current_edid_read];
                edid->current_edid_read++;
        } else {
-               gvt_err("No EDID available during the reading?\n");
+               gvt_vgpu_err("No EDID available during the reading?\n");
        }
        return chr;
 }
@@ -223,7 +223,7 @@ static int gmbus1_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
                        vgpu_vreg(vgpu, PCH_GMBUS2) |= GMBUS_ACTIVE;
                        break;
                default:
-                       gvt_err("Unknown/reserved GMBUS cycle detected!\n");
+                       gvt_vgpu_err("Unknown/reserved GMBUS cycle detected!\n");
                        break;
                }
                /*
@@ -292,8 +292,7 @@ static int gmbus3_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
                 */
        } else {
                memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
-               gvt_err("vgpu%d: warning: gmbus3 read with nothing returned\n",
-                               vgpu->id);
+               gvt_vgpu_err("warning: gmbus3 read with nothing returned\n");
        }
        return 0;
 }
@@ -496,7 +495,8 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
                        unsigned char val = edid_get_byte(vgpu);
 
                        aux_data_for_write = (val << 16);
-               }
+               } else
+                       aux_data_for_write = (0xff << 16);
        }
        /* write the return value in AUX_CH_DATA reg which includes:
         * ACK of I2C_WRITE
index 46eb9fd3c03f6b2fdb19fec6550a5f4347038f88..f1f426a97aa9d43826010d7be90f6bffdbe59426 100644 (file)
@@ -172,6 +172,7 @@ static int emulate_execlist_ctx_schedule_out(
                struct intel_vgpu_execlist *execlist,
                struct execlist_ctx_descriptor_format *ctx)
 {
+       struct intel_vgpu *vgpu = execlist->vgpu;
        struct intel_vgpu_execlist_slot *running = execlist->running_slot;
        struct intel_vgpu_execlist_slot *pending = execlist->pending_slot;
        struct execlist_ctx_descriptor_format *ctx0 = &running->ctx[0];
@@ -183,7 +184,7 @@ static int emulate_execlist_ctx_schedule_out(
        gvt_dbg_el("schedule out context id %x\n", ctx->context_id);
 
        if (WARN_ON(!same_context(ctx, execlist->running_context))) {
-               gvt_err("schedule out context is not running context,"
+               gvt_vgpu_err("schedule out context is not running context,"
                                "ctx id %x running ctx id %x\n",
                                ctx->context_id,
                                execlist->running_context->context_id);
@@ -254,7 +255,7 @@ static struct intel_vgpu_execlist_slot *get_next_execlist_slot(
        status.udw = vgpu_vreg(vgpu, status_reg + 4);
 
        if (status.execlist_queue_full) {
-               gvt_err("virtual execlist slots are full\n");
+               gvt_vgpu_err("virtual execlist slots are full\n");
                return NULL;
        }
 
@@ -270,11 +271,12 @@ static int emulate_execlist_schedule_in(struct intel_vgpu_execlist *execlist,
 
        struct execlist_ctx_descriptor_format *ctx0, *ctx1;
        struct execlist_context_status_format status;
+       struct intel_vgpu *vgpu = execlist->vgpu;
 
        gvt_dbg_el("emulate schedule-in\n");
 
        if (!slot) {
-               gvt_err("no available execlist slot\n");
+               gvt_vgpu_err("no available execlist slot\n");
                return -EINVAL;
        }
 
@@ -375,7 +377,6 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
 
                vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0, 4, 0);
                if (IS_ERR(vma)) {
-                       gvt_err("Cannot pin\n");
                        return;
                }
 
@@ -428,7 +429,6 @@ static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
        vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL,
                                       0, CACHELINE_BYTES, 0);
        if (IS_ERR(vma)) {
-               gvt_err("Cannot pin indirect ctx obj\n");
                return;
        }
 
@@ -561,6 +561,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
 {
        struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc;
        struct intel_vgpu_mm *mm;
+       struct intel_vgpu *vgpu = workload->vgpu;
        int page_table_level;
        u32 pdp[8];
 
@@ -569,7 +570,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
        } else if (desc->addressing_mode == 3) { /* legacy 64 bit */
                page_table_level = 4;
        } else {
-               gvt_err("Advanced Context mode(SVM) is not supported!\n");
+               gvt_vgpu_err("Advanced Context mode(SVM) is not supported!\n");
                return -EINVAL;
        }
 
@@ -583,7 +584,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
                mm = intel_vgpu_create_mm(workload->vgpu, INTEL_GVT_MM_PPGTT,
                                pdp, page_table_level, 0);
                if (IS_ERR(mm)) {
-                       gvt_err("fail to create mm object.\n");
+                       gvt_vgpu_err("fail to create mm object.\n");
                        return PTR_ERR(mm);
                }
        }
@@ -609,7 +610,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
        ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm,
                        (u32)((desc->lrca + 1) << GTT_PAGE_SHIFT));
        if (ring_context_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_err("invalid guest context LRCA: %x\n", desc->lrca);
+               gvt_vgpu_err("invalid guest context LRCA: %x\n", desc->lrca);
                return -EINVAL;
        }
 
@@ -724,8 +725,7 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
                        continue;
 
                if (!desc[i]->privilege_access) {
-                       gvt_err("vgpu%d: unexpected GGTT elsp submission\n",
-                                       vgpu->id);
+                       gvt_vgpu_err("unexpected GGTT elsp submission\n");
                        return -EINVAL;
                }
 
@@ -735,15 +735,13 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
        }
 
        if (!valid_desc_bitmap) {
-               gvt_err("vgpu%d: no valid desc in a elsp submission\n",
-                               vgpu->id);
+               gvt_vgpu_err("no valid desc in a elsp submission\n");
                return -EINVAL;
        }
 
        if (!test_bit(0, (void *)&valid_desc_bitmap) &&
                        test_bit(1, (void *)&valid_desc_bitmap)) {
-               gvt_err("vgpu%d: weird elsp submission, desc 0 is not valid\n",
-                               vgpu->id);
+               gvt_vgpu_err("weird elsp submission, desc 0 is not valid\n");
                return -EINVAL;
        }
 
@@ -752,8 +750,7 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
                ret = submit_context(vgpu, ring_id, &valid_desc[i],
                                emulate_schedule_in);
                if (ret) {
-                       gvt_err("vgpu%d: fail to schedule workload\n",
-                                       vgpu->id);
+                       gvt_vgpu_err("fail to schedule workload\n");
                        return ret;
                }
                emulate_schedule_in = false;
index 6a5ff23ded907c475adff1151199add49c289994..b832bea64e0367ed6c25bf031a2a71db82d7edcc 100644 (file)
@@ -49,8 +49,8 @@ bool intel_gvt_ggtt_validate_range(struct intel_vgpu *vgpu, u64 addr, u32 size)
 {
        if ((!vgpu_gmadr_is_valid(vgpu, addr)) || (size
                        && !vgpu_gmadr_is_valid(vgpu, addr + size - 1))) {
-               gvt_err("vgpu%d: invalid range gmadr 0x%llx size 0x%x\n",
-                               vgpu->id, addr, size);
+               gvt_vgpu_err("invalid range gmadr 0x%llx size 0x%x\n",
+                               addr, size);
                return false;
        }
        return true;
@@ -430,7 +430,7 @@ static int gtt_entry_p2m(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *p,
 
        mfn = intel_gvt_hypervisor_gfn_to_mfn(vgpu, gfn);
        if (mfn == INTEL_GVT_INVALID_ADDR) {
-               gvt_err("fail to translate gfn: 0x%lx\n", gfn);
+               gvt_vgpu_err("fail to translate gfn: 0x%lx\n", gfn);
                return -ENXIO;
        }
 
@@ -611,7 +611,7 @@ static inline int init_shadow_page(struct intel_vgpu *vgpu,
 
        daddr = dma_map_page(kdev, p->page, 0, 4096, PCI_DMA_BIDIRECTIONAL);
        if (dma_mapping_error(kdev, daddr)) {
-               gvt_err("fail to map dma addr\n");
+               gvt_vgpu_err("fail to map dma addr\n");
                return -EINVAL;
        }
 
@@ -735,7 +735,7 @@ retry:
                if (reclaim_one_mm(vgpu->gvt))
                        goto retry;
 
-               gvt_err("fail to allocate ppgtt shadow page\n");
+               gvt_vgpu_err("fail to allocate ppgtt shadow page\n");
                return ERR_PTR(-ENOMEM);
        }
 
@@ -750,14 +750,14 @@ retry:
         */
        ret = init_shadow_page(vgpu, &spt->shadow_page, type);
        if (ret) {
-               gvt_err("fail to initialize shadow page for spt\n");
+               gvt_vgpu_err("fail to initialize shadow page for spt\n");
                goto err;
        }
 
        ret = intel_vgpu_init_guest_page(vgpu, &spt->guest_page,
                        gfn, ppgtt_write_protection_handler, NULL);
        if (ret) {
-               gvt_err("fail to initialize guest page for spt\n");
+               gvt_vgpu_err("fail to initialize guest page for spt\n");
                goto err;
        }
 
@@ -776,8 +776,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_find_shadow_page(
        if (p)
                return shadow_page_to_ppgtt_spt(p);
 
-       gvt_err("vgpu%d: fail to find ppgtt shadow page: 0x%lx\n",
-                       vgpu->id, mfn);
+       gvt_vgpu_err("fail to find ppgtt shadow page: 0x%lx\n", mfn);
        return NULL;
 }
 
@@ -827,8 +826,8 @@ static int ppgtt_invalidate_shadow_page_by_shadow_entry(struct intel_vgpu *vgpu,
        }
        s = ppgtt_find_shadow_page(vgpu, ops->get_pfn(e));
        if (!s) {
-               gvt_err("vgpu%d: fail to find shadow page: mfn: 0x%lx\n",
-                               vgpu->id, ops->get_pfn(e));
+               gvt_vgpu_err("fail to find shadow page: mfn: 0x%lx\n",
+                               ops->get_pfn(e));
                return -ENXIO;
        }
        return ppgtt_invalidate_shadow_page(s);
@@ -836,6 +835,7 @@ static int ppgtt_invalidate_shadow_page_by_shadow_entry(struct intel_vgpu *vgpu,
 
 static int ppgtt_invalidate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
 {
+       struct intel_vgpu *vgpu = spt->vgpu;
        struct intel_gvt_gtt_entry e;
        unsigned long index;
        int ret;
@@ -854,7 +854,7 @@ static int ppgtt_invalidate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
 
        for_each_present_shadow_entry(spt, &e, index) {
                if (!gtt_type_is_pt(get_next_pt_type(e.type))) {
-                       gvt_err("GVT doesn't support pse bit for now\n");
+                       gvt_vgpu_err("GVT doesn't support pse bit for now\n");
                        return -EINVAL;
                }
                ret = ppgtt_invalidate_shadow_page_by_shadow_entry(
@@ -868,8 +868,8 @@ release:
        ppgtt_free_shadow_page(spt);
        return 0;
 fail:
-       gvt_err("vgpu%d: fail: shadow page %p shadow entry 0x%llx type %d\n",
-                       spt->vgpu->id, spt, e.val64, e.type);
+       gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n",
+                       spt, e.val64, e.type);
        return ret;
 }
 
@@ -914,8 +914,8 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_shadow_page_by_guest_entry(
        }
        return s;
 fail:
-       gvt_err("vgpu%d: fail: shadow page %p guest entry 0x%llx type %d\n",
-                       vgpu->id, s, we->val64, we->type);
+       gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
+                       s, we->val64, we->type);
        return ERR_PTR(ret);
 }
 
@@ -953,7 +953,7 @@ static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
 
        for_each_present_guest_entry(spt, &ge, i) {
                if (!gtt_type_is_pt(get_next_pt_type(ge.type))) {
-                       gvt_err("GVT doesn't support pse bit now\n");
+                       gvt_vgpu_err("GVT doesn't support pse bit now\n");
                        ret = -EINVAL;
                        goto fail;
                }
@@ -969,8 +969,8 @@ static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
        }
        return 0;
 fail:
-       gvt_err("vgpu%d: fail: shadow page %p guest entry 0x%llx type %d\n",
-                       vgpu->id, spt, ge.val64, ge.type);
+       gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
+                       spt, ge.val64, ge.type);
        return ret;
 }
 
@@ -999,7 +999,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
                struct intel_vgpu_ppgtt_spt *s =
                        ppgtt_find_shadow_page(vgpu, ops->get_pfn(&e));
                if (!s) {
-                       gvt_err("fail to find guest page\n");
+                       gvt_vgpu_err("fail to find guest page\n");
                        ret = -ENXIO;
                        goto fail;
                }
@@ -1011,8 +1011,8 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
        ppgtt_set_shadow_entry(spt, &e, index);
        return 0;
 fail:
-       gvt_err("vgpu%d: fail: shadow page %p guest entry 0x%llx type %d\n",
-                       vgpu->id, spt, e.val64, e.type);
+       gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
+                       spt, e.val64, e.type);
        return ret;
 }
 
@@ -1046,8 +1046,8 @@ static int ppgtt_handle_guest_entry_add(struct intel_vgpu_guest_page *gpt,
        }
        return 0;
 fail:
-       gvt_err("vgpu%d: fail: spt %p guest entry 0x%llx type %d\n", vgpu->id,
-                       spt, we->val64, we->type);
+       gvt_vgpu_err("fail: spt %p guest entry 0x%llx type %d\n",
+               spt, we->val64, we->type);
        return ret;
 }
 
@@ -1250,8 +1250,8 @@ static int ppgtt_handle_guest_write_page_table(
        }
        return 0;
 fail:
-       gvt_err("vgpu%d: fail: shadow page %p guest entry 0x%llx type %d.\n",
-                       vgpu->id, spt, we->val64, we->type);
+       gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d.\n",
+                       spt, we->val64, we->type);
        return ret;
 }
 
@@ -1493,7 +1493,7 @@ static int shadow_mm(struct intel_vgpu_mm *mm)
 
                spt = ppgtt_populate_shadow_page_by_guest_entry(vgpu, &ge);
                if (IS_ERR(spt)) {
-                       gvt_err("fail to populate guest root pointer\n");
+                       gvt_vgpu_err("fail to populate guest root pointer\n");
                        ret = PTR_ERR(spt);
                        goto fail;
                }
@@ -1566,7 +1566,7 @@ struct intel_vgpu_mm *intel_vgpu_create_mm(struct intel_vgpu *vgpu,
 
        ret = gtt->mm_alloc_page_table(mm);
        if (ret) {
-               gvt_err("fail to allocate page table for mm\n");
+               gvt_vgpu_err("fail to allocate page table for mm\n");
                goto fail;
        }
 
@@ -1584,7 +1584,7 @@ struct intel_vgpu_mm *intel_vgpu_create_mm(struct intel_vgpu *vgpu,
        }
        return mm;
 fail:
-       gvt_err("fail to create mm\n");
+       gvt_vgpu_err("fail to create mm\n");
        if (mm)
                intel_gvt_mm_unreference(mm);
        return ERR_PTR(ret);
@@ -1760,7 +1760,7 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
                        mm->page_table_level, gma, gpa);
        return gpa;
 err:
-       gvt_err("invalid mm type: %d gma %lx\n", mm->type, gma);
+       gvt_vgpu_err("invalid mm type: %d gma %lx\n", mm->type, gma);
        return INTEL_GVT_INVALID_ADDR;
 }
 
@@ -1836,13 +1836,16 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
        if (ops->test_present(&e)) {
                ret = gtt_entry_p2m(vgpu, &e, &m);
                if (ret) {
-                       gvt_err("vgpu%d: fail to translate guest gtt entry\n",
-                                       vgpu->id);
-                       return ret;
+                       gvt_vgpu_err("fail to translate guest gtt entry\n");
+                       /* guest driver may read/write the entry when partial
+                        * update the entry in this situation p2m will fail
+                        * settting the shadow entry to point to a scratch page
+                        */
+                       ops->set_pfn(&m, gvt->gtt.scratch_ggtt_mfn);
                }
        } else {
                m = e;
-               m.val64 = 0;
+               ops->set_pfn(&m, gvt->gtt.scratch_ggtt_mfn);
        }
 
        ggtt_set_shadow_entry(ggtt_mm, &m, g_gtt_index);
@@ -1893,14 +1896,14 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
 
        scratch_pt = (void *)get_zeroed_page(GFP_KERNEL);
        if (!scratch_pt) {
-               gvt_err("fail to allocate scratch page\n");
+               gvt_vgpu_err("fail to allocate scratch page\n");
                return -ENOMEM;
        }
 
        daddr = dma_map_page(dev, virt_to_page(scratch_pt), 0,
                        4096, PCI_DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, daddr)) {
-               gvt_err("fail to dmamap scratch_pt\n");
+               gvt_vgpu_err("fail to dmamap scratch_pt\n");
                __free_page(virt_to_page(scratch_pt));
                return -ENOMEM;
        }
@@ -2003,7 +2006,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
        ggtt_mm = intel_vgpu_create_mm(vgpu, INTEL_GVT_MM_GGTT,
                        NULL, 1, 0);
        if (IS_ERR(ggtt_mm)) {
-               gvt_err("fail to create mm for ggtt.\n");
+               gvt_vgpu_err("fail to create mm for ggtt.\n");
                return PTR_ERR(ggtt_mm);
        }
 
@@ -2076,7 +2079,6 @@ static int setup_spt_oos(struct intel_gvt *gvt)
        for (i = 0; i < preallocated_oos_pages; i++) {
                oos_page = kzalloc(sizeof(*oos_page), GFP_KERNEL);
                if (!oos_page) {
-                       gvt_err("fail to pre-allocate oos page\n");
                        ret = -ENOMEM;
                        goto fail;
                }
@@ -2166,7 +2168,7 @@ int intel_vgpu_g2v_create_ppgtt_mm(struct intel_vgpu *vgpu,
                mm = intel_vgpu_create_mm(vgpu, INTEL_GVT_MM_PPGTT,
                                pdp, page_table_level, 0);
                if (IS_ERR(mm)) {
-                       gvt_err("fail to create mm\n");
+                       gvt_vgpu_err("fail to create mm\n");
                        return PTR_ERR(mm);
                }
        }
@@ -2196,7 +2198,7 @@ int intel_vgpu_g2v_destroy_ppgtt_mm(struct intel_vgpu *vgpu,
 
        mm = intel_vgpu_find_ppgtt_mm(vgpu, page_table_level, pdp);
        if (!mm) {
-               gvt_err("fail to find ppgtt instance.\n");
+               gvt_vgpu_err("fail to find ppgtt instance.\n");
                return -EINVAL;
        }
        intel_gvt_mm_unreference(mm);
index 23791920ced1eed3e7aa1566b843a464fcfe3b29..6dfc48b63b718b4c4e6f5c62794db5ce279b18a4 100644 (file)
@@ -162,7 +162,6 @@ struct intel_vgpu {
        atomic_t running_workload_num;
        DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
        struct i915_gem_context *shadow_ctx;
-       struct notifier_block shadow_ctx_notifier_block;
 
 #if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
        struct {
@@ -233,6 +232,7 @@ struct intel_gvt {
        struct intel_gvt_gtt gtt;
        struct intel_gvt_opregion opregion;
        struct intel_gvt_workload_scheduler scheduler;
+       struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
        DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
        struct intel_vgpu_type *types;
        unsigned int num_types;
index 8e43395c748a15cc60f6e80d7b43f8b28fbce4aa..6da9ae1618e35e39fb06e99caec00e1455132873 100644 (file)
@@ -181,11 +181,9 @@ static int sanitize_fence_mmio_access(struct intel_vgpu *vgpu,
                                        GVT_FAILSAFE_UNSUPPORTED_GUEST);
 
                if (!vgpu->mmio.disable_warn_untrack) {
-                       gvt_err("vgpu%d: found oob fence register access\n",
-                                       vgpu->id);
-                       gvt_err("vgpu%d: total fence %d, access fence %d\n",
-                                       vgpu->id, vgpu_fence_sz(vgpu),
-                                       fence_num);
+                       gvt_vgpu_err("found oob fence register access\n");
+                       gvt_vgpu_err("total fence %d, access fence %d\n",
+                                       vgpu_fence_sz(vgpu), fence_num);
                }
                memset(p_data, 0, bytes);
                return -EINVAL;
@@ -249,7 +247,7 @@ static int mul_force_wake_write(struct intel_vgpu *vgpu,
                        break;
                default:
                        /*should not hit here*/
-                       gvt_err("invalid forcewake offset 0x%x\n", offset);
+                       gvt_vgpu_err("invalid forcewake offset 0x%x\n", offset);
                        return -EINVAL;
                }
        } else {
@@ -530,7 +528,7 @@ static int check_fdi_rx_train_status(struct intel_vgpu *vgpu,
                fdi_tx_train_bits = FDI_LINK_TRAIN_PATTERN_2;
                fdi_iir_check_bits = FDI_RX_SYMBOL_LOCK;
        } else {
-               gvt_err("Invalid train pattern %d\n", train_pattern);
+               gvt_vgpu_err("Invalid train pattern %d\n", train_pattern);
                return -EINVAL;
        }
 
@@ -588,7 +586,7 @@ static int update_fdi_rx_iir_status(struct intel_vgpu *vgpu,
        else if (FDI_RX_IMR_TO_PIPE(offset) != INVALID_INDEX)
                index = FDI_RX_IMR_TO_PIPE(offset);
        else {
-               gvt_err("Unsupport registers %x\n", offset);
+               gvt_vgpu_err("Unsupport registers %x\n", offset);
                return -EINVAL;
        }
 
@@ -818,7 +816,7 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
        u32 data;
 
        if (!dpy_is_valid_port(port_index)) {
-               gvt_err("GVT(%d): Unsupported DP port access!\n", vgpu->id);
+               gvt_vgpu_err("Unsupported DP port access!\n");
                return 0;
        }
 
@@ -972,6 +970,14 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
        return 0;
 }
 
+static int mbctl_write(struct intel_vgpu *vgpu, unsigned int offset,
+               void *p_data, unsigned int bytes)
+{
+       *(u32 *)p_data &= (~GEN6_MBCTL_ENABLE_BOOT_FETCH);
+       write_vreg(vgpu, offset, p_data, bytes);
+       return 0;
+}
+
 static int vga_control_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
                void *p_data, unsigned int bytes)
 {
@@ -1016,8 +1022,7 @@ static void write_virtual_sbi_register(struct intel_vgpu *vgpu,
 
        if (i == num) {
                if (num == SBI_REG_MAX) {
-                       gvt_err("vgpu%d: SBI caching meets maximum limits\n",
-                                       vgpu->id);
+                       gvt_vgpu_err("SBI caching meets maximum limits\n");
                        return;
                }
                display->sbi.number++;
@@ -1097,7 +1102,7 @@ static int pvinfo_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
                break;
        }
        if (invalid_read)
-               gvt_err("invalid pvinfo read: [%x:%x] = %x\n",
+               gvt_vgpu_err("invalid pvinfo read: [%x:%x] = %x\n",
                                offset, bytes, *(u32 *)p_data);
        vgpu->pv_notified = true;
        return 0;
@@ -1125,7 +1130,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification)
        case 1: /* Remove this in guest driver. */
                break;
        default:
-               gvt_err("Invalid PV notification %d\n", notification);
+               gvt_vgpu_err("Invalid PV notification %d\n", notification);
        }
        return ret;
 }
@@ -1181,7 +1186,7 @@ static int pvinfo_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
                enter_failsafe_mode(vgpu, GVT_FAILSAFE_INSUFFICIENT_RESOURCE);
                break;
        default:
-               gvt_err("invalid pvinfo write offset %x bytes %x data %x\n",
+               gvt_vgpu_err("invalid pvinfo write offset %x bytes %x data %x\n",
                                offset, bytes, data);
                break;
        }
@@ -1415,7 +1420,8 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
        if (execlist->elsp_dwords.index == 3) {
                ret = intel_vgpu_submit_execlist(vgpu, ring_id);
                if(ret)
-                       gvt_err("fail submit workload on ring %d\n", ring_id);
+                       gvt_vgpu_err("fail submit workload on ring %d\n",
+                               ring_id);
        }
 
        ++execlist->elsp_dwords.index;
@@ -2240,7 +2246,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
        MMIO_D(0x7180, D_ALL);
        MMIO_D(0x7408, D_ALL);
        MMIO_D(0x7c00, D_ALL);
-       MMIO_D(GEN6_MBCTL, D_ALL);
+       MMIO_DH(GEN6_MBCTL, D_ALL, NULL, mbctl_write);
        MMIO_D(0x911c, D_ALL);
        MMIO_D(0x9120, D_ALL);
        MMIO_DFH(GEN7_UCGCTL4, D_ALL, F_CMD_ACCESS, NULL, NULL);
@@ -2988,3 +2994,20 @@ int intel_vgpu_default_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
        write_vreg(vgpu, offset, p_data, bytes);
        return 0;
 }
+
+/**
+ * intel_gvt_in_force_nonpriv_whitelist - if a mmio is in whitelist to be
+ * force-nopriv register
+ *
+ * @gvt: a GVT device
+ * @offset: register offset
+ *
+ * Returns:
+ * True if the register is in force-nonpriv whitelist;
+ * False if outside;
+ */
+bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt,
+                                         unsigned int offset)
+{
+       return in_whitelist(offset);
+}
index 84d801638edece195bad5b659c5d739c1afcf0fc..d641214578a7dc6631e866bbc91c2d38f3e95a76 100644 (file)
@@ -426,7 +426,7 @@ static void kvmgt_protect_table_del(struct kvmgt_guest_info *info,
 
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
-       struct intel_vgpu *vgpu;
+       struct intel_vgpu *vgpu = NULL;
        struct intel_vgpu_type *type;
        struct device *pdev;
        void *gvt;
@@ -437,7 +437,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 
        type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj));
        if (!type) {
-               gvt_err("failed to find type %s to create\n",
+               gvt_vgpu_err("failed to find type %s to create\n",
                                                kobject_name(kobj));
                ret = -EINVAL;
                goto out;
@@ -446,7 +446,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
        vgpu = intel_gvt_ops->vgpu_create(gvt, type);
        if (IS_ERR_OR_NULL(vgpu)) {
                ret = vgpu == NULL ? -EFAULT : PTR_ERR(vgpu);
-               gvt_err("failed to create intel vgpu: %d\n", ret);
+               gvt_vgpu_err("failed to create intel vgpu: %d\n", ret);
                goto out;
        }
 
@@ -526,7 +526,8 @@ static int intel_vgpu_open(struct mdev_device *mdev)
        ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &events,
                                &vgpu->vdev.iommu_notifier);
        if (ret != 0) {
-               gvt_err("vfio_register_notifier for iommu failed: %d\n", ret);
+               gvt_vgpu_err("vfio_register_notifier for iommu failed: %d\n",
+                       ret);
                goto out;
        }
 
@@ -534,7 +535,8 @@ static int intel_vgpu_open(struct mdev_device *mdev)
        ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY, &events,
                                &vgpu->vdev.group_notifier);
        if (ret != 0) {
-               gvt_err("vfio_register_notifier for group failed: %d\n", ret);
+               gvt_vgpu_err("vfio_register_notifier for group failed: %d\n",
+                       ret);
                goto undo_iommu;
        }
 
@@ -635,7 +637,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
 
 
        if (index >= VFIO_PCI_NUM_REGIONS) {
-               gvt_err("invalid index: %u\n", index);
+               gvt_vgpu_err("invalid index: %u\n", index);
                return -EINVAL;
        }
 
@@ -669,7 +671,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
        case VFIO_PCI_VGA_REGION_INDEX:
        case VFIO_PCI_ROM_REGION_INDEX:
        default:
-               gvt_err("unsupported region: %u\n", index);
+               gvt_vgpu_err("unsupported region: %u\n", index);
        }
 
        return ret == 0 ? count : ret;
@@ -861,7 +863,7 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu,
 
                trigger = eventfd_ctx_fdget(fd);
                if (IS_ERR(trigger)) {
-                       gvt_err("eventfd_ctx_fdget failed\n");
+                       gvt_vgpu_err("eventfd_ctx_fdget failed\n");
                        return PTR_ERR(trigger);
                }
                vgpu->vdev.msi_trigger = trigger;
@@ -1120,7 +1122,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
                        ret = vfio_set_irqs_validate_and_prepare(&hdr, max,
                                                VFIO_PCI_NUM_IRQS, &data_size);
                        if (ret) {
-                               gvt_err("intel:vfio_set_irqs_validate_and_prepare failed\n");
+                               gvt_vgpu_err("intel:vfio_set_irqs_validate_and_prepare failed\n");
                                return -EINVAL;
                        }
                        if (data_size) {
@@ -1310,7 +1312,7 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
 
        kvm = vgpu->vdev.kvm;
        if (!kvm || kvm->mm != current->mm) {
-               gvt_err("KVM is required to use Intel vGPU\n");
+               gvt_vgpu_err("KVM is required to use Intel vGPU\n");
                return -ESRCH;
        }
 
@@ -1324,6 +1326,7 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
        vgpu->handle = (unsigned long)info;
        info->vgpu = vgpu;
        info->kvm = kvm;
+       kvm_get_kvm(info->kvm);
 
        kvmgt_protect_table_init(info);
        gvt_cache_init(vgpu);
@@ -1337,12 +1340,15 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
 
 static bool kvmgt_guest_exit(struct kvmgt_guest_info *info)
 {
+       struct intel_vgpu *vgpu = info->vgpu;
+
        if (!info) {
-               gvt_err("kvmgt_guest_info invalid\n");
+               gvt_vgpu_err("kvmgt_guest_info invalid\n");
                return false;
        }
 
        kvm_page_track_unregister_notifier(info->kvm, &info->track_node);
+       kvm_put_kvm(info->kvm);
        kvmgt_protect_table_destroy(info);
        gvt_cache_destroy(info->vgpu);
        vfree(info);
@@ -1383,12 +1389,14 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn)
        unsigned long iova, pfn;
        struct kvmgt_guest_info *info;
        struct device *dev;
+       struct intel_vgpu *vgpu;
        int rc;
 
        if (!handle_valid(handle))
                return INTEL_GVT_INVALID_ADDR;
 
        info = (struct kvmgt_guest_info *)handle;
+       vgpu = info->vgpu;
        iova = gvt_cache_find(info->vgpu, gfn);
        if (iova != INTEL_GVT_INVALID_ADDR)
                return iova;
@@ -1397,13 +1405,14 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn)
        dev = mdev_dev(info->vgpu->vdev.mdev);
        rc = vfio_pin_pages(dev, &gfn, 1, IOMMU_READ | IOMMU_WRITE, &pfn);
        if (rc != 1) {
-               gvt_err("vfio_pin_pages failed for gfn 0x%lx: %d\n", gfn, rc);
+               gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx: %d\n",
+                       gfn, rc);
                return INTEL_GVT_INVALID_ADDR;
        }
        /* transfer to host iova for GFX to use DMA */
        rc = gvt_dma_map_iova(info->vgpu, pfn, &iova);
        if (rc) {
-               gvt_err("gvt_dma_map_iova failed for gfn: 0x%lx\n", gfn);
+               gvt_vgpu_err("gvt_dma_map_iova failed for gfn: 0x%lx\n", gfn);
                vfio_unpin_pages(dev, &gfn, 1);
                return INTEL_GVT_INVALID_ADDR;
        }
@@ -1417,7 +1426,7 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
 {
        struct kvmgt_guest_info *info;
        struct kvm *kvm;
-       int ret;
+       int idx, ret;
        bool kthread = current->mm == NULL;
 
        if (!handle_valid(handle))
@@ -1429,8 +1438,10 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
        if (kthread)
                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)
                unuse_mm(kvm->mm);
index 60b698cb836592747cf354840e930211230c1622..1ba3bdb093416674c2f44014942971bcdcd8ea9e 100644 (file)
@@ -142,10 +142,10 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
                        ret = intel_gvt_hypervisor_read_gpa(vgpu, pa,
                                        p_data, bytes);
                        if (ret) {
-                               gvt_err("vgpu%d: guest page read error %d, "
+                               gvt_vgpu_err("guest page read error %d, "
                                        "gfn 0x%lx, pa 0x%llx, var 0x%x, len %d\n",
-                                       vgpu->id, ret,
-                                       gp->gfn, pa, *(u32 *)p_data, bytes);
+                                       ret, gp->gfn, pa, *(u32 *)p_data,
+                                       bytes);
                        }
                        mutex_unlock(&gvt->lock);
                        return ret;
@@ -200,14 +200,13 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
                ret = intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
 
                if (!vgpu->mmio.disable_warn_untrack) {
-                       gvt_err("vgpu%d: read untracked MMIO %x(%dB) val %x\n",
-                               vgpu->id, offset, bytes, *(u32 *)p_data);
+                       gvt_vgpu_err("read untracked MMIO %x(%dB) val %x\n",
+                               offset, bytes, *(u32 *)p_data);
 
                        if (offset == 0x206c) {
-                               gvt_err("------------------------------------------\n");
-                               gvt_err("vgpu%d: likely triggers a gfx reset\n",
-                                       vgpu->id);
-                               gvt_err("------------------------------------------\n");
+                               gvt_vgpu_err("------------------------------------------\n");
+                               gvt_vgpu_err("likely triggers a gfx reset\n");
+                               gvt_vgpu_err("------------------------------------------\n");
                                vgpu->mmio.disable_warn_untrack = true;
                        }
                }
@@ -220,8 +219,8 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
        mutex_unlock(&gvt->lock);
        return 0;
 err:
-       gvt_err("vgpu%d: fail to emulate MMIO read %08x len %d\n",
-                       vgpu->id, offset, bytes);
+       gvt_vgpu_err("fail to emulate MMIO read %08x len %d\n",
+                       offset, bytes);
        mutex_unlock(&gvt->lock);
        return ret;
 }
@@ -259,10 +258,11 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
                if (gp) {
                        ret = gp->handler(gp, pa, p_data, bytes);
                        if (ret) {
-                               gvt_err("vgpu%d: guest page write error %d, "
-                                       "gfn 0x%lx, pa 0x%llx, var 0x%x, len %d\n",
-                                       vgpu->id, ret,
-                                       gp->gfn, pa, *(u32 *)p_data, bytes);
+                               gvt_err("guest page write error %d, "
+                                       "gfn 0x%lx, pa 0x%llx, "
+                                       "var 0x%x, len %d\n",
+                                       ret, gp->gfn, pa,
+                                       *(u32 *)p_data, bytes);
                        }
                        mutex_unlock(&gvt->lock);
                        return ret;
@@ -329,8 +329,8 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
 
                        /* all register bits are RO. */
                        if (ro_mask == ~(u64)0) {
-                               gvt_err("vgpu%d: try to write RO reg %x\n",
-                                               vgpu->id, offset);
+                               gvt_vgpu_err("try to write RO reg %x\n",
+                                       offset);
                                ret = 0;
                                goto out;
                        }
@@ -360,8 +360,8 @@ out:
        mutex_unlock(&gvt->lock);
        return 0;
 err:
-       gvt_err("vgpu%d: fail to emulate MMIO write %08x len %d\n",
-                       vgpu->id, offset, bytes);
+       gvt_vgpu_err("fail to emulate MMIO write %08x len %d\n", offset,
+                    bytes);
        mutex_unlock(&gvt->lock);
        return ret;
 }
index 3bc620f56f351e774dc8658c9f06c79d0b24446b..a3a027025cd0a40f9543e6ee76b385a4ad761dcc 100644 (file)
@@ -107,4 +107,7 @@ int intel_vgpu_default_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
                                 void *p_data, unsigned int bytes);
 int intel_vgpu_default_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
                                  void *p_data, unsigned int bytes);
+
+bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt,
+                                         unsigned int offset);
 #endif
index 5d1caf9daba9bdc82ed90018a6d31ec23825e680..311799136d7f6e9e2fd96537da3c69918d7258ee 100644 (file)
@@ -67,14 +67,15 @@ static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
                mfn = intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu)->va
                        + i * PAGE_SIZE);
                if (mfn == INTEL_GVT_INVALID_ADDR) {
-                       gvt_err("fail to get MFN from VA\n");
+                       gvt_vgpu_err("fail to get MFN from VA\n");
                        return -EINVAL;
                }
                ret = intel_gvt_hypervisor_map_gfn_to_mfn(vgpu,
                                vgpu_opregion(vgpu)->gfn[i],
                                mfn, 1, map);
                if (ret) {
-                       gvt_err("fail to map GFN to MFN, errno: %d\n", ret);
+                       gvt_vgpu_err("fail to map GFN to MFN, errno: %d\n",
+                               ret);
                        return ret;
                }
        }
@@ -287,7 +288,7 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
        parm = vgpu_opregion(vgpu)->va + INTEL_GVT_OPREGION_PARM;
 
        if (!(swsci & SWSCI_SCI_SELECT)) {
-               gvt_err("vgpu%d: requesting SMI service\n", vgpu->id);
+               gvt_vgpu_err("requesting SMI service\n");
                return 0;
        }
        /* ignore non 0->1 trasitions */
@@ -300,9 +301,8 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
        func = GVT_OPREGION_FUNC(*scic);
        subfunc = GVT_OPREGION_SUBFUNC(*scic);
        if (!querying_capabilities(*scic)) {
-               gvt_err("vgpu%d: requesting runtime service: func \"%s\","
+               gvt_vgpu_err("requesting runtime service: func \"%s\","
                                " subfunc \"%s\"\n",
-                               vgpu->id,
                                opregion_func_name(func),
                                opregion_subfunc_name(subfunc));
                /*
index 73f052a4f4244d9c31ce8ad875978a50f8d084c4..0beb83563b0870edecae35cf5a5807ba1bfc4ae8 100644 (file)
@@ -167,7 +167,7 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
        I915_WRITE_FW(reg, 0x1);
 
        if (wait_for_atomic((I915_READ_FW(reg) == 0), 50))
-               gvt_err("timeout in invalidate ring (%d) tlb\n", ring_id);
+               gvt_vgpu_err("timeout in invalidate ring (%d) tlb\n", ring_id);
        else
                vgpu_vreg(vgpu, regs[ring_id]) = 0;
 
@@ -207,7 +207,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
                l3_offset.reg = 0xb020;
                for (i = 0; i < 32; i++) {
                        gen9_render_mocs_L3[i] = I915_READ(l3_offset);
-                       I915_WRITE(l3_offset, vgpu_vreg(vgpu, offset));
+                       I915_WRITE(l3_offset, vgpu_vreg(vgpu, l3_offset));
                        POSTING_READ(l3_offset);
                        l3_offset.reg += 4;
                }
index 06c9584ac5f0333c28d628d797686b82d8f82806..34b9acdf34791c84170cd6c96203a5b84f860b77 100644 (file)
@@ -101,7 +101,7 @@ struct tbs_sched_data {
        struct list_head runq_head;
 };
 
-#define GVT_DEFAULT_TIME_SLICE (1 * HZ / 1000)
+#define GVT_DEFAULT_TIME_SLICE (msecs_to_jiffies(1))
 
 static void tbs_sched_func(struct work_struct *work)
 {
@@ -223,7 +223,7 @@ static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
                return;
 
        list_add_tail(&vgpu_data->list, &sched_data->runq_head);
-       schedule_delayed_work(&sched_data->work, sched_data->period);
+       schedule_delayed_work(&sched_data->work, 0);
 }
 
 static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu)
index d3a56c9490257d4deeb4dfa3bbfa0a8e10d2bb47..a44782412f2c9922bd4ec4fa5160bdb588db6cf0 100644 (file)
@@ -84,7 +84,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
                                (u32)((workload->ctx_desc.lrca + i) <<
                                GTT_PAGE_SHIFT));
                if (context_gpa == INTEL_GVT_INVALID_ADDR) {
-                       gvt_err("Invalid guest context descriptor\n");
+                       gvt_vgpu_err("Invalid guest context descriptor\n");
                        return -EINVAL;
                }
 
@@ -127,19 +127,22 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
        return 0;
 }
 
+static inline bool is_gvt_request(struct drm_i915_gem_request *req)
+{
+       return i915_gem_context_force_single_submission(req->ctx);
+}
+
 static int shadow_context_status_change(struct notifier_block *nb,
                unsigned long action, void *data)
 {
-       struct intel_vgpu *vgpu = container_of(nb,
-                       struct intel_vgpu, shadow_ctx_notifier_block);
-       struct drm_i915_gem_request *req =
-               (struct drm_i915_gem_request *)data;
-       struct intel_gvt_workload_scheduler *scheduler =
-               &vgpu->gvt->scheduler;
+       struct drm_i915_gem_request *req = (struct drm_i915_gem_request *)data;
+       struct intel_gvt *gvt = container_of(nb, struct intel_gvt,
+                               shadow_ctx_notifier_block[req->engine->id]);
+       struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
        struct intel_vgpu_workload *workload =
                scheduler->current_workload[req->engine->id];
 
-       if (unlikely(!workload))
+       if (!is_gvt_request(req) || unlikely(!workload))
                return NOTIFY_OK;
 
        switch (action) {
@@ -175,7 +178,9 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
        int ring_id = workload->ring_id;
        struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
        struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
+       struct intel_engine_cs *engine = dev_priv->engine[ring_id];
        struct drm_i915_gem_request *rq;
+       struct intel_vgpu *vgpu = workload->vgpu;
        int ret;
 
        gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
@@ -187,9 +192,24 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
 
        mutex_lock(&dev_priv->drm.struct_mutex);
 
+       /* pin shadow context by gvt even the shadow context will be pinned
+        * when i915 alloc request. That is because gvt will update the guest
+        * context from shadow context when workload is completed, and at that
+        * moment, i915 may already unpined the shadow context to make the
+        * shadow_ctx pages invalid. So gvt need to pin itself. After update
+        * the guest context, gvt can unpin the shadow_ctx safely.
+        */
+       ret = engine->context_pin(engine, shadow_ctx);
+       if (ret) {
+               gvt_vgpu_err("fail to pin shadow context\n");
+               workload->status = ret;
+               mutex_unlock(&dev_priv->drm.struct_mutex);
+               return ret;
+       }
+
        rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
        if (IS_ERR(rq)) {
-               gvt_err("fail to allocate gem request\n");
+               gvt_vgpu_err("fail to allocate gem request\n");
                ret = PTR_ERR(rq);
                goto out;
        }
@@ -202,9 +222,12 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
        if (ret)
                goto out;
 
-       ret = intel_gvt_scan_and_shadow_wa_ctx(&workload->wa_ctx);
-       if (ret)
-               goto out;
+       if ((workload->ring_id == RCS) &&
+           (workload->wa_ctx.indirect_ctx.size != 0)) {
+               ret = intel_gvt_scan_and_shadow_wa_ctx(&workload->wa_ctx);
+               if (ret)
+                       goto out;
+       }
 
        ret = populate_shadow_context(workload);
        if (ret)
@@ -227,6 +250,9 @@ out:
 
        if (!IS_ERR_OR_NULL(rq))
                i915_add_request_no_flush(rq);
+       else
+               engine->context_unpin(engine, shadow_ctx);
+
        mutex_unlock(&dev_priv->drm.struct_mutex);
        return ret;
 }
@@ -322,7 +348,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
                                (u32)((workload->ctx_desc.lrca + i) <<
                                        GTT_PAGE_SHIFT));
                if (context_gpa == INTEL_GVT_INVALID_ADDR) {
-                       gvt_err("invalid guest context descriptor\n");
+                       gvt_vgpu_err("invalid guest context descriptor\n");
                        return;
                }
 
@@ -376,6 +402,10 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
         * For the workload w/o request, directly complete the workload.
         */
        if (workload->req) {
+               struct drm_i915_private *dev_priv =
+                       workload->vgpu->gvt->dev_priv;
+               struct intel_engine_cs *engine =
+                       dev_priv->engine[workload->ring_id];
                wait_event(workload->shadow_ctx_status_wq,
                           !atomic_read(&workload->shadow_ctx_active));
 
@@ -388,6 +418,10 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
                                         INTEL_GVT_EVENT_MAX)
                                intel_vgpu_trigger_virtual_event(vgpu, event);
                }
+               mutex_lock(&dev_priv->drm.struct_mutex);
+               /* unpin shadow ctx as the shadow_ctx update is done */
+               engine->context_unpin(engine, workload->vgpu->shadow_ctx);
+               mutex_unlock(&dev_priv->drm.struct_mutex);
        }
 
        gvt_dbg_sched("ring id %d complete workload %p status %d\n",
@@ -417,6 +451,7 @@ static int workload_thread(void *priv)
        int ring_id = p->ring_id;
        struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
        struct intel_vgpu_workload *workload = NULL;
+       struct intel_vgpu *vgpu = NULL;
        int ret;
        bool need_force_wake = IS_SKYLAKE(gvt->dev_priv);
        DEFINE_WAIT_FUNC(wait, woken_wake_function);
@@ -459,25 +494,14 @@ static int workload_thread(void *priv)
                mutex_unlock(&gvt->lock);
 
                if (ret) {
-                       gvt_err("fail to dispatch workload, skip\n");
+                       vgpu = workload->vgpu;
+                       gvt_vgpu_err("fail to dispatch workload, skip\n");
                        goto complete;
                }
 
                gvt_dbg_sched("ring id %d wait workload %p\n",
                                workload->ring_id, workload);
-retry:
-               i915_wait_request(workload->req,
-                                        0, MAX_SCHEDULE_TIMEOUT);
-               /* I915 has replay mechanism and a request will be replayed
-                * if there is i915 reset. So the seqno will be updated anyway.
-                * If the seqno is not updated yet after waiting, which means
-                * the replay may still be in progress and we can wait again.
-                */
-               if (!i915_gem_request_completed(workload->req)) {
-                       gvt_dbg_sched("workload %p not completed, wait again\n",
-                                       workload);
-                       goto retry;
-               }
+               i915_wait_request(workload->req, 0, MAX_SCHEDULE_TIMEOUT);
 
 complete:
                gvt_dbg_sched("will complete workload %p, status: %d\n",
@@ -513,15 +537,16 @@ void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu)
 void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt)
 {
        struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
-       int i;
+       struct intel_engine_cs *engine;
+       enum intel_engine_id i;
 
        gvt_dbg_core("clean workload scheduler\n");
 
-       for (i = 0; i < I915_NUM_ENGINES; i++) {
-               if (scheduler->thread[i]) {
-                       kthread_stop(scheduler->thread[i]);
-                       scheduler->thread[i] = NULL;
-               }
+       for_each_engine(engine, gvt->dev_priv, i) {
+               atomic_notifier_chain_unregister(
+                                       &engine->context_status_notifier,
+                                       &gvt->shadow_ctx_notifier_block[i]);
+               kthread_stop(scheduler->thread[i]);
        }
 }
 
@@ -529,18 +554,15 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
 {
        struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
        struct workload_thread_param *param = NULL;
+       struct intel_engine_cs *engine;
+       enum intel_engine_id i;
        int ret;
-       int i;
 
        gvt_dbg_core("init workload scheduler\n");
 
        init_waitqueue_head(&scheduler->workload_complete_wq);
 
-       for (i = 0; i < I915_NUM_ENGINES; i++) {
-               /* check ring mask at init time */
-               if (!HAS_ENGINE(gvt->dev_priv, i))
-                       continue;
-
+       for_each_engine(engine, gvt->dev_priv, i) {
                init_waitqueue_head(&scheduler->waitq[i]);
 
                param = kzalloc(sizeof(*param), GFP_KERNEL);
@@ -559,6 +581,11 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
                        ret = PTR_ERR(scheduler->thread[i]);
                        goto err;
                }
+
+               gvt->shadow_ctx_notifier_block[i].notifier_call =
+                                       shadow_context_status_change;
+               atomic_notifier_chain_register(&engine->context_status_notifier,
+                                       &gvt->shadow_ctx_notifier_block[i]);
        }
        return 0;
 err:
@@ -570,9 +597,6 @@ err:
 
 void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
 {
-       atomic_notifier_chain_unregister(&vgpu->shadow_ctx->status_notifier,
-                       &vgpu->shadow_ctx_notifier_block);
-
        i915_gem_context_put_unlocked(vgpu->shadow_ctx);
 }
 
@@ -587,10 +611,5 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
 
        vgpu->shadow_ctx->engine[RCS].initialised = true;
 
-       vgpu->shadow_ctx_notifier_block.notifier_call =
-               shadow_context_status_change;
-
-       atomic_notifier_chain_register(&vgpu->shadow_ctx->status_notifier,
-                                      &vgpu->shadow_ctx_notifier_block);
        return 0;
 }
index e703556eba999a95fd1a728538f6412db28068ae..1c75402a59c1377e7abd410f2dc58dcec0df7094 100644 (file)
@@ -248,6 +248,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_IRQ_ACTIVE:
        case I915_PARAM_ALLOW_BATCHBUFFER:
        case I915_PARAM_LAST_DISPATCH:
+       case I915_PARAM_HAS_EXEC_CONSTANTS:
                /* Reject all old ums/dri params. */
                return -ENODEV;
        case I915_PARAM_CHIPSET_ID:
@@ -274,9 +275,6 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_HAS_BSD2:
                value = !!dev_priv->engine[VCS2];
                break;
-       case I915_PARAM_HAS_EXEC_CONSTANTS:
-               value = INTEL_GEN(dev_priv) >= 4;
-               break;
        case I915_PARAM_HAS_LLC:
                value = HAS_LLC(dev_priv);
                break;
@@ -1788,7 +1786,7 @@ void i915_reset(struct drm_i915_private *dev_priv)
                goto error;
        }
 
-       i915_gem_reset_finish(dev_priv);
+       i915_gem_reset(dev_priv);
        intel_overlay_reset(dev_priv);
 
        /* Ok, now get things going again... */
@@ -1814,6 +1812,7 @@ void i915_reset(struct drm_i915_private *dev_priv)
        i915_queue_hangcheck(dev_priv);
 
 wakeup:
+       i915_gem_reset_finish(dev_priv);
        enable_irq(dev_priv->drm.irq);
        wake_up_bit(&error->flags, I915_RESET_IN_PROGRESS);
        return;
index 7febe6eecf722ad4f89b8484b7d6ce31c4d84c58..1e53c31b6826ec996b2d153e1dd32232b77dd9d7 100644 (file)
@@ -1325,7 +1325,7 @@ struct intel_gen6_power_mgmt {
        unsigned boosts;
 
        /* manual wa residency calculations */
-       struct intel_rps_ei up_ei, down_ei;
+       struct intel_rps_ei ei;
 
        /*
         * Protects RPS/RC6 register access and PCU communication.
@@ -2064,8 +2064,6 @@ struct drm_i915_private {
 
        const struct intel_device_info info;
 
-       int relative_constants_mode;
-
        void __iomem *regs;
 
        struct intel_uncore uncore;
@@ -3342,6 +3340,7 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
 }
 
 int i915_gem_reset_prepare(struct drm_i915_private *dev_priv);
+void i915_gem_reset(struct drm_i915_private *dev_priv);
 void i915_gem_reset_finish(struct drm_i915_private *dev_priv);
 void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
 void i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
index 10777da730394f7a63a7c1a551e6cd40b132fd0d..67b1fc5a03313b80bc9459543b8dec3743ea953b 100644 (file)
@@ -2719,7 +2719,16 @@ int i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
        for_each_engine(engine, dev_priv, id) {
                struct drm_i915_gem_request *request;
 
+               /* Prevent request submission to the hardware until we have
+                * completed the reset in i915_gem_reset_finish(). If a request
+                * is completed by one engine, it may then queue a request
+                * to a second via its engine->irq_tasklet *just* as we are
+                * calling engine->init_hw() and also writing the ELSP.
+                * Turning off the engine->irq_tasklet until the reset is over
+                * prevents the race.
+                */
                tasklet_kill(&engine->irq_tasklet);
+               tasklet_disable(&engine->irq_tasklet);
 
                if (engine_stalled(engine)) {
                        request = i915_gem_find_active_request(engine);
@@ -2834,7 +2843,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
        engine->reset_hw(engine, request);
 }
 
-void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
+void i915_gem_reset(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
@@ -2856,6 +2865,17 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
        }
 }
 
+void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
+{
+       struct intel_engine_cs *engine;
+       enum intel_engine_id id;
+
+       lockdep_assert_held(&dev_priv->drm.struct_mutex);
+
+       for_each_engine(engine, dev_priv, id)
+               tasklet_enable(&engine->irq_tasklet);
+}
+
 static void nop_submit_request(struct drm_i915_gem_request *request)
 {
        dma_fence_set_error(&request->fence, -EIO);
@@ -4674,8 +4694,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
        init_waitqueue_head(&dev_priv->gpu_error.wait_queue);
        init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
 
-       dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL;
-
        init_waitqueue_head(&dev_priv->pending_flip_queue);
 
        dev_priv->mm.interruptible = true;
index 17f90c6182081c932652715ed34724f1c71b373d..e2d83b6d376b03e8bdef54bc9ed9e7c9a3d0138c 100644 (file)
@@ -311,7 +311,6 @@ __create_hw_context(struct drm_i915_private *dev_priv,
        ctx->ring_size = 4 * PAGE_SIZE;
        ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) <<
                             GEN8_CTX_ADDRESSING_MODE_SHIFT;
-       ATOMIC_INIT_NOTIFIER_HEAD(&ctx->status_notifier);
 
        /* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not
         * present or not in use we still need a small bias as ring wraparound
index 0ac750b90f3d33f5585351fe284da68eaf6cb1e2..e9c008fe14b1d77500e7d456ef37705053685130 100644 (file)
@@ -160,9 +160,6 @@ struct i915_gem_context {
        /** desc_template: invariant fields for the HW context descriptor */
        u32 desc_template;
 
-       /** status_notifier: list of callbacks for context-switch changes */
-       struct atomic_notifier_head status_notifier;
-
        /** guilty_count: How many times this context has caused a GPU hang. */
        unsigned int guilty_count;
        /**
index d02cfaefe1c84e86cf39d74aa1ef09a4d1345af1..30e0675fd7dab7949d3cb3cb498be852d7448ac9 100644 (file)
@@ -1408,10 +1408,7 @@ execbuf_submit(struct i915_execbuffer_params *params,
               struct drm_i915_gem_execbuffer2 *args,
               struct list_head *vmas)
 {
-       struct drm_i915_private *dev_priv = params->request->i915;
        u64 exec_start, exec_len;
-       int instp_mode;
-       u32 instp_mask;
        int ret;
 
        ret = i915_gem_execbuffer_move_to_gpu(params->request, vmas);
@@ -1422,56 +1419,11 @@ execbuf_submit(struct i915_execbuffer_params *params,
        if (ret)
                return ret;
 
-       instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
-       instp_mask = I915_EXEC_CONSTANTS_MASK;
-       switch (instp_mode) {
-       case I915_EXEC_CONSTANTS_REL_GENERAL:
-       case I915_EXEC_CONSTANTS_ABSOLUTE:
-       case I915_EXEC_CONSTANTS_REL_SURFACE:
-               if (instp_mode != 0 && params->engine->id != RCS) {
-                       DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
-                       return -EINVAL;
-               }
-
-               if (instp_mode != dev_priv->relative_constants_mode) {
-                       if (INTEL_INFO(dev_priv)->gen < 4) {
-                               DRM_DEBUG("no rel constants on pre-gen4\n");
-                               return -EINVAL;
-                       }
-
-                       if (INTEL_INFO(dev_priv)->gen > 5 &&
-                           instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
-                               DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
-                               return -EINVAL;
-                       }
-
-                       /* The HW changed the meaning on this bit on gen6 */
-                       if (INTEL_INFO(dev_priv)->gen >= 6)
-                               instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
-               }
-               break;
-       default:
-               DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
+       if (args->flags & I915_EXEC_CONSTANTS_MASK) {
+               DRM_DEBUG("I915_EXEC_CONSTANTS_* unsupported\n");
                return -EINVAL;
        }
 
-       if (params->engine->id == RCS &&
-           instp_mode != dev_priv->relative_constants_mode) {
-               struct intel_ring *ring = params->request->ring;
-
-               ret = intel_ring_begin(params->request, 4);
-               if (ret)
-                       return ret;
-
-               intel_ring_emit(ring, MI_NOOP);
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-               intel_ring_emit_reg(ring, INSTPM);
-               intel_ring_emit(ring, instp_mask << 16 | instp_mode);
-               intel_ring_advance(ring);
-
-               dev_priv->relative_constants_mode = instp_mode;
-       }
-
        if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
                ret = i915_reset_gen7_sol_offsets(params->request);
                if (ret)
index 401006b4c6a36bf2a8058c2b47eb38105ab5baf4..d5d2b4c6ed382d687719a088d943580ccacbba15 100644 (file)
@@ -263,7 +263,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv)
                                I915_SHRINK_BOUND |
                                I915_SHRINK_UNBOUND |
                                I915_SHRINK_ACTIVE);
-       rcu_barrier(); /* wait until our RCU delayed slab frees are completed */
+       synchronize_rcu(); /* wait for our earlier RCU delayed slab frees */
 
        return freed;
 }
index e6ffef2f707a01934a3a6f777b1dc7548ef370c8..b6c886ac901bd78cfa7beb1a3aaaf706821a6d2b 100644 (file)
@@ -1046,68 +1046,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv,
        ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT);
 }
 
-static bool vlv_c0_above(struct drm_i915_private *dev_priv,
-                        const struct intel_rps_ei *old,
-                        const struct intel_rps_ei *now,
-                        int threshold)
-{
-       u64 time, c0;
-       unsigned int mul = 100;
-
-       if (old->cz_clock == 0)
-               return false;
-
-       if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
-               mul <<= 8;
-
-       time = now->cz_clock - old->cz_clock;
-       time *= threshold * dev_priv->czclk_freq;
-
-       /* Workload can be split between render + media, e.g. SwapBuffers
-        * being blitted in X after being rendered in mesa. To account for
-        * this we need to combine both engines into our activity counter.
-        */
-       c0 = now->render_c0 - old->render_c0;
-       c0 += now->media_c0 - old->media_c0;
-       c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC;
-
-       return c0 >= time;
-}
-
 void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
 {
-       vlv_c0_read(dev_priv, &dev_priv->rps.down_ei);
-       dev_priv->rps.up_ei = dev_priv->rps.down_ei;
+       memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei));
 }
 
 static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
 {
+       const struct intel_rps_ei *prev = &dev_priv->rps.ei;
        struct intel_rps_ei now;
        u32 events = 0;
 
-       if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0)
+       if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0)
                return 0;
 
        vlv_c0_read(dev_priv, &now);
        if (now.cz_clock == 0)
                return 0;
 
-       if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) {
-               if (!vlv_c0_above(dev_priv,
-                                 &dev_priv->rps.down_ei, &now,
-                                 dev_priv->rps.down_threshold))
-                       events |= GEN6_PM_RP_DOWN_THRESHOLD;
-               dev_priv->rps.down_ei = now;
-       }
+       if (prev->cz_clock) {
+               u64 time, c0;
+               unsigned int mul;
+
+               mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */
+               if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
+                       mul <<= 8;
 
-       if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
-               if (vlv_c0_above(dev_priv,
-                                &dev_priv->rps.up_ei, &now,
-                                dev_priv->rps.up_threshold))
-                       events |= GEN6_PM_RP_UP_THRESHOLD;
-               dev_priv->rps.up_ei = now;
+               time = now.cz_clock - prev->cz_clock;
+               time *= dev_priv->czclk_freq;
+
+               /* Workload can be split between render + media,
+                * e.g. SwapBuffers being blitted in X after being rendered in
+                * mesa. To account for this we need to combine both engines
+                * into our activity counter.
+                */
+               c0 = now.render_c0 - prev->render_c0;
+               c0 += now.media_c0 - prev->media_c0;
+               c0 *= mul;
+
+               if (c0 > time * dev_priv->rps.up_threshold)
+                       events = GEN6_PM_RP_UP_THRESHOLD;
+               else if (c0 < time * dev_priv->rps.down_threshold)
+                       events = GEN6_PM_RP_DOWN_THRESHOLD;
        }
 
+       dev_priv->rps.ei = now;
        return events;
 }
 
@@ -4228,7 +4211,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
        /* Let's track the enabled rps events */
        if (IS_VALLEYVIEW(dev_priv))
                /* WaGsvRC0ResidencyMethod:vlv */
-               dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED;
+               dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
        else
                dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
 
@@ -4266,6 +4249,16 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
        if (!IS_GEN2(dev_priv))
                dev->vblank_disable_immediate = true;
 
+       /* Most platforms treat the display irq block as an always-on
+        * power domain. vlv/chv can disable it at runtime and need
+        * special care to avoid writing any of the display block registers
+        * outside of the power domain. We defer setting up the display irqs
+        * in this case to the runtime pm.
+        */
+       dev_priv->display_irqs_enabled = true;
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               dev_priv->display_irqs_enabled = false;
+
        dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
        dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
 
index 0085bc745f6aa5256cf21c1ae76dd2cbce80e387..de219b71fb76ecbfab51d58bd379064b555c8241 100644 (file)
@@ -35,7 +35,6 @@
  */
 
 #define I915_CSR_GLK "i915/glk_dmc_ver1_01.bin"
-MODULE_FIRMWARE(I915_CSR_GLK);
 #define GLK_CSR_VERSION_REQUIRED       CSR_VERSION(1, 1)
 
 #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin"
index 3282b0f4b13412162bfc8500576ab507eac36d14..ed1f4f272b4fb3907adeea175216173fea5253fb 100644 (file)
@@ -16696,12 +16696,11 @@ int intel_modeset_init(struct drm_device *dev)
                }
        }
 
-       intel_update_czclk(dev_priv);
-       intel_update_cdclk(dev_priv);
-       dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
-
        intel_shared_dpll_init(dev);
 
+       intel_update_czclk(dev_priv);
+       intel_modeset_init_hw(dev);
+
        if (dev_priv->max_cdclk_freq == 0)
                intel_update_max_cdclk(dev_priv);
 
@@ -17258,8 +17257,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
 
        intel_init_gt_powersave(dev_priv);
 
-       intel_modeset_init_hw(dev);
-
        intel_setup_overlay(dev_priv);
 }
 
index 371acf109e343295ae060c4cf49908bf5607118e..ab1be5c80ea5960df983940e70f98f0d49cbd8e1 100644 (file)
@@ -105,6 +105,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
        /* Nothing to do here, execute in order of dependencies */
        engine->schedule = NULL;
 
+       ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
+
        dev_priv->engine[id] = engine;
        return 0;
 }
index d23c0fcff7516a9f3df4363010e2c3dfa84e3c00..8c04eca84351cbbe5d7f385fd6d262f40a080a28 100644 (file)
@@ -77,6 +77,11 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
                goto bail;
        }
 
+       if (!i915.enable_execlists) {
+               DRM_INFO("GPU guest virtualisation [GVT-g] disabled due to disabled execlist submission [i915.enable_execlists module parameter]\n");
+               goto bail;
+       }
+
        /*
         * We're not in host or fail to find a MPT module, disable GVT-g
         */
index ebae2bd839189c07588e88a526f3f804d08157b3..24b2fa5b62824dfa86d87c9e5d1c630957192867 100644 (file)
@@ -1298,16 +1298,34 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 
 static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
+       struct drm_i915_private *dev_priv =
+               to_i915(crtc_state->base.crtc->dev);
+       struct drm_atomic_state *state = crtc_state->base.state;
+       struct drm_connector_state *connector_state;
+       struct drm_connector *connector;
+       int i;
 
-       if (HAS_GMCH_DISPLAY(to_i915(dev)))
+       if (HAS_GMCH_DISPLAY(dev_priv))
                return false;
 
        /*
         * HDMI 12bpc affects the clocks, so it's only possible
         * when not cloning with other encoder types.
         */
-       return crtc_state->output_types == 1 << INTEL_OUTPUT_HDMI;
+       if (crtc_state->output_types != 1 << INTEL_OUTPUT_HDMI)
+               return false;
+
+       for_each_connector_in_state(state, connector, connector_state, i) {
+               const struct drm_display_info *info = &connector->display_info;
+
+               if (connector_state->crtc != crtc_state->base.crtc)
+                       continue;
+
+               if ((info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) == 0)
+                       return false;
+       }
+
+       return true;
 }
 
 bool intel_hdmi_compute_config(struct intel_encoder *encoder,
index b62e3f8ad415f6173470c90a3cb1b35b04f91c4b..54208bef7a83561eb72c29d26079fa447211203c 100644 (file)
@@ -219,7 +219,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
                        }
                }
        }
-       if (dev_priv->display.hpd_irq_setup)
+       if (dev_priv->display_irqs_enabled && dev_priv->display.hpd_irq_setup)
                dev_priv->display.hpd_irq_setup(dev_priv);
        spin_unlock_irq(&dev_priv->irq_lock);
 
@@ -425,7 +425,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
                }
        }
 
-       if (storm_detected)
+       if (storm_detected && dev_priv->display_irqs_enabled)
                dev_priv->display.hpd_irq_setup(dev_priv);
        spin_unlock(&dev_priv->irq_lock);
 
@@ -471,10 +471,12 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
         * Interrupt setup is already guaranteed to be single-threaded, this is
         * just to make the assert_spin_locked checks happy.
         */
-       spin_lock_irq(&dev_priv->irq_lock);
-       if (dev_priv->display.hpd_irq_setup)
-               dev_priv->display.hpd_irq_setup(dev_priv);
-       spin_unlock_irq(&dev_priv->irq_lock);
+       if (dev_priv->display_irqs_enabled && dev_priv->display.hpd_irq_setup) {
+               spin_lock_irq(&dev_priv->irq_lock);
+               if (dev_priv->display_irqs_enabled)
+                       dev_priv->display.hpd_irq_setup(dev_priv);
+               spin_unlock_irq(&dev_priv->irq_lock);
+       }
 }
 
 static void i915_hpd_poll_init_work(struct work_struct *work)
index ebf8023d21e6fba52c01b54d46fb3456b4709731..471af3b480adc38a3a48c27d1999805836cf5630 100644 (file)
@@ -345,7 +345,8 @@ execlists_context_status_change(struct drm_i915_gem_request *rq,
        if (!IS_ENABLED(CONFIG_DRM_I915_GVT))
                return;
 
-       atomic_notifier_call_chain(&rq->ctx->status_notifier, status, rq);
+       atomic_notifier_call_chain(&rq->engine->context_status_notifier,
+                                  status, rq);
 }
 
 static void
index 940bab22d4649b848259a28f74ec5e77d6715fb6..6a29784d2b4137c9805e85ffb80265e05e46af53 100644 (file)
@@ -4928,8 +4928,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
 {
        u32 mask = 0;
 
+       /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */
        if (val > dev_priv->rps.min_freq_softlimit)
-               mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
+               mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
        if (val < dev_priv->rps.max_freq_softlimit)
                mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
 
@@ -5039,7 +5040,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv)
 {
        mutex_lock(&dev_priv->rps.hw_lock);
        if (dev_priv->rps.enabled) {
-               if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED))
+               if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED)
                        gen6_rps_reset_ei(dev_priv);
                I915_WRITE(GEN6_PMINTRMSK,
                           gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
index 91bc4abf5d3e578ae9dffe2dd2adfd9c4305e31e..6c5f9958197d5541381e7c2838c909fe19fa1520 100644 (file)
@@ -2024,6 +2024,8 @@ static int intel_ring_context_pin(struct intel_engine_cs *engine,
                ret = context_pin(ctx, flags);
                if (ret)
                        goto error;
+
+               ce->state->obj->mm.dirty = true;
        }
 
        /* The kernel context is only used as a placeholder for flushing the
index 79c2b8d72322cf58cacd3f732c5a55ce0ef68f3b..13dccb18cd43ed85aee58a6a15618c515094a83b 100644 (file)
@@ -403,6 +403,9 @@ struct intel_engine_cs {
         */
        struct i915_gem_context *legacy_active_context;
 
+       /* status_notifier: list of callbacks for context-switch changes */
+       struct atomic_notifier_head context_status_notifier;
+
        struct intel_engine_hangcheck hangcheck;
 
        bool needs_cmd_parser;
index 684f1703aa5c7189bc55ca1633aeafd78a97c55a..aaa3e80fecb425164a3e5bcf799081aa7d2cf049 100644 (file)
@@ -213,8 +213,8 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
                        rbo->placement.num_busy_placement = 0;
                        for (i = 0; i < rbo->placement.num_placement; i++) {
                                if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) {
-                                       if (rbo->placements[0].fpfn < fpfn)
-                                               rbo->placements[0].fpfn = fpfn;
+                                       if (rbo->placements[i].fpfn < fpfn)
+                                               rbo->placements[i].fpfn = fpfn;
                                } else {
                                        rbo->placement.busy_placement =
                                                &rbo->placements[i];
index 72e1588580a1187f8ba0c05fe62fbaf1cde550d1..c7af9fdd20c729184654222dfc8b4bc6a870c066 100644 (file)
@@ -2985,9 +2985,13 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
                        max_sclk = 75000;
                }
        } else if (rdev->family == CHIP_OLAND) {
-               if ((rdev->pdev->device == 0x6604) &&
-                   (rdev->pdev->subsystem_vendor == 0x1028) &&
-                   (rdev->pdev->subsystem_device == 0x066F)) {
+               if ((rdev->pdev->revision == 0xC7) ||
+                   (rdev->pdev->revision == 0x80) ||
+                   (rdev->pdev->revision == 0x81) ||
+                   (rdev->pdev->revision == 0x83) ||
+                   (rdev->pdev->revision == 0x87) ||
+                   (rdev->pdev->device == 0x6604) ||
+                   (rdev->pdev->device == 0x6605)) {
                        max_sclk = 75000;
                }
        }
index 0c06844af4455d6319e83c183fbbd594e61cd678..9fcf05ca492b0c065a323f69be32ed3cc93b630f 100644 (file)
@@ -846,6 +846,17 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
        drm_atomic_helper_crtc_destroy_state(crtc, state);
 }
 
+static void
+vc4_crtc_reset(struct drm_crtc *crtc)
+{
+       if (crtc->state)
+               __drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+       crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL);
+       if (crtc->state)
+               crtc->state->crtc = crtc;
+}
+
 static const struct drm_crtc_funcs vc4_crtc_funcs = {
        .set_config = drm_atomic_helper_set_config,
        .destroy = vc4_crtc_destroy,
@@ -853,7 +864,7 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
        .set_property = NULL,
        .cursor_set = NULL, /* handled by drm_mode_cursor_universal */
        .cursor_move = NULL, /* handled by drm_mode_cursor_universal */
-       .reset = drm_atomic_helper_crtc_reset,
+       .reset = vc4_crtc_reset,
        .atomic_duplicate_state = vc4_crtc_duplicate_state,
        .atomic_destroy_state = vc4_crtc_destroy_state,
        .gamma_set = vc4_crtc_gamma_set,
index 1aeb80e5242461830f1d4075f0fb59bcb6ddc898..8c54cb8f5d6d1013ec1f4a39e8f88fcfe3333758 100644 (file)
@@ -175,11 +175,11 @@ config HID_CHERRY
        Support for Cherry Cymotion keyboard.
 
 config HID_CHICONY
-       tristate "Chicony Tactical pad"
+       tristate "Chicony devices"
        depends on HID
        default !EXPERT
        ---help---
-       Support for Chicony Tactical pad.
+       Support for Chicony Tactical pad and special keys on Chicony keyboards.
 
 config HID_CORSAIR
        tristate "Corsair devices"
@@ -190,6 +190,7 @@ config HID_CORSAIR
 
        Supported devices:
        - Vengeance K90
+       - Scimitar PRO RGB
 
 config HID_PRODIKEYS
        tristate "Prodikeys PC-MIDI Keyboard support"
index bc3cec199feefdf437d0c0141c5ff6f73aa10308..f04ed9aabc3f9fea0baf5b074acd83b6d07527c6 100644 (file)
@@ -86,6 +86,7 @@ static const struct hid_device_id ch_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, ch_devices);
index e9e87d337446918f672771551f41041755d83d22..63ec1993eaaa905af1583f7169e6be812cf0486d 100644 (file)
@@ -1870,6 +1870,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
@@ -1910,6 +1911,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
@@ -2110,6 +2112,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) },
        { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
index c0303f61c26a94f1998f6883d42a0fc8cb41f432..9ba5d98a118042a52dc40b895c3b2e8df67c0b39 100644 (file)
@@ -3,8 +3,10 @@
  *
  * Supported devices:
  *  - Vengeance K90 Keyboard
+ *  - Scimitar PRO RGB Gaming Mouse
  *
  * Copyright (c) 2015 Clement Vuchener
+ * Copyright (c) 2017 Oscar Campos
  */
 
 /*
@@ -670,10 +672,51 @@ static int corsair_input_mapping(struct hid_device *dev,
        return 0;
 }
 
+/*
+ * The report descriptor of Corsair Scimitar RGB Pro gaming mouse is
+ * non parseable as they define two consecutive Logical Minimum for
+ * the Usage Page (Consumer) in rdescs bytes 75 and 77 being 77 0x16
+ * that should be obviousy 0x26 for Logical Magimum of 16 bits. This
+ * prevents poper parsing of the report descriptor due Logical
+ * Minimum being larger than Logical Maximum.
+ *
+ * This driver fixes the report descriptor for:
+ * - USB ID b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse
+ */
+
+static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+        unsigned int *rsize)
+{
+       struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+
+       if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+               /*
+                * Corsair Scimitar RGB Pro report descriptor is broken and
+                * defines two different Logical Minimum for the Consumer
+                * Application. The byte 77 should be a 0x26 defining a 16
+                * bits integer for the Logical Maximum but it is a 0x16
+                * instead (Logical Minimum)
+                */
+               switch (hdev->product) {
+               case USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB:
+                       if (*rsize >= 172 && rdesc[75] == 0x15 && rdesc[77] == 0x16
+                       && rdesc[78] == 0xff && rdesc[79] == 0x0f) {
+                               hid_info(hdev, "Fixing up report descriptor\n");
+                               rdesc[77] = 0x26;
+                       }
+                       break;
+               }
+
+       }
+       return rdesc;
+}
+
 static const struct hid_device_id corsair_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90),
                .driver_data = CORSAIR_USE_K90_MACRO |
                               CORSAIR_USE_K90_BACKLIGHT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
+            USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
        {}
 };
 
@@ -686,10 +729,14 @@ static struct hid_driver corsair_driver = {
        .event = corsair_event,
        .remove = corsair_remove,
        .input_mapping = corsair_input_mapping,
+       .report_fixup = corsair_mouse_report_fixup,
 };
 
 module_hid_driver(corsair_driver);
 
 MODULE_LICENSE("GPL");
+/* Original K90 driver author */
 MODULE_AUTHOR("Clement Vuchener");
+/* Scimitar PRO RGB driver author */
+MODULE_AUTHOR("Oscar Campos");
 MODULE_DESCRIPTION("HID driver for Corsair devices");
index 86c95d30ac801f2895caef97a575955289d352a4..4e2648c86c8c56142cd06b6a269433f72c5c07c9 100644 (file)
 #define USB_DEVICE_ID_CORSAIR_K70RGB    0x1b13
 #define USB_DEVICE_ID_CORSAIR_STRAFE    0x1b15
 #define USB_DEVICE_ID_CORSAIR_K65RGB    0x1b17
+#define USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE  0x1b38
+#define USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE  0x1b39
+#define USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB  0x1b3e
 
 #define USB_VENDOR_ID_CREATIVELABS     0x041e
 #define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51     0x322c
 
 #define USB_VENDOR_ID_JESS             0x0c45
 #define USB_DEVICE_ID_JESS_YUREX       0x1010
+#define USB_DEVICE_ID_JESS_ZEN_AIO_KBD 0x5112
 
 #define USB_VENDOR_ID_JESS2            0x0f30
 #define USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD 0x0111
 
 #define USB_VENDOR_ID_XIN_MO                   0x16c0
 #define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE       0x05e1
+#define USB_DEVICE_ID_THT_2P_ARCADE            0x75e1
 
 #define USB_VENDOR_ID_XIROKU           0x1477
 #define USB_DEVICE_ID_XIROKU_SPX       0x1006
index f405b07d03816506215bd19fe3c878393370484a..740996f9bdd49dde3d26659f68d2addbff291c60 100644 (file)
@@ -2632,6 +2632,8 @@ err_stop:
                sony_leds_remove(sc);
        if (sc->quirks & SONY_BATTERY_SUPPORT)
                sony_battery_remove(sc);
+       if (sc->touchpad)
+               sony_unregister_touchpad(sc);
        sony_cancel_work_sync(sc);
        kfree(sc->output_report_dmabuf);
        sony_remove_dev_list(sc);
index 7df5227a7e61d6ff79acd62cb009e29ffa4b79d8..9ad7731d2e10dad45268b55fbcf9dfc025570682 100644 (file)
@@ -46,6 +46,7 @@ static int xinmo_event(struct hid_device *hdev, struct hid_field *field,
 
 static const struct hid_device_id xinmo_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
        { }
 };
 
index d6847a664446529831395a962aacab7cb49ab8f5..a69a3c88ab29f5fd736ad18a358fc185f63be99c 100644 (file)
@@ -80,6 +80,9 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
index be8f7e2a026f428f51200e395792dd715a612eeb..e2666ef84dc1ca479646fd1211f45341704755a8 100644 (file)
@@ -2165,6 +2165,14 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
 
        wacom_update_name(wacom, wireless ? " (WL)" : "");
 
+       /* pen only Bamboo neither support touch nor pad */
+       if ((features->type == BAMBOO_PEN) &&
+           ((features->device_type & WACOM_DEVICETYPE_TOUCH) ||
+           (features->device_type & WACOM_DEVICETYPE_PAD))) {
+               error = -ENODEV;
+               goto fail;
+       }
+
        error = wacom_add_shared_data(hdev);
        if (error)
                goto fail;
@@ -2208,14 +2216,8 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
        /* touch only Bamboo doesn't support pen */
        if ((features->type == BAMBOO_TOUCH) &&
            (features->device_type & WACOM_DEVICETYPE_PEN)) {
-               error = -ENODEV;
-               goto fail_quirks;
-       }
-
-       /* pen only Bamboo neither support touch nor pad */
-       if ((features->type == BAMBOO_PEN) &&
-           ((features->device_type & WACOM_DEVICETYPE_TOUCH) ||
-           (features->device_type & WACOM_DEVICETYPE_PAD))) {
+               cancel_delayed_work_sync(&wacom->init_work);
+               _wacom_query_tablet_data(wacom);
                error = -ENODEV;
                goto fail_quirks;
        }
@@ -2579,7 +2581,9 @@ static void wacom_remove(struct hid_device *hdev)
 
        /* make sure we don't trigger the LEDs */
        wacom_led_groups_release(wacom);
-       wacom_release_resources(wacom);
+
+       if (wacom->wacom_wac.features.type != REMOTE)
+               wacom_release_resources(wacom);
 
        hid_set_drvdata(hdev, NULL);
 }
index 4aa3de9f1163b30eb64b4304f285a4167aef0cf0..94250c293be2a18b247e2be006a0e7e4faf4f6f8 100644 (file)
@@ -1959,8 +1959,10 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
                input_set_capability(input, EV_KEY, BTN_TOOL_BRUSH);
                input_set_capability(input, EV_KEY, BTN_TOOL_PENCIL);
                input_set_capability(input, EV_KEY, BTN_TOOL_AIRBRUSH);
-               input_set_capability(input, EV_KEY, BTN_TOOL_MOUSE);
-               input_set_capability(input, EV_KEY, BTN_TOOL_LENS);
+               if (!(features->device_type & WACOM_DEVICETYPE_DIRECT)) {
+                       input_set_capability(input, EV_KEY, BTN_TOOL_MOUSE);
+                       input_set_capability(input, EV_KEY, BTN_TOOL_LENS);
+               }
                break;
        case WACOM_HID_WD_FINGERWHEEL:
                wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
@@ -4197,10 +4199,10 @@ static const struct wacom_features wacom_features_0x343 =
          WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
 static const struct wacom_features wacom_features_0x360 =
        { "Wacom Intuos Pro M", 44800, 29600, 8191, 63,
-         INTUOSP2_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 9, .touch_max = 10 };
+         INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 };
 static const struct wacom_features wacom_features_0x361 =
        { "Wacom Intuos Pro L", 62200, 43200, 8191, 63,
-         INTUOSP2_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 9, .touch_max = 10 };
+         INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 };
 
 static const struct wacom_features wacom_features_HID_ANY_ID =
        { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
index bd0d1988feb2ad85f94faaebb939167119c1cca0..321b8833fa6f35a5a1941d319816ed2ffc83a6d2 100644 (file)
@@ -502,12 +502,15 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
 
        wait_for_completion(&info->waitevent);
 
-       if (channel->rescind) {
-               ret = -ENODEV;
-               goto post_msg_err;
-       }
-
 post_msg_err:
+       /*
+        * If the channel has been rescinded;
+        * we will be awakened by the rescind
+        * handler; set the error code to zero so we don't leak memory.
+        */
+       if (channel->rescind)
+               ret = 0;
+
        spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
        list_del(&info->msglistentry);
        spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
@@ -530,15 +533,13 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
        int ret;
 
        /*
-        * vmbus_on_event(), running in the tasklet, can race
+        * vmbus_on_event(), running in the per-channel tasklet, can race
         * with vmbus_close_internal() in the case of SMP guest, e.g., when
         * the former is accessing channel->inbound.ring_buffer, the latter
-        * could be freeing the ring_buffer pages.
-        *
-        * To resolve the race, we can serialize them by disabling the
-        * tasklet when the latter is running here.
+        * could be freeing the ring_buffer pages, so here we must stop it
+        * first.
         */
-       hv_event_tasklet_disable(channel);
+       tasklet_disable(&channel->callback_event);
 
        /*
         * In case a device driver's probe() fails (e.g.,
@@ -605,8 +606,6 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
                get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 
 out:
-       hv_event_tasklet_enable(channel);
-
        return ret;
 }
 
index f33465d78a025680d7515978fdbcc432d51a8062..fbcb063523082840b61bf23d7852f36da4682647 100644 (file)
@@ -350,7 +350,8 @@ static struct vmbus_channel *alloc_channel(void)
 static void free_channel(struct vmbus_channel *channel)
 {
        tasklet_kill(&channel->callback_event);
-       kfree(channel);
+
+       kfree_rcu(channel, rcu);
 }
 
 static void percpu_channel_enq(void *arg)
@@ -359,14 +360,14 @@ static void percpu_channel_enq(void *arg)
        struct hv_per_cpu_context *hv_cpu
                = this_cpu_ptr(hv_context.cpu_context);
 
-       list_add_tail(&channel->percpu_list, &hv_cpu->chan_list);
+       list_add_tail_rcu(&channel->percpu_list, &hv_cpu->chan_list);
 }
 
 static void percpu_channel_deq(void *arg)
 {
        struct vmbus_channel *channel = arg;
 
-       list_del(&channel->percpu_list);
+       list_del_rcu(&channel->percpu_list);
 }
 
 
@@ -381,19 +382,6 @@ static void vmbus_release_relid(u32 relid)
                       true);
 }
 
-void hv_event_tasklet_disable(struct vmbus_channel *channel)
-{
-       tasklet_disable(&channel->callback_event);
-}
-
-void hv_event_tasklet_enable(struct vmbus_channel *channel)
-{
-       tasklet_enable(&channel->callback_event);
-
-       /* In case there is any pending event */
-       tasklet_schedule(&channel->callback_event);
-}
-
 void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
 {
        unsigned long flags;
@@ -402,7 +390,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
        BUG_ON(!channel->rescind);
        BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
 
-       hv_event_tasklet_disable(channel);
        if (channel->target_cpu != get_cpu()) {
                put_cpu();
                smp_call_function_single(channel->target_cpu,
@@ -411,7 +398,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
                percpu_channel_deq(channel);
                put_cpu();
        }
-       hv_event_tasklet_enable(channel);
 
        if (channel->primary_channel == NULL) {
                list_del(&channel->listentry);
@@ -505,7 +491,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 
        init_vp_index(newchannel, dev_type);
 
-       hv_event_tasklet_disable(newchannel);
        if (newchannel->target_cpu != get_cpu()) {
                put_cpu();
                smp_call_function_single(newchannel->target_cpu,
@@ -515,7 +500,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
                percpu_channel_enq(newchannel);
                put_cpu();
        }
-       hv_event_tasklet_enable(newchannel);
 
        /*
         * This state is used to indicate a successful open
@@ -565,7 +549,6 @@ err_deq_chan:
        list_del(&newchannel->listentry);
        mutex_unlock(&vmbus_connection.channel_mutex);
 
-       hv_event_tasklet_disable(newchannel);
        if (newchannel->target_cpu != get_cpu()) {
                put_cpu();
                smp_call_function_single(newchannel->target_cpu,
@@ -574,7 +557,6 @@ err_deq_chan:
                percpu_channel_deq(newchannel);
                put_cpu();
        }
-       hv_event_tasklet_enable(newchannel);
 
        vmbus_release_relid(newchannel->offermsg.child_relid);
 
@@ -814,6 +796,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
        /* Allocate the channel object and save this offer. */
        newchannel = alloc_channel();
        if (!newchannel) {
+               vmbus_release_relid(offer->child_relid);
                pr_err("Unable to allocate channel object\n");
                return;
        }
index 9aee6014339dffc8627d173446e7bfe0dc06247c..a5596a642ed06b31beb5b2e19347e10b9abb0ed2 100644 (file)
@@ -71,7 +71,6 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data);
 static const char fcopy_devname[] = "vmbus/hv_fcopy";
 static u8 *recv_buffer;
 static struct hvutil_transport *hvt;
-static struct completion release_event;
 /*
  * This state maintains the version number registered by the daemon.
  */
@@ -331,7 +330,6 @@ static void fcopy_on_reset(void)
 
        if (cancel_delayed_work_sync(&fcopy_timeout_work))
                fcopy_respond_to_host(HV_E_FAIL);
-       complete(&release_event);
 }
 
 int hv_fcopy_init(struct hv_util_service *srv)
@@ -339,7 +337,6 @@ int hv_fcopy_init(struct hv_util_service *srv)
        recv_buffer = srv->recv_buffer;
        fcopy_transaction.recv_channel = srv->channel;
 
-       init_completion(&release_event);
        /*
         * When this driver loads, the user level daemon that
         * processes the host requests may not yet be running.
@@ -361,5 +358,4 @@ void hv_fcopy_deinit(void)
        fcopy_transaction.state = HVUTIL_DEVICE_DYING;
        cancel_delayed_work_sync(&fcopy_timeout_work);
        hvutil_transport_destroy(hvt);
-       wait_for_completion(&release_event);
 }
index de263712e247c2b8c47f450f3d1b7eb387f1e073..a1adfe2cfb34244e8f86a48cc1143c0f439be709 100644 (file)
@@ -101,7 +101,6 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
 static const char kvp_devname[] = "vmbus/hv_kvp";
 static u8 *recv_buffer;
 static struct hvutil_transport *hvt;
-static struct completion release_event;
 /*
  * Register the kernel component with the user-level daemon.
  * As part of this registration, pass the LIC version number.
@@ -714,7 +713,6 @@ static void kvp_on_reset(void)
        if (cancel_delayed_work_sync(&kvp_timeout_work))
                kvp_respond_to_host(NULL, HV_E_FAIL);
        kvp_transaction.state = HVUTIL_DEVICE_INIT;
-       complete(&release_event);
 }
 
 int
@@ -723,7 +721,6 @@ hv_kvp_init(struct hv_util_service *srv)
        recv_buffer = srv->recv_buffer;
        kvp_transaction.recv_channel = srv->channel;
 
-       init_completion(&release_event);
        /*
         * When this driver loads, the user level daemon that
         * processes the host requests may not yet be running.
@@ -747,5 +744,4 @@ void hv_kvp_deinit(void)
        cancel_delayed_work_sync(&kvp_timeout_work);
        cancel_work_sync(&kvp_sendkey_work);
        hvutil_transport_destroy(hvt);
-       wait_for_completion(&release_event);
 }
index bcc03f0748d61cd5a8c9f31447b77fd8b2e7e13b..e659d1b94a5794f11272086374e45b5fc99a3df6 100644 (file)
@@ -79,7 +79,6 @@ static int dm_reg_value;
 static const char vss_devname[] = "vmbus/hv_vss";
 static __u8 *recv_buffer;
 static struct hvutil_transport *hvt;
-static struct completion release_event;
 
 static void vss_timeout_func(struct work_struct *dummy);
 static void vss_handle_request(struct work_struct *dummy);
@@ -361,13 +360,11 @@ static void vss_on_reset(void)
        if (cancel_delayed_work_sync(&vss_timeout_work))
                vss_respond_to_host(HV_E_FAIL);
        vss_transaction.state = HVUTIL_DEVICE_INIT;
-       complete(&release_event);
 }
 
 int
 hv_vss_init(struct hv_util_service *srv)
 {
-       init_completion(&release_event);
        if (vmbus_proto_version < VERSION_WIN8_1) {
                pr_warn("Integration service 'Backup (volume snapshot)'"
                        " not supported on this host version.\n");
@@ -400,5 +397,4 @@ void hv_vss_deinit(void)
        cancel_delayed_work_sync(&vss_timeout_work);
        cancel_work_sync(&vss_handle_request_work);
        hvutil_transport_destroy(hvt);
-       wait_for_completion(&release_event);
 }
index 3042eaa13062bbdfbdba853521b7632d35e619e8..186b10083c552b1e026cc056bd131fe8548b2f03 100644 (file)
@@ -590,6 +590,8 @@ static int hv_timesync_init(struct hv_util_service *srv)
        if (!hyperv_cs)
                return -ENODEV;
 
+       spin_lock_init(&host_ts.lock);
+
        INIT_WORK(&wrk.work, hv_set_host_time);
 
        /*
index c235a95152671104cd7042a451b16ccd0d0d06ab..4402a71e23f7f7277c6d1561c4a8db5d46489b8d 100644 (file)
@@ -182,10 +182,11 @@ static int hvt_op_release(struct inode *inode, struct file *file)
         * connects back.
         */
        hvt_reset(hvt);
-       mutex_unlock(&hvt->lock);
 
        if (mode_old == HVUTIL_TRANSPORT_DESTROY)
-               hvt_transport_free(hvt);
+               complete(&hvt->release);
+
+       mutex_unlock(&hvt->lock);
 
        return 0;
 }
@@ -304,6 +305,7 @@ struct hvutil_transport *hvutil_transport_init(const char *name,
 
        init_waitqueue_head(&hvt->outmsg_q);
        mutex_init(&hvt->lock);
+       init_completion(&hvt->release);
 
        spin_lock(&hvt_list_lock);
        list_add(&hvt->list, &hvt_list);
@@ -351,6 +353,8 @@ void hvutil_transport_destroy(struct hvutil_transport *hvt)
        if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0)
                cn_del_callback(&hvt->cn_id);
 
-       if (mode_old != HVUTIL_TRANSPORT_CHARDEV)
-               hvt_transport_free(hvt);
+       if (mode_old == HVUTIL_TRANSPORT_CHARDEV)
+               wait_for_completion(&hvt->release);
+
+       hvt_transport_free(hvt);
 }
index d98f5225c3e693468fdb27ccc03de8d17e2a8576..79afb626e1668981beaa740b4e7d618f22ab194d 100644 (file)
@@ -41,6 +41,7 @@ struct hvutil_transport {
        int outmsg_len;                     /* its length */
        wait_queue_head_t outmsg_q;         /* poll/read wait queue */
        struct mutex lock;                  /* protects struct members */
+       struct completion release;          /* synchronize with fd release */
 };
 
 struct hvutil_transport *hvutil_transport_init(const char *name,
index da6b59ba594039e6d490e8cc9903f41f99032900..8370b9dc6037c17959abc3d9c45c9b233bd0004f 100644 (file)
@@ -939,8 +939,10 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
                if (relid == 0)
                        continue;
 
+               rcu_read_lock();
+
                /* Find channel based on relid */
-               list_for_each_entry(channel, &hv_cpu->chan_list, percpu_list) {
+               list_for_each_entry_rcu(channel, &hv_cpu->chan_list, percpu_list) {
                        if (channel->offermsg.child_relid != relid)
                                continue;
 
@@ -956,6 +958,8 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
                                tasklet_schedule(&channel->callback_event);
                        }
                }
+
+               rcu_read_unlock();
        }
 }
 
index cccef87963e050afb99181d63d3ed5dcf401d5a1..975c43d446f8593d0e701efeaf8da133717cff74 100644 (file)
@@ -646,6 +646,9 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
                else
                        err = atk_read_value_new(sensor, value);
 
+               if (err)
+                       return err;
+
                sensor->is_valid = true;
                sensor->last_updated = jiffies;
                sensor->cached_value = *value;
index efb01c247e2d90680f02980af76148799f3823fc..4dfc7238313ebd393e0e4dc0e17bb4414d1e8b68 100644 (file)
@@ -3198,7 +3198,7 @@ static int __init sm_it87_init(void)
 {
        int sioaddr[2] = { REG_2E, REG_4E };
        struct it87_sio_data sio_data;
-       unsigned short isa_address;
+       unsigned short isa_address[2];
        bool found = false;
        int i, err;
 
@@ -3208,15 +3208,29 @@ static int __init sm_it87_init(void)
 
        for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
                memset(&sio_data, 0, sizeof(struct it87_sio_data));
-               isa_address = 0;
-               err = it87_find(sioaddr[i], &isa_address, &sio_data);
-               if (err || isa_address == 0)
+               isa_address[i] = 0;
+               err = it87_find(sioaddr[i], &isa_address[i], &sio_data);
+               if (err || isa_address[i] == 0)
                        continue;
+               /*
+                * Don't register second chip if its ISA address matches
+                * the first chip's ISA address.
+                */
+               if (i && isa_address[i] == isa_address[0])
+                       break;
 
-               err = it87_device_add(i, isa_address, &sio_data);
+               err = it87_device_add(i, isa_address[i], &sio_data);
                if (err)
                        goto exit_dev_unregister;
+
                found = true;
+
+               /*
+                * IT8705F may respond on both SIO addresses.
+                * Stop probing after finding one.
+                */
+               if (sio_data.type == it87)
+                       break;
        }
 
        if (!found) {
index c1b9275978f9d9ee9172e99e569de7dca48b491d..281491cca5103ad4b82e2f2a52be6f2408262bdb 100644 (file)
@@ -311,7 +311,7 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
                data->pwm[channel] = val << 8;
                err = i2c_smbus_write_word_swapped(client,
                                                   MAX31790_REG_PWMOUT(channel),
-                                                  val);
+                                                  data->pwm[channel]);
                break;
        case hwmon_pwm_enable:
                fan_config = data->fan_config[channel];
index cdd9b3b26195aa38f03a910d10e483bca61edcca..7563eceeaaeaa3a4e70855a6d9622e960b0ab6c0 100644 (file)
@@ -221,8 +221,10 @@ static int intel_th_output_activate(struct intel_th_device *thdev)
        else
                intel_th_trace_enable(thdev);
 
-       if (ret)
+       if (ret) {
                pm_runtime_put(&thdev->dev);
+               module_put(thdrv->driver.owner);
+       }
 
        return ret;
 }
index 0bba3842336e6d6b9cb9a2b78ca91d7ff2712dcd..590cf90dd21a61a6855dd99885c99da7d2dbc33a 100644 (file)
@@ -85,6 +85,16 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
                .driver_data = (kernel_ulong_t)0,
        },
+       {
+               /* Denverton */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
+               .driver_data = (kernel_ulong_t)0,
+       },
+       {
+               /* Gemini Lake */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
+               .driver_data = (kernel_ulong_t)0,
+       },
        { 0 },
 };
 
index dfc1c0e37c4022b66da0facee93af030c70c4e73..ad31d21da3165f73ecc8f7beb1feef4fc186cbe5 100644 (file)
@@ -35,7 +35,6 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
@@ -117,6 +116,10 @@ static const struct chip_desc chips[] = {
                .has_irq = 1,
                .muxtype = pca954x_isswi,
        },
+       [pca_9546] = {
+               .nchans = 4,
+               .muxtype = pca954x_isswi,
+       },
        [pca_9547] = {
                .nchans = 8,
                .enable = 0x8,
@@ -134,28 +137,13 @@ static const struct i2c_device_id pca954x_id[] = {
        { "pca9543", pca_9543 },
        { "pca9544", pca_9544 },
        { "pca9545", pca_9545 },
-       { "pca9546", pca_9545 },
+       { "pca9546", pca_9546 },
        { "pca9547", pca_9547 },
        { "pca9548", pca_9548 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, pca954x_id);
 
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id pca954x_acpi_ids[] = {
-       { .id = "PCA9540", .driver_data = pca_9540 },
-       { .id = "PCA9542", .driver_data = pca_9542 },
-       { .id = "PCA9543", .driver_data = pca_9543 },
-       { .id = "PCA9544", .driver_data = pca_9544 },
-       { .id = "PCA9545", .driver_data = pca_9545 },
-       { .id = "PCA9546", .driver_data = pca_9545 },
-       { .id = "PCA9547", .driver_data = pca_9547 },
-       { .id = "PCA9548", .driver_data = pca_9548 },
-       { }
-};
-MODULE_DEVICE_TABLE(acpi, pca954x_acpi_ids);
-#endif
-
 #ifdef CONFIG_OF
 static const struct of_device_id pca954x_of_match[] = {
        { .compatible = "nxp,pca9540", .data = &chips[pca_9540] },
@@ -393,17 +381,8 @@ static int pca954x_probe(struct i2c_client *client,
        match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
        if (match)
                data->chip = of_device_get_match_data(&client->dev);
-       else if (id)
+       else
                data->chip = &chips[id->driver_data];
-       else {
-               const struct acpi_device_id *acpi_id;
-
-               acpi_id = acpi_match_device(ACPI_PTR(pca954x_acpi_ids),
-                                               &client->dev);
-               if (!acpi_id)
-                       return -ENODEV;
-               data->chip = &chips[acpi_id->driver_data];
-       }
 
        data->last_chan = 0;               /* force the first selection */
 
@@ -492,7 +471,6 @@ static struct i2c_driver pca954x_driver = {
                .name   = "pca954x",
                .pm     = &pca954x_pm,
                .of_match_table = of_match_ptr(pca954x_of_match),
-               .acpi_match_table = ACPI_PTR(pca954x_acpi_ids),
        },
        .probe          = pca954x_probe,
        .remove         = pca954x_remove,
index ad9dec30bb304ffbbb0f67f01b753f7bc88cd891..4282ceca3d8f9f417a1a511b3d608896a7ad4159 100644 (file)
@@ -169,7 +169,9 @@ static irqreturn_t tiadc_irq_h(int irq, void *private)
 {
        struct iio_dev *indio_dev = private;
        struct tiadc_device *adc_dev = iio_priv(indio_dev);
-       unsigned int status, config;
+       unsigned int status, config, adc_fsm;
+       unsigned short count = 0;
+
        status = tiadc_readl(adc_dev, REG_IRQSTATUS);
 
        /*
@@ -183,6 +185,15 @@ static irqreturn_t tiadc_irq_h(int irq, void *private)
                tiadc_writel(adc_dev, REG_CTRL, config);
                tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
                                | IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
+
+               /* wait for idle state.
+                * ADC needs to finish the current conversion
+                * before disabling the module
+                */
+               do {
+                       adc_fsm = tiadc_readl(adc_dev, REG_ADCFSM);
+               } while (adc_fsm != 0x10 && count++ < 100);
+
                tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
                return IRQ_HANDLED;
        } else if (status & IRQENB_FIFO1THRES) {
index a3cce3a38300796b6b0899aa7fe2190481c7137d..ecf592d69043ae82e2e85184096471bfebef95e2 100644 (file)
@@ -51,8 +51,6 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
                        st->report_state.report_id,
                        st->report_state.index,
                        HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
-
-               poll_value = hid_sensor_read_poll_value(st);
        } else {
                int val;
 
@@ -89,7 +87,9 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
        sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
                               st->power_state.index,
                               sizeof(state_val), &state_val);
-       if (state && poll_value)
+       if (state)
+               poll_value = hid_sensor_read_poll_value(st);
+       if (poll_value > 0)
                msleep_interruptible(poll_value * 2);
 
        return 0;
index 78532ce074497985dfa22fb881b3639e480ae7ed..81b572d7699a89bb17baa21321744c7b518e5c0a 100644 (file)
@@ -193,8 +193,8 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
        if (err < 0)
                goto out;
 
-       fifo_watermark = ((data & ~ST_LSM6DSX_FIFO_TH_MASK) << 8) |
-                         (fifo_watermark & ST_LSM6DSX_FIFO_TH_MASK);
+       fifo_watermark = ((data << 8) & ~ST_LSM6DSX_FIFO_TH_MASK) |
+                        (fifo_watermark & ST_LSM6DSX_FIFO_TH_MASK);
 
        wdata = cpu_to_le16(fifo_watermark);
        err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_THL_ADDR,
index 6dd8cbd7ce9531a5883173f34eb30edc45301083..e13370dc9b1cb424c4c2d43f0e92b9fadca78df9 100644 (file)
@@ -763,7 +763,7 @@ power_off:
        return ret;
 }
 
-static int __exit ak8974_remove(struct i2c_client *i2c)
+static int ak8974_remove(struct i2c_client *i2c)
 {
        struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
        struct ak8974 *ak8974 = iio_priv(indio_dev);
@@ -845,7 +845,7 @@ static struct i2c_driver ak8974_driver = {
                .of_match_table = of_match_ptr(ak8974_of_match),
        },
        .probe    = ak8974_probe,
-       .remove   = __exit_p(ak8974_remove),
+       .remove   = ak8974_remove,
        .id_table = ak8974_id,
 };
 module_i2c_driver(ak8974_driver);
index e95510117a6dd7069f1251796eaebd1ea8283693..f2ae75fa3128b9101985bb92e882b596404c7ebc 100644 (file)
@@ -29,7 +29,13 @@ static int __ib_process_cq(struct ib_cq *cq, int budget)
 {
        int i, n, completed = 0;
 
-       while ((n = ib_poll_cq(cq, IB_POLL_BATCH, cq->wc)) > 0) {
+       /*
+        * budget might be (-1) if the caller does not
+        * want to bound this call, thus we need unsigned
+        * minimum here.
+        */
+       while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH,
+                       budget - completed), cq->wc)) > 0) {
                for (i = 0; i < n; i++) {
                        struct ib_wc *wc = &cq->wc[i];
 
@@ -196,7 +202,7 @@ void ib_free_cq(struct ib_cq *cq)
                irq_poll_disable(&cq->iop);
                break;
        case IB_POLL_WORKQUEUE:
-               flush_work(&cq->work);
+               cancel_work_sync(&cq->work);
                break;
        default:
                WARN_ON_ONCE(1);
index 593d2ce6ec7cec115b58006a5cb13c49bec72d83..7c9e34d679d325d101f937e97ea25dfe76f79f80 100644 (file)
@@ -336,12 +336,26 @@ int ib_register_device(struct ib_device *device,
        struct device *parent = device->dev.parent;
 
        WARN_ON_ONCE(!parent);
-       if (!device->dev.dma_ops)
-               device->dev.dma_ops = parent->dma_ops;
-       if (!device->dev.dma_mask)
-               device->dev.dma_mask = parent->dma_mask;
-       if (!device->dev.coherent_dma_mask)
-               device->dev.coherent_dma_mask = parent->coherent_dma_mask;
+       WARN_ON_ONCE(device->dma_device);
+       if (device->dev.dma_ops) {
+               /*
+                * The caller provided custom DMA operations. Copy the
+                * DMA-related fields that are used by e.g. dma_alloc_coherent()
+                * into device->dev.
+                */
+               device->dma_device = &device->dev;
+               if (!device->dev.dma_mask)
+                       device->dev.dma_mask = parent->dma_mask;
+               if (!device->dev.coherent_dma_mask)
+                       device->dev.coherent_dma_mask =
+                               parent->coherent_dma_mask;
+       } else {
+               /*
+                * The caller did not provide custom DMA operations. Use the
+                * DMA mapping operations of the parent device.
+                */
+               device->dma_device = parent;
+       }
 
        mutex_lock(&device_mutex);
 
@@ -1015,8 +1029,7 @@ static int __init ib_core_init(void)
                return -ENOMEM;
 
        ib_comp_wq = alloc_workqueue("ib-comp-wq",
-                       WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM,
-                       WQ_UNBOUND_MAX_ACTIVE);
+                       WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
        if (!ib_comp_wq) {
                ret = -ENOMEM;
                goto err;
index 0f5d43d1f5fc30d812a6a3988d90b30cdb459da0..70c3e9e795082b7152ea754a52fc68c412dee7ca 100644 (file)
@@ -160,6 +160,9 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
                return NOTIFY_DONE;
 
        iwdev = &hdl->device;
+       if (iwdev->init_state < INET_NOTIFIER)
+               return NOTIFY_DONE;
+
        netdev = iwdev->ldev->netdev;
        upper_dev = netdev_master_upper_dev_get(netdev);
        if (netdev != event_netdev)
@@ -214,6 +217,9 @@ int i40iw_inet6addr_event(struct notifier_block *notifier,
                return NOTIFY_DONE;
 
        iwdev = &hdl->device;
+       if (iwdev->init_state < INET_NOTIFIER)
+               return NOTIFY_DONE;
+
        netdev = iwdev->ldev->netdev;
        if (netdev != event_netdev)
                return NOTIFY_DONE;
@@ -260,6 +266,8 @@ int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void *
                if (!iwhdl)
                        return NOTIFY_DONE;
                iwdev = &iwhdl->device;
+               if (iwdev->init_state < INET_NOTIFIER)
+                       return NOTIFY_DONE;
                p = (__be32 *)neigh->primary_key;
                i40iw_copy_ip_ntohl(local_ipaddr, p);
                if (neigh->nud_state & NUD_VALID) {
index bc9fb144e57b8e3a05863223156f25b7f17e6a34..c52edeafd616a3be52fec913430405e5adff13d2 100644 (file)
@@ -372,7 +372,7 @@ static int _ocrdma_pd_mgr_put_bitmap(struct ocrdma_dev *dev, u16 pd_id,
        return 0;
 }
 
-static u8 ocrdma_put_pd_num(struct ocrdma_dev *dev, u16 pd_id,
+static int ocrdma_put_pd_num(struct ocrdma_dev *dev, u16 pd_id,
                                   bool dpp_pool)
 {
        int status;
index 12c4208fd7013b78c5e1bf736d82461c05c814c3..af9f596bb68b294cc587f13924a645ac70e6235c 100644 (file)
@@ -7068,7 +7068,7 @@ static void qib_7322_txchk_change(struct qib_devdata *dd, u32 start,
        unsigned long flags;
 
        while (wait) {
-               unsigned long shadow;
+               unsigned long shadow = 0;
                int cstart, previ = -1;
 
                /*
index 3cd96c1b95029d2d365279d3ccfeebe038e3a2e4..9fbe22d3467b222988cf33fee7c04f1996a84928 100644 (file)
@@ -69,6 +69,9 @@
  */
 #define PCI_DEVICE_ID_VMWARE_PVRDMA    0x0820
 
+#define PVRDMA_NUM_RING_PAGES          4
+#define PVRDMA_QP_NUM_HEADER_PAGES     1
+
 struct pvrdma_dev;
 
 struct pvrdma_page_dir {
index e69d6f3cae32b5018ea4a09efd299ec402aa4a4f..09078ccfaec719b8800ce87beaafbaa92b50cbff 100644 (file)
@@ -132,7 +132,7 @@ enum pvrdma_pci_resource {
 
 enum pvrdma_device_ctl {
        PVRDMA_DEVICE_CTL_ACTIVATE,     /* Activate device. */
-       PVRDMA_DEVICE_CTL_QUIESCE,      /* Quiesce device. */
+       PVRDMA_DEVICE_CTL_UNQUIESCE,    /* Unquiesce device. */
        PVRDMA_DEVICE_CTL_RESET,        /* Reset device. */
 };
 
index 100bea5c42ffb74375552131ebb1fbd5cbdc3659..34ebc7615411d9e3574e50fc0bf083056ef756cf 100644 (file)
@@ -56,7 +56,7 @@
 #include "pvrdma.h"
 
 #define DRV_NAME       "vmw_pvrdma"
-#define DRV_VERSION    "1.0.0.0-k"
+#define DRV_VERSION    "1.0.1.0-k"
 
 static DEFINE_MUTEX(pvrdma_device_list_lock);
 static LIST_HEAD(pvrdma_device_list);
@@ -660,7 +660,16 @@ static void pvrdma_netdevice_event_handle(struct pvrdma_dev *dev,
                pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ERR);
                break;
        case NETDEV_UP:
-               pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ACTIVE);
+               pvrdma_write_reg(dev, PVRDMA_REG_CTL,
+                                PVRDMA_DEVICE_CTL_UNQUIESCE);
+
+               mb();
+
+               if (pvrdma_read_reg(dev, PVRDMA_REG_ERR))
+                       dev_err(&dev->pdev->dev,
+                               "failed to activate device during link up\n");
+               else
+                       pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ACTIVE);
                break;
        default:
                dev_dbg(&dev->pdev->dev, "ignore netdevice event %ld on %s\n",
@@ -858,7 +867,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
        dev->dsr->resp_slot_dma = (u64)slot_dma;
 
        /* Async event ring */
-       dev->dsr->async_ring_pages.num_pages = 4;
+       dev->dsr->async_ring_pages.num_pages = PVRDMA_NUM_RING_PAGES;
        ret = pvrdma_page_dir_init(dev, &dev->async_pdir,
                                   dev->dsr->async_ring_pages.num_pages, true);
        if (ret)
@@ -867,7 +876,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
        dev->dsr->async_ring_pages.pdir_dma = dev->async_pdir.dir_dma;
 
        /* CQ notification ring */
-       dev->dsr->cq_ring_pages.num_pages = 4;
+       dev->dsr->cq_ring_pages.num_pages = PVRDMA_NUM_RING_PAGES;
        ret = pvrdma_page_dir_init(dev, &dev->cq_pdir,
                                   dev->dsr->cq_ring_pages.num_pages, true);
        if (ret)
index dbbfd35e7da7ade590bc0b13784e82ba9266f213..30062aad3af1a2cfa6d14ce9bd60250644b85ab8 100644 (file)
@@ -170,8 +170,9 @@ static int pvrdma_set_sq_size(struct pvrdma_dev *dev, struct ib_qp_cap *req_cap,
                                             sizeof(struct pvrdma_sge) *
                                             qp->sq.max_sg);
        /* Note: one extra page for the header. */
-       qp->npages_send = 1 + (qp->sq.wqe_cnt * qp->sq.wqe_size +
-                              PAGE_SIZE - 1) / PAGE_SIZE;
+       qp->npages_send = PVRDMA_QP_NUM_HEADER_PAGES +
+                         (qp->sq.wqe_cnt * qp->sq.wqe_size + PAGE_SIZE - 1) /
+                                                               PAGE_SIZE;
 
        return 0;
 }
@@ -288,7 +289,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
                        qp->npages = qp->npages_send + qp->npages_recv;
 
                        /* Skip header page. */
-                       qp->sq.offset = PAGE_SIZE;
+                       qp->sq.offset = PVRDMA_QP_NUM_HEADER_PAGES * PAGE_SIZE;
 
                        /* Recv queue pages are after send pages. */
                        qp->rq.offset = qp->npages_send * PAGE_SIZE;
@@ -341,7 +342,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
        cmd->qp_type = ib_qp_type_to_pvrdma(init_attr->qp_type);
        cmd->access_flags = IB_ACCESS_LOCAL_WRITE;
        cmd->total_chunks = qp->npages;
-       cmd->send_chunks = qp->npages_send - 1;
+       cmd->send_chunks = qp->npages_send - PVRDMA_QP_NUM_HEADER_PAGES;
        cmd->pdir_dma = qp->pdir.dir_dma;
 
        dev_dbg(&dev->pdev->dev, "create queuepair with %d, %d, %d, %d\n",
@@ -554,13 +555,13 @@ out:
        return ret;
 }
 
-static inline void *get_sq_wqe(struct pvrdma_qp *qp, int n)
+static inline void *get_sq_wqe(struct pvrdma_qp *qp, unsigned int n)
 {
        return pvrdma_page_dir_get_ptr(&qp->pdir,
                                       qp->sq.offset + n * qp->sq.wqe_size);
 }
 
-static inline void *get_rq_wqe(struct pvrdma_qp *qp, int n)
+static inline void *get_rq_wqe(struct pvrdma_qp *qp, unsigned int n)
 {
        return pvrdma_page_dir_get_ptr(&qp->pdir,
                                       qp->rq.offset + n * qp->rq.wqe_size);
@@ -598,9 +599,7 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        unsigned long flags;
        struct pvrdma_sq_wqe_hdr *wqe_hdr;
        struct pvrdma_sge *sge;
-       int i, index;
-       int nreq;
-       int ret;
+       int i, ret;
 
        /*
         * In states lower than RTS, we can fail immediately. In other states,
@@ -613,9 +612,8 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
        spin_lock_irqsave(&qp->sq.lock, flags);
 
-       index = pvrdma_idx(&qp->sq.ring->prod_tail, qp->sq.wqe_cnt);
-       for (nreq = 0; wr; nreq++, wr = wr->next) {
-               unsigned int tail;
+       while (wr) {
+               unsigned int tail = 0;
 
                if (unlikely(!pvrdma_idx_ring_has_space(
                                qp->sq.ring, qp->sq.wqe_cnt, &tail))) {
@@ -680,7 +678,7 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                        }
                }
 
-               wqe_hdr = (struct pvrdma_sq_wqe_hdr *)get_sq_wqe(qp, index);
+               wqe_hdr = (struct pvrdma_sq_wqe_hdr *)get_sq_wqe(qp, tail);
                memset(wqe_hdr, 0, sizeof(*wqe_hdr));
                wqe_hdr->wr_id = wr->wr_id;
                wqe_hdr->num_sge = wr->num_sge;
@@ -771,12 +769,11 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                /* Make sure wqe is written before index update */
                smp_wmb();
 
-               index++;
-               if (unlikely(index >= qp->sq.wqe_cnt))
-                       index = 0;
                /* Update shared sq ring */
                pvrdma_idx_ring_inc(&qp->sq.ring->prod_tail,
                                    qp->sq.wqe_cnt);
+
+               wr = wr->next;
        }
 
        ret = 0;
@@ -806,7 +803,6 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
        struct pvrdma_qp *qp = to_vqp(ibqp);
        struct pvrdma_rq_wqe_hdr *wqe_hdr;
        struct pvrdma_sge *sge;
-       int index, nreq;
        int ret = 0;
        int i;
 
@@ -821,9 +817,8 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 
        spin_lock_irqsave(&qp->rq.lock, flags);
 
-       index = pvrdma_idx(&qp->rq.ring->prod_tail, qp->rq.wqe_cnt);
-       for (nreq = 0; wr; nreq++, wr = wr->next) {
-               unsigned int tail;
+       while (wr) {
+               unsigned int tail = 0;
 
                if (unlikely(wr->num_sge > qp->rq.max_sg ||
                             wr->num_sge < 0)) {
@@ -843,7 +838,7 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                        goto out;
                }
 
-               wqe_hdr = (struct pvrdma_rq_wqe_hdr *)get_rq_wqe(qp, index);
+               wqe_hdr = (struct pvrdma_rq_wqe_hdr *)get_rq_wqe(qp, tail);
                wqe_hdr->wr_id = wr->wr_id;
                wqe_hdr->num_sge = wr->num_sge;
                wqe_hdr->total_len = 0;
@@ -859,12 +854,11 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                /* Make sure wqe is written before index update */
                smp_wmb();
 
-               index++;
-               if (unlikely(index >= qp->rq.wqe_cnt))
-                       index = 0;
                /* Update shared rq ring */
                pvrdma_idx_ring_inc(&qp->rq.ring->prod_tail,
                                    qp->rq.wqe_cnt);
+
+               wr = wr->next;
        }
 
        spin_unlock_irqrestore(&qp->rq.lock, flags);
index e202b8142759f58e0c06317ce1e4f3d798c54f37..6b712eecbd37d9ca5a0bf312028dc7b23c1c2fd8 100644 (file)
@@ -170,9 +170,9 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi,
 
        spin_lock_irq(&rdi->mmap_offset_lock);
        if (rdi->mmap_offset == 0)
-               rdi->mmap_offset = PAGE_SIZE;
+               rdi->mmap_offset = ALIGN(PAGE_SIZE, SHMLBA);
        ip->offset = rdi->mmap_offset;
-       rdi->mmap_offset += size;
+       rdi->mmap_offset += ALIGN(size, SHMLBA);
        spin_unlock_irq(&rdi->mmap_offset_lock);
 
        INIT_LIST_HEAD(&ip->pending_mmaps);
index 7d1ac27ed2516dad367354f36b15903cb3197ade..6332dedc11e8a3306697e494ab89996b34d453ab 100644 (file)
@@ -22,4 +22,4 @@ config RDMA_RXE
        To configure and work with soft-RoCE driver please use the
        following wiki page under "configure Soft-RoCE (RXE)" section:
 
-       https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
+       https://github.com/linux-rdma/rdma-core/blob/master/Documentation/rxe.md
index c572a4c09359c9f91fcf7f55466fadff012fbc82..bd812e00988ed32f5517ce952a0e2186c4678f87 100644 (file)
@@ -156,10 +156,10 @@ struct rxe_mmap_info *rxe_create_mmap_info(struct rxe_dev *rxe,
        spin_lock_bh(&rxe->mmap_offset_lock);
 
        if (rxe->mmap_offset == 0)
-               rxe->mmap_offset = PAGE_SIZE;
+               rxe->mmap_offset = ALIGN(PAGE_SIZE, SHMLBA);
 
        ip->info.offset = rxe->mmap_offset;
-       rxe->mmap_offset += size;
+       rxe->mmap_offset += ALIGN(size, SHMLBA);
 
        spin_unlock_bh(&rxe->mmap_offset_lock);
 
index dbfde0dc6ff7e7bcf3c6b182b5f49fc5daf65009..9f95f50b290904fe67797cacfa5af2f565e3188d 100644 (file)
@@ -729,11 +729,11 @@ next_wqe:
        ret = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, &pkt, skb);
        if (ret) {
                qp->need_req_skb = 1;
-               kfree_skb(skb);
 
                rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
 
                if (ret == -EAGAIN) {
+                       kfree_skb(skb);
                        rxe_run_task(&qp->req.task, 1);
                        goto exit;
                }
index d404a8aba7afcaf8ab8addd38949ddf5adcd0847..c9dd385ce62e2c65b97e5bf16e5d8f6288b6f19c 100644 (file)
@@ -813,18 +813,17 @@ static enum resp_states execute(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
                WARN_ON_ONCE(1);
        }
 
-       /* We successfully processed this new request. */
-       qp->resp.msn++;
-
        /* next expected psn, read handles this separately */
        qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK;
 
        qp->resp.opcode = pkt->opcode;
        qp->resp.status = IB_WC_SUCCESS;
 
-       if (pkt->mask & RXE_COMP_MASK)
+       if (pkt->mask & RXE_COMP_MASK) {
+               /* We successfully processed this new request. */
+               qp->resp.msn++;
                return RESPST_COMPLETE;
-       else if (qp_type(qp) == IB_QPT_RC)
+       else if (qp_type(qp) == IB_QPT_RC)
                return RESPST_ACKNOWLEDGE;
        else
                return RESPST_CLEANUP;
index 9d0b22ad58c15759c3b92472083da15af5c42bac..c1ae4aeae2f90e5a9c1376a296529d912d77d457 100644 (file)
@@ -430,6 +430,7 @@ struct iser_fr_desc {
        struct list_head                  list;
        struct iser_reg_resources         rsc;
        struct iser_pi_context           *pi_ctx;
+       struct list_head                  all_list;
 };
 
 /**
@@ -443,6 +444,7 @@ struct iser_fr_pool {
        struct list_head        list;
        spinlock_t              lock;
        int                     size;
+       struct list_head        all_list;
 };
 
 /**
index 30b622f2ab7382ca04a8affbd26dfd01ff98716c..c538a38c91ce95acf8e00fcdf43fa28588ad2f49 100644 (file)
@@ -362,6 +362,7 @@ int iser_alloc_fastreg_pool(struct ib_conn *ib_conn,
        int i, ret;
 
        INIT_LIST_HEAD(&fr_pool->list);
+       INIT_LIST_HEAD(&fr_pool->all_list);
        spin_lock_init(&fr_pool->lock);
        fr_pool->size = 0;
        for (i = 0; i < cmds_max; i++) {
@@ -373,6 +374,7 @@ int iser_alloc_fastreg_pool(struct ib_conn *ib_conn,
                }
 
                list_add_tail(&desc->list, &fr_pool->list);
+               list_add_tail(&desc->all_list, &fr_pool->all_list);
                fr_pool->size++;
        }
 
@@ -392,13 +394,13 @@ void iser_free_fastreg_pool(struct ib_conn *ib_conn)
        struct iser_fr_desc *desc, *tmp;
        int i = 0;
 
-       if (list_empty(&fr_pool->list))
+       if (list_empty(&fr_pool->all_list))
                return;
 
        iser_info("freeing conn %p fr pool\n", ib_conn);
 
-       list_for_each_entry_safe(desc, tmp, &fr_pool->list, list) {
-               list_del(&desc->list);
+       list_for_each_entry_safe(desc, tmp, &fr_pool->all_list, all_list) {
+               list_del(&desc->all_list);
                iser_free_reg_res(&desc->rsc);
                if (desc->pi_ctx)
                        iser_free_pi_ctx(desc->pi_ctx);
index d96aa27dfcdc9776260c72753b48b63691af1b04..db64adfbe1aff092b4418832c1c81cce0901e044 100644 (file)
@@ -141,6 +141,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
 
        interface = intf->cur_altsetting;
 
+       if (interface->desc.bNumEndpoints < 2)
+               return -ENODEV;
+
        epirq = &interface->endpoint[0].desc;
        epout = &interface->endpoint[1].desc;
 
index 9cc6d057c302a1753f33e9072ab5f5384f1eec40..23c191a2a0715abe9584760742327b25f058d53b 100644 (file)
@@ -700,6 +700,10 @@ static int cm109_usb_probe(struct usb_interface *intf,
        int error = -ENOMEM;
 
        interface = intf->cur_altsetting;
+
+       if (interface->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        endpoint = &interface->endpoint[0].desc;
 
        if (!usb_endpoint_is_int_in(endpoint))
index 9c0ea36913b4a98293911f62a2d649dc08a855cd..f4e8fbec6a942a8ea7a48e268b1e96f9fe458369 100644 (file)
@@ -1667,6 +1667,10 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
                return -EINVAL;
 
        alt = pcu->ctrl_intf->cur_altsetting;
+
+       if (alt->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        pcu->ep_ctrl = &alt->endpoint[0].desc;
        pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
 
index 79c964c075f14029a8072a6ad441927a0a40cf04..6e7ff9561d9261f31f919720925e12d8f1720b98 100644 (file)
@@ -875,6 +875,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
        int ret, pipe, i;
 
        interface = intf->cur_altsetting;
+
+       if (interface->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        endpoint = &interface->endpoint[0].desc;
        if (!usb_endpoint_is_int_in(endpoint))
                return -ENODEV;
index 72b28ebfe360030cbeeadec8a52385a9de09a7f0..f210e19ddba66b86312b09c6925c55ea9fc0fab7 100644 (file)
@@ -1282,10 +1282,8 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
        /* handle buttons */
        if (pkt_id == SS4_PACKET_ID_STICK) {
                f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
-               if (!(priv->flags & ALPS_BUTTONPAD)) {
-                       f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
-                       f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
-               }
+               f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
+               f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
        } else {
                f->left = !!(SS4_BTN_V2(p) & 0x01);
                if (!(priv->flags & ALPS_BUTTONPAD)) {
@@ -2462,14 +2460,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
        int num_y_electrode;
        int x_pitch, y_pitch, x_phys, y_phys;
 
-       num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
-       num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
+       if (IS_SS4PLUS_DEV(priv->dev_id)) {
+               num_x_electrode =
+                       SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
+               num_y_electrode =
+                       SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
+
+               priv->x_max =
+                       (num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
+               priv->y_max =
+                       (num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
 
-       priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
-       priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
+               x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
+               y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
 
-       x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
-       y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
+       } else {
+               num_x_electrode =
+                       SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
+               num_y_electrode =
+                       SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
+
+               priv->x_max =
+                       (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
+               priv->y_max =
+                       (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
+
+               x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
+               y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
+       }
 
        x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
        y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
@@ -2485,7 +2503,10 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
 {
        unsigned char is_btnless;
 
-       is_btnless = (otp[1][1] >> 3) & 0x01;
+       if (IS_SS4PLUS_DEV(priv->dev_id))
+               is_btnless = (otp[1][0] >> 1) & 0x01;
+       else
+               is_btnless = (otp[1][1] >> 3) & 0x01;
 
        if (is_btnless)
                priv->flags |= ALPS_BUTTONPAD;
@@ -2493,6 +2514,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
        return 0;
 }
 
+static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
+                                      struct alps_data *priv)
+{
+       bool is_dual = false;
+
+       if (IS_SS4PLUS_DEV(priv->dev_id))
+               is_dual = (otp[0][0] >> 4) & 0x01;
+
+       if (is_dual)
+               priv->flags |= ALPS_DUALPOINT |
+                                       ALPS_DUALPOINT_WITH_PRESSURE;
+
+       return 0;
+}
+
 static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
                                    struct alps_data *priv)
 {
@@ -2508,6 +2544,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
 
        alps_update_btn_info_ss4_v2(otp, priv);
 
+       alps_update_dual_info_ss4_v2(otp, priv);
+
        return 0;
 }
 
@@ -2753,10 +2791,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
                if (alps_set_defaults_ss4_v2(psmouse, priv))
                        return -EIO;
 
-               if (priv->fw_ver[1] == 0x1)
-                       priv->flags |= ALPS_DUALPOINT |
-                                       ALPS_DUALPOINT_WITH_PRESSURE;
-
                break;
        }
 
@@ -2827,10 +2861,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
                           ec[2] >= 0x90 && ec[2] <= 0x9d) {
                        protocol = &alps_v3_protocol_data;
                } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
-                          e7[2] == 0x14 && ec[1] == 0x02) {
-                       protocol = &alps_v8_protocol_data;
-               } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
-                          e7[2] == 0x28 && ec[1] == 0x01) {
+                          (e7[2] == 0x14 || e7[2] == 0x28)) {
                        protocol = &alps_v8_protocol_data;
                } else {
                        psmouse_dbg(psmouse,
@@ -2840,7 +2871,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
        }
 
        if (priv) {
-               /* Save the Firmware version */
+               /* Save Device ID and Firmware version */
+               memcpy(priv->dev_id, e7, 3);
                memcpy(priv->fw_ver, ec, 3);
                error = alps_set_protocol(psmouse, priv, protocol);
                if (error)
index 6d279aa27cb9a10d70a2e732fe9599297883cbc0..4334f2805d93c7a3e8454a8cf0d950a14999278c 100644 (file)
@@ -54,6 +54,16 @@ enum SS4_PACKET_ID {
 
 #define SS4_MASK_NORMAL_BUTTONS                0x07
 
+#define SS4PLUS_COUNT_PER_ELECTRODE    128
+#define SS4PLUS_NUMSENSOR_XOFFSET      16
+#define SS4PLUS_NUMSENSOR_YOFFSET      5
+#define SS4PLUS_MIN_PITCH_MM           37
+
+#define IS_SS4PLUS_DEV(_b)     (((_b[0]) == 0x73) &&   \
+                                ((_b[1]) == 0x03) &&   \
+                                ((_b[2]) == 0x28)              \
+                               )
+
 #define SS4_IS_IDLE_V2(_b)     (((_b[0]) == 0x18) &&           \
                                 ((_b[1]) == 0x10) &&           \
                                 ((_b[2]) == 0x00) &&           \
@@ -283,6 +293,7 @@ struct alps_data {
        int addr_command;
        u16 proto_version;
        u8 byte0, mask0;
+       u8 dev_id[3];
        u8 fw_ver[3];
        int flags;
        int x_max;
index 352050e9031dc31ab87e7d3cdb2948b2ead7dee1..d5ab9ddef3e37eeb553307c7406adc1f2c011057 100644 (file)
@@ -218,17 +218,19 @@ static int elan_query_product(struct elan_tp_data *data)
 
 static int elan_check_ASUS_special_fw(struct elan_tp_data *data)
 {
-       if (data->ic_type != 0x0E)
-               return false;
-
-       switch (data->product_id) {
-       case 0x05 ... 0x07:
-       case 0x09:
-       case 0x13:
+       if (data->ic_type == 0x0E) {
+               switch (data->product_id) {
+               case 0x05 ... 0x07:
+               case 0x09:
+               case 0x13:
+                       return true;
+               }
+       } else if (data->ic_type == 0x08 && data->product_id == 0x26) {
+               /* ASUS EeeBook X205TA */
                return true;
-       default:
-               return false;
        }
+
+       return false;
 }
 
 static int __elan_initialize(struct elan_tp_data *data)
index 1986786133824d5b7cc815ec98efe61afd2624e2..34dfee555b201b0577e6e5fc0c58c63e7cc8cac7 100644 (file)
@@ -170,6 +170,10 @@ static int rmi_f30_config(struct rmi_function *fn)
                                rmi_get_platform_data(fn->rmi_dev);
        int error;
 
+       /* can happen if f30_data.disable is set */
+       if (!f30)
+               return 0;
+
        if (pdata->f30_data.trackstick_buttons) {
                /* Try [re-]establish link to F03. */
                f30->f03 = rmi_find_function(fn->rmi_dev, 0x03);
index 05afd16ea9c9efc0bb52efe49510444478e1e220..312bd6ca919806f2593e12814e5037469d609c0f 100644 (file)
@@ -119,6 +119,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
                },
        },
+       {
+               /* Dell Embedded Box PC 3000 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
+               },
+       },
        {
                /* OQO Model 01 */
                .matches = {
@@ -513,6 +520,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
                },
        },
+       {
+               /* TUXEDO BU1406 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
+               },
+       },
        { }
 };
 
index cd852059b99e81899f8436f31071c929eb470b83..df4bea96d7ed7d10e66478c929feb1094ff5f09c 100644 (file)
@@ -340,6 +340,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
        int error;
        int i;
 
+       if (intf->cur_altsetting->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!hanwang || !input_dev) {
index e850d7e8afbc4d22afb1bc73b2e99fc3f1cf5e8f..4d9d64908b595f9828e8e82e47e57b6b2935c07f 100644 (file)
@@ -122,6 +122,9 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
        struct input_dev *input_dev;
        int error = -ENOMEM;
 
+       if (intf->cur_altsetting->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!kbtab || !input_dev)
index aefb6e11f88a0838917b0a3b7a59dc9eae6b37f2..4c0eecae065c113a26400469d7def3c2b9bcc635 100644 (file)
@@ -527,6 +527,9 @@ static int sur40_probe(struct usb_interface *interface,
        if (iface_desc->desc.bInterfaceClass != 0xFF)
                return -ENODEV;
 
+       if (iface_desc->desc.bNumEndpoints < 5)
+               return -ENODEV;
+
        /* Use endpoint #4 (0x86). */
        endpoint = &iface_desc->endpoint[4].desc;
        if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)
index 98940d1392cb0cd19d648b6a25f2a5ba36c052d4..b17536d6e69bdbf956a61d8c3dff06351a1a51df 100644 (file)
@@ -3202,7 +3202,7 @@ static void amd_iommu_get_resv_regions(struct device *dev,
 
        region = iommu_alloc_resv_region(MSI_RANGE_START,
                                         MSI_RANGE_END - MSI_RANGE_START + 1,
-                                        0, IOMMU_RESV_RESERVED);
+                                        0, IOMMU_RESV_MSI);
        if (!region)
                return;
        list_add_tail(&region->list, head);
index 5806a6acc94ecd7543c2435558a0907ec0934ff2..591bb96047c9765fd3e0fb536d3f26ca0a5f187f 100644 (file)
@@ -1888,7 +1888,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
        int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
 
        region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
-                                        prot, IOMMU_RESV_MSI);
+                                        prot, IOMMU_RESV_SW_MSI);
        if (!region)
                return;
 
index abf6496843a617070289377ffad3fd1e119b0aa6..b493c99e17f74de338805167c3ddb104e3354b62 100644 (file)
@@ -1608,7 +1608,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
        int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
 
        region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
-                                        prot, IOMMU_RESV_MSI);
+                                        prot, IOMMU_RESV_SW_MSI);
        if (!region)
                return;
 
index a7e0821c9967e490258921238e6640723e79375d..c01bfcdb238316c049ae0dd6b4bf2d43c6c61440 100644 (file)
@@ -512,7 +512,13 @@ static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
        spin_lock_irqsave(&data->lock, flags);
        if (data->active && data->version >= MAKE_MMU_VER(3, 3)) {
                clk_enable(data->clk_master);
-               __sysmmu_tlb_invalidate_entry(data, iova, 1);
+               if (sysmmu_block(data)) {
+                       if (data->version >= MAKE_MMU_VER(5, 0))
+                               __sysmmu_tlb_invalidate(data);
+                       else
+                               __sysmmu_tlb_invalidate_entry(data, iova, 1);
+                       sysmmu_unblock(data);
+               }
                clk_disable(data->clk_master);
        }
        spin_unlock_irqrestore(&data->lock, flags);
index 238ad3447712d263ef9d67a109c2d86c03693a87..d412a313a37232997d406e53379e1466d10b93e7 100644 (file)
@@ -916,7 +916,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
                                 * which we used for the IOMMU lookup. Strictly speaking
                                 * we could do this for all PCI devices; we only need to
                                 * get the BDF# from the scope table for ACPI matches. */
-                               if (pdev->is_virtfn)
+                               if (pdev && pdev->is_virtfn)
                                        goto got_pdev;
 
                                *bus = drhd->devices[i].bus;
@@ -5249,7 +5249,7 @@ static void intel_iommu_get_resv_regions(struct device *device,
 
        reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
                                      IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
-                                     0, IOMMU_RESV_RESERVED);
+                                     0, IOMMU_RESV_MSI);
        if (!reg)
                return;
        list_add_tail(&reg->list, head);
index 1c049e2e12bf0ddacbc0e8ff9cbb09751996a549..8d6ca28c3e1f14a6c364aae89640ee6535f8f0d6 100644 (file)
@@ -422,8 +422,12 @@ static int __arm_v7s_map(struct arm_v7s_io_pgtable *data, unsigned long iova,
                        pte |= ARM_V7S_ATTR_NS_TABLE;
 
                __arm_v7s_set_pte(ptep, pte, 1, cfg);
-       } else {
+       } else if (ARM_V7S_PTE_IS_TABLE(pte, lvl)) {
                cptep = iopte_deref(pte, lvl);
+       } else {
+               /* We require an unmap first */
+               WARN_ON(!selftest_running);
+               return -EEXIST;
        }
 
        /* Rinse, repeat */
index feacc54bec683b535fcba37e47ecb46af014ef5a..f9bc6ebb8140b06c845355560fd6e5d113912073 100644 (file)
@@ -335,8 +335,12 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
                if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
                        pte |= ARM_LPAE_PTE_NSTABLE;
                __arm_lpae_set_pte(ptep, pte, cfg);
-       } else {
+       } else if (!iopte_leaf(pte, lvl)) {
                cptep = iopte_deref(pte, data);
+       } else {
+               /* We require an unmap first */
+               WARN_ON(!selftest_running);
+               return -EEXIST;
        }
 
        /* Rinse, repeat */
index 8ea14f41a979fd4e72e3a6093e5fa8d2a0eff24a..3b67144dead2e3811918af8fa44ec6e67a19c955 100644 (file)
@@ -72,6 +72,7 @@ static const char * const iommu_group_resv_type_string[] = {
        [IOMMU_RESV_DIRECT]     = "direct",
        [IOMMU_RESV_RESERVED]   = "reserved",
        [IOMMU_RESV_MSI]        = "msi",
+       [IOMMU_RESV_SW_MSI]     = "msi",
 };
 
 #define IOMMU_GROUP_ATTR(_name, _mode, _show, _store)          \
@@ -1743,8 +1744,8 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
 }
 
 struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
-                                                 size_t length,
-                                                 int prot, int type)
+                                                 size_t length, int prot,
+                                                 enum iommu_resv_type type)
 {
        struct iommu_resv_region *region;
 
index 125528f39e92c2377846f799a841e23ef1e98654..8162121bb1bcd766e06c74c7a8e6fc337a57a605 100644 (file)
@@ -262,6 +262,7 @@ config IRQ_MXS
 
 config MVEBU_ODMI
        bool
+       select GENERIC_MSI_IRQ_DOMAIN
 
 config MVEBU_PIC
        bool
index 11d12bccc4e7f10d72fa41f5464ed4d6b6f02a5f..cd20df12d63d98f0e1ae7315b135493699feca4e 100644 (file)
@@ -991,8 +991,12 @@ static void __init gic_map_single_int(struct device_node *node,
 
 static void __init gic_map_interrupts(struct device_node *node)
 {
+       gic_map_single_int(node, GIC_LOCAL_INT_WD);
+       gic_map_single_int(node, GIC_LOCAL_INT_COMPARE);
        gic_map_single_int(node, GIC_LOCAL_INT_TIMER);
        gic_map_single_int(node, GIC_LOCAL_INT_PERFCTR);
+       gic_map_single_int(node, GIC_LOCAL_INT_SWINT0);
+       gic_map_single_int(node, GIC_LOCAL_INT_SWINT1);
        gic_map_single_int(node, GIC_LOCAL_INT_FDC);
 }
 
index 67fd8ffa60a418f6538d6b358c3e3d91f4f385b6..669a4c82f1ffa4c79b5e47173536faedecf52c34 100644 (file)
@@ -321,7 +321,7 @@ static const struct of_device_id vdoa_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, vdoa_dt_ids);
 
-static const struct platform_driver vdoa_driver = {
+static struct platform_driver vdoa_driver = {
        .probe          = vdoa_probe,
        .remove         = vdoa_remove,
        .driver         = {
index cbb03768f5d73574b4d95939a08d7605e94dd6d7..0f0c389f889713ad024eda400ea1f70799710dae 100644 (file)
@@ -861,9 +861,7 @@ int gsc_prepare_addr(struct gsc_ctx *ctx, struct vb2_buffer *vb,
 
        if ((frame->fmt->pixelformat == V4L2_PIX_FMT_VYUY) ||
                (frame->fmt->pixelformat == V4L2_PIX_FMT_YVYU) ||
-               (frame->fmt->pixelformat == V4L2_PIX_FMT_NV61) ||
                (frame->fmt->pixelformat == V4L2_PIX_FMT_YVU420) ||
-               (frame->fmt->pixelformat == V4L2_PIX_FMT_NV21) ||
                (frame->fmt->pixelformat == V4L2_PIX_FMT_YVU420M))
                swap(addr->cb, addr->cr);
 
index 823608112d89c14272c9ca2f5f8ebf46ffd30383..7918b928f0589b59b52c17c8470c3e3159d33c1e 100644 (file)
@@ -632,8 +632,8 @@ static int bdisp_open(struct file *file)
 
 error_ctrls:
        bdisp_ctrls_delete(ctx);
-error_fh:
        v4l2_fh_del(&ctx->fh);
+error_fh:
        v4l2_fh_exit(&ctx->fh);
        bdisp_hw_free_nodes(ctx);
 mem_ctx:
index ab9866024ec7983d597efd157476820222ad8134..04033efe7ad5394d4fd9493ce6b790de1404666b 100644 (file)
@@ -36,16 +36,18 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 le
 int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
 {
        struct hexline *hx;
-       u8 reset;
-       int ret,pos=0;
+       u8 *buf;
+       int ret, pos = 0;
+       u16 cpu_cs_register = cypress[type].cpu_cs_register;
 
-       hx = kmalloc(sizeof(*hx), GFP_KERNEL);
-       if (!hx)
+       buf = kmalloc(sizeof(*hx), GFP_KERNEL);
+       if (!buf)
                return -ENOMEM;
+       hx = (struct hexline *)buf;
 
        /* stop the CPU */
-       reset = 1;
-       if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+       buf[0] = 1;
+       if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
                err("could not stop the USB controller CPU.");
 
        while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
@@ -61,21 +63,21 @@ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw
        }
        if (ret < 0) {
                err("firmware download failed at %d with %d",pos,ret);
-               kfree(hx);
+               kfree(buf);
                return ret;
        }
 
        if (ret == 0) {
                /* restart the CPU */
-               reset = 0;
-               if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
+               buf[0] = 0;
+               if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
                        err("could not restart the USB controller CPU.");
                        ret = -EINVAL;
                }
        } else
                ret = -EIO;
 
-       kfree(hx);
+       kfree(buf);
 
        return ret;
 }
index 5457c361ad586424050c98958bdefd22a4c17db7..bf0fe0137dfed2c893001abb8cfe8b83861dae08 100644 (file)
@@ -1947,9 +1947,7 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev,
        if (!of_property_read_u32(child, "dma-channel", &val))
                gpmc_onenand_data->dma_channel = val;
 
-       gpmc_onenand_init(gpmc_onenand_data);
-
-       return 0;
+       return gpmc_onenand_init(gpmc_onenand_data);
 }
 #else
 static int gpmc_probe_onenand_child(struct platform_device *pdev,
index 91f645992c9416ab07e765a05c006143fb15a17f..b27ea98b781f77747c010f90f20d9da6883a3070 100644 (file)
@@ -1792,15 +1792,14 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
 
        /* If we're permanently dead, give up. */
        if (state == pci_channel_io_perm_failure) {
-               /* Tell the AFU drivers; but we don't care what they
-                * say, we're going away.
-                */
                for (i = 0; i < adapter->slices; i++) {
                        afu = adapter->afu[i];
-                       /* Only participate in EEH if we are on a virtual PHB */
-                       if (afu->phb == NULL)
-                               return PCI_ERS_RESULT_NONE;
-                       cxl_vphb_error_detected(afu, state);
+                       /*
+                        * Tell the AFU drivers; but we don't care what they
+                        * say, we're going away.
+                        */
+                       if (afu->phb != NULL)
+                               cxl_vphb_error_detected(afu, state);
                }
                return PCI_ERS_RESULT_DISCONNECT;
        }
index 3600c9993a9830504d0cc5bcd61c4b8f19376762..29f2daed37e07b1e1359a2d36ff54bd04208233a 100644 (file)
@@ -112,11 +112,9 @@ struct mkhi_msg {
 
 static int mei_osver(struct mei_cl_device *cldev)
 {
-       int ret;
        const size_t size = sizeof(struct mkhi_msg_hdr) +
                            sizeof(struct mkhi_fwcaps) +
                            sizeof(struct mei_os_ver);
-       size_t length = 8;
        char buf[size];
        struct mkhi_msg *req;
        struct mkhi_fwcaps *fwcaps;
@@ -137,15 +135,7 @@ static int mei_osver(struct mei_cl_device *cldev)
        os_ver = (struct mei_os_ver *)fwcaps->data;
        os_ver->os_type = OSTYPE_LINUX;
 
-       ret = __mei_cl_send(cldev->cl, buf, size, mode);
-       if (ret < 0)
-               return ret;
-
-       ret = __mei_cl_recv(cldev->cl, buf, length, 0);
-       if (ret < 0)
-               return ret;
-
-       return 0;
+       return __mei_cl_send(cldev->cl, buf, size, mode);
 }
 
 static void mei_mkhi_fix(struct mei_cl_device *cldev)
@@ -160,7 +150,7 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev)
                return;
 
        ret = mei_osver(cldev);
-       if (ret)
+       if (ret < 0)
                dev_err(&cldev->dev, "OS version command failed %d\n", ret);
 
        mei_cldev_disable(cldev);
index cfb1cdf176fa9001e83894c63c9eb6480516d230..13c55b8f9261861c20710c4ce039c0d605937909 100644 (file)
@@ -124,8 +124,6 @@ int mei_reset(struct mei_device *dev)
 
        mei_clear_interrupts(dev);
 
-       mei_synchronize_irq(dev);
-
        /* we're already in reset, cancel the init timer
         * if the reset was called due the hbm protocol error
         * we need to call it before hw start
@@ -304,6 +302,9 @@ static void mei_reset_work(struct work_struct *work)
                container_of(work, struct mei_device,  reset_work);
        int ret;
 
+       mei_clear_interrupts(dev);
+       mei_synchronize_irq(dev);
+
        mutex_lock(&dev->device_lock);
 
        ret = mei_reset(dev);
@@ -328,6 +329,9 @@ void mei_stop(struct mei_device *dev)
 
        mei_cancel_work(dev);
 
+       mei_clear_interrupts(dev);
+       mei_synchronize_irq(dev);
+
        mutex_lock(&dev->device_lock);
 
        dev->dev_state = MEI_DEV_POWER_DOWN;
index 9d659542a335b444914f2ead245f0975ac970a2b..dad5abee656ef550b0ac041e354e2c7ef89164e3 100644 (file)
@@ -566,10 +566,10 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
         */
        error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS,
                        PCI_IRQ_MSIX);
-       if (error) {
+       if (error < 0) {
                error = pci_alloc_irq_vectors(pdev, 1, 1,
                                PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
-               if (error)
+               if (error < 0)
                        goto err_remove_bitmap;
        } else {
                vmci_dev->exclusive_vectors = true;
index 1621fa08e2069298f6a8438c8babdf11ae4a817c..ff3da960c4736147b2c1348681412953508ac49b 100644 (file)
@@ -1560,11 +1560,8 @@ static bool mmc_blk_rw_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
                               struct mmc_blk_request *brq, struct request *req,
                               bool old_req_pending)
 {
-       struct mmc_queue_req *mq_rq;
        bool req_pending;
 
-       mq_rq = container_of(brq, struct mmc_queue_req, brq);
-
        /*
         * If this is an SD card and we're writing, we can first
         * mark the known good sectors as ok.
@@ -1701,7 +1698,8 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req)
                case MMC_BLK_CMD_ERR:
                        req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending);
                        if (mmc_blk_reset(md, card->host, type)) {
-                               mmc_blk_rw_cmd_abort(card, old_req);
+                               if (req_pending)
+                                       mmc_blk_rw_cmd_abort(card, old_req);
                                mmc_blk_rw_try_restart(mq, new_req);
                                return;
                        }
@@ -1817,6 +1815,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                mmc_blk_issue_flush(mq, req);
        } else {
                mmc_blk_issue_rw_rq(mq, req);
+               card->host->context_info.is_waiting_last_req = false;
        }
 
 out:
index 7fd722868875f396e3e4e8147774913ab860b0e2..b502601df228156c60e03e3ddabd64006bd515f7 100644 (file)
@@ -1730,7 +1730,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                err = mmc_select_hs400(card);
                if (err)
                        goto free_card;
-       } else {
+       } else if (!mmc_card_hs400es(card)) {
                /* Select the desired bus width optionally */
                err = mmc_select_bus_width(card);
                if (err > 0 && mmc_card_hs(card)) {
index 8e32580c12b520017eb73af884f1b04607c3a78b..b235d8da0602a84e78ff8a4478016f642c67bf43 100644 (file)
@@ -580,7 +580,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
                }
        }
        sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-                       (mode << 8) | (div % 0xff));
+                     (mode << 8) | div);
        sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
        while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
                cpu_relax();
@@ -1559,7 +1559,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
        host->src_clk_freq = clk_get_rate(host->src_clk);
        /* Set host parameters to mmc */
        mmc->ops = &mt_msdc_ops;
-       mmc->f_min = host->src_clk_freq / (4 * 255);
+       mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
 
        mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
        /* MMC core transfer sizes tunable parameters */
index 410a55b1c25fe5f2ef32ff8f2d26c4c3286f4b71..1cfd7f90033944c6a6441aaf7256b1ce44350354 100644 (file)
 #include "sdhci-pltfm.h"
 #include <linux/of.h>
 
-#define SDHCI_ARASAN_CLK_CTRL_OFFSET   0x2c
 #define SDHCI_ARASAN_VENDOR_REGISTER   0x78
 
 #define VENDOR_ENHANCED_STROBE         BIT(0)
-#define CLK_CTRL_TIMEOUT_SHIFT         16
-#define CLK_CTRL_TIMEOUT_MASK          (0xf << CLK_CTRL_TIMEOUT_SHIFT)
-#define CLK_CTRL_TIMEOUT_MIN_EXP       13
 
 #define PHY_CLK_TOO_SLOW_HZ            400000
 
@@ -163,15 +159,15 @@ static int sdhci_arasan_syscon_write(struct sdhci_host *host,
 
 static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 {
-       u32 div;
        unsigned long freq;
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 
-       div = readl(host->ioaddr + SDHCI_ARASAN_CLK_CTRL_OFFSET);
-       div = (div & CLK_CTRL_TIMEOUT_MASK) >> CLK_CTRL_TIMEOUT_SHIFT;
+       /* SDHCI timeout clock is in kHz */
+       freq = DIV_ROUND_UP(clk_get_rate(pltfm_host->clk), 1000);
 
-       freq = clk_get_rate(pltfm_host->clk);
-       freq /= 1 << (CLK_CTRL_TIMEOUT_MIN_EXP + div);
+       /* or in MHz */
+       if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
+               freq = DIV_ROUND_UP(freq, 1000);
 
        return freq;
 }
index 2f9ad213377a2ccb9091693ba749266fa4b420c4..d5430ed02a67896616bd1371a22f51bb59be8ee2 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "sdhci-pltfm.h"
 
+#define SDMMC_MC1R     0x204
+#define                SDMMC_MC1R_DDR          BIT(3)
 #define SDMMC_CACR     0x230
 #define                SDMMC_CACR_CAPWREN      BIT(0)
 #define                SDMMC_CACR_KEY          (0x46 << 8)
@@ -85,11 +87,37 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
 
+/*
+ * In this specific implementation of the SDHCI controller, the power register
+ * needs to have a valid voltage set even when the power supply is managed by
+ * an external regulator.
+ */
+static void sdhci_at91_set_power(struct sdhci_host *host, unsigned char mode,
+                    unsigned short vdd)
+{
+       if (!IS_ERR(host->mmc->supply.vmmc)) {
+               struct mmc_host *mmc = host->mmc;
+
+               spin_unlock_irq(&host->lock);
+               mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+               spin_lock_irq(&host->lock);
+       }
+       sdhci_set_power_noreg(host, mode, vdd);
+}
+
+void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing)
+{
+       if (timing == MMC_TIMING_MMC_DDR52)
+               sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R);
+       sdhci_set_uhs_signaling(host, timing);
+}
+
 static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
        .set_clock              = sdhci_at91_set_clock,
        .set_bus_width          = sdhci_set_bus_width,
        .reset                  = sdhci_reset,
-       .set_uhs_signaling      = sdhci_set_uhs_signaling,
+       .set_uhs_signaling      = sdhci_at91_set_uhs_signaling,
+       .set_power              = sdhci_at91_set_power,
 };
 
 static const struct sdhci_pltfm_data soc_data_sama5d2 = {
index 982b3e349426141710abef87f75819c518bf4a45..86560d590786f3f62a65c8668f2e601fd27b75be 100644 (file)
@@ -451,6 +451,8 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
        if (mode == MMC_POWER_OFF)
                return;
 
+       spin_unlock_irq(&host->lock);
+
        /*
         * Bus power might not enable after D3 -> D0 transition due to the
         * present state not yet having propagated. Retry for up to 2ms.
@@ -463,6 +465,8 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
                reg |= SDHCI_POWER_ON;
                sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
        }
+
+       spin_lock_irq(&host->lock);
 }
 
 static const struct sdhci_ops sdhci_intel_byt_ops = {
index 6fdd7a70f229b8bfd08f6d8b9df509dd0fec2bbd..63bc33a54d0dd8e63b50197611be31aae6f288fc 100644 (file)
@@ -1362,7 +1362,9 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
                        return;
                }
                timeout--;
-               mdelay(1);
+               spin_unlock_irq(&host->lock);
+               usleep_range(900, 1100);
+               spin_lock_irq(&host->lock);
        }
 
        clk |= SDHCI_CLOCK_CARD_EN;
@@ -1828,6 +1830,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
        struct sdhci_host *host = mmc_priv(mmc);
        unsigned long flags;
 
+       if (enable)
+               pm_runtime_get_noresume(host->mmc->parent);
+
        spin_lock_irqsave(&host->lock, flags);
        if (enable)
                host->flags |= SDHCI_SDIO_IRQ_ENABLED;
@@ -1836,6 +1841,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 
        sdhci_enable_sdio_irq_nolock(host, enable);
        spin_unlock_irqrestore(&host->lock, flags);
+
+       if (!enable)
+               pm_runtime_put_noidle(host->mmc->parent);
 }
 
 static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
index d2c386f09d69f4edd20b0ac778624b40f826f1e3..1d843357422e8a398590aa1bcd883ab644b5d56e 100644 (file)
@@ -426,6 +426,9 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
        struct ushc_data *ushc;
        int ret;
 
+       if (intf->cur_altsetting->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
        if (mmc == NULL)
                return -ENOMEM;
index 8a280e7d66bddc998763288a5756b2ae6a7f70bc..127adbeefb105cc031f3782b534d175f29fb7143 100644 (file)
 #define XP_ECC_CNT1_DESC_DED_WIDTH             8
 #define XP_ECC_CNT1_DESC_SEC_INDEX             0
 #define XP_ECC_CNT1_DESC_SEC_WIDTH             8
-#define XP_ECC_IER_DESC_DED_INDEX              0
+#define XP_ECC_IER_DESC_DED_INDEX              5
 #define XP_ECC_IER_DESC_DED_WIDTH              1
-#define XP_ECC_IER_DESC_SEC_INDEX              1
+#define XP_ECC_IER_DESC_SEC_INDEX              4
 #define XP_ECC_IER_DESC_SEC_WIDTH              1
-#define XP_ECC_IER_RX_DED_INDEX                        2
+#define XP_ECC_IER_RX_DED_INDEX                        3
 #define XP_ECC_IER_RX_DED_WIDTH                        1
-#define XP_ECC_IER_RX_SEC_INDEX                        3
+#define XP_ECC_IER_RX_SEC_INDEX                        2
 #define XP_ECC_IER_RX_SEC_WIDTH                        1
-#define XP_ECC_IER_TX_DED_INDEX                        4
+#define XP_ECC_IER_TX_DED_INDEX                        1
 #define XP_ECC_IER_TX_DED_WIDTH                        1
-#define XP_ECC_IER_TX_SEC_INDEX                        5
+#define XP_ECC_IER_TX_SEC_INDEX                        0
 #define XP_ECC_IER_TX_SEC_WIDTH                        1
-#define XP_ECC_ISR_DESC_DED_INDEX              0
+#define XP_ECC_ISR_DESC_DED_INDEX              5
 #define XP_ECC_ISR_DESC_DED_WIDTH              1
-#define XP_ECC_ISR_DESC_SEC_INDEX              1
+#define XP_ECC_ISR_DESC_SEC_INDEX              4
 #define XP_ECC_ISR_DESC_SEC_WIDTH              1
-#define XP_ECC_ISR_RX_DED_INDEX                        2
+#define XP_ECC_ISR_RX_DED_INDEX                        3
 #define XP_ECC_ISR_RX_DED_WIDTH                        1
-#define XP_ECC_ISR_RX_SEC_INDEX                        3
+#define XP_ECC_ISR_RX_SEC_INDEX                        2
 #define XP_ECC_ISR_RX_SEC_WIDTH                        1
-#define XP_ECC_ISR_TX_DED_INDEX                        4
+#define XP_ECC_ISR_TX_DED_INDEX                        1
 #define XP_ECC_ISR_TX_DED_WIDTH                        1
-#define XP_ECC_ISR_TX_SEC_INDEX                        5
+#define XP_ECC_ISR_TX_SEC_INDEX                        0
 #define XP_ECC_ISR_TX_SEC_WIDTH                        1
 #define XP_I2C_MUTEX_BUSY_INDEX                        31
 #define XP_I2C_MUTEX_BUSY_WIDTH                        1
 #define RX_PACKET_ATTRIBUTES_CSUM_DONE_WIDTH   1
 #define RX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX   1
 #define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH   1
-#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX  2
-#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH  1
+#define RX_PACKET_ATTRIBUTES_LAST_INDEX                2
+#define RX_PACKET_ATTRIBUTES_LAST_WIDTH                1
 #define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_INDEX        3
 #define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_WIDTH        1
 #define RX_PACKET_ATTRIBUTES_CONTEXT_INDEX     4
 #define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH   1
 #define RX_PACKET_ATTRIBUTES_RSS_HASH_INDEX    6
 #define RX_PACKET_ATTRIBUTES_RSS_HASH_WIDTH    1
+#define RX_PACKET_ATTRIBUTES_FIRST_INDEX       7
+#define RX_PACKET_ATTRIBUTES_FIRST_WIDTH       1
 
 #define RX_NORMAL_DESC0_OVT_INDEX              0
 #define RX_NORMAL_DESC0_OVT_WIDTH              16
index 937f37a5dcb2cded9963b3732bddb08557ad50ba..24a687ce4388182716438770c49e2dca7ff81114 100644 (file)
@@ -1896,10 +1896,15 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
 
        /* Get the header length */
        if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD)) {
+               XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+                              FIRST, 1);
                rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2,
                                                      RX_NORMAL_DESC2, HL);
                if (rdata->rx.hdr_len)
                        pdata->ext_stats.rx_split_header_packets++;
+       } else {
+               XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+                              FIRST, 0);
        }
 
        /* Get the RSS hash */
@@ -1922,19 +1927,16 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
                }
        }
 
-       /* Get the packet length */
-       rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
-
-       if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) {
-               /* Not all the data has been transferred for this packet */
-               XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-                              INCOMPLETE, 1);
+       /* Not all the data has been transferred for this packet */
+       if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD))
                return 0;
-       }
 
        /* This is the last of the data for this packet */
        XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-                      INCOMPLETE, 0);
+                      LAST, 1);
+
+       /* Get the packet length */
+       rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
 
        /* Set checksum done indicator as appropriate */
        if (netdev->features & NETIF_F_RXCSUM)
index ffea9859f5a72be1edbfdb1d52d2c70a0df2b19e..a713abd9d03e63aea8aab96c4f5569d1d6b3e44d 100644 (file)
@@ -1971,13 +1971,12 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
 {
        struct sk_buff *skb;
        u8 *packet;
-       unsigned int copy_len;
 
        skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len);
        if (!skb)
                return NULL;
 
-       /* Start with the header buffer which may contain just the header
+       /* Pull in the header buffer which may contain just the header
         * or the header plus data
         */
        dma_sync_single_range_for_cpu(pdata->dev, rdata->rx.hdr.dma_base,
@@ -1986,30 +1985,49 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
 
        packet = page_address(rdata->rx.hdr.pa.pages) +
                 rdata->rx.hdr.pa.pages_offset;
-       copy_len = (rdata->rx.hdr_len) ? rdata->rx.hdr_len : len;
-       copy_len = min(rdata->rx.hdr.dma_len, copy_len);
-       skb_copy_to_linear_data(skb, packet, copy_len);
-       skb_put(skb, copy_len);
-
-       len -= copy_len;
-       if (len) {
-               /* Add the remaining data as a frag */
-               dma_sync_single_range_for_cpu(pdata->dev,
-                                             rdata->rx.buf.dma_base,
-                                             rdata->rx.buf.dma_off,
-                                             rdata->rx.buf.dma_len,
-                                             DMA_FROM_DEVICE);
-
-               skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
-                               rdata->rx.buf.pa.pages,
-                               rdata->rx.buf.pa.pages_offset,
-                               len, rdata->rx.buf.dma_len);
-               rdata->rx.buf.pa.pages = NULL;
-       }
+       skb_copy_to_linear_data(skb, packet, len);
+       skb_put(skb, len);
 
        return skb;
 }
 
+static unsigned int xgbe_rx_buf1_len(struct xgbe_ring_data *rdata,
+                                    struct xgbe_packet_data *packet)
+{
+       /* Always zero if not the first descriptor */
+       if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, FIRST))
+               return 0;
+
+       /* First descriptor with split header, return header length */
+       if (rdata->rx.hdr_len)
+               return rdata->rx.hdr_len;
+
+       /* First descriptor but not the last descriptor and no split header,
+        * so the full buffer was used
+        */
+       if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, LAST))
+               return rdata->rx.hdr.dma_len;
+
+       /* First descriptor and last descriptor and no split header, so
+        * calculate how much of the buffer was used
+        */
+       return min_t(unsigned int, rdata->rx.hdr.dma_len, rdata->rx.len);
+}
+
+static unsigned int xgbe_rx_buf2_len(struct xgbe_ring_data *rdata,
+                                    struct xgbe_packet_data *packet,
+                                    unsigned int len)
+{
+       /* Always the full buffer if not the last descriptor */
+       if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, LAST))
+               return rdata->rx.buf.dma_len;
+
+       /* Last descriptor so calculate how much of the buffer was used
+        * for the last bit of data
+        */
+       return rdata->rx.len - len;
+}
+
 static int xgbe_tx_poll(struct xgbe_channel *channel)
 {
        struct xgbe_prv_data *pdata = channel->pdata;
@@ -2092,8 +2110,8 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
        struct napi_struct *napi;
        struct sk_buff *skb;
        struct skb_shared_hwtstamps *hwtstamps;
-       unsigned int incomplete, error, context_next, context;
-       unsigned int len, rdesc_len, max_len;
+       unsigned int last, error, context_next, context;
+       unsigned int len, buf1_len, buf2_len, max_len;
        unsigned int received = 0;
        int packet_count = 0;
 
@@ -2103,7 +2121,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
        if (!ring)
                return 0;
 
-       incomplete = 0;
+       last = 0;
        context_next = 0;
 
        napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi;
@@ -2137,9 +2155,8 @@ read_again:
                received++;
                ring->cur++;
 
-               incomplete = XGMAC_GET_BITS(packet->attributes,
-                                           RX_PACKET_ATTRIBUTES,
-                                           INCOMPLETE);
+               last = XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+                                     LAST);
                context_next = XGMAC_GET_BITS(packet->attributes,
                                              RX_PACKET_ATTRIBUTES,
                                              CONTEXT_NEXT);
@@ -2148,7 +2165,7 @@ read_again:
                                         CONTEXT);
 
                /* Earlier error, just drain the remaining data */
-               if ((incomplete || context_next) && error)
+               if ((!last || context_next) && error)
                        goto read_again;
 
                if (error || packet->errors) {
@@ -2160,16 +2177,22 @@ read_again:
                }
 
                if (!context) {
-                       /* Length is cumulative, get this descriptor's length */
-                       rdesc_len = rdata->rx.len - len;
-                       len += rdesc_len;
+                       /* Get the data length in the descriptor buffers */
+                       buf1_len = xgbe_rx_buf1_len(rdata, packet);
+                       len += buf1_len;
+                       buf2_len = xgbe_rx_buf2_len(rdata, packet, len);
+                       len += buf2_len;
 
-                       if (rdesc_len && !skb) {
+                       if (!skb) {
                                skb = xgbe_create_skb(pdata, napi, rdata,
-                                                     rdesc_len);
-                               if (!skb)
+                                                     buf1_len);
+                               if (!skb) {
                                        error = 1;
-                       } else if (rdesc_len) {
+                                       goto skip_data;
+                               }
+                       }
+
+                       if (buf2_len) {
                                dma_sync_single_range_for_cpu(pdata->dev,
                                                        rdata->rx.buf.dma_base,
                                                        rdata->rx.buf.dma_off,
@@ -2179,13 +2202,14 @@ read_again:
                                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                                rdata->rx.buf.pa.pages,
                                                rdata->rx.buf.pa.pages_offset,
-                                               rdesc_len,
+                                               buf2_len,
                                                rdata->rx.buf.dma_len);
                                rdata->rx.buf.pa.pages = NULL;
                        }
                }
 
-               if (incomplete || context_next)
+skip_data:
+               if (!last || context_next)
                        goto read_again;
 
                if (!skb)
@@ -2243,7 +2267,7 @@ next_packet:
        }
 
        /* Check if we need to save state before leaving */
-       if (received && (incomplete || context_next)) {
+       if (received && (!last || context_next)) {
                rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
                rdata->state_saved = 1;
                rdata->state.skb = skb;
index dad63623be6a93672974fb43ee50b518fff59ab5..d05fbfdce5e52e640042f36ba3eb831a3a42ce8a 100644 (file)
@@ -98,6 +98,7 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
 
        if (err < 0)
                goto err_exit;
+       ndev->mtu = new_mtu;
 
        if (netif_running(ndev)) {
                aq_ndev_close(ndev);
index 1093ea18823a32fc6cb441ab45b0b3a9a82fecc2..0592a0330cf0d601f4b9a27f0d349aeccc66f833 100644 (file)
@@ -137,6 +137,7 @@ static struct aq_hw_caps_s hw_atl_a0_hw_caps_ = {
        .tx_rings = HW_ATL_A0_TX_RINGS,
        .rx_rings = HW_ATL_A0_RX_RINGS,
        .hw_features = NETIF_F_HW_CSUM |
+                       NETIF_F_RXCSUM |
                        NETIF_F_RXHASH |
                        NETIF_F_SG |
                        NETIF_F_TSO,
index 8bdee3ddd5a0bd9044063caf5686fefcc6b5465f..f3957e9303405c3f26c9f7f7d6507009d5804534 100644 (file)
@@ -188,6 +188,7 @@ static struct aq_hw_caps_s hw_atl_b0_hw_caps_ = {
        .tx_rings = HW_ATL_B0_TX_RINGS,
        .rx_rings = HW_ATL_B0_RX_RINGS,
        .hw_features = NETIF_F_HW_CSUM |
+                       NETIF_F_RXCSUM |
                        NETIF_F_RXHASH |
                        NETIF_F_SG |
                        NETIF_F_TSO |
index 69015fa50f2096c77999539179446e5ab38fa759..365895ed3c3e240584da21fad2caebc6384482d5 100644 (file)
@@ -3481,7 +3481,8 @@ static int bcmgenet_suspend(struct device *d)
 
        bcmgenet_netif_stop(dev);
 
-       phy_suspend(priv->phydev);
+       if (!device_may_wakeup(d))
+               phy_suspend(priv->phydev);
 
        netif_device_detach(dev);
 
@@ -3578,7 +3579,8 @@ static int bcmgenet_resume(struct device *d)
 
        netif_device_attach(dev);
 
-       phy_resume(priv->phydev);
+       if (!device_may_wakeup(d))
+               phy_resume(priv->phydev);
 
        if (priv->eee.eee_enabled)
                bcmgenet_eee_enable_set(dev, true);
index e87607621e62a076104d67046a10603305d66ecf..2f9281936f0e434a328e1c716a29a76be2d9090c 100644 (file)
@@ -220,20 +220,6 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
        udelay(60);
 }
 
-static void bcmgenet_internal_phy_setup(struct net_device *dev)
-{
-       struct bcmgenet_priv *priv = netdev_priv(dev);
-       u32 reg;
-
-       /* Power up PHY */
-       bcmgenet_phy_power_set(dev, true);
-       /* enable APD */
-       reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-       reg |= EXT_PWR_DN_EN_LD;
-       bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
-       bcmgenet_mii_reset(dev);
-}
-
 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
 {
        u32 reg;
@@ -281,7 +267,6 @@ int bcmgenet_mii_config(struct net_device *dev)
 
                if (priv->internal_phy) {
                        phy_name = "internal PHY";
-                       bcmgenet_internal_phy_setup(dev);
                } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
                        phy_name = "MoCA";
                        bcmgenet_moca_phy_setup(priv);
index 05c1c1dd7751bd720fac026876c7fcf7392eca03..cebfe3bd086e36f60f717579f03037058b1d1d9e 100644 (file)
@@ -325,7 +325,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
                return PTR_ERR(kern_buf);
 
        rc = sscanf(kern_buf, "%x:%x", &addr, &len);
-       if (rc < 2) {
+       if (rc < 2 || len > UINT_MAX >> 2) {
                netdev_warn(bnad->netdev, "failed to read user buffer\n");
                kfree(kern_buf);
                return -EINVAL;
index 5f11b4dc95d2d1b271c9a47b3e890ef4662af2e4..b23d6545f83562b8d9d12b4a885514dfd5257743 100644 (file)
@@ -1257,6 +1257,7 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
                                release_sub_crq_queue(adapter,
                                                      adapter->tx_scrq[i]);
                        }
+               kfree(adapter->tx_scrq);
                adapter->tx_scrq = NULL;
        }
 
@@ -1269,6 +1270,7 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
                                release_sub_crq_queue(adapter,
                                                      adapter->rx_scrq[i]);
                        }
+               kfree(adapter->rx_scrq);
                adapter->rx_scrq = NULL;
        }
 }
index e8c105164931f31ff0cf5ed12acef455d0010eda..0e0fa70305659521ed50d1cf1bc40fd38aa3ad04 100644 (file)
@@ -2305,6 +2305,17 @@ static int sync_toggles(struct mlx4_dev *dev)
                rd_toggle = swab32(readl(&priv->mfunc.comm->slave_read));
                if (wr_toggle == 0xffffffff || rd_toggle == 0xffffffff) {
                        /* PCI might be offline */
+
+                       /* If device removal has been requested,
+                        * do not continue retrying.
+                        */
+                       if (dev->persist->interface_state &
+                           MLX4_INTERFACE_STATE_NOWAIT) {
+                               mlx4_warn(dev,
+                                         "communication channel is offline\n");
+                               return -EIO;
+                       }
+
                        msleep(100);
                        wr_toggle = swab32(readl(&priv->mfunc.comm->
                                           slave_write));
index 21377c315083b686d8db25033583dd020d7e50a6..703205475524d689cd2762f2d2ce3abfd2b6ebcb 100644 (file)
@@ -1940,6 +1940,14 @@ static int mlx4_comm_check_offline(struct mlx4_dev *dev)
                               (u32)(1 << COMM_CHAN_OFFLINE_OFFSET));
                if (!offline_bit)
                        return 0;
+
+               /* If device removal has been requested,
+                * do not continue retrying.
+                */
+               if (dev->persist->interface_state &
+                   MLX4_INTERFACE_STATE_NOWAIT)
+                       break;
+
                /* There are cases as part of AER/Reset flow that PF needs
                 * around 100 msec to load. We therefore sleep for 100 msec
                 * to allow other tasks to make use of that CPU during this
@@ -3955,6 +3963,9 @@ static void mlx4_remove_one(struct pci_dev *pdev)
        struct devlink *devlink = priv_to_devlink(priv);
        int active_vfs = 0;
 
+       if (mlx4_is_slave(dev))
+               persist->interface_state |= MLX4_INTERFACE_STATE_NOWAIT;
+
        mutex_lock(&persist->interface_state_mutex);
        persist->interface_state |= MLX4_INTERFACE_STATE_DELETION;
        mutex_unlock(&persist->interface_state_mutex);
index caa837e5e2b991fc3666776d2050fe20b1c6c7f6..a380353a78c2d349291e33aa3a1ef7af837111c2 100644 (file)
@@ -361,6 +361,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
        case MLX5_CMD_OP_QUERY_VPORT_COUNTER:
        case MLX5_CMD_OP_ALLOC_Q_COUNTER:
        case MLX5_CMD_OP_QUERY_Q_COUNTER:
+       case MLX5_CMD_OP_SET_RATE_LIMIT:
+       case MLX5_CMD_OP_QUERY_RATE_LIMIT:
        case MLX5_CMD_OP_ALLOC_PD:
        case MLX5_CMD_OP_ALLOC_UAR:
        case MLX5_CMD_OP_CONFIG_INT_MODERATION:
@@ -497,6 +499,8 @@ const char *mlx5_command_str(int command)
        MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER);
        MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER);
        MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER);
+       MLX5_COMMAND_STR_CASE(SET_RATE_LIMIT);
+       MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT);
        MLX5_COMMAND_STR_CASE(ALLOC_PD);
        MLX5_COMMAND_STR_CASE(DEALLOC_PD);
        MLX5_COMMAND_STR_CASE(ALLOC_UAR);
index f6a6ded204f61cda53c6233d80b3db7cde678c6e..dc52053128bc752ccd398449330c24c0bdf8b3a1 100644 (file)
@@ -928,10 +928,6 @@ void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv);
 int mlx5e_attach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
 void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
 u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout);
-void mlx5e_add_vxlan_port(struct net_device *netdev,
-                         struct udp_tunnel_info *ti);
-void mlx5e_del_vxlan_port(struct net_device *netdev,
-                         struct udp_tunnel_info *ti);
 
 int mlx5e_get_offload_stats(int attr_id, const struct net_device *dev,
                            void *sp);
index 8ef64c4db2c21ad6a752338cb32b054a5e5f3968..66c133757a5ee8daae122e93322306b1c5c44336 100644 (file)
@@ -3100,8 +3100,8 @@ static int mlx5e_get_vf_stats(struct net_device *dev,
                                            vf_stats);
 }
 
-void mlx5e_add_vxlan_port(struct net_device *netdev,
-                         struct udp_tunnel_info *ti)
+static void mlx5e_add_vxlan_port(struct net_device *netdev,
+                                struct udp_tunnel_info *ti)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
 
@@ -3114,8 +3114,8 @@ void mlx5e_add_vxlan_port(struct net_device *netdev,
        mlx5e_vxlan_queue_work(priv, ti->sa_family, be16_to_cpu(ti->port), 1);
 }
 
-void mlx5e_del_vxlan_port(struct net_device *netdev,
-                         struct udp_tunnel_info *ti)
+static void mlx5e_del_vxlan_port(struct net_device *netdev,
+                                struct udp_tunnel_info *ti)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
 
index 2c864574a9d5faeaa3b329f3bc0ab0d4e0cc7b55..f621373bd7a564aca3ddd1247117467daffc72df 100644 (file)
@@ -393,8 +393,6 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
        .ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
        .ndo_setup_tc            = mlx5e_rep_ndo_setup_tc,
        .ndo_get_stats64         = mlx5e_rep_get_stats,
-       .ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
-       .ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
        .ndo_has_offload_stats   = mlx5e_has_offload_stats,
        .ndo_get_offload_stats   = mlx5e_get_offload_stats,
 };
index 3d371688fbbbf3544170468840829e15095ea3a0..bafcb349a50c6d3809aa329d43382e51dbd3ffe4 100644 (file)
@@ -601,6 +601,10 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
        if (lro_num_seg > 1) {
                mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
                skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg);
+               /* Subtract one since we already counted this as one
+                * "regular" packet in mlx5e_complete_rx_cqe()
+                */
+               rq->stats.packets += lro_num_seg - 1;
                rq->stats.lro_packets++;
                rq->stats.lro_bytes += cqe_bcnt;
        }
index 79481f4cf264320648d0ea9c335cf6a3b23faf01..fade7233dac5256cb69d0fc67b0c3cb1a4444da5 100644 (file)
@@ -133,6 +133,23 @@ err_create_ft:
        return rule;
 }
 
+static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
+                                 struct mlx5e_tc_flow *flow)
+{
+       struct mlx5_fc *counter = NULL;
+
+       if (!IS_ERR(flow->rule)) {
+               counter = mlx5_flow_rule_counter(flow->rule);
+               mlx5_del_flow_rules(flow->rule);
+               mlx5_fc_destroy(priv->mdev, counter);
+       }
+
+       if (!mlx5e_tc_num_filters(priv) && (priv->fs.tc.t)) {
+               mlx5_destroy_flow_table(priv->fs.tc.t);
+               priv->fs.tc.t = NULL;
+       }
+}
+
 static struct mlx5_flow_handle *
 mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
                      struct mlx5_flow_spec *spec,
@@ -149,7 +166,24 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 }
 
 static void mlx5e_detach_encap(struct mlx5e_priv *priv,
-                              struct mlx5e_tc_flow *flow) {
+                              struct mlx5e_tc_flow *flow);
+
+static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
+                                 struct mlx5e_tc_flow *flow)
+{
+       struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+
+       mlx5_eswitch_del_offloaded_rule(esw, flow->rule, flow->attr);
+
+       mlx5_eswitch_del_vlan_action(esw, flow->attr);
+
+       if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
+               mlx5e_detach_encap(priv, flow);
+}
+
+static void mlx5e_detach_encap(struct mlx5e_priv *priv,
+                              struct mlx5e_tc_flow *flow)
+{
        struct list_head *next = flow->encap.next;
 
        list_del(&flow->encap);
@@ -173,25 +207,10 @@ static void mlx5e_detach_encap(struct mlx5e_priv *priv,
 static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
                              struct mlx5e_tc_flow *flow)
 {
-       struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
-       struct mlx5_fc *counter = NULL;
-
-       if (!IS_ERR(flow->rule)) {
-               counter = mlx5_flow_rule_counter(flow->rule);
-               mlx5_del_flow_rules(flow->rule);
-               mlx5_fc_destroy(priv->mdev, counter);
-       }
-
-       if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
-               mlx5_eswitch_del_vlan_action(esw, flow->attr);
-               if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
-                       mlx5e_detach_encap(priv, flow);
-       }
-
-       if (!mlx5e_tc_num_filters(priv) && (priv->fs.tc.t)) {
-               mlx5_destroy_flow_table(priv->fs.tc.t);
-               priv->fs.tc.t = NULL;
-       }
+       if (flow->flags & MLX5E_TC_FLOW_ESWITCH)
+               mlx5e_tc_del_fdb_flow(priv, flow);
+       else
+               mlx5e_tc_del_nic_flow(priv, flow);
 }
 
 static void parse_vxlan_attr(struct mlx5_flow_spec *spec,
@@ -248,12 +267,15 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
                        skb_flow_dissector_target(f->dissector,
                                                  FLOW_DISSECTOR_KEY_ENC_PORTS,
                                                  f->mask);
+               struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+               struct net_device *up_dev = mlx5_eswitch_get_uplink_netdev(esw);
+               struct mlx5e_priv *up_priv = netdev_priv(up_dev);
 
                /* Full udp dst port must be given */
                if (memchr_inv(&mask->dst, 0xff, sizeof(mask->dst)))
                        goto vxlan_match_offload_err;
 
-               if (mlx5e_vxlan_lookup_port(priv, be16_to_cpu(key->dst)) &&
+               if (mlx5e_vxlan_lookup_port(up_priv, be16_to_cpu(key->dst)) &&
                    MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
                        parse_vxlan_attr(spec, f);
                else {
@@ -976,6 +998,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
                              struct mlx5_esw_flow_attr *attr)
 {
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+       struct net_device *up_dev = mlx5_eswitch_get_uplink_netdev(esw);
+       struct mlx5e_priv *up_priv = netdev_priv(up_dev);
        unsigned short family = ip_tunnel_info_af(tun_info);
        struct ip_tunnel_key *key = &tun_info->key;
        struct mlx5_encap_entry *e;
@@ -996,7 +1020,7 @@ vxlan_encap_offload_err:
                return -EOPNOTSUPP;
        }
 
-       if (mlx5e_vxlan_lookup_port(priv, be16_to_cpu(key->tp_dst)) &&
+       if (mlx5e_vxlan_lookup_port(up_priv, be16_to_cpu(key->tp_dst)) &&
            MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
                tunnel_type = MLX5_HEADER_TYPE_VXLAN;
        } else {
@@ -1112,14 +1136,16 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
                }
 
                if (is_tcf_vlan(a)) {
-                       if (tcf_vlan_action(a) == VLAN_F_POP) {
+                       if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
                                attr->action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
-                       } else if (tcf_vlan_action(a) == VLAN_F_PUSH) {
+                       } else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
                                if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q))
                                        return -EOPNOTSUPP;
 
                                attr->action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
                                attr->vlan = tcf_vlan_push_vid(a);
+                       } else { /* action is TCA_VLAN_ACT_MODIFY */
+                               return -EOPNOTSUPP;
                        }
                        continue;
                }
index f193128bac4b8c18504ec1f5905def3baa5c4633..57f5e2d7ebd1a91a1a1cf618e60caf1f015914a3 100644 (file)
@@ -274,15 +274,18 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_sq *sq, struct sk_buff *skb)
                        sq->stats.tso_bytes += skb->len - ihs;
                }
 
+               sq->stats.packets += skb_shinfo(skb)->gso_segs;
                num_bytes = skb->len + (skb_shinfo(skb)->gso_segs - 1) * ihs;
        } else {
                bf = sq->bf_budget &&
                     !skb->xmit_more &&
                     !skb_shinfo(skb)->nr_frags;
                ihs = mlx5e_get_inline_hdr_size(sq, skb, bf);
+               sq->stats.packets++;
                num_bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
        }
 
+       sq->stats.bytes += num_bytes;
        wi->num_bytes = num_bytes;
 
        ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
@@ -381,8 +384,6 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_sq *sq, struct sk_buff *skb)
        if (bf)
                sq->bf_budget--;
 
-       sq->stats.packets++;
-       sq->stats.bytes += num_bytes;
        return NETDEV_TX_OK;
 
 dma_unmap_wqe_err:
index 5b78883d565413ec59a00ecba4ddb483e4eecd3f..ad329b1680b455ddd4cdfda56bf512bfbea37529 100644 (file)
@@ -209,6 +209,7 @@ struct mlx5_esw_offload {
        struct mlx5_eswitch_rep *vport_reps;
        DECLARE_HASHTABLE(encap_tbl, 8);
        u8 inline_mode;
+       u64 num_flows;
 };
 
 struct mlx5_eswitch {
@@ -271,6 +272,11 @@ struct mlx5_flow_handle *
 mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
                                struct mlx5_flow_spec *spec,
                                struct mlx5_esw_flow_attr *attr);
+void
+mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw,
+                               struct mlx5_flow_handle *rule,
+                               struct mlx5_esw_flow_attr *attr);
+
 struct mlx5_flow_handle *
 mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn);
 
index 4f5b0d47d5f38237129a7c90a1240b8615615d32..307ec6c5fd3b62dffe6cfd5f2541dad9fc155fc3 100644 (file)
@@ -93,10 +93,27 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
                                   spec, &flow_act, dest, i);
        if (IS_ERR(rule))
                mlx5_fc_destroy(esw->dev, counter);
+       else
+               esw->offloads.num_flows++;
 
        return rule;
 }
 
+void
+mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw,
+                               struct mlx5_flow_handle *rule,
+                               struct mlx5_esw_flow_attr *attr)
+{
+       struct mlx5_fc *counter = NULL;
+
+       if (!IS_ERR(rule)) {
+               counter = mlx5_flow_rule_counter(rule);
+               mlx5_del_flow_rules(rule);
+               mlx5_fc_destroy(esw->dev, counter);
+               esw->offloads.num_flows--;
+       }
+}
+
 static int esw_set_global_vlan_pop(struct mlx5_eswitch *esw, u8 val)
 {
        struct mlx5_eswitch_rep *rep;
@@ -908,6 +925,11 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode)
            MLX5_CAP_INLINE_MODE_VPORT_CONTEXT)
                return -EOPNOTSUPP;
 
+       if (esw->offloads.num_flows > 0) {
+               esw_warn(dev, "Can't set inline mode when flows are configured\n");
+               return -EOPNOTSUPP;
+       }
+
        err = esw_inline_mode_from_devlink(mode, &mlx5_mode);
        if (err)
                goto out;
index e2bd600d19de09c8e4049e0b83ec2b9eae645729..60154a175bd3866f2b461a357c60d86283afde12 100644 (file)
@@ -87,7 +87,7 @@ static struct mlx5_profile profile[] = {
        [2] = {
                .mask           = MLX5_PROF_MASK_QP_SIZE |
                                  MLX5_PROF_MASK_MR_CACHE,
-               .log_max_qp     = 17,
+               .log_max_qp     = 18,
                .mr_cache[0]    = {
                        .size   = 500,
                        .limit  = 250
index 334bcc6df6b2ba90a43da4baf7b44cc5ebfa1bac..50d28261b6b9ea22f42c26be0e9f0e0bed194109 100644 (file)
@@ -2404,7 +2404,7 @@ static void efx_udp_tunnel_del(struct net_device *dev, struct udp_tunnel_info *t
        tnl.type = (u16)efx_tunnel_type;
        tnl.port = ti->port;
 
-       if (efx->type->udp_tnl_add_port)
+       if (efx->type->udp_tnl_del_port)
                (void)efx->type->udp_tnl_del_port(efx, tnl);
 }
 
index 296c8efd0038c8f66f41e9a58e30920462272192..9e631952b86f3d4ddd9108e1fe0db7c96d8363d2 100644 (file)
@@ -74,15 +74,21 @@ config TI_CPSW
          will be called cpsw.
 
 config TI_CPTS
-       tristate "TI Common Platform Time Sync (CPTS) Support"
+       bool "TI Common Platform Time Sync (CPTS) Support"
        depends on TI_CPSW || TI_KEYSTONE_NETCP
-       imply PTP_1588_CLOCK
+       depends on PTP_1588_CLOCK
        ---help---
          This driver supports the Common Platform Time Sync unit of
          the CPSW Ethernet Switch and Keystone 2 1g/10g Switch Subsystem.
          The unit can time stamp PTP UDP/IPv4 and Layer 2 packets, and the
          driver offers a PTP Hardware Clock.
 
+config TI_CPTS_MOD
+       tristate
+       depends on TI_CPTS
+       default y if TI_CPSW=y || TI_KEYSTONE_NETCP=y
+       default m
+
 config TI_KEYSTONE_NETCP
        tristate "TI Keystone NETCP Core Support"
        select TI_CPSW_ALE
index 1e7c10bf87132cda8e9c7ef2afc118ba1725388e..10e6b0ce51baf3115b8c72d40e933f10873186f0 100644 (file)
@@ -12,7 +12,7 @@ obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
 obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
 obj-$(CONFIG_TI_CPSW_PHY_SEL) += cpsw-phy-sel.o
 obj-$(CONFIG_TI_CPSW_ALE) += cpsw_ale.o
-obj-$(CONFIG_TI_CPTS) += cpts.o
+obj-$(CONFIG_TI_CPTS_MOD) += cpts.o
 obj-$(CONFIG_TI_CPSW) += ti_cpsw.o
 ti_cpsw-y := cpsw.o
 
index b75d9cdcfb0c415c7abeaa97cebeacbc917e1abd..ae48c809bac9fe13b0a92e086f0a1c6a4cf6feaf 100644 (file)
@@ -45,6 +45,8 @@ MODULE_DESCRIPTION("FUJITSU Extended Socket Network Device Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+#define ACPI_MOTHERBOARD_RESOURCE_HID "PNP0C02"
+
 static int fjes_request_irq(struct fjes_adapter *);
 static void fjes_free_irq(struct fjes_adapter *);
 
@@ -78,7 +80,7 @@ static void fjes_rx_irq(struct fjes_adapter *, int);
 static int fjes_poll(struct napi_struct *, int);
 
 static const struct acpi_device_id fjes_acpi_ids[] = {
-       {"PNP0C02", 0},
+       {ACPI_MOTHERBOARD_RESOURCE_HID, 0},
        {"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids);
@@ -115,18 +117,17 @@ static struct resource fjes_resource[] = {
        },
 };
 
-static int fjes_acpi_add(struct acpi_device *device)
+static bool is_extended_socket_device(struct acpi_device *device)
 {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
        char str_buf[sizeof(FJES_ACPI_SYMBOL) + 1];
-       struct platform_device *plat_dev;
        union acpi_object *str;
        acpi_status status;
        int result;
 
        status = acpi_evaluate_object(device->handle, "_STR", NULL, &buffer);
        if (ACPI_FAILURE(status))
-               return -ENODEV;
+               return false;
 
        str = buffer.pointer;
        result = utf16s_to_utf8s((wchar_t *)str->string.pointer,
@@ -136,10 +137,42 @@ static int fjes_acpi_add(struct acpi_device *device)
 
        if (strncmp(FJES_ACPI_SYMBOL, str_buf, strlen(FJES_ACPI_SYMBOL)) != 0) {
                kfree(buffer.pointer);
-               return -ENODEV;
+               return false;
        }
        kfree(buffer.pointer);
 
+       return true;
+}
+
+static int acpi_check_extended_socket_status(struct acpi_device *device)
+{
+       unsigned long long sta;
+       acpi_status status;
+
+       status = acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       if (!((sta & ACPI_STA_DEVICE_PRESENT) &&
+             (sta & ACPI_STA_DEVICE_ENABLED) &&
+             (sta & ACPI_STA_DEVICE_UI) &&
+             (sta & ACPI_STA_DEVICE_FUNCTIONING)))
+               return -ENODEV;
+
+       return 0;
+}
+
+static int fjes_acpi_add(struct acpi_device *device)
+{
+       struct platform_device *plat_dev;
+       acpi_status status;
+
+       if (!is_extended_socket_device(device))
+               return -ENODEV;
+
+       if (acpi_check_extended_socket_status(device))
+               return -ENODEV;
+
        status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
                                     fjes_get_acpi_resource, fjes_resource);
        if (ACPI_FAILURE(status))
@@ -1316,7 +1349,7 @@ static void fjes_netdev_setup(struct net_device *netdev)
        netdev->min_mtu = fjes_support_mtu[0];
        netdev->max_mtu = fjes_support_mtu[3];
        netdev->flags |= IFF_BROADCAST;
-       netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER;
+       netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 }
 
 static void fjes_irq_watch_task(struct work_struct *work)
@@ -1473,11 +1506,44 @@ static void fjes_watch_unshare_task(struct work_struct *work)
        }
 }
 
+static acpi_status
+acpi_find_extended_socket_device(acpi_handle obj_handle, u32 level,
+                                void *context, void **return_value)
+{
+       struct acpi_device *device;
+       bool *found = context;
+       int result;
+
+       result = acpi_bus_get_device(obj_handle, &device);
+       if (result)
+               return AE_OK;
+
+       if (strcmp(acpi_device_hid(device), ACPI_MOTHERBOARD_RESOURCE_HID))
+               return AE_OK;
+
+       if (!is_extended_socket_device(device))
+               return AE_OK;
+
+       if (acpi_check_extended_socket_status(device))
+               return AE_OK;
+
+       *found = true;
+       return AE_CTRL_TERMINATE;
+}
+
 /* fjes_init_module - Driver Registration Routine */
 static int __init fjes_init_module(void)
 {
+       bool found = false;
        int result;
 
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+                           acpi_find_extended_socket_device, NULL, &found,
+                           NULL);
+
+       if (!found)
+               return -ENODEV;
+
        pr_info("%s - version %s - %s\n",
                fjes_driver_string, fjes_driver_version, fjes_copyright);
 
index 4c1d8cca247b921e263268bf8344898c31bb488a..8dd0b87703288ccc5f067e495f5b297cde00fba1 100644 (file)
@@ -1231,8 +1231,11 @@ void netvsc_channel_cb(void *context)
                return;
 
        net_device = net_device_to_netvsc_device(ndev);
-       if (unlikely(net_device->destroy) &&
-           netvsc_channel_idle(net_device, q_idx))
+       if (unlikely(!net_device))
+               return;
+
+       if (unlikely(net_device->destroy &&
+                    netvsc_channel_idle(net_device, q_idx)))
                return;
 
        /* commit_rd_index() -> hv_signal_on_read() needs this. */
index 34cc3c590aa5c5c49509159d8fbf0f0cfcfca988..cc88cd7856f5e5ec4d3e3e309cbefe196c5b27ec 100644 (file)
@@ -1931,6 +1931,8 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
                return -EINVAL;
 
        tun->set_features = features;
+       tun->dev->wanted_features &= ~TUN_USER_FEATURES;
+       tun->dev->wanted_features |= features;
        netdev_update_features(tun->dev);
 
        return 0;
index 8056745506832867165f03ae0b24c2f1a578d849..156f7f85e4860d682d679df68bfe8cfe2a3d4b3b 100644 (file)
@@ -580,6 +580,10 @@ static const struct usb_device_id products[] = {
                USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
+       {       /* Motorola Mapphone devices with MDM6600 */
+               USB_VENDOR_AND_INTERFACE_INFO(0x22b8, USB_CLASS_VENDOR_SPEC, 0xfb, 0xff),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
 
        /* 2. Combined interface devices matching on class+protocol */
        {       /* Huawei E367 and possibly others in "Windows mode" */
@@ -925,6 +929,8 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x413c, 0x81a9, 8)},    /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81b1, 8)},    /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81b3, 8)},    /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
+       {QMI_FIXED_INTF(0x413c, 0x81b6, 8)},    /* Dell Wireless 5811e */
+       {QMI_FIXED_INTF(0x413c, 0x81b6, 10)},   /* Dell Wireless 5811e */
        {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)},    /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
        {QMI_FIXED_INTF(0x22de, 0x9061, 3)},    /* WeTelecom WPD-600N */
        {QMI_FIXED_INTF(0x1e0e, 0x9001, 5)},    /* SIMCom 7230E */
index 986243c932ccd6fe19c592805c1c63274f5e5555..0b1b9188625d527e01d098d3ca09389dcfd7bf4d 100644 (file)
@@ -32,7 +32,7 @@
 #define NETNEXT_VERSION                "08"
 
 /* Information for net */
-#define NET_VERSION            "8"
+#define NET_VERSION            "9"
 
 #define DRIVER_VERSION         "v1." NETNEXT_VERSION "." NET_VERSION
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
@@ -501,6 +501,8 @@ enum rtl_register_content {
 #define RTL8153_RMS            RTL8153_MAX_PACKET
 #define RTL8152_TX_TIMEOUT     (5 * HZ)
 #define RTL8152_NAPI_WEIGHT    64
+#define rx_reserved_size(x)    ((x) + VLAN_ETH_HLEN + CRC_SIZE + \
+                                sizeof(struct rx_desc) + RX_ALIGN)
 
 /* rtl8152 flags */
 enum rtl8152_flags {
@@ -1362,6 +1364,7 @@ static int alloc_all_mem(struct r8152 *tp)
        spin_lock_init(&tp->rx_lock);
        spin_lock_init(&tp->tx_lock);
        INIT_LIST_HEAD(&tp->tx_free);
+       INIT_LIST_HEAD(&tp->rx_done);
        skb_queue_head_init(&tp->tx_queue);
        skb_queue_head_init(&tp->rx_queue);
 
@@ -2252,8 +2255,7 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)
 
 static void r8153_set_rx_early_size(struct r8152 *tp)
 {
-       u32 mtu = tp->netdev->mtu;
-       u32 ocp_data = (agg_buf_sz - mtu - VLAN_ETH_HLEN - VLAN_HLEN) / 8;
+       u32 ocp_data = (agg_buf_sz - rx_reserved_size(tp->netdev->mtu)) / 4;
 
        ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data);
 }
@@ -2898,7 +2900,8 @@ static void r8153_first_init(struct r8152 *tp)
 
        rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX);
 
-       ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS);
+       ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + CRC_SIZE;
+       ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data);
        ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO);
 
        ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0);
@@ -2950,7 +2953,8 @@ static void r8153_enter_oob(struct r8152 *tp)
                usleep_range(1000, 2000);
        }
 
-       ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS);
+       ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + CRC_SIZE;
+       ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data);
 
        ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
        ocp_data &= ~TEREDO_WAKE_MASK;
@@ -4200,8 +4204,14 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
 
        dev->mtu = new_mtu;
 
-       if (netif_running(dev) && netif_carrier_ok(dev))
-               r8153_set_rx_early_size(tp);
+       if (netif_running(dev)) {
+               u32 rms = new_mtu + VLAN_ETH_HLEN + CRC_SIZE;
+
+               ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rms);
+
+               if (netif_carrier_ok(dev))
+                       r8153_set_rx_early_size(tp);
+       }
 
        mutex_unlock(&tp->control);
 
index fea687f35b5ac6f373396a860a3ff16a8e59fd66..d6988db1930d6b38db5f932a81c6c64b9c76776a 100644 (file)
@@ -462,8 +462,10 @@ static void vrf_rt6_release(struct net_device *dev, struct net_vrf *vrf)
        }
 
        if (rt6_local) {
-               if (rt6_local->rt6i_idev)
+               if (rt6_local->rt6i_idev) {
                        in6_dev_put(rt6_local->rt6i_idev);
+                       rt6_local->rt6i_idev = NULL;
+               }
 
                dst = &rt6_local->dst;
                dev_put(dst->dev);
index 33fb26833cd0a6b259a131d66972bf7620606f5b..d9f37ee4bfdd3eee9e0a0c11e30165a8b6a7d5ea 100644 (file)
@@ -51,7 +51,7 @@ const struct ath10k_hw_regs qca6174_regs = {
        .rtc_soc_base_address                   = 0x00000800,
        .rtc_wmac_base_address                  = 0x00001000,
        .soc_core_base_address                  = 0x0003a000,
-       .wlan_mac_base_address                  = 0x00020000,
+       .wlan_mac_base_address                  = 0x00010000,
        .ce_wrapper_base_address                = 0x00034000,
        .ce0_base_address                       = 0x00034400,
        .ce1_base_address                       = 0x00034800,
index d37b1695c64eac9096cfe7c11b3ef06764d4626a..6927caecd48e515557d011491463c48a3b1ea95c 100644 (file)
@@ -2319,7 +2319,7 @@ iwl_mvm_mac_release_buffered_frames(struct ieee80211_hw *hw,
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 
-       /* Called when we need to transmit (a) frame(s) from agg queue */
+       /* Called when we need to transmit (a) frame(s) from agg or dqa queue */
 
        iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames,
                                          tids, more_data, true);
@@ -2338,7 +2338,8 @@ static void __iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
        for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
                struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 
-               if (tid_data->state != IWL_AGG_ON &&
+               if (!iwl_mvm_is_dqa_supported(mvm) &&
+                   tid_data->state != IWL_AGG_ON &&
                    tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA)
                        continue;
 
index bd1dcc863d8f338df994a9b177d498df2eef49cb..b51a2853cc804a7ad8416423c3cea4554808125d 100644 (file)
@@ -3135,7 +3135,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
                                       struct ieee80211_sta *sta,
                                       enum ieee80211_frame_release_type reason,
                                       u16 cnt, u16 tids, bool more_data,
-                                      bool agg)
+                                      bool single_sta_queue)
 {
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_mvm_add_sta_cmd cmd = {
@@ -3155,14 +3155,14 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
        for_each_set_bit(tid, &_tids, IWL_MAX_TID_COUNT)
                cmd.awake_acs |= BIT(tid_to_ucode_ac[tid]);
 
-       /* If we're releasing frames from aggregation queues then check if the
-        * all queues combined that we're releasing frames from have
+       /* If we're releasing frames from aggregation or dqa queues then check
+        * if all the queues that we're releasing frames from, combined, have:
         *  - more frames than the service period, in which case more_data
         *    needs to be set
         *  - fewer than 'cnt' frames, in which case we need to adjust the
         *    firmware command (but do that unconditionally)
         */
-       if (agg) {
+       if (single_sta_queue) {
                int remaining = cnt;
                int sleep_tx_count;
 
@@ -3172,7 +3172,8 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
                        u16 n_queued;
 
                        tid_data = &mvmsta->tid_data[tid];
-                       if (WARN(tid_data->state != IWL_AGG_ON &&
+                       if (WARN(!iwl_mvm_is_dqa_supported(mvm) &&
+                                tid_data->state != IWL_AGG_ON &&
                                 tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA,
                                 "TID %d state is %d\n",
                                 tid, tid_data->state)) {
index 4be34f902278c8bb36521346dfcd7980976e8786..1927ce6077984fff4cde0f767ee97ea42de49761 100644 (file)
@@ -547,7 +547,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
                                       struct ieee80211_sta *sta,
                                       enum ieee80211_frame_release_type reason,
                                       u16 cnt, u16 tids, bool more_data,
-                                      bool agg);
+                                      bool single_sta_queue);
 int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
                      bool drain);
 void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
index dd2b4a30081993823634e18752187c576a656b79..3f37075f4cde3cf21da485cd94b1a3f705abac62 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016        Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -34,6 +34,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -628,8 +629,10 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
         * values.
         * Note that we don't need to make sure it isn't agg'd, since we're
         * TXing non-sta
+        * For DQA mode - we shouldn't increase it though
         */
-       atomic_inc(&mvm->pending_frames[sta_id]);
+       if (!iwl_mvm_is_dqa_supported(mvm))
+               atomic_inc(&mvm->pending_frames[sta_id]);
 
        return 0;
 }
@@ -1005,11 +1008,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        spin_unlock(&mvmsta->lock);
 
-       /* Increase pending frames count if this isn't AMPDU */
-       if ((iwl_mvm_is_dqa_supported(mvm) &&
-            mvmsta->tid_data[tx_cmd->tid_tspec].state != IWL_AGG_ON &&
-            mvmsta->tid_data[tx_cmd->tid_tspec].state != IWL_AGG_STARTING) ||
-           (!iwl_mvm_is_dqa_supported(mvm) && !is_ampdu))
+       /* Increase pending frames count if this isn't AMPDU or DQA queue */
+       if (!iwl_mvm_is_dqa_supported(mvm) && !is_ampdu)
                atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
 
        return 0;
@@ -1079,12 +1079,13 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
        lockdep_assert_held(&mvmsta->lock);
 
        if ((tid_data->state == IWL_AGG_ON ||
-            tid_data->state == IWL_EMPTYING_HW_QUEUE_DELBA) &&
+            tid_data->state == IWL_EMPTYING_HW_QUEUE_DELBA ||
+            iwl_mvm_is_dqa_supported(mvm)) &&
            iwl_mvm_tid_queued(tid_data) == 0) {
                /*
-                * Now that this aggregation queue is empty tell mac80211 so it
-                * knows we no longer have frames buffered for the station on
-                * this TID (for the TIM bitmap calculation.)
+                * Now that this aggregation or DQA queue is empty tell
+                * mac80211 so it knows we no longer have frames buffered for
+                * the station on this TID (for the TIM bitmap calculation.)
                 */
                ieee80211_sta_set_buffered(sta, tid, false);
        }
@@ -1257,7 +1258,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
        u8 skb_freed = 0;
        u16 next_reclaimed, seq_ctl;
        bool is_ndp = false;
-       bool txq_agg = false; /* Is this TXQ aggregated */
 
        __skb_queue_head_init(&skbs);
 
@@ -1283,6 +1283,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
                        info->flags |= IEEE80211_TX_STAT_ACK;
                        break;
                case TX_STATUS_FAIL_DEST_PS:
+                       /* In DQA, the FW should have stopped the queue and not
+                        * return this status
+                        */
+                       WARN_ON(iwl_mvm_is_dqa_supported(mvm));
                        info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
                        break;
                default:
@@ -1387,15 +1391,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
                        bool send_eosp_ndp = false;
 
                        spin_lock_bh(&mvmsta->lock);
-                       if (iwl_mvm_is_dqa_supported(mvm)) {
-                               enum iwl_mvm_agg_state state;
-
-                               state = mvmsta->tid_data[tid].state;
-                               txq_agg = (state == IWL_AGG_ON ||
-                                       state == IWL_EMPTYING_HW_QUEUE_DELBA);
-                       } else {
-                               txq_agg = txq_id >= mvm->first_agg_queue;
-                       }
 
                        if (!is_ndp) {
                                tid_data->next_reclaimed = next_reclaimed;
@@ -1452,11 +1447,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
         * If the txq is not an AMPDU queue, there is no chance we freed
         * several skbs. Check that out...
         */
-       if (txq_agg)
+       if (iwl_mvm_is_dqa_supported(mvm) || txq_id >= mvm->first_agg_queue)
                goto out;
 
        /* We can't free more than one frame at once on a shared queue */
-       WARN_ON(!iwl_mvm_is_dqa_supported(mvm) && (skb_freed > 1));
+       WARN_ON(skb_freed > 1);
 
        /* If we have still frames for this STA nothing to do here */
        if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id]))
index 5ebca1d0cfc750969793c26ac5f37e858e897fc4..b62e03d11c2e27c240d02a4e7813958da562aca8 100644 (file)
@@ -57,8 +57,8 @@ MODULE_PARM_DESC(mfg_mode, "manufacturing mode enable:1, disable:0");
  * In case of any errors during inittialization, this function also ensures
  * proper cleanup before exiting.
  */
-static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
-                           void **padapter)
+static int mwifiex_register(void *card, struct device *dev,
+                           struct mwifiex_if_ops *if_ops, void **padapter)
 {
        struct mwifiex_adapter *adapter;
        int i;
@@ -68,6 +68,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
                return -ENOMEM;
 
        *padapter = adapter;
+       adapter->dev = dev;
        adapter->card = card;
 
        /* Save interface specific operations in adapter */
@@ -1568,12 +1569,11 @@ mwifiex_add_card(void *card, struct completion *fw_done,
 {
        struct mwifiex_adapter *adapter;
 
-       if (mwifiex_register(card, if_ops, (void **)&adapter)) {
+       if (mwifiex_register(card, dev, if_ops, (void **)&adapter)) {
                pr_err("%s: software init failed\n", __func__);
                goto err_init_sw;
        }
 
-       adapter->dev = dev;
        mwifiex_probe_of(adapter);
 
        adapter->iface_type = iface_type;
@@ -1718,6 +1718,9 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter)
        wiphy_unregister(adapter->wiphy);
        wiphy_free(adapter->wiphy);
 
+       if (adapter->irq_wakeup >= 0)
+               device_init_wakeup(adapter->dev, false);
+
        /* Unregister device */
        mwifiex_dbg(adapter, INFO,
                    "info: unregister device\n");
index a0d918094889df6cd9de14046b773d6112b2006b..b8c990d10d6ecb11491cbf5ed345ecbdd7dc0359 100644 (file)
@@ -2739,6 +2739,21 @@ static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
        schedule_work(&card->work);
 }
 
+static void mwifiex_pcie_free_buffers(struct mwifiex_adapter *adapter)
+{
+       struct pcie_service_card *card = adapter->card;
+       const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+
+       if (reg->sleep_cookie)
+               mwifiex_pcie_delete_sleep_cookie_buf(adapter);
+
+       mwifiex_pcie_delete_cmdrsp_buf(adapter);
+       mwifiex_pcie_delete_evtbd_ring(adapter);
+       mwifiex_pcie_delete_rxbd_ring(adapter);
+       mwifiex_pcie_delete_txbd_ring(adapter);
+       card->cmdrsp_buf = NULL;
+}
+
 /*
  * This function initializes the PCI-E host memory space, WCB rings, etc.
  *
@@ -2850,13 +2865,6 @@ err_enable_dev:
 
 /*
  * This function cleans up the allocated card buffers.
- *
- * The following are freed by this function -
- *      - TXBD ring buffers
- *      - RXBD ring buffers
- *      - Event BD ring buffers
- *      - Command response ring buffer
- *      - Sleep cookie buffer
  */
 static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
 {
@@ -2875,6 +2883,8 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
                                    "Failed to write driver not-ready signature\n");
        }
 
+       mwifiex_pcie_free_buffers(adapter);
+
        if (pdev) {
                pci_iounmap(pdev, card->pci_mmap);
                pci_iounmap(pdev, card->pci_mmap1);
@@ -3126,10 +3136,7 @@ err_cre_txbd:
        pci_iounmap(pdev, card->pci_mmap1);
 }
 
-/* This function cleans up the PCI-E host memory space.
- * Some code is extracted from mwifiex_unregister_dev()
- *
- */
+/* This function cleans up the PCI-E host memory space. */
 static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
 {
        struct pcie_service_card *card = adapter->card;
@@ -3140,14 +3147,7 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
 
        adapter->seq_num = 0;
 
-       if (reg->sleep_cookie)
-               mwifiex_pcie_delete_sleep_cookie_buf(adapter);
-
-       mwifiex_pcie_delete_cmdrsp_buf(adapter);
-       mwifiex_pcie_delete_evtbd_ring(adapter);
-       mwifiex_pcie_delete_rxbd_ring(adapter);
-       mwifiex_pcie_delete_txbd_ring(adapter);
-       card->cmdrsp_buf = NULL;
+       mwifiex_pcie_free_buffers(adapter);
 }
 
 static struct mwifiex_if_ops pcie_ops = {
index 779f516e7a4ec405ff919f9b248d21ff0f748b8b..47a479f26e5d7de3605c0263d1a0cdbba1b7e1c1 100644 (file)
@@ -343,8 +343,6 @@ static int __nvme_rdma_init_request(struct nvme_rdma_ctrl *ctrl,
        struct ib_device *ibdev = dev->dev;
        int ret;
 
-       BUG_ON(queue_idx >= ctrl->queue_count);
-
        ret = nvme_rdma_alloc_qe(ibdev, &req->sqe, sizeof(struct nvme_command),
                        DMA_TO_DEVICE);
        if (ret)
@@ -652,8 +650,22 @@ out_free_queues:
 
 static int nvme_rdma_init_io_queues(struct nvme_rdma_ctrl *ctrl)
 {
+       struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
+       unsigned int nr_io_queues;
        int i, ret;
 
+       nr_io_queues = min(opts->nr_io_queues, num_online_cpus());
+       ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
+       if (ret)
+               return ret;
+
+       ctrl->queue_count = nr_io_queues + 1;
+       if (ctrl->queue_count < 2)
+               return 0;
+
+       dev_info(ctrl->ctrl.device,
+               "creating %d I/O queues.\n", nr_io_queues);
+
        for (i = 1; i < ctrl->queue_count; i++) {
                ret = nvme_rdma_init_queue(ctrl, i,
                                           ctrl->ctrl.opts->queue_size);
@@ -1791,20 +1803,8 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
 
 static int nvme_rdma_create_io_queues(struct nvme_rdma_ctrl *ctrl)
 {
-       struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
        int ret;
 
-       ret = nvme_set_queue_count(&ctrl->ctrl, &opts->nr_io_queues);
-       if (ret)
-               return ret;
-
-       ctrl->queue_count = opts->nr_io_queues + 1;
-       if (ctrl->queue_count < 2)
-               return 0;
-
-       dev_info(ctrl->ctrl.device,
-               "creating %d I/O queues.\n", opts->nr_io_queues);
-
        ret = nvme_rdma_init_io_queues(ctrl);
        if (ret)
                return ret;
index 11b0a0a5f661b502d15a22868fe78369ef428627..798653b329b28cb8925cfab4993cc5c6b6afc147 100644 (file)
@@ -425,6 +425,13 @@ void nvmet_sq_setup(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq,
        ctrl->sqs[qid] = sq;
 }
 
+static void nvmet_confirm_sq(struct percpu_ref *ref)
+{
+       struct nvmet_sq *sq = container_of(ref, struct nvmet_sq, ref);
+
+       complete(&sq->confirm_done);
+}
+
 void nvmet_sq_destroy(struct nvmet_sq *sq)
 {
        /*
@@ -433,7 +440,8 @@ void nvmet_sq_destroy(struct nvmet_sq *sq)
         */
        if (sq->ctrl && sq->ctrl->sqs && sq->ctrl->sqs[0] == sq)
                nvmet_async_events_free(sq->ctrl);
-       percpu_ref_kill(&sq->ref);
+       percpu_ref_kill_and_confirm(&sq->ref, nvmet_confirm_sq);
+       wait_for_completion(&sq->confirm_done);
        wait_for_completion(&sq->free_done);
        percpu_ref_exit(&sq->ref);
 
@@ -461,6 +469,7 @@ int nvmet_sq_init(struct nvmet_sq *sq)
                return ret;
        }
        init_completion(&sq->free_done);
+       init_completion(&sq->confirm_done);
 
        return 0;
 }
index d1f06e7768ff1d7ff6ee787ff6d94eb01576252f..22f7bc6bac7fa77dd48198cde3a31ef60ead531b 100644 (file)
@@ -223,8 +223,6 @@ static void nvme_loop_submit_async_event(struct nvme_ctrl *arg, int aer_idx)
 static int nvme_loop_init_iod(struct nvme_loop_ctrl *ctrl,
                struct nvme_loop_iod *iod, unsigned int queue_idx)
 {
-       BUG_ON(queue_idx >= ctrl->queue_count);
-
        iod->req.cmd = &iod->cmd;
        iod->req.rsp = &iod->rsp;
        iod->queue = &ctrl->queues[queue_idx];
@@ -288,9 +286,9 @@ static struct blk_mq_ops nvme_loop_admin_mq_ops = {
 
 static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl)
 {
+       nvmet_sq_destroy(&ctrl->queues[0].nvme_sq);
        blk_cleanup_queue(ctrl->ctrl.admin_q);
        blk_mq_free_tag_set(&ctrl->admin_tag_set);
-       nvmet_sq_destroy(&ctrl->queues[0].nvme_sq);
 }
 
 static void nvme_loop_free_ctrl(struct nvme_ctrl *nctrl)
@@ -314,6 +312,43 @@ free_ctrl:
        kfree(ctrl);
 }
 
+static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl)
+{
+       int i;
+
+       for (i = 1; i < ctrl->queue_count; i++)
+               nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
+}
+
+static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl)
+{
+       struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
+       unsigned int nr_io_queues;
+       int ret, i;
+
+       nr_io_queues = min(opts->nr_io_queues, num_online_cpus());
+       ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
+       if (ret || !nr_io_queues)
+               return ret;
+
+       dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n", nr_io_queues);
+
+       for (i = 1; i <= nr_io_queues; i++) {
+               ctrl->queues[i].ctrl = ctrl;
+               ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
+               if (ret)
+                       goto out_destroy_queues;
+
+               ctrl->queue_count++;
+       }
+
+       return 0;
+
+out_destroy_queues:
+       nvme_loop_destroy_io_queues(ctrl);
+       return ret;
+}
+
 static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
 {
        int error;
@@ -385,17 +420,13 @@ out_free_sq:
 
 static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl)
 {
-       int i;
-
        nvme_stop_keep_alive(&ctrl->ctrl);
 
        if (ctrl->queue_count > 1) {
                nvme_stop_queues(&ctrl->ctrl);
                blk_mq_tagset_busy_iter(&ctrl->tag_set,
                                        nvme_cancel_request, &ctrl->ctrl);
-
-               for (i = 1; i < ctrl->queue_count; i++)
-                       nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
+               nvme_loop_destroy_io_queues(ctrl);
        }
 
        if (ctrl->ctrl.state == NVME_CTRL_LIVE)
@@ -467,19 +498,14 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
        if (ret)
                goto out_disable;
 
-       for (i = 1; i <= ctrl->ctrl.opts->nr_io_queues; i++) {
-               ctrl->queues[i].ctrl = ctrl;
-               ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
-               if (ret)
-                       goto out_free_queues;
-
-               ctrl->queue_count++;
-       }
+       ret = nvme_loop_init_io_queues(ctrl);
+       if (ret)
+               goto out_destroy_admin;
 
-       for (i = 1; i <= ctrl->ctrl.opts->nr_io_queues; i++) {
+       for (i = 1; i < ctrl->queue_count; i++) {
                ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
                if (ret)
-                       goto out_free_queues;
+                       goto out_destroy_io;
        }
 
        changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
@@ -492,9 +518,9 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
 
        return;
 
-out_free_queues:
-       for (i = 1; i < ctrl->queue_count; i++)
-               nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
+out_destroy_io:
+       nvme_loop_destroy_io_queues(ctrl);
+out_destroy_admin:
        nvme_loop_destroy_admin_queue(ctrl);
 out_disable:
        dev_warn(ctrl->ctrl.device, "Removing after reset failure\n");
@@ -533,25 +559,12 @@ static const struct nvme_ctrl_ops nvme_loop_ctrl_ops = {
 
 static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
 {
-       struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
        int ret, i;
 
-       ret = nvme_set_queue_count(&ctrl->ctrl, &opts->nr_io_queues);
-       if (ret || !opts->nr_io_queues)
+       ret = nvme_loop_init_io_queues(ctrl);
+       if (ret)
                return ret;
 
-       dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n",
-               opts->nr_io_queues);
-
-       for (i = 1; i <= opts->nr_io_queues; i++) {
-               ctrl->queues[i].ctrl = ctrl;
-               ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
-               if (ret)
-                       goto out_destroy_queues;
-
-               ctrl->queue_count++;
-       }
-
        memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set));
        ctrl->tag_set.ops = &nvme_loop_mq_ops;
        ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size;
@@ -575,7 +588,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
                goto out_free_tagset;
        }
 
-       for (i = 1; i <= opts->nr_io_queues; i++) {
+       for (i = 1; i < ctrl->queue_count; i++) {
                ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
                if (ret)
                        goto out_cleanup_connect_q;
@@ -588,8 +601,7 @@ out_cleanup_connect_q:
 out_free_tagset:
        blk_mq_free_tag_set(&ctrl->tag_set);
 out_destroy_queues:
-       for (i = 1; i < ctrl->queue_count; i++)
-               nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
+       nvme_loop_destroy_io_queues(ctrl);
        return ret;
 }
 
index 1370eee0a3c0f6295722d22e0c103a2f6cece47b..f7ff15f17ca97d65161cdb6a164e62deff339916 100644 (file)
@@ -73,6 +73,7 @@ struct nvmet_sq {
        u16                     qid;
        u16                     size;
        struct completion       free_done;
+       struct completion       confirm_done;
 };
 
 /**
index 9aa1da3778b3ac1d2262bfe9b845b65b9cd942d9..ecc4fe8625612442ded6a554e762d029b908c8dc 100644 (file)
@@ -703,11 +703,6 @@ static void nvmet_rdma_handle_command(struct nvmet_rdma_queue *queue,
 {
        u16 status;
 
-       cmd->queue = queue;
-       cmd->n_rdma = 0;
-       cmd->req.port = queue->port;
-
-
        ib_dma_sync_single_for_cpu(queue->dev->device,
                cmd->cmd->sge[0].addr, cmd->cmd->sge[0].length,
                DMA_FROM_DEVICE);
@@ -760,9 +755,12 @@ static void nvmet_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc)
 
        cmd->queue = queue;
        rsp = nvmet_rdma_get_rsp(queue);
+       rsp->queue = queue;
        rsp->cmd = cmd;
        rsp->flags = 0;
        rsp->req.cmd = cmd->nvme_cmd;
+       rsp->req.port = queue->port;
+       rsp->n_rdma = 0;
 
        if (unlikely(queue->state != NVMET_RDMA_Q_LIVE)) {
                unsigned long flags;
index bc090daa850a4b8fdb8a29c8592582eda8aee668..5dc53d420ca8ca805c0c036c23e3c1a3fc42ac00 100644 (file)
@@ -939,8 +939,10 @@ parport_register_dev_model(struct parport *port, const char *name,
         * pardevice fields. -arca
         */
        port->ops->init_state(par_dev, par_dev->state);
-       port->proc_device = par_dev;
-       parport_device_proc_register(par_dev);
+       if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) {
+               port->proc_device = par_dev;
+               parport_device_proc_register(par_dev);
+       }
 
        return par_dev;
 
index 52b5bdccf5f0c2ab462cc695e332a8b3e3234970..b89c373555c553d6042571b1b780d04b5cef0960 100644 (file)
@@ -14,6 +14,7 @@
  * Copyright (C) 2015 - 2016 Cavium, Inc.
  */
 
+#include <linux/bitfield.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/of_address.h>
@@ -334,6 +335,50 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
 
+#define PEM_RES_BASE           0x87e0c0000000UL
+#define PEM_NODE_MASK          GENMASK(45, 44)
+#define PEM_INDX_MASK          GENMASK(26, 24)
+#define PEM_MIN_DOM_IN_NODE    4
+#define PEM_MAX_DOM_IN_NODE    10
+
+static void thunder_pem_reserve_range(struct device *dev, int seg,
+                                     struct resource *r)
+{
+       resource_size_t start = r->start, end = r->end;
+       struct resource *res;
+       const char *regionid;
+
+       regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg);
+       if (!regionid)
+               return;
+
+       res = request_mem_region(start, end - start + 1, regionid);
+       if (res)
+               res->flags &= ~IORESOURCE_BUSY;
+       else
+               kfree(regionid);
+
+       dev_info(dev, "%pR %s reserved\n", r,
+                res ? "has been" : "could not be");
+}
+
+static void thunder_pem_legacy_fw(struct acpi_pci_root *root,
+                                struct resource *res_pem)
+{
+       int node = acpi_get_node(root->device->handle);
+       int index;
+
+       if (node == NUMA_NO_NODE)
+               node = 0;
+
+       index = root->segment - PEM_MIN_DOM_IN_NODE;
+       index -= node * PEM_MAX_DOM_IN_NODE;
+       res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) |
+                                       FIELD_PREP(PEM_INDX_MASK, index);
+       res_pem->end = res_pem->start + SZ_16M - 1;
+       res_pem->flags = IORESOURCE_MEM;
+}
+
 static int thunder_pem_acpi_init(struct pci_config_window *cfg)
 {
        struct device *dev = cfg->parent;
@@ -346,10 +391,17 @@ static int thunder_pem_acpi_init(struct pci_config_window *cfg)
        if (!res_pem)
                return -ENOMEM;
 
-       ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem);
+       ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
+
+       /*
+        * If we fail to gather resources it means that we run with old
+        * FW where we need to calculate PEM-specific resources manually.
+        */
        if (ret) {
-               dev_err(dev, "can't get rc base address\n");
-               return ret;
+               thunder_pem_legacy_fw(root, res_pem);
+               /* Reserve PEM-specific resources and PCI configuration space */
+               thunder_pem_reserve_range(dev, root->segment, res_pem);
+               thunder_pem_reserve_range(dev, root->segment, &cfg->res);
        }
 
        return thunder_pem_init(dev, cfg, res_pem);
index bd4c9ec25edc22531ae450b2bb08f1d2aecd7b62..384c27e664fec8aa777246dce0bca499728ae42a 100644 (file)
@@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
 {
        struct device *dev = &bdev->dev;
        struct iproc_pcie *pcie;
-       LIST_HEAD(res);
-       struct resource res_mem;
+       LIST_HEAD(resources);
        int ret;
 
        pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -63,22 +62,23 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
 
        pcie->base_addr = bdev->addr;
 
-       res_mem.start = bdev->addr_s[0];
-       res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
-       res_mem.name = "PCIe MEM space";
-       res_mem.flags = IORESOURCE_MEM;
-       pci_add_resource(&res, &res_mem);
+       pcie->mem.start = bdev->addr_s[0];
+       pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
+       pcie->mem.name = "PCIe MEM space";
+       pcie->mem.flags = IORESOURCE_MEM;
+       pci_add_resource(&resources, &pcie->mem);
 
        pcie->map_irq = iproc_pcie_bcma_map_irq;
 
-       ret = iproc_pcie_setup(pcie, &res);
-       if (ret)
+       ret = iproc_pcie_setup(pcie, &resources);
+       if (ret) {
                dev_err(dev, "PCIe controller setup failed\n");
-
-       pci_free_resource_list(&res);
+               pci_free_resource_list(&resources);
+               return ret;
+       }
 
        bcma_set_drvdata(bdev, pcie);
-       return ret;
+       return 0;
 }
 
 static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
index f4909bb0b2ad1505c3e084820f36104387add8f5..8c6a327ca6cdf883f32ea9a6fa0e7e1e28ab0e98 100644 (file)
@@ -51,7 +51,7 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
        struct device_node *np = dev->of_node;
        struct resource reg;
        resource_size_t iobase = 0;
-       LIST_HEAD(res);
+       LIST_HEAD(resources);
        int ret;
 
        pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -96,10 +96,10 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
                pcie->phy = NULL;
        }
 
-       ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
+       ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
+                                              &iobase);
        if (ret) {
-               dev_err(dev,
-                       "unable to get PCI host bridge resources\n");
+               dev_err(dev, "unable to get PCI host bridge resources\n");
                return ret;
        }
 
@@ -112,14 +112,15 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
                pcie->map_irq = of_irq_parse_and_map_pci;
        }
 
-       ret = iproc_pcie_setup(pcie, &res);
-       if (ret)
+       ret = iproc_pcie_setup(pcie, &resources);
+       if (ret) {
                dev_err(dev, "PCIe controller setup failed\n");
-
-       pci_free_resource_list(&res);
+               pci_free_resource_list(&resources);
+               return ret;
+       }
 
        platform_set_drvdata(pdev, pcie);
-       return ret;
+       return 0;
 }
 
 static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
index 04fed8e907f12b602b5fb1f11ff59971ebd0b87f..0bbe2ea44f3e1559dda22adc85ea70a8862684bd 100644 (file)
@@ -90,6 +90,7 @@ struct iproc_pcie {
 #ifdef CONFIG_ARM
        struct pci_sys_data sysdata;
 #endif
+       struct resource mem;
        struct pci_bus *root_bus;
        struct phy *phy;
        int (*map_irq)(const struct pci_dev *, u8, u8);
index dc5277ad1b5a7a5a7b27a7329f0f6382587e6050..005cadb7a3f8e9076700bf24d280383a0d321c85 100644 (file)
@@ -449,6 +449,7 @@ config PHY_QCOM_UFS
 config PHY_QCOM_USB_HS
        tristate "Qualcomm USB HS PHY module"
        depends on USB_ULPI_BUS
+       depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
        select GENERIC_PHY
        help
          Support for the USB high-speed ULPI compliant phy on Qualcomm
@@ -510,12 +511,4 @@ config PHY_MESON8B_USB2
          and GXBB SoCs.
          If unsure, say N.
 
-config PHY_NSP_USB3
-       tristate "Broadcom NorthStar plus USB3 PHY driver"
-       depends on OF && (ARCH_BCM_NSP || COMPILE_TEST)
-       select GENERIC_PHY
-       default ARCH_BCM_NSP
-       help
-         Enable this to support the Broadcom Northstar plus USB3 PHY.
-         If unsure, say N.
 endmenu
index e7b0feb1e125a58c25fb96e784deae62bfb891e7..dd8f3b5d2918cd91bd48592b6771ca539321b086 100644 (file)
@@ -62,4 +62,3 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE)         += phy-bcm-cygnus-pcie.o
 obj-$(CONFIG_ARCH_TEGRA) += tegra/
 obj-$(CONFIG_PHY_NS2_PCIE)             += phy-bcm-ns2-pcie.o
 obj-$(CONFIG_PHY_MESON8B_USB2)         += phy-meson8b-usb2.o
-obj-$(CONFIG_PHY_NSP_USB3)             += phy-bcm-nsp-usb3.o
diff --git a/drivers/phy/phy-bcm-nsp-usb3.c b/drivers/phy/phy-bcm-nsp-usb3.c
deleted file mode 100644 (file)
index 49024ea..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 Broadcom
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mdio.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/phy/phy.h>
-#include <linux/regmap.h>
-
-#define NSP_USB3_RST_CTRL_OFFSET       0x3f8
-
-/* mdio reg access */
-#define NSP_USB3_PHY_BASE_ADDR_REG     0x1f
-
-#define NSP_USB3_PHY_PLL30_BLOCK       0x8000
-#define NSP_USB3_PLL_CONTROL           0x01
-#define NSP_USB3_PLLA_CONTROL0         0x0a
-#define NSP_USB3_PLLA_CONTROL1         0x0b
-
-#define NSP_USB3_PHY_TX_PMD_BLOCK      0x8040
-#define NSP_USB3_TX_PMD_CONTROL1       0x01
-
-#define NSP_USB3_PHY_PIPE_BLOCK                0x8060
-#define NSP_USB3_LFPS_CMP              0x02
-#define NSP_USB3_LFPS_DEGLITCH         0x03
-
-struct nsp_usb3_phy {
-       struct regmap *usb3_ctrl;
-       struct phy *phy;
-       struct mdio_device *mdiodev;
-};
-
-static int nsp_usb3_phy_init(struct phy *phy)
-{
-       struct nsp_usb3_phy *iphy = phy_get_drvdata(phy);
-       struct mii_bus *bus = iphy->mdiodev->bus;
-       int addr = iphy->mdiodev->addr;
-       u32 data;
-       int rc;
-
-       rc = regmap_read(iphy->usb3_ctrl, 0, &data);
-       if (rc)
-               return rc;
-       data |= 1;
-       rc = regmap_write(iphy->usb3_ctrl, 0, data);
-       if (rc)
-               return rc;
-
-       rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 1);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
-                          NSP_USB3_PHY_PLL30_BLOCK);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x1000);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL0, 0x6400);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0xc000);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0x8000);
-       if (rc)
-               return rc;
-
-       rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 0);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x9000);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
-                          NSP_USB3_PHY_PIPE_BLOCK);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_CMP, 0xf30d);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_DEGLITCH, 0x6302);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
-                          NSP_USB3_PHY_TX_PMD_BLOCK);
-       if (rc)
-               return rc;
-
-       rc = mdiobus_write(bus, addr, NSP_USB3_TX_PMD_CONTROL1, 0x1003);
-
-       return rc;
-}
-
-static struct phy_ops nsp_usb3_phy_ops = {
-       .init   = nsp_usb3_phy_init,
-       .owner  = THIS_MODULE,
-};
-
-static int nsp_usb3_phy_probe(struct mdio_device *mdiodev)
-{
-       struct device *dev = &mdiodev->dev;
-       struct phy_provider *provider;
-       struct nsp_usb3_phy *iphy;
-
-       iphy = devm_kzalloc(dev, sizeof(*iphy), GFP_KERNEL);
-       if (!iphy)
-               return -ENOMEM;
-       iphy->mdiodev = mdiodev;
-
-       iphy->usb3_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
-                                                "usb3-ctrl-syscon");
-       if (IS_ERR(iphy->usb3_ctrl))
-               return PTR_ERR(iphy->usb3_ctrl);
-
-       iphy->phy = devm_phy_create(dev, dev->of_node, &nsp_usb3_phy_ops);
-       if (IS_ERR(iphy->phy)) {
-               dev_err(dev, "failed to create PHY\n");
-               return PTR_ERR(iphy->phy);
-       }
-
-       phy_set_drvdata(iphy->phy, iphy);
-
-       provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-       if (IS_ERR(provider)) {
-               dev_err(dev, "could not register PHY provider\n");
-               return PTR_ERR(provider);
-       }
-
-       return 0;
-}
-
-static const struct of_device_id nsp_usb3_phy_of_match[] = {
-       {.compatible = "brcm,nsp-usb3-phy",},
-       { /* sentinel */ }
-};
-
-static struct mdio_driver nsp_usb3_phy_driver = {
-       .mdiodrv = {
-               .driver = {
-                       .name = "nsp-usb3-phy",
-                       .of_match_table = nsp_usb3_phy_of_match,
-               },
-       },
-       .probe = nsp_usb3_phy_probe,
-};
-
-mdio_module_driver(nsp_usb3_phy_driver);
-
-MODULE_DESCRIPTION("Broadcom NSP USB3 PHY driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com");
index 4f60b83641d5952d55edd37137283114ea9ba836..60baf25d98e25eb3e716979a54223dd3d03e198d 100644 (file)
@@ -254,8 +254,8 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        exynos_phy->blk_base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(exynos_phy->phy_base))
-               return PTR_ERR(exynos_phy->phy_base);
+       if (IS_ERR(exynos_phy->blk_base))
+               return PTR_ERR(exynos_phy->blk_base);
 
        exynos_phy->drv_data = drv_data;
 
index 7671424d46cbe0a5628caee0615cde2d79b8d478..31a3a98d067caa4440a25e901eba69bdf3b0e862 100644 (file)
@@ -667,11 +667,11 @@ static const char * const uart_ao_b_groups[] = {
 };
 
 static const char * const i2c_ao_groups[] = {
-       "i2c_sdk_ao", "i2c_sda_ao",
+       "i2c_sck_ao", "i2c_sda_ao",
 };
 
 static const char * const i2c_slave_ao_groups[] = {
-       "i2c_slave_sdk_ao", "i2c_slave_sda_ao",
+       "i2c_slave_sck_ao", "i2c_slave_sda_ao",
 };
 
 static const char * const remote_input_ao_groups[] = {
index 676efcc032d26178718c601116a1a387622760c5..3ae8066bc1279c1c23dfc7144215fb48879efae8 100644 (file)
@@ -1285,6 +1285,22 @@ static void st_gpio_irq_unmask(struct irq_data *d)
        writel(BIT(d->hwirq), bank->base + REG_PIO_SET_PMASK);
 }
 
+static int st_gpio_irq_request_resources(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+       st_gpio_direction_input(gc, d->hwirq);
+
+       return gpiochip_lock_as_irq(gc, d->hwirq);
+}
+
+static void st_gpio_irq_release_resources(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+       gpiochip_unlock_as_irq(gc, d->hwirq);
+}
+
 static int st_gpio_irq_set_type(struct irq_data *d, unsigned type)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -1438,12 +1454,14 @@ static struct gpio_chip st_gpio_template = {
 };
 
 static struct irq_chip st_gpio_irqchip = {
-       .name           = "GPIO",
-       .irq_disable    = st_gpio_irq_mask,
-       .irq_mask       = st_gpio_irq_mask,
-       .irq_unmask     = st_gpio_irq_unmask,
-       .irq_set_type   = st_gpio_irq_set_type,
-       .flags          = IRQCHIP_SKIP_SET_WAKE,
+       .name                   = "GPIO",
+       .irq_request_resources  = st_gpio_irq_request_resources,
+       .irq_release_resources  = st_gpio_irq_release_resources,
+       .irq_disable            = st_gpio_irq_mask,
+       .irq_mask               = st_gpio_irq_mask,
+       .irq_unmask             = st_gpio_irq_unmask,
+       .irq_set_type           = st_gpio_irq_set_type,
+       .flags                  = IRQCHIP_SKIP_SET_WAKE,
 };
 
 static int st_gpiolib_register_bank(struct st_pinctrl *info,
index b68ae424cee247d51541d4ceb36aaa8c8c9132f6..743d1f458205fac1a5c26c683fdc38f12e401095 100644 (file)
@@ -405,6 +405,36 @@ static const struct msm_pingroup ipq4019_groups[] = {
        PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
        PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(83, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(84, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(85, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(88, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(89, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(90, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(91, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(92, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(93, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(94, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(98, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
 };
 
 static const struct msm_pinctrl_soc_data ipq4019_pinctrl = {
index c978be5eb9ebe37a4e9df59c76791b79b47b6cfc..273badd925611aa86e19e3a4aebc6691cf812fcb 100644 (file)
@@ -609,10 +609,6 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
 
        raw_spin_lock_irqsave(&pctrl->lock, flags);
 
-       val = readl(pctrl->regs + g->intr_status_reg);
-       val &= ~BIT(g->intr_status_bit);
-       writel(val, pctrl->regs + g->intr_status_reg);
-
        val = readl(pctrl->regs + g->intr_cfg_reg);
        val |= BIT(g->intr_enable_bit);
        writel(val, pctrl->regs + g->intr_cfg_reg);
index f9ddba7decc18563916d5adc118958fad46f0073..d7aa22cff480ed63d73c9e1e6f8fbf22d0eda290 100644 (file)
@@ -988,9 +988,16 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
 
        for (i = 0; i < ctrl->nr_ext_resources + 1; i++) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-               virt_base[i] = devm_ioremap_resource(&pdev->dev, res);
-               if (IS_ERR(virt_base[i]))
-                       return ERR_CAST(virt_base[i]);
+               if (!res) {
+                       dev_err(&pdev->dev, "failed to get mem%d resource\n", i);
+                       return ERR_PTR(-EINVAL);
+               }
+               virt_base[i] = devm_ioremap(&pdev->dev, res->start,
+                                               resource_size(res));
+               if (!virt_base[i]) {
+                       dev_err(&pdev->dev, "failed to ioremap %pR\n", res);
+                       return ERR_PTR(-EIO);
+               }
        }
 
        bank = d->pin_banks;
index 815a88673d38193b8c1313265d46b536738b3586..542077069391b9b262192a502809708476072e7e 100644 (file)
@@ -1,6 +1,6 @@
 config PINCTRL_TI_IODELAY
        tristate "TI IODelay Module pinconf driver"
-       depends on OF
+       depends on OF && (SOC_DRA7XX || COMPILE_TEST)
        select GENERIC_PINCTRL_GROUPS
        select GENERIC_PINMUX_FUNCTIONS
        select GENERIC_PINCONF
index 09b4df74291e2618e95e842dc4f5d7bdb178ec93..bb865695d7a62d20fa66800c8ed421dcfa8cd8c2 100644 (file)
@@ -193,10 +193,7 @@ static int __init ptp_kvm_init(void)
 
        kvm_ptp_clock.ptp_clock = ptp_clock_register(&kvm_ptp_clock.caps, NULL);
 
-       if (IS_ERR(kvm_ptp_clock.ptp_clock))
-               return PTR_ERR(kvm_ptp_clock.ptp_clock);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(kvm_ptp_clock.ptp_clock);
 }
 
 module_init(ptp_kvm_init);
index 9d19b9a62011b376be541b247336d455952bb42b..315a4be8dc1e64f429fb6bd5bab9700a0d254f29 100644 (file)
@@ -37,8 +37,8 @@
 #include "tsi721.h"
 
 #ifdef DEBUG
-u32 dbg_level;
-module_param(dbg_level, uint, S_IWUSR | S_IRUGO);
+u32 tsi_dbg_level;
+module_param_named(dbg_level, tsi_dbg_level, uint, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(dbg_level, "Debugging output level (default 0 = none)");
 #endif
 
index 5941437cbdd164c7e0c491f33117401bc6fe54e2..957eadc5815095045f06291dbc2b83bbaea795d7 100644 (file)
@@ -40,11 +40,11 @@ enum {
 };
 
 #ifdef DEBUG
-extern u32 dbg_level;
+extern u32 tsi_dbg_level;
 
 #define tsi_debug(level, dev, fmt, arg...)                             \
        do {                                                            \
-               if (DBG_##level & dbg_level)                            \
+               if (DBG_##level & tsi_dbg_level)                                \
                        dev_dbg(dev, "%s: " fmt "\n", __func__, ##arg); \
        } while (0)
 #else
index 65f86bc24c07c7032726700e09a1d9ef3cdfb3c2..1dc43fc5f65f38d8028388548452bd12218641fc 100644 (file)
@@ -76,7 +76,7 @@ config QCOM_ADSP_PIL
        depends on OF && ARCH_QCOM
        depends on REMOTEPROC
        depends on QCOM_SMEM
-       depends on QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n)
+       depends on RPMSG_QCOM_SMD || QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n && RPMSG_QCOM_SMD=n)
        select MFD_SYSCON
        select QCOM_MDT_LOADER
        select QCOM_RPROC_COMMON
@@ -93,7 +93,7 @@ config QCOM_Q6V5_PIL
        depends on OF && ARCH_QCOM
        depends on QCOM_SMEM
        depends on REMOTEPROC
-       depends on QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n)
+       depends on RPMSG_QCOM_SMD || QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n && RPMSG_QCOM_SMD=n)
        select MFD_SYSCON
        select QCOM_RPROC_COMMON
        select QCOM_SCM
@@ -104,7 +104,7 @@ config QCOM_Q6V5_PIL
 config QCOM_WCNSS_PIL
        tristate "Qualcomm WCNSS Peripheral Image Loader"
        depends on OF && ARCH_QCOM
-       depends on QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n)
+       depends on RPMSG_QCOM_SMD || QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n && RPMSG_QCOM_SMD=n)
        depends on QCOM_SMEM
        depends on REMOTEPROC
        select QCOM_MDT_LOADER
index 4bf55b5d78be53cd0aced1b7e5f2b59fcf93d186..3c52867dfe28e33b04f85858dfdb9285eef11ba2 100644 (file)
@@ -1253,20 +1253,6 @@ config SCSI_LPFC_DEBUG_FS
          This makes debugging information from the lpfc driver
          available via the debugfs filesystem.
 
-config LPFC_NVME_INITIATOR
-       bool "Emulex LightPulse Fibre Channel NVME Initiator Support"
-       depends on SCSI_LPFC && NVME_FC
-       ---help---
-         This enables NVME Initiator support in the Emulex lpfc driver.
-
-config LPFC_NVME_TARGET
-       bool "Emulex LightPulse Fibre Channel NVME Initiator Support"
-       depends on SCSI_LPFC && NVME_TARGET_FC
-       ---help---
-         This enables NVME Target support in the Emulex lpfc driver.
-         Target enablement must still be enabled on a per adapter
-         basis by module parameters.
-
 config SCSI_SIM710
        tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
        depends on (EISA || MCA) && SCSI
index a3ad042934870d4bd8bd5ded29a00516156d9168..c8172f16cf33cd6454ae571c3310f6451afa8b79 100644 (file)
@@ -2056,7 +2056,6 @@ static int fillup_pools(struct aac_dev *dev, struct hw_fib **hw_fib_pool,
 {
        struct hw_fib **hw_fib_p;
        struct fib **fib_p;
-       int rcode = 1;
 
        hw_fib_p = hw_fib_pool;
        fib_p = fib_pool;
@@ -2074,11 +2073,11 @@ static int fillup_pools(struct aac_dev *dev, struct hw_fib **hw_fib_pool,
                }
        }
 
+       /*
+        * Get the actual number of allocated fibs
+        */
        num = hw_fib_p - hw_fib_pool;
-       if (!num)
-               rcode = 0;
-
-       return rcode;
+       return num;
 }
 
 static void wakeup_fibctx_threads(struct aac_dev *dev,
@@ -2186,7 +2185,6 @@ static void aac_process_events(struct aac_dev *dev)
        struct fib *fib;
        unsigned long flags;
        spinlock_t *t_lock;
-       unsigned int rcode;
 
        t_lock = dev->queues->queue[HostNormCmdQueue].lock;
        spin_lock_irqsave(t_lock, flags);
@@ -2269,8 +2267,8 @@ static void aac_process_events(struct aac_dev *dev)
                 * Fill up fib pointer pools with actual fibs
                 * and hw_fibs
                 */
-               rcode = fillup_pools(dev, hw_fib_pool, fib_pool, num);
-               if (!rcode)
+               num = fillup_pools(dev, hw_fib_pool, fib_pool, num);
+               if (!num)
                        goto free_mem;
 
                /*
index 48e200102221c518dacba0a7137c77170e81c53a..c01b47e5b55a899a48b28553a41747b04d2903cc 100644 (file)
@@ -113,7 +113,7 @@ struct alua_queue_data {
 #define ALUA_POLICY_SWITCH_ALL         1
 
 static void alua_rtpg_work(struct work_struct *work);
-static void alua_rtpg_queue(struct alua_port_group *pg,
+static bool alua_rtpg_queue(struct alua_port_group *pg,
                            struct scsi_device *sdev,
                            struct alua_queue_data *qdata, bool force);
 static void alua_check(struct scsi_device *sdev, bool force);
@@ -862,7 +862,13 @@ static void alua_rtpg_work(struct work_struct *work)
        kref_put(&pg->kref, release_port_group);
 }
 
-static void alua_rtpg_queue(struct alua_port_group *pg,
+/**
+ * alua_rtpg_queue() - cause RTPG to be submitted asynchronously
+ *
+ * Returns true if and only if alua_rtpg_work() will be called asynchronously.
+ * That function is responsible for calling @qdata->fn().
+ */
+static bool alua_rtpg_queue(struct alua_port_group *pg,
                            struct scsi_device *sdev,
                            struct alua_queue_data *qdata, bool force)
 {
@@ -870,8 +876,8 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
        unsigned long flags;
        struct workqueue_struct *alua_wq = kaluad_wq;
 
-       if (!pg)
-               return;
+       if (WARN_ON_ONCE(!pg) || scsi_device_get(sdev))
+               return false;
 
        spin_lock_irqsave(&pg->lock, flags);
        if (qdata) {
@@ -884,14 +890,12 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
                pg->flags |= ALUA_PG_RUN_RTPG;
                kref_get(&pg->kref);
                pg->rtpg_sdev = sdev;
-               scsi_device_get(sdev);
                start_queue = 1;
        } else if (!(pg->flags & ALUA_PG_RUN_RTPG) && force) {
                pg->flags |= ALUA_PG_RUN_RTPG;
                /* Do not queue if the worker is already running */
                if (!(pg->flags & ALUA_PG_RUNNING)) {
                        kref_get(&pg->kref);
-                       sdev = NULL;
                        start_queue = 1;
                }
        }
@@ -900,13 +904,17 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
                alua_wq = kaluad_sync_wq;
        spin_unlock_irqrestore(&pg->lock, flags);
 
-       if (start_queue &&
-           !queue_delayed_work(alua_wq, &pg->rtpg_work,
-                               msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS))) {
-               if (sdev)
-                       scsi_device_put(sdev);
-               kref_put(&pg->kref, release_port_group);
+       if (start_queue) {
+               if (queue_delayed_work(alua_wq, &pg->rtpg_work,
+                               msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS)))
+                       sdev = NULL;
+               else
+                       kref_put(&pg->kref, release_port_group);
        }
+       if (sdev)
+               scsi_device_put(sdev);
+
+       return true;
 }
 
 /*
@@ -1007,11 +1015,13 @@ static int alua_activate(struct scsi_device *sdev,
                mutex_unlock(&h->init_mutex);
                goto out;
        }
-       fn = NULL;
        rcu_read_unlock();
        mutex_unlock(&h->init_mutex);
 
-       alua_rtpg_queue(pg, sdev, qdata, true);
+       if (alua_rtpg_queue(pg, sdev, qdata, true))
+               fn = NULL;
+       else
+               err = SCSI_DH_DEV_OFFLINED;
        kref_put(&pg->kref, release_port_group);
 out:
        if (fn)
index 524a0c755ed7e74cd790778ec7c04ae452cc853d..9d659aaace15d0e3ec28c69a14688b81a544d8b7 100644 (file)
@@ -2956,7 +2956,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
        /* fill_cmd can't fail here, no data buffer to map. */
        (void) fill_cmd(c, reset_type, h, NULL, 0, 0,
                        scsi3addr, TYPE_MSG);
-       rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
+       rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
        if (rc) {
                dev_warn(&h->pdev->dev, "Failed to send reset command\n");
                goto out;
@@ -3714,7 +3714,7 @@ exit_failed:
  *  # (integer code indicating one of several NOT READY states
  *     describing why a volume is to be kept offline)
  */
-static int hpsa_volume_offline(struct ctlr_info *h,
+static unsigned char hpsa_volume_offline(struct ctlr_info *h,
                                        unsigned char scsi3addr[])
 {
        struct CommandList *c;
@@ -3735,7 +3735,7 @@ static int hpsa_volume_offline(struct ctlr_info *h,
                                        DEFAULT_TIMEOUT);
        if (rc) {
                cmd_free(h, c);
-               return 0;
+               return HPSA_VPD_LV_STATUS_UNSUPPORTED;
        }
        sense = c->err_info->SenseInfo;
        if (c->err_info->SenseLen > sizeof(c->err_info->SenseInfo))
@@ -3746,19 +3746,13 @@ static int hpsa_volume_offline(struct ctlr_info *h,
        cmd_status = c->err_info->CommandStatus;
        scsi_status = c->err_info->ScsiStatus;
        cmd_free(h, c);
-       /* Is the volume 'not ready'? */
-       if (cmd_status != CMD_TARGET_STATUS ||
-               scsi_status != SAM_STAT_CHECK_CONDITION ||
-               sense_key != NOT_READY ||
-               asc != ASC_LUN_NOT_READY)  {
-               return 0;
-       }
 
        /* Determine the reason for not ready state */
        ldstat = hpsa_get_volume_status(h, scsi3addr);
 
        /* Keep volume offline in certain cases: */
        switch (ldstat) {
+       case HPSA_LV_FAILED:
        case HPSA_LV_UNDERGOING_ERASE:
        case HPSA_LV_NOT_AVAILABLE:
        case HPSA_LV_UNDERGOING_RPI:
@@ -3780,7 +3774,7 @@ static int hpsa_volume_offline(struct ctlr_info *h,
        default:
                break;
        }
-       return 0;
+       return HPSA_LV_OK;
 }
 
 /*
@@ -3853,10 +3847,10 @@ static int hpsa_update_device_info(struct ctlr_info *h,
        /* Do an inquiry to the device to see what it is. */
        if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff,
                (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
-               /* Inquiry failed (msg printed already) */
                dev_err(&h->pdev->dev,
-                       "hpsa_update_device_info: inquiry failed\n");
-               rc = -EIO;
+                       "%s: inquiry failed, device will be skipped.\n",
+                       __func__);
+               rc = HPSA_INQUIRY_FAILED;
                goto bail_out;
        }
 
@@ -3885,15 +3879,20 @@ static int hpsa_update_device_info(struct ctlr_info *h,
        if ((this_device->devtype == TYPE_DISK ||
                this_device->devtype == TYPE_ZBC) &&
                is_logical_dev_addr_mode(scsi3addr)) {
-               int volume_offline;
+               unsigned char volume_offline;
 
                hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level);
                if (h->fw_support & MISC_FW_RAID_OFFLOAD_BASIC)
                        hpsa_get_ioaccel_status(h, scsi3addr, this_device);
                volume_offline = hpsa_volume_offline(h, scsi3addr);
-               if (volume_offline < 0 || volume_offline > 0xff)
-                       volume_offline = HPSA_VPD_LV_STATUS_UNSUPPORTED;
-               this_device->volume_offline = volume_offline & 0xff;
+               this_device->volume_offline = volume_offline;
+               if (volume_offline == HPSA_LV_FAILED) {
+                       rc = HPSA_LV_FAILED;
+                       dev_err(&h->pdev->dev,
+                               "%s: LV failed, device will be skipped.\n",
+                               __func__);
+                       goto bail_out;
+               }
        } else {
                this_device->raid_level = RAID_UNKNOWN;
                this_device->offload_config = 0;
@@ -4379,8 +4378,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
                        goto out;
                }
                if (rc) {
-                       dev_warn(&h->pdev->dev,
-                               "Inquiry failed, skipping device.\n");
+                       h->drv_req_rescan = 1;
                        continue;
                }
 
@@ -5558,7 +5556,7 @@ static void hpsa_scan_complete(struct ctlr_info *h)
 
        spin_lock_irqsave(&h->scan_lock, flags);
        h->scan_finished = 1;
-       wake_up_all(&h->scan_wait_queue);
+       wake_up(&h->scan_wait_queue);
        spin_unlock_irqrestore(&h->scan_lock, flags);
 }
 
@@ -5576,11 +5574,23 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
        if (unlikely(lockup_detected(h)))
                return hpsa_scan_complete(h);
 
+       /*
+        * If a scan is already waiting to run, no need to add another
+        */
+       spin_lock_irqsave(&h->scan_lock, flags);
+       if (h->scan_waiting) {
+               spin_unlock_irqrestore(&h->scan_lock, flags);
+               return;
+       }
+
+       spin_unlock_irqrestore(&h->scan_lock, flags);
+
        /* wait until any scan already in progress is finished. */
        while (1) {
                spin_lock_irqsave(&h->scan_lock, flags);
                if (h->scan_finished)
                        break;
+               h->scan_waiting = 1;
                spin_unlock_irqrestore(&h->scan_lock, flags);
                wait_event(h->scan_wait_queue, h->scan_finished);
                /* Note: We don't need to worry about a race between this
@@ -5590,6 +5600,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
                 */
        }
        h->scan_finished = 0; /* mark scan as in progress */
+       h->scan_waiting = 0;
        spin_unlock_irqrestore(&h->scan_lock, flags);
 
        if (unlikely(lockup_detected(h)))
@@ -8792,6 +8803,7 @@ reinit_after_soft_reset:
        init_waitqueue_head(&h->event_sync_wait_queue);
        mutex_init(&h->reset_mutex);
        h->scan_finished = 1; /* no scan currently in progress */
+       h->scan_waiting = 0;
 
        pci_set_drvdata(pdev, h);
        h->ndevices = 0;
index bf6cdc1066544fa5fe2df6f5396d17ca4b4c8909..6f04f2ad412530a76d615b394250d502221d5457 100644 (file)
@@ -201,6 +201,7 @@ struct ctlr_info {
        dma_addr_t              errinfo_pool_dhandle;
        unsigned long           *cmd_pool_bits;
        int                     scan_finished;
+       u8                      scan_waiting : 1;
        spinlock_t              scan_lock;
        wait_queue_head_t       scan_wait_queue;
 
index a584cdf0705846ef13a0375ecb2e1579513ecf92..5961705eef767526f66a6dbc1bbb1e7feec70c85 100644 (file)
 #define CFGTBL_BusType_Fibre2G  0x00000200l
 
 /* VPD Inquiry types */
+#define HPSA_INQUIRY_FAILED            0x02
 #define HPSA_VPD_SUPPORTED_PAGES        0x00
 #define HPSA_VPD_LV_DEVICE_ID           0x83
 #define HPSA_VPD_LV_DEVICE_GEOMETRY     0xC1
 /* Logical volume states */
 #define HPSA_VPD_LV_STATUS_UNSUPPORTED                 0xff
 #define HPSA_LV_OK                                      0x0
+#define HPSA_LV_FAILED                                 0x01
 #define HPSA_LV_NOT_AVAILABLE                          0x0b
 #define HPSA_LV_UNDERGOING_ERASE                       0x0F
 #define HPSA_LV_UNDERGOING_RPI                         0x12
index 763f012fdeca00e21f086be86efa1ec12d65c5f0..87f5e694dbedd8a7eda74c1a5dccd0e9008e8c93 100644 (file)
@@ -221,7 +221,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
                task->num_scatter = qc->n_elem;
        } else {
                for_each_sg(qc->sg, sg, qc->n_elem, si)
-                       xfer += sg->length;
+                       xfer += sg_dma_len(sg);
 
                task->total_xfer_len = xfer;
                task->num_scatter = si;
index 5c3be3e6f5e2aebfa3da8d47a92775cb17d774a4..22819afbaef5c4a229ce66ebdf8d681b47fbbc2f 100644 (file)
@@ -3315,9 +3315,9 @@ LPFC_ATTR_R(nvmet_mrq_post, LPFC_DEF_MRQ_POST,
  * lpfc_enable_fc4_type: Defines what FC4 types are supported.
  * Supported Values:  1 - register just FCP
  *                    3 - register both FCP and NVME
- * Supported values are [1,3]. Default value is 3
+ * Supported values are [1,3]. Default value is 1
  */
-LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH,
+LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_FCP,
            LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH,
            "Define fc4 type to register with fabric.");
 
index c05f56c3023f1edb2ace78b50de25ef99f4b829e..7b7d314af0e0878f4a37eef337ebf29de84a3d1c 100644 (file)
 /* hbqinfo output buffer size */
 #define LPFC_HBQINFO_SIZE 8192
 
-enum {
-       DUMP_FCP,
-       DUMP_NVME,
-       DUMP_MBX,
-       DUMP_ELS,
-       DUMP_NVMELS,
-};
-
 /* nvmestat output buffer size */
 #define LPFC_NVMESTAT_SIZE 8192
 #define LPFC_NVMEKTIME_SIZE 8192
@@ -283,8 +275,22 @@ struct lpfc_idiag {
        struct lpfc_idiag_offset offset;
        void *ptr_private;
 };
+
+#else
+
+#define lpfc_nvmeio_data(phba, fmt, arg...) \
+       no_printk(fmt, ##arg)
+
 #endif
 
+enum {
+       DUMP_FCP,
+       DUMP_NVME,
+       DUMP_MBX,
+       DUMP_ELS,
+       DUMP_NVMELS,
+};
+
 /* Mask for discovery_trace */
 #define LPFC_DISC_TRC_ELS_CMD          0x1     /* Trace ELS commands */
 #define LPFC_DISC_TRC_ELS_RSP          0x2     /* Trace ELS response */
index d9c61d030034da95854d2524406c17c202a317b9..a5ca37e45fb68266303244ca91fdc01d60e08f62 100644 (file)
@@ -7968,7 +7968,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        did, vport->port_state, ndlp->nlp_flag);
 
                phba->fc_stat.elsRcvPRLI++;
-               if (vport->port_state < LPFC_DISC_AUTH) {
+               if ((vport->port_state < LPFC_DISC_AUTH) &&
+                   (vport->fc_flag & FC_FABRIC)) {
                        rjt_err = LSRJT_UNABLE_TPC;
                        rjt_exp = LSEXP_NOTHING_MORE;
                        break;
index 2697d49da4d7762d13430cfd9737463d909bf93f..6cc561b042118ed6d172dddb8221d77c8a793ee4 100644 (file)
@@ -5891,10 +5891,17 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
                /* Check to see if it matches any module parameter */
                for (i = 0; i < lpfc_enable_nvmet_cnt; i++) {
                        if (wwn == lpfc_enable_nvmet[i]) {
+#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
                                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                                "6017 NVME Target %016llx\n",
                                                wwn);
                                phba->nvmet_support = 1; /* a match */
+#else
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "6021 Can't enable NVME Target."
+                                               " NVME_TARGET_FC infrastructure"
+                                               " is not in kernel\n");
+#endif
                        }
                }
        }
index 0a4c1908140940cc116450cc5d5cb5a7a99de634..0024de1c6c1fea8e4568007a23296dd46f709826 100644 (file)
@@ -2149,7 +2149,7 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
        /* localport is allocated from the stack, but the registration
         * call allocates heap memory as well as the private area.
         */
-#ifdef CONFIG_LPFC_NVME_INITIATOR
+#if (IS_ENABLED(CONFIG_NVME_FC))
        ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template,
                                         &vport->phba->pcidev->dev, &localport);
 #else
@@ -2190,7 +2190,7 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
 void
 lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
 {
-#ifdef CONFIG_LPFC_NVME_INITIATOR
+#if (IS_ENABLED(CONFIG_NVME_FC))
        struct nvme_fc_local_port *localport;
        struct lpfc_nvme_lport *lport;
        struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL;
@@ -2274,7 +2274,7 @@ lpfc_nvme_update_localport(struct lpfc_vport *vport)
 int
 lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
-#ifdef CONFIG_LPFC_NVME_INITIATOR
+#if (IS_ENABLED(CONFIG_NVME_FC))
        int ret = 0;
        struct nvme_fc_local_port *localport;
        struct lpfc_nvme_lport *lport;
@@ -2403,7 +2403,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 void
 lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
-#ifdef CONFIG_LPFC_NVME_INITIATOR
+#if (IS_ENABLED(CONFIG_NVME_FC))
        int ret;
        struct nvme_fc_local_port *localport;
        struct lpfc_nvme_lport *lport;
index b7739a554fe00505401bae97183ec3ce69559768..acba1b67e505e9bbe57cbb4ea86c79a0a1e079f7 100644 (file)
@@ -520,7 +520,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
        struct lpfc_hba *phba = ctxp->phba;
        struct lpfc_iocbq *nvmewqeq;
        unsigned long iflags;
-       int rc, id;
+       int rc;
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
        if (phba->ktime_on) {
@@ -530,7 +530,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
                        ctxp->ts_nvme_data = ktime_get_ns();
        }
        if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) {
-               id = smp_processor_id();
+               int id = smp_processor_id();
                ctxp->cpu = id;
                if (id < LPFC_CHECK_CPU_CNT)
                        phba->cpucheck_xmt_io[id]++;
@@ -671,7 +671,7 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)
        lpfc_tgttemplate.target_features = NVMET_FCTGTFEAT_READDATA_RSP |
                                           NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED;
 
-#ifdef CONFIG_LPFC_NVME_TARGET
+#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
        error = nvmet_fc_register_targetport(&pinfo, &lpfc_tgttemplate,
                                             &phba->pcidev->dev,
                                             &phba->targetport);
@@ -756,7 +756,7 @@ lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba,
 void
 lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
 {
-#ifdef CONFIG_LPFC_NVME_TARGET
+#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
        struct lpfc_nvmet_tgtport *tgtp;
 
        if (phba->nvmet_support == 0)
@@ -788,7 +788,7 @@ static void
 lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                           struct hbq_dmabuf *nvmebuf)
 {
-#ifdef CONFIG_LPFC_NVME_TARGET
+#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
        struct lpfc_nvmet_tgtport *tgtp;
        struct fc_frame_header *fc_hdr;
        struct lpfc_nvmet_rcv_ctx *ctxp;
@@ -891,7 +891,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
                            struct rqb_dmabuf *nvmebuf,
                            uint64_t isr_timestamp)
 {
-#ifdef CONFIG_LPFC_NVME_TARGET
+#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
        struct lpfc_nvmet_rcv_ctx *ctxp;
        struct lpfc_nvmet_tgtport *tgtp;
        struct fc_frame_header *fc_hdr;
index e7e5974e1a2c435ef2ee0a79276e981fcb79cc87..2b209bbb4c9165fa7afdeff0f233f649684f8495 100644 (file)
@@ -35,8 +35,8 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "07.701.16.00-rc1"
-#define MEGASAS_RELDATE                                "February 2, 2017"
+#define MEGASAS_VERSION                                "07.701.17.00-rc1"
+#define MEGASAS_RELDATE                                "March 2, 2017"
 
 /*
  * Device IDs
index 7ac9a9ee9bd473c3cc0b6178975f46e3d32f3b77..0016f12cc563e7c6e1eb3c2a87685f60c83b9747 100644 (file)
@@ -1963,6 +1963,9 @@ scan_target:
        if (!mr_device_priv_data)
                return -ENOMEM;
        sdev->hostdata = mr_device_priv_data;
+
+       atomic_set(&mr_device_priv_data->r1_ldio_hint,
+                  instance->r1_ldio_hint_default);
        return 0;
 }
 
@@ -5034,10 +5037,12 @@ megasas_setup_irqs_msix(struct megasas_instance *instance, u8 is_probe)
                                         &instance->irq_context[j]);
                        /* Retry irq register for IO_APIC*/
                        instance->msix_vectors = 0;
-                       if (is_probe)
+                       if (is_probe) {
+                               pci_free_irq_vectors(instance->pdev);
                                return megasas_setup_irqs_ioapic(instance);
-                       else
+                       } else {
                                return -1;
+                       }
                }
        }
        return 0;
@@ -5277,9 +5282,11 @@ static int megasas_init_fw(struct megasas_instance *instance)
                        MPI2_REPLY_POST_HOST_INDEX_OFFSET);
        }
 
-       i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY);
-       if (i < 0)
-               goto fail_setup_irqs;
+       if (!instance->msix_vectors) {
+               i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY);
+               if (i < 0)
+                       goto fail_setup_irqs;
+       }
 
        dev_info(&instance->pdev->dev,
                "firmware supports msix\t: (%d)", fw_msix_count);
index 29650ba669da58da099cf91e9de0aae504146bb0..f990ab4d45e1bf72b3adf8991b11c01309c7530b 100644 (file)
@@ -2159,7 +2159,7 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context,
                                cpu_sel = MR_RAID_CTX_CPUSEL_1;
 
                        if (is_stream_detected(rctx_g35) &&
-                           (raid->level == 5) &&
+                           ((raid->level == 5) || (raid->level == 6)) &&
                            (raid->writeMode == MR_RL_WRITE_THROUGH_MODE) &&
                            (cpu_sel == MR_RAID_CTX_CPUSEL_FCFS))
                                cpu_sel = MR_RAID_CTX_CPUSEL_0;
@@ -2338,7 +2338,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
                                fp_possible = false;
                                atomic_dec(&instance->fw_outstanding);
                        } else if ((scsi_buff_len > MR_LARGE_IO_MIN_SIZE) ||
-                                  atomic_dec_if_positive(&mrdev_priv->r1_ldio_hint)) {
+                                  (atomic_dec_if_positive(&mrdev_priv->r1_ldio_hint) > 0)) {
                                fp_possible = false;
                                atomic_dec(&instance->fw_outstanding);
                                if (scsi_buff_len > MR_LARGE_IO_MIN_SIZE)
index 8e3d92807cb8033acea1bc3c9e990b05f521f8a8..92775a8b74b1cdc068b8d8808b7bd9ccd5b212eb 100644 (file)
@@ -2007,6 +2007,7 @@ static void qedi_remove(struct pci_dev *pdev)
 
 static struct pci_device_id qedi_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, 0x165E) },
+       { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, 0x8084) },
        { 0 },
 };
 MODULE_DEVICE_TABLE(pci, qedi_pci_tbl);
index 41d5b09f7326fb706f132fc64bcfe54023e37309..3e7011757c8267022744e19778f49cc4db286822 100644 (file)
@@ -1651,7 +1651,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
                                /* Don't abort commands in adapter during EEH
                                 * recovery as it's not accessible/responding.
                                 */
-                               if (GET_CMD_SP(sp) && !ha->flags.eeh_busy) {
+                               if (GET_CMD_SP(sp) && !ha->flags.eeh_busy &&
+                                   (sp->type == SRB_SCSI_CMD)) {
                                        /* Get a reference to the sp and drop the lock.
                                         * The reference ensures this sp->done() call
                                         * - and not the call in qla2xxx_eh_abort() -
index 29b86505f796d9fa57c19b958c1c7ae4ef31b298..225abaad4d1cc86f462574a8143bc2ffb2cc69a8 100644 (file)
@@ -996,6 +996,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
                result = get_user(val, ip);
                if (result)
                        return result;
+               if (val > SG_MAX_CDB_SIZE)
+                       return -ENOMEM;
                sfp->next_cmd_len = (val > 0) ? val : 0;
                return 0;
        case SG_GET_VERSION_NUM:
index a72a4ba78125b09a135c781533d46b1cbf0bc042..8e5e6c04c035e1e134d84670ff19459597df35b1 100644 (file)
@@ -309,8 +309,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
 
        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        mmio_base = devm_ioremap_resource(dev, mem_res);
-       if (IS_ERR(*(void **)&mmio_base)) {
-               err = PTR_ERR(*(void **)&mmio_base);
+       if (IS_ERR(mmio_base)) {
+               err = PTR_ERR(mmio_base);
                goto out;
        }
 
index 1359913bf840ce0522e09fe72b5c93bd210e4db7..096e95b911bd7b29abf2c06a58191b76ce0a4139 100644 (file)
@@ -4662,8 +4662,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
                }
                if (ufshcd_is_clkscaling_supported(hba))
                        hba->clk_scaling.active_reqs--;
-               if (ufshcd_is_clkscaling_supported(hba))
-                       hba->clk_scaling.active_reqs--;
        }
 
        /* clear corresponding bits of completed commands */
@@ -7642,7 +7640,7 @@ static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
        if (kstrtoul(buf, 0, &value))
                return -EINVAL;
 
-       if ((value < UFS_PM_LVL_0) || (value >= UFS_PM_LVL_MAX))
+       if (value >= UFS_PM_LVL_MAX)
                return -EINVAL;
 
        spin_lock_irqsave(hba->host->host_lock, flags);
index 91048eeca28b2dc3d81f234ed60bbfdd796f8277..69d0f430b2d190756de94d4b6b6334d1af2dfa50 100644 (file)
@@ -107,8 +107,6 @@ struct cpufreq_cooling_device {
 };
 static DEFINE_IDA(cpufreq_ida);
 
-static unsigned int cpufreq_dev_count;
-
 static DEFINE_MUTEX(cooling_list_lock);
 static LIST_HEAD(cpufreq_dev_list);
 
@@ -395,13 +393,20 @@ static int get_static_power(struct cpufreq_cooling_device *cpufreq_device,
 
        opp = dev_pm_opp_find_freq_exact(cpufreq_device->cpu_dev, freq_hz,
                                         true);
+       if (IS_ERR(opp)) {
+               dev_warn_ratelimited(cpufreq_device->cpu_dev,
+                                    "Failed to find OPP for frequency %lu: %ld\n",
+                                    freq_hz, PTR_ERR(opp));
+               return -EINVAL;
+       }
+
        voltage = dev_pm_opp_get_voltage(opp);
        dev_pm_opp_put(opp);
 
        if (voltage == 0) {
-               dev_warn_ratelimited(cpufreq_device->cpu_dev,
-                                    "Failed to get voltage for frequency %lu: %ld\n",
-                                    freq_hz, IS_ERR(opp) ? PTR_ERR(opp) : 0);
+               dev_err_ratelimited(cpufreq_device->cpu_dev,
+                                   "Failed to get voltage for frequency %lu\n",
+                                   freq_hz);
                return -EINVAL;
        }
 
@@ -693,9 +698,9 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
 
        *state = cpufreq_cooling_get_level(cpu, target_freq);
        if (*state == THERMAL_CSTATE_INVALID) {
-               dev_warn_ratelimited(&cdev->device,
-                                    "Failed to convert %dKHz for cpu %d into a cdev state\n",
-                                    target_freq, cpu);
+               dev_err_ratelimited(&cdev->device,
+                                   "Failed to convert %dKHz for cpu %d into a cdev state\n",
+                                   target_freq, cpu);
                return -EINVAL;
        }
 
@@ -771,6 +776,7 @@ __cpufreq_cooling_register(struct device_node *np,
        unsigned int freq, i, num_cpus;
        int ret;
        struct thermal_cooling_device_ops *cooling_ops;
+       bool first;
 
        if (!alloc_cpumask_var(&temp_mask, GFP_KERNEL))
                return ERR_PTR(-ENOMEM);
@@ -874,13 +880,14 @@ __cpufreq_cooling_register(struct device_node *np,
        cpufreq_dev->cool_dev = cool_dev;
 
        mutex_lock(&cooling_list_lock);
+       /* Register the notifier for first cpufreq cooling device */
+       first = list_empty(&cpufreq_dev_list);
        list_add(&cpufreq_dev->node, &cpufreq_dev_list);
+       mutex_unlock(&cooling_list_lock);
 
-       /* Register the notifier for first cpufreq cooling device */
-       if (!cpufreq_dev_count++)
+       if (first)
                cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
                                          CPUFREQ_POLICY_NOTIFIER);
-       mutex_unlock(&cooling_list_lock);
 
        goto put_policy;
 
@@ -1021,6 +1028,7 @@ EXPORT_SYMBOL(of_cpufreq_power_cooling_register);
 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 {
        struct cpufreq_cooling_device *cpufreq_dev;
+       bool last;
 
        if (!cdev)
                return;
@@ -1028,14 +1036,15 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
        cpufreq_dev = cdev->devdata;
 
        mutex_lock(&cooling_list_lock);
+       list_del(&cpufreq_dev->node);
        /* Unregister the notifier for the last cpufreq cooling device */
-       if (!--cpufreq_dev_count)
+       last = list_empty(&cpufreq_dev_list);
+       mutex_unlock(&cooling_list_lock);
+
+       if (last)
                cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
                                            CPUFREQ_POLICY_NOTIFIER);
 
-       list_del(&cpufreq_dev->node);
-       mutex_unlock(&cooling_list_lock);
-
        thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
        ida_simple_remove(&cpufreq_ida, cpufreq_dev->id);
        kfree(cpufreq_dev->dyn_power_table);
index 7743a78d472397bbf9a10c0b1ac2d7e4b163a6a6..4bf4ad58cffda0172a48138248f4b406790c58e8 100644 (file)
@@ -186,16 +186,22 @@ get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq)
                return 0;
 
        opp = dev_pm_opp_find_freq_exact(dev, freq, true);
-       if (IS_ERR(opp) && (PTR_ERR(opp) == -ERANGE))
+       if (PTR_ERR(opp) == -ERANGE)
                opp = dev_pm_opp_find_freq_exact(dev, freq, false);
 
+       if (IS_ERR(opp)) {
+               dev_err_ratelimited(dev, "Failed to find OPP for frequency %lu: %ld\n",
+                                   freq, PTR_ERR(opp));
+               return 0;
+       }
+
        voltage = dev_pm_opp_get_voltage(opp) / 1000; /* mV */
        dev_pm_opp_put(opp);
 
        if (voltage == 0) {
-               dev_warn_ratelimited(dev,
-                                    "Failed to get voltage for frequency %lu: %ld\n",
-                                    freq, IS_ERR(opp) ? PTR_ERR(opp) : 0);
+               dev_err_ratelimited(dev,
+                                   "Failed to get voltage for frequency %lu\n",
+                                   freq);
                return 0;
        }
 
index 6ee55a2d47bb429f73cf9d2b2711b109f6746a3d..e65808c482f1847d09d819a24defb0e5cf6508b5 100644 (file)
@@ -257,7 +257,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
 {
        unsigned int baud = tty_termios_baud_rate(termios);
        struct dw8250_data *d = p->private_data;
-       unsigned int rate;
+       long rate;
        int ret;
 
        if (IS_ERR(d->clk) || !old)
@@ -265,7 +265,12 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
 
        clk_disable_unprepare(d->clk);
        rate = clk_round_rate(d->clk, baud * 16);
-       ret = clk_set_rate(d->clk, rate);
+       if (rate < 0)
+               ret = rate;
+       else if (rate == 0)
+               ret = -ENOENT;
+       else
+               ret = clk_set_rate(d->clk, rate);
        clk_prepare_enable(d->clk);
 
        if (!ret)
index a65fb8197aecb6af029bc4469d5920618dd39359..0e3f529d50e9d07bd684c92ddda4878ac553b9e7 100644 (file)
@@ -128,9 +128,13 @@ config SERIAL_8250_PCI
          by the parport_serial driver, enabled with CONFIG_PARPORT_SERIAL.
 
 config SERIAL_8250_EXAR
-        tristate "8250/16550 PCI device support"
-        depends on SERIAL_8250_PCI
+       tristate "8250/16550 Exar/Commtech PCI/PCIe device support"
+       depends on SERIAL_8250_PCI
        default SERIAL_8250
+       help
+         This builds support for XR17C1xx, XR17V3xx and some Commtech
+         422x PCIe serial cards that are not covered by the more generic
+         SERIAL_8250_PCI option.
 
 config SERIAL_8250_HP300
        tristate
index 8789ea423ccfd1054d9d5433538d0a8e466525dd..b0a377725d636c11cddad62470d821a31f1fff96 100644 (file)
@@ -2373,7 +2373,7 @@ static int __init pl011_console_match(struct console *co, char *name, int idx,
        if (strcmp(name, "qdf2400_e44") == 0) {
                pr_info_once("UART: Working around QDF2400 SoC erratum 44");
                qdf2400_e44_present = true;
-       } else if (strcmp(name, "pl011") != 0 || strcmp(name, "ttyAMA") != 0) {
+       } else if (strcmp(name, "pl011") != 0) {
                return -ENODEV;
        }
 
@@ -2452,18 +2452,37 @@ static void pl011_early_write(struct console *con, const char *s, unsigned n)
        uart_console_write(&dev->port, s, n, pl011_putc);
 }
 
+/*
+ * On non-ACPI systems, earlycon is enabled by specifying
+ * "earlycon=pl011,<address>" on the kernel command line.
+ *
+ * On ACPI ARM64 systems, an "early" console is enabled via the SPCR table,
+ * by specifying only "earlycon" on the command line.  Because it requires
+ * SPCR, the console starts after ACPI is parsed, which is later than a
+ * traditional early console.
+ *
+ * To get the traditional early console that starts before ACPI is parsed,
+ * specify the full "earlycon=pl011,<address>" option.
+ */
 static int __init pl011_early_console_setup(struct earlycon_device *device,
                                            const char *opt)
 {
        if (!device->port.membase)
                return -ENODEV;
 
-       device->con->write = qdf2400_e44_present ?
-                               qdf2400_e44_early_write : pl011_early_write;
+       /* On QDF2400 SOCs affected by Erratum 44, the "qdf2400_e44" must
+        * also be specified, e.g. "earlycon=pl011,<address>,qdf2400_e44".
+        */
+       if (!strcmp(device->options, "qdf2400_e44"))
+               device->con->write = qdf2400_e44_early_write;
+       else
+               device->con->write = pl011_early_write;
+
        return 0;
 }
 OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup);
 OF_EARLYCON_DECLARE(pl011, "arm,sbsa-uart", pl011_early_console_setup);
+EARLYCON_DECLARE(qdf2400_e44, pl011_early_console_setup);
 
 #else
 #define AMBA_CONSOLE   NULL
index dcebb28ffbc412d5282ef32b7f3c133ff984ab46..1f50a83ef958609c3f27473b135e84e65303330d 100644 (file)
@@ -1951,6 +1951,11 @@ static void atmel_flush_buffer(struct uart_port *port)
                atmel_uart_writel(port, ATMEL_PDC_TCR, 0);
                atmel_port->pdc_tx.ofs = 0;
        }
+       /*
+        * in uart_flush_buffer(), the xmit circular buffer has just
+        * been cleared, so we have to reset tx_len accordingly.
+        */
+       atmel_port->tx_len = 0;
 }
 
 /*
@@ -2483,6 +2488,9 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
        pdc_tx = atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN;
        atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
 
+       /* Make sure that tx path is actually able to send characters */
+       atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
+
        uart_console_write(port, s, count, atmel_console_putchar);
 
        /*
index 6989b227d1349baeb0cb05ed9f7cff8572e36324..be94246b6fcca1874161470035b9d9bd91237f88 100644 (file)
@@ -1088,7 +1088,7 @@ static void mxs_auart_settermios(struct uart_port *u,
                                        AUART_LINECTRL_BAUD_DIV_MAX);
                baud_max = u->uartclk * 32 / AUART_LINECTRL_BAUD_DIV_MIN;
                baud = uart_get_baud_rate(u, termios, old, baud_min, baud_max);
-               div = u->uartclk * 32 / baud;
+               div = DIV_ROUND_CLOSEST(u->uartclk * 32, baud);
        }
 
        ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
index bcf1d33e6ffe0b3cb9952e88046658df1358543b..c334bcc59c649eedc2933ac29c4dc1ef45ae21d2 100644 (file)
@@ -575,12 +575,13 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
                        pinctrl_select_state(ascport->pinctrl,
                                             ascport->states[NO_HW_FLOWCTRL]);
 
-                       gpiod = devm_get_gpiod_from_child(port->dev, "rts",
-                                                         &np->fwnode);
-                       if (!IS_ERR(gpiod)) {
-                               gpiod_direction_output(gpiod, 0);
+                       gpiod = devm_fwnode_get_gpiod_from_child(port->dev,
+                                                                "rts",
+                                                                &np->fwnode,
+                                                                GPIOD_OUT_LOW,
+                                                                np->name);
+                       if (!IS_ERR(gpiod))
                                ascport->rts = gpiod;
-                       }
                }
        }
 
index 68947f6de5ad6339adea804182597229c3eb1d38..b0500a0a87b86161b8cf8befcee9753ff6cda74d 100644 (file)
@@ -271,10 +271,13 @@ const struct file_operations tty_ldiscs_proc_fops = {
 
 struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
 {
+       struct tty_ldisc *ld;
+
        ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
-       if (!tty->ldisc)
+       ld = tty->ldisc;
+       if (!ld)
                ldsem_up_read(&tty->ldisc_sem);
-       return tty->ldisc;
+       return ld;
 }
 EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
 
@@ -488,41 +491,6 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
        tty_ldisc_debug(tty, "%p: closed\n", ld);
 }
 
-/**
- *     tty_ldisc_restore       -       helper for tty ldisc change
- *     @tty: tty to recover
- *     @old: previous ldisc
- *
- *     Restore the previous line discipline or N_TTY when a line discipline
- *     change fails due to an open error
- */
-
-static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
-{
-       struct tty_ldisc *new_ldisc;
-       int r;
-
-       /* There is an outstanding reference here so this is safe */
-       old = tty_ldisc_get(tty, old->ops->num);
-       WARN_ON(IS_ERR(old));
-       tty->ldisc = old;
-       tty_set_termios_ldisc(tty, old->ops->num);
-       if (tty_ldisc_open(tty, old) < 0) {
-               tty_ldisc_put(old);
-               /* This driver is always present */
-               new_ldisc = tty_ldisc_get(tty, N_TTY);
-               if (IS_ERR(new_ldisc))
-                       panic("n_tty: get");
-               tty->ldisc = new_ldisc;
-               tty_set_termios_ldisc(tty, N_TTY);
-               r = tty_ldisc_open(tty, new_ldisc);
-               if (r < 0)
-                       panic("Couldn't open N_TTY ldisc for "
-                             "%s --- error %d.",
-                             tty_name(tty), r);
-       }
-}
-
 /**
  *     tty_set_ldisc           -       set line discipline
  *     @tty: the terminal to set
@@ -536,12 +504,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
 
 int tty_set_ldisc(struct tty_struct *tty, int disc)
 {
-       int retval;
-       struct tty_ldisc *old_ldisc, *new_ldisc;
-
-       new_ldisc = tty_ldisc_get(tty, disc);
-       if (IS_ERR(new_ldisc))
-               return PTR_ERR(new_ldisc);
+       int retval, old_disc;
 
        tty_lock(tty);
        retval = tty_ldisc_lock(tty, 5 * HZ);
@@ -554,7 +517,8 @@ int tty_set_ldisc(struct tty_struct *tty, int disc)
        }
 
        /* Check the no-op case */
-       if (tty->ldisc->ops->num == disc)
+       old_disc = tty->ldisc->ops->num;
+       if (old_disc == disc)
                goto out;
 
        if (test_bit(TTY_HUPPED, &tty->flags)) {
@@ -563,34 +527,25 @@ int tty_set_ldisc(struct tty_struct *tty, int disc)
                goto out;
        }
 
-       old_ldisc = tty->ldisc;
-
-       /* Shutdown the old discipline. */
-       tty_ldisc_close(tty, old_ldisc);
-
-       /* Now set up the new line discipline. */
-       tty->ldisc = new_ldisc;
-       tty_set_termios_ldisc(tty, disc);
-
-       retval = tty_ldisc_open(tty, new_ldisc);
+       retval = tty_ldisc_reinit(tty, disc);
        if (retval < 0) {
                /* Back to the old one or N_TTY if we can't */
-               tty_ldisc_put(new_ldisc);
-               tty_ldisc_restore(tty, old_ldisc);
+               if (tty_ldisc_reinit(tty, old_disc) < 0) {
+                       pr_err("tty: TIOCSETD failed, reinitializing N_TTY\n");
+                       if (tty_ldisc_reinit(tty, N_TTY) < 0) {
+                               /* At this point we have tty->ldisc == NULL. */
+                               pr_err("tty: reinitializing N_TTY failed\n");
+                       }
+               }
        }
 
-       if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
+       if (tty->ldisc && tty->ldisc->ops->num != old_disc &&
+           tty->ops->set_ldisc) {
                down_read(&tty->termios_rwsem);
                tty->ops->set_ldisc(tty);
                up_read(&tty->termios_rwsem);
        }
 
-       /* At this point we hold a reference to the new ldisc and a
-          reference to the old ldisc, or we hold two references to
-          the old ldisc (if it was restored as part of error cleanup
-          above). In either case, releasing a single reference from
-          the old ldisc is correct. */
-       new_ldisc = old_ldisc;
 out:
        tty_ldisc_unlock(tty);
 
@@ -598,7 +553,6 @@ out:
           already running */
        tty_buffer_restart_work(tty->port);
 err:
-       tty_ldisc_put(new_ldisc);       /* drop the extra reference */
        tty_unlock(tty);
        return retval;
 }
@@ -659,10 +613,8 @@ int tty_ldisc_reinit(struct tty_struct *tty, int disc)
        int retval;
 
        ld = tty_ldisc_get(tty, disc);
-       if (IS_ERR(ld)) {
-               BUG_ON(disc == N_TTY);
+       if (IS_ERR(ld))
                return PTR_ERR(ld);
-       }
 
        if (tty->ldisc) {
                tty_ldisc_close(tty, tty->ldisc);
@@ -674,10 +626,8 @@ int tty_ldisc_reinit(struct tty_struct *tty, int disc)
        tty_set_termios_ldisc(tty, disc);
        retval = tty_ldisc_open(tty, tty->ldisc);
        if (retval) {
-               if (!WARN_ON(disc == N_TTY)) {
-                       tty_ldisc_put(tty->ldisc);
-                       tty->ldisc = NULL;
-               }
+               tty_ldisc_put(tty->ldisc);
+               tty->ldisc = NULL;
        }
        return retval;
 }
index c5f0fc906136b580b23df4e3708fd04d2c01e27b..8af8d9542663379ef1367ceb871f4753314bc984 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/sched/signal.h>
 #include <linux/sched/debug.h>
-#include <linux/sched/debug.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
index f03692ec552056845c6fa50947e38abca47ea66b..8fb309a0ff6b5dae0c6f867cd323585aeff17252 100644 (file)
@@ -1381,7 +1381,7 @@ static int usbtmc_probe(struct usb_interface *intf,
 
        dev_dbg(&intf->dev, "%s called\n", __func__);
 
-       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -1444,6 +1444,13 @@ static int usbtmc_probe(struct usb_interface *intf,
                        break;
                }
        }
+
+       if (!data->bulk_out || !data->bulk_in) {
+               dev_err(&intf->dev, "bulk endpoints not found\n");
+               retcode = -ENODEV;
+               goto err_put;
+       }
+
        /* Find int endpoint */
        for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
                endpoint = &iface_desc->endpoint[n].desc;
@@ -1469,8 +1476,10 @@ static int usbtmc_probe(struct usb_interface *intf,
        if (data->iin_ep_present) {
                /* allocate int urb */
                data->iin_urb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!data->iin_urb)
+               if (!data->iin_urb) {
+                       retcode = -ENOMEM;
                        goto error_register;
+               }
 
                /* Protect interrupt in endpoint data until iin_urb is freed */
                kref_get(&data->kref);
@@ -1478,8 +1487,10 @@ static int usbtmc_probe(struct usb_interface *intf,
                /* allocate buffer for interrupt in */
                data->iin_buffer = kmalloc(data->iin_wMaxPacketSize,
                                        GFP_KERNEL);
-               if (!data->iin_buffer)
+               if (!data->iin_buffer) {
+                       retcode = -ENOMEM;
                        goto error_register;
+               }
 
                /* fill interrupt urb */
                usb_fill_int_urb(data->iin_urb, data->usb_dev,
@@ -1512,6 +1523,7 @@ error_register:
        sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
        sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
        usbtmc_free_int(data);
+err_put:
        kref_put(&data->kref, usbtmc_delete);
        return retcode;
 }
index 25dbd8c7aec73345d357c2a75ff0cde26c918217..4be52c602e9b7a7de6a76ecb4be686cb12ec9950 100644 (file)
@@ -280,6 +280,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
 
                        /*
                         * Adjust bInterval for quirked devices.
+                        */
+                       /*
+                        * This quirk fixes bIntervals reported in ms.
+                        */
+                       if (to_usb_device(ddev)->quirks &
+                               USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
+                               n = clamp(fls(d->bInterval) + 3, i, j);
+                               i = j = n;
+                       }
+                       /*
                         * This quirk fixes bIntervals reported in
                         * linear microframes.
                         */
index 612fab6e54fb84f2d84372d202c77823fc3be921..79bdca5cb9c7ae8f01b1f4a25c7ceacd9c716e2c 100644 (file)
@@ -520,8 +520,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
         */
        tbuf_size =  max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
        tbuf = kzalloc(tbuf_size, GFP_KERNEL);
-       if (!tbuf)
-               return -ENOMEM;
+       if (!tbuf) {
+               status = -ENOMEM;
+               goto err_alloc;
+       }
 
        bufp = tbuf;
 
@@ -734,6 +736,7 @@ error:
        }
 
        kfree(tbuf);
+ err_alloc:
 
        /* any errors get returned through the urb completion */
        spin_lock_irq(&hcd_root_hub_lock);
index f0dd08198d7426b9973bb676bca12b8cb76d7e7b..5286bf67869a83e1d7e1d3f1ca0ebc87db5cf7a4 100644 (file)
@@ -4275,7 +4275,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
        struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
        int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
 
-       if (!udev->usb2_hw_lpm_capable)
+       if (!udev->usb2_hw_lpm_capable || !udev->bos)
                return;
 
        if (hub)
index 24f9f98968a5d860f83920287a5b7deb4c98bed6..96b21b0dac1e8c15fb20c19c85d13a58ab95b285 100644 (file)
@@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* M-Systems Flash Disk Pioneers */
        { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Baum Vario Ultra */
+       { USB_DEVICE(0x0904, 0x6101), .driver_info =
+                       USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+       { USB_DEVICE(0x0904, 0x6102), .driver_info =
+                       USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+       { USB_DEVICE(0x0904, 0x6103), .driver_info =
+                       USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+
        /* Keytouch QWERTY Panel keyboard */
        { USB_DEVICE(0x0926, 0x3333), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
index 0d75158e43fe4807569db4d10204cee406b097b7..79e7a3480d51b07abf3988a51f1790f6caec7ca3 100644 (file)
@@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
                int status)
 {
        struct dwc3                     *dwc = dep->dwc;
+       unsigned int                    unmap_after_complete = false;
 
        req->started = false;
        list_del(&req->list);
@@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
        if (req->request.status == -EINPROGRESS)
                req->request.status = status;
 
-       if (dwc->ep0_bounced && dep->number <= 1)
+       /*
+        * NOTICE we don't want to unmap before calling ->complete() if we're
+        * dealing with a bounced ep0 request. If we unmap it here, we would end
+        * up overwritting the contents of req->buf and this could confuse the
+        * gadget driver.
+        */
+       if (dwc->ep0_bounced && dep->number <= 1) {
                dwc->ep0_bounced = false;
-
-       usb_gadget_unmap_request_by_dev(dwc->sysdev,
-                       &req->request, req->direction);
+               unmap_after_complete = true;
+       } else {
+               usb_gadget_unmap_request_by_dev(dwc->sysdev,
+                               &req->request, req->direction);
+       }
 
        trace_dwc3_gadget_giveback(req);
 
@@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
        usb_gadget_giveback_request(&dep->endpoint, &req->request);
        spin_lock(&dwc->lock);
 
+       if (unmap_after_complete)
+               usb_gadget_unmap_request_by_dev(dwc->sysdev,
+                               &req->request, req->direction);
+
        if (dep->number > 1)
                pm_runtime_put(dwc->dev);
 }
index a30766ca422644ce91be7660b8822b4a7357f7f3..5e3828d9dac7f3af922456d141191ddd0733bbaf 100644 (file)
@@ -535,13 +535,15 @@ static int acm_notify_serial_state(struct f_acm *acm)
 {
        struct usb_composite_dev *cdev = acm->port.func.config->cdev;
        int                     status;
+       __le16                  serial_state;
 
        spin_lock(&acm->lock);
        if (acm->notify_req) {
                dev_dbg(&cdev->gadget->dev, "acm ttyGS%d serial state %04x\n",
                        acm->port_num, acm->serial_state);
+               serial_state = cpu_to_le16(acm->serial_state);
                status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE,
-                               0, &acm->serial_state, sizeof(acm->serial_state));
+                               0, &serial_state, sizeof(acm->serial_state));
        } else {
                acm->pending = true;
                status = 0;
index 89b48bcc377a16d426d6f5826a2e1ce5301124b6..5eea44823ca06d06955eb2bc51782cac6cd345ec 100644 (file)
@@ -367,7 +367,7 @@ try_again:
        count  = min_t(unsigned, count, hidg->report_length);
 
        spin_unlock_irqrestore(&hidg->write_spinlock, flags);
-       status = copy_from_user(hidg->req->buf, buffer, count);
+       status = copy_from_user(req->buf, buffer, count);
 
        if (status != 0) {
                ERROR(hidg->func.config->cdev,
@@ -378,9 +378,9 @@ try_again:
 
        spin_lock_irqsave(&hidg->write_spinlock, flags);
 
-       /* we our function has been disabled by host */
+       /* when our function has been disabled by host */
        if (!hidg->req) {
-               free_ep_req(hidg->in_ep, hidg->req);
+               free_ep_req(hidg->in_ep, req);
                /*
                 * TODO
                 * Should we fail with error here?
@@ -394,7 +394,7 @@ try_again:
        req->complete = f_hidg_req_complete;
        req->context  = hidg;
 
-       status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
+       status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
        if (status < 0) {
                ERROR(hidg->func.config->cdev,
                        "usb_ep_queue error on int endpoint %zd\n", status);
index 29b41b5dee04d2e0e3e87a6dc97d6dde84af49d0..f8a1881609a2c808f690f6d31ea6bcaf118b8bb4 100644 (file)
@@ -594,6 +594,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
        opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
        opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
 
+       /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
+       if (opts->streaming_maxburst &&
+           (opts->streaming_maxpacket % 1024) != 0) {
+               opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
+               INFO(cdev, "overriding streaming_maxpacket to %d\n",
+                    opts->streaming_maxpacket);
+       }
+
        /* Fill in the FS/HS/SS Video Streaming specific descriptors from the
         * module parameters.
         *
@@ -625,7 +633,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
        uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
        uvc_ss_streaming_comp.wBytesPerInterval =
                cpu_to_le16(max_packet_size * max_packet_mult *
-                           opts->streaming_maxburst);
+                           (opts->streaming_maxburst + 1));
 
        /* Allocate endpoints. */
        ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
index a97da645c1b9eaecc5e5bb0bcb5ad25857c43ec8..8a365aad66fe2e38eaf0a869ae0f774349f694f2 100644 (file)
@@ -1523,7 +1523,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev,
                td = phys_to_virt(addr);
                addr2 = (dma_addr_t)td->next;
                pci_pool_free(dev->data_requests, td, addr);
-               td->next = 0x00;
                addr = addr2;
        }
        req->chain_len = 1;
index bd02a6cd8e2c081f53c82b6f1face7b38bd0dbf7..6ed468fa7d5e593ca2e0fdabc6048fb7f2dd9f5d 100644 (file)
@@ -344,6 +344,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
 static struct platform_driver usb_xhci_driver = {
        .probe  = xhci_plat_probe,
        .remove = xhci_plat_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
        .driver = {
                .name = "xhci-hcd",
                .pm = DEV_PM_OPS,
index d9936c771fa074593e77aad4aa86f0771388e6b1..a3309aa02993dfa79e52a2b93a87b9efa289d498 100644 (file)
@@ -1989,6 +1989,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
                case TRB_NORMAL:
                        td->urb->actual_length = requested - remaining;
                        goto finish_td;
+               case TRB_STATUS:
+                       td->urb->actual_length = requested;
+                       goto finish_td;
                default:
                        xhci_warn(xhci, "WARN: unexpected TRB Type %d\n",
                                  trb_type);
index 50aee8b7718b30dc86938bba6a5e540e179ecdb9..953fd8f62df0787b0479286c12513656f141614f 100644 (file)
@@ -1477,6 +1477,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        struct xhci_ring *ep_ring;
        struct xhci_virt_ep *ep;
        struct xhci_command *command;
+       struct xhci_virt_device *vdev;
 
        xhci = hcd_to_xhci(hcd);
        spin_lock_irqsave(&xhci->lock, flags);
@@ -1485,15 +1486,27 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 
        /* Make sure the URB hasn't completed or been unlinked already */
        ret = usb_hcd_check_unlink_urb(hcd, urb, status);
-       if (ret || !urb->hcpriv)
+       if (ret)
                goto done;
+
+       /* give back URB now if we can't queue it for cancel */
+       vdev = xhci->devs[urb->dev->slot_id];
+       urb_priv = urb->hcpriv;
+       if (!vdev || !urb_priv)
+               goto err_giveback;
+
+       ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+       ep = &vdev->eps[ep_index];
+       ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
+       if (!ep || !ep_ring)
+               goto err_giveback;
+
        temp = readl(&xhci->op_regs->status);
        if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
                xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                                "HW died, freeing TD.");
-               urb_priv = urb->hcpriv;
                for (i = urb_priv->num_tds_done;
-                    i < urb_priv->num_tds && xhci->devs[urb->dev->slot_id];
+                    i < urb_priv->num_tds;
                     i++) {
                        td = &urb_priv->td[i];
                        if (!list_empty(&td->td_list))
@@ -1501,23 +1514,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                        if (!list_empty(&td->cancelled_td_list))
                                list_del_init(&td->cancelled_td_list);
                }
-
-               usb_hcd_unlink_urb_from_ep(hcd, urb);
-               spin_unlock_irqrestore(&xhci->lock, flags);
-               usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
-               xhci_urb_free_priv(urb_priv);
-               return ret;
+               goto err_giveback;
        }
 
-       ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-       ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
-       ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
-       if (!ep_ring) {
-               ret = -EINVAL;
-               goto done;
-       }
-
-       urb_priv = urb->hcpriv;
        i = urb_priv->num_tds_done;
        if (i < urb_priv->num_tds)
                xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
@@ -1554,6 +1553,14 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 done:
        spin_unlock_irqrestore(&xhci->lock, flags);
        return ret;
+
+err_giveback:
+       if (urb_priv)
+               xhci_urb_free_priv(urb_priv);
+       usb_hcd_unlink_urb_from_ep(hcd, urb);
+       spin_unlock_irqrestore(&xhci->lock, flags);
+       usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
+       return ret;
 }
 
 /* Drop an endpoint from a new bandwidth configuration for this device.
index 8b9fd7534f698b937b5a89113acc12c716368075..502bfe30a077a20120616af74b378c62bc2ec6d9 100644 (file)
@@ -347,6 +347,9 @@ static int idmouse_probe(struct usb_interface *interface,
        if (iface_desc->desc.bInterfaceClass != 0x0A)
                return -ENODEV;
 
+       if (iface_desc->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        /* allocate memory for our device state and initialize it */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL)
index 77176511658f3328f830ecdbd056f072a6c84f8a..d3d12475326663def2ce1f389f06f040d2a56126 100644 (file)
@@ -366,6 +366,10 @@ static int lvs_rh_probe(struct usb_interface *intf,
 
        hdev = interface_to_usbdev(intf);
        desc = intf->cur_altsetting;
+
+       if (desc->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        endpoint = &desc->endpoint[0].desc;
 
        /* valid only for SS root hub */
index e45a3a680db8f6490257c0f6decdfd6d1d8247d8..07014cad6dbe357bca938561eaf976dbbee902d4 100644 (file)
@@ -709,6 +709,11 @@ static int uss720_probe(struct usb_interface *intf,
 
        interface = intf->cur_altsetting;
 
+       if (interface->desc.bNumEndpoints < 3) {
+               usb_put_dev(usbdev);
+               return -ENODEV;
+       }
+
        /*
         * Allocate parport interface 
         */
index d8bae6ca890475b16bf7d45058ae35713ca46656..0c3664ab705eed549e73d53dea13976066182ee1 100644 (file)
@@ -2490,8 +2490,8 @@ static int musb_remove(struct platform_device *pdev)
        musb_host_cleanup(musb);
        musb_gadget_cleanup(musb);
 
-       spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
+       spin_lock_irqsave(&musb->lock, flags);
        musb_disable_interrupts(musb);
        musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
        spin_unlock_irqrestore(&musb->lock, flags);
index 00e272bfee39a94520f16aeef03beed6a08ea43c..355655f8a3fbc9c4e3d8acd03eefa31a5736fb2f 100644 (file)
@@ -238,8 +238,27 @@ static void cppi41_dma_callback(void *private_data,
                        transferred < cppi41_channel->packet_sz)
                cppi41_channel->prog_len = 0;
 
-       if (cppi41_channel->is_tx)
-               empty = musb_is_tx_fifo_empty(hw_ep);
+       if (cppi41_channel->is_tx) {
+               u8 type;
+
+               if (is_host_active(musb))
+                       type = hw_ep->out_qh->type;
+               else
+                       type = hw_ep->ep_in.type;
+
+               if (type == USB_ENDPOINT_XFER_ISOC)
+                       /*
+                        * Don't use the early-TX-interrupt workaround below
+                        * for Isoch transfter. Since Isoch are periodic
+                        * transfer, by the time the next transfer is
+                        * scheduled, the current one should be done already.
+                        *
+                        * This avoids audio playback underrun issue.
+                        */
+                       empty = true;
+               else
+                       empty = musb_is_tx_fifo_empty(hw_ep);
+       }
 
        if (!cppi41_channel->is_tx || empty) {
                cppi41_trans_done(cppi41_channel);
index 7c047c4a2565cca25690c47d85a2bb9eb29f728e..9c7ee26ef388062bdc5e1f1fb2097fc010882950 100644 (file)
@@ -933,7 +933,7 @@ static int dsps_probe(struct platform_device *pdev)
        if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) {
                ret = dsps_setup_optional_vbus_irq(pdev, glue);
                if (ret)
-                       return ret;
+                       goto err_iounmap;
        }
 
        platform_set_drvdata(pdev, glue);
@@ -946,6 +946,8 @@ static int dsps_probe(struct platform_device *pdev)
 
 err:
        pm_runtime_disable(&pdev->dev);
+err_iounmap:
+       iounmap(glue->usbss_base);
        return ret;
 }
 
@@ -956,6 +958,7 @@ static int dsps_remove(struct platform_device *pdev)
        platform_device_unregister(glue->musb);
 
        pm_runtime_disable(&pdev->dev);
+       iounmap(glue->usbss_base);
 
        return 0;
 }
index b3b33cf7ddf608f24b0bca12f1c241261837f791..f333024660b4d0d4c6c8f54e5b209285de9a169a 100644 (file)
@@ -136,7 +136,7 @@ static int isp1301_remove(struct i2c_client *client)
 static struct i2c_driver isp1301_driver = {
        .driver = {
                .name = DRV_NAME,
-               .of_match_table = of_match_ptr(isp1301_of_match),
+               .of_match_table = isp1301_of_match,
        },
        .probe = isp1301_probe,
        .remove = isp1301_remove,
index 42cc72e54c051b2115c358bcee8bfc534258d206..af67a0de6b5d475d2be95952ddfb2354546a0fbb 100644 (file)
@@ -233,6 +233,14 @@ static void option_instat_callback(struct urb *urb);
 #define BANDRICH_PRODUCT_1012                  0x1012
 
 #define QUALCOMM_VENDOR_ID                     0x05C6
+/* These Quectel products use Qualcomm's vendor ID */
+#define QUECTEL_PRODUCT_UC20                   0x9003
+#define QUECTEL_PRODUCT_UC15                   0x9090
+
+#define QUECTEL_VENDOR_ID                      0x2c7c
+/* These Quectel products use Quectel's vendor ID */
+#define QUECTEL_PRODUCT_EC21                   0x0121
+#define QUECTEL_PRODUCT_EC25                   0x0125
 
 #define CMOTECH_VENDOR_ID                      0x16d8
 #define CMOTECH_PRODUCT_6001                   0x6001
@@ -1161,7 +1169,14 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
-       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
+       /* Quectel products using Qualcomm vendor ID */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       /* Quectel products using Quectel vendor ID */
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25),
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
index 696458db7e3c45e661a9825d05df0fe25dc0a832..38b3f0d8cd580f2366136003934d00a475b1d7f1 100644 (file)
@@ -169,6 +169,8 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_SWI(0x413c, 0x81a9)},   /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
        {DEVICE_SWI(0x413c, 0x81b1)},   /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
        {DEVICE_SWI(0x413c, 0x81b3)},   /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
+       {DEVICE_SWI(0x413c, 0x81b5)},   /* Dell Wireless 5811e QDL */
+       {DEVICE_SWI(0x413c, 0x81b6)},   /* Dell Wireless 5811e QDL */
 
        /* Huawei devices */
        {DEVICE_HWI(0x03f0, 0x581d)},   /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
index 252c7bd9218afd5db373325b55b561c304ab0e88..d01496fd27fe88460988745a57c32c0cf5f14840 100644 (file)
@@ -39,6 +39,9 @@ int wa_create(struct wahc *wa, struct usb_interface *iface,
        int result;
        struct device *dev = &iface->dev;
 
+       if (iface->cur_altsetting->desc.bNumEndpoints < 3)
+               return -ENODEV;
+
        result = wa_rpipes_create(wa);
        if (result < 0)
                goto error_rpipes_create;
index 0aa6c3c29d17260f684b8bf79944eff43af04427..35a1e777b4497ad0ad1cfa18db0834354732b128 100644 (file)
@@ -823,6 +823,9 @@ static int hwarc_probe(struct usb_interface *iface,
        struct hwarc *hwarc;
        struct device *dev = &iface->dev;
 
+       if (iface->cur_altsetting->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        result = -ENOMEM;
        uwb_rc = uwb_rc_alloc();
        if (uwb_rc == NULL) {
index 2bfc846ac071341ace37aa50dc126fc5b08a519f..6345e85822a42457f11c607effb3fbb66ce8c89f 100644 (file)
@@ -362,6 +362,9 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
                                 result);
        }
 
+       if (iface->cur_altsetting->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        result = -ENOMEM;
        i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL);
        if (i1480_usb == NULL) {
index 609f4f982c74c59a5b4fd87dfd83367765ebbc1e..561084ab387f3fd7c8ae3fa3e91c27d8329f7fe4 100644 (file)
@@ -403,6 +403,7 @@ static void vfio_group_release(struct kref *kref)
        struct iommu_group *iommu_group = group->iommu_group;
 
        WARN_ON(!list_empty(&group->device_list));
+       WARN_ON(group->notifier.head);
 
        list_for_each_entry_safe(unbound, tmp,
                                 &group->unbound_list, unbound_next) {
@@ -1573,6 +1574,10 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep)
                return -EBUSY;
        }
 
+       /* Warn if previous user didn't cleanup and re-init to drop them */
+       if (WARN_ON(group->notifier.head))
+               BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
+
        filep->private_data = group;
 
        return 0;
@@ -1584,9 +1589,6 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep)
 
        filep->private_data = NULL;
 
-       /* Any user didn't unregister? */
-       WARN_ON(group->notifier.head);
-
        vfio_group_try_dissolve_container(group);
 
        atomic_dec(&group->opened);
index c26fa1f3ed8606e65870f05aa47b7eca5fdf381e..32d2633092a37edf64ec4b9d2afc9fa4f12ea77d 100644 (file)
@@ -1182,8 +1182,7 @@ static struct vfio_group *find_iommu_group(struct vfio_domain *domain,
        return NULL;
 }
 
-static bool vfio_iommu_has_resv_msi(struct iommu_group *group,
-                                   phys_addr_t *base)
+static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base)
 {
        struct list_head group_resv_regions;
        struct iommu_resv_region *region, *next;
@@ -1192,7 +1191,7 @@ static bool vfio_iommu_has_resv_msi(struct iommu_group *group,
        INIT_LIST_HEAD(&group_resv_regions);
        iommu_get_group_resv_regions(group, &group_resv_regions);
        list_for_each_entry(region, &group_resv_regions, list) {
-               if (region->type & IOMMU_RESV_MSI) {
+               if (region->type == IOMMU_RESV_SW_MSI) {
                        *base = region->start;
                        ret = true;
                        goto out;
@@ -1283,7 +1282,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
        if (ret)
                goto out_domain;
 
-       resv_msi = vfio_iommu_has_resv_msi(iommu_group, &resv_msi_base);
+       resv_msi = vfio_iommu_has_sw_msi(iommu_group, &resv_msi_base);
 
        INIT_LIST_HEAD(&domain->group_list);
        list_add(&group->next, &domain->group_list);
index ce5e63d2c66aac7d019c422ec294cab025e94e5e..44eed8eb0725b25e3c9765e19387e7c338ab9bbb 100644 (file)
@@ -223,6 +223,46 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt)
        return len;
 }
 
+static int
+vhost_transport_cancel_pkt(struct vsock_sock *vsk)
+{
+       struct vhost_vsock *vsock;
+       struct virtio_vsock_pkt *pkt, *n;
+       int cnt = 0;
+       LIST_HEAD(freeme);
+
+       /* Find the vhost_vsock according to guest context id  */
+       vsock = vhost_vsock_get(vsk->remote_addr.svm_cid);
+       if (!vsock)
+               return -ENODEV;
+
+       spin_lock_bh(&vsock->send_pkt_list_lock);
+       list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) {
+               if (pkt->vsk != vsk)
+                       continue;
+               list_move(&pkt->list, &freeme);
+       }
+       spin_unlock_bh(&vsock->send_pkt_list_lock);
+
+       list_for_each_entry_safe(pkt, n, &freeme, list) {
+               if (pkt->reply)
+                       cnt++;
+               list_del(&pkt->list);
+               virtio_transport_free_pkt(pkt);
+       }
+
+       if (cnt) {
+               struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX];
+               int new_cnt;
+
+               new_cnt = atomic_sub_return(cnt, &vsock->queued_replies);
+               if (new_cnt + cnt >= tx_vq->num && new_cnt < tx_vq->num)
+                       vhost_poll_queue(&tx_vq->poll);
+       }
+
+       return 0;
+}
+
 static struct virtio_vsock_pkt *
 vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,
                      unsigned int out, unsigned int in)
@@ -675,6 +715,7 @@ static struct virtio_transport vhost_transport = {
                .release                  = virtio_transport_release,
                .connect                  = virtio_transport_connect,
                .shutdown                 = virtio_transport_shutdown,
+               .cancel_pkt               = vhost_transport_cancel_pkt,
 
                .dgram_enqueue            = virtio_transport_dgram_enqueue,
                .dgram_dequeue            = virtio_transport_dgram_dequeue,
index 4e1191508228cd86f6c3ee8174f4320c89e14686..34adf9b9c0538815db33f62ed842de49be5222e7 100644 (file)
@@ -242,11 +242,11 @@ static inline void update_stat(struct virtio_balloon *vb, int idx,
 
 #define pages_to_bytes(x) ((u64)(x) << PAGE_SHIFT)
 
-static void update_balloon_stats(struct virtio_balloon *vb)
+static unsigned int update_balloon_stats(struct virtio_balloon *vb)
 {
        unsigned long events[NR_VM_EVENT_ITEMS];
        struct sysinfo i;
-       int idx = 0;
+       unsigned int idx = 0;
        long available;
 
        all_vm_events(events);
@@ -254,18 +254,22 @@ static void update_balloon_stats(struct virtio_balloon *vb)
 
        available = si_mem_available();
 
+#ifdef CONFIG_VM_EVENT_COUNTERS
        update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
                                pages_to_bytes(events[PSWPIN]));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
                                pages_to_bytes(events[PSWPOUT]));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]);
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]);
+#endif
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE,
                                pages_to_bytes(i.freeram));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
                                pages_to_bytes(i.totalram));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL,
                                pages_to_bytes(available));
+
+       return idx;
 }
 
 /*
@@ -291,14 +295,14 @@ static void stats_handle_request(struct virtio_balloon *vb)
 {
        struct virtqueue *vq;
        struct scatterlist sg;
-       unsigned int len;
+       unsigned int len, num_stats;
 
-       update_balloon_stats(vb);
+       num_stats = update_balloon_stats(vb);
 
        vq = vb->stats_vq;
        if (!virtqueue_get_buf(vq, &len))
                return;
-       sg_init_one(&sg, vb->stats, sizeof(vb->stats));
+       sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
        virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
        virtqueue_kick(vq);
 }
@@ -423,13 +427,16 @@ static int init_vqs(struct virtio_balloon *vb)
        vb->deflate_vq = vqs[1];
        if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
                struct scatterlist sg;
+               unsigned int num_stats;
                vb->stats_vq = vqs[2];
 
                /*
                 * Prime this virtqueue with one buffer so the hypervisor can
                 * use it to signal us later (it can't be broken yet!).
                 */
-               sg_init_one(&sg, vb->stats, sizeof vb->stats);
+               num_stats = update_balloon_stats(vb);
+
+               sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
                if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
                    < 0)
                        BUG();
index df548a6fb844f701d65301503d998a05e6d19703..590534910dc617836e18c91b6576410a0299de26 100644 (file)
@@ -147,7 +147,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        const char *name = dev_name(&vp_dev->vdev.dev);
-       int i, err = -ENOMEM, allocated_vectors, nvectors;
+       int i, j, err = -ENOMEM, allocated_vectors, nvectors;
        unsigned flags = PCI_IRQ_MSIX;
        bool shared = false;
        u16 msix_vec;
@@ -212,7 +212,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
        if (!vp_dev->msix_vector_map)
                goto out_disable_config_irq;
 
-       allocated_vectors = 1; /* vector 0 is the config interrupt */
+       allocated_vectors = j = 1; /* vector 0 is the config interrupt */
        for (i = 0; i < nvqs; ++i) {
                if (!names[i]) {
                        vqs[i] = NULL;
@@ -236,18 +236,19 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
                        continue;
                }
 
-               snprintf(vp_dev->msix_names[i + 1],
+               snprintf(vp_dev->msix_names[j],
                         sizeof(*vp_dev->msix_names), "%s-%s",
                         dev_name(&vp_dev->vdev.dev), names[i]);
                err = request_irq(pci_irq_vector(vp_dev->pci_dev, msix_vec),
                                  vring_interrupt, IRQF_SHARED,
-                                 vp_dev->msix_names[i + 1], vqs[i]);
+                                 vp_dev->msix_names[j], vqs[i]);
                if (err) {
                        /* don't free this irq on error */
                        vp_dev->msix_vector_map[i] = VIRTIO_MSI_NO_VECTOR;
                        goto out_remove_vqs;
                }
                vp_dev->msix_vector_map[i] = msix_vec;
+               j++;
 
                /*
                 * Use a different vector for each queue if they are available,
index 4ce10bcca18b1f600c351675142240dbe94a4022..23e391d3ec015d0c5b38b21619898c282826f59c 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/syscore_ops.h>
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 #include <xen/xen.h>
-#include <xen/xen-ops.h>
 #include <xen/interface/platform.h>
 #include <asm/xen/hypercall.h>
 
@@ -408,7 +408,7 @@ static int check_acpi_ids(struct acpi_processor *pr_backup)
        acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
                            ACPI_UINT32_MAX,
                            read_acpi_id, NULL, NULL, NULL);
-       acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL);
+       acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, read_acpi_id, NULL, NULL);
 
 upload:
        if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) {
@@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(void)
        return rc;
 }
 
-static int xen_acpi_processor_resume(struct notifier_block *nb,
-                                    unsigned long action, void *data)
+static void xen_acpi_processor_resume_worker(struct work_struct *dummy)
 {
+       int rc;
+
        bitmap_zero(acpi_ids_done, nr_acpi_bits);
-       return xen_upload_processor_pm_data();
+
+       rc = xen_upload_processor_pm_data();
+       if (rc != 0)
+               pr_info("ACPI data upload failed, error = %d\n", rc);
+}
+
+static void xen_acpi_processor_resume(void)
+{
+       static DECLARE_WORK(wq, xen_acpi_processor_resume_worker);
+
+       /*
+        * xen_upload_processor_pm_data() calls non-atomic code.
+        * However, the context for xen_acpi_processor_resume is syscore
+        * with only the boot CPU online and in an atomic context.
+        *
+        * So defer the upload for some point safer.
+        */
+       schedule_work(&wq);
 }
 
-struct notifier_block xen_acpi_processor_resume_nb = {
-       .notifier_call = xen_acpi_processor_resume,
+static struct syscore_ops xap_syscore_ops = {
+       .resume = xen_acpi_processor_resume,
 };
 
 static int __init xen_acpi_processor_init(void)
@@ -527,7 +545,7 @@ static int __init xen_acpi_processor_init(void)
        if (rc)
                goto err_unregister;
 
-       xen_resume_notifier_register(&xen_acpi_processor_resume_nb);
+       register_syscore_ops(&xap_syscore_ops);
 
        return 0;
 err_unregister:
@@ -544,7 +562,7 @@ static void __exit xen_acpi_processor_exit(void)
 {
        int i;
 
-       xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb);
+       unregister_syscore_ops(&xap_syscore_ops);
        kfree(acpi_ids_done);
        kfree(acpi_id_present);
        kfree(acpi_id_cst_present);
index 29b7fc28c607232987cc3b28fbe9a92e0f766df7..c4115901d9064f68217c3be825f233d7d6872cf6 100644 (file)
@@ -1259,7 +1259,7 @@ struct btrfs_root {
        atomic_t will_be_snapshoted;
 
        /* For qgroup metadata space reserve */
-       atomic_t qgroup_meta_rsv;
+       atomic64_t qgroup_meta_rsv;
 };
 static inline u32 btrfs_inode_sectorsize(const struct inode *inode)
 {
index 08b74daf35d05f70dac01adbac73d10925f50879..eb1ee7b6f532b74409a6bb50fdb204cb2c8332a1 100644 (file)
@@ -1342,7 +1342,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
        atomic_set(&root->orphan_inodes, 0);
        atomic_set(&root->refs, 1);
        atomic_set(&root->will_be_snapshoted, 0);
-       atomic_set(&root->qgroup_meta_rsv, 0);
+       atomic64_set(&root->qgroup_meta_rsv, 0);
        root->log_transid = 0;
        root->log_transid_committed = -1;
        root->last_log_commit = 0;
index 28e81922a21c1ecead950f50cf3e685ad03c57f6..27fdb250b4467f65a8c6a42d06835f3bb3a36aec 100644 (file)
@@ -1714,7 +1714,8 @@ static int __process_pages_contig(struct address_space *mapping,
                         * can we find nothing at @index.
                         */
                        ASSERT(page_ops & PAGE_LOCK);
-                       return ret;
+                       err = -EAGAIN;
+                       goto out;
                }
 
                for (i = 0; i < ret; i++) {
@@ -2583,26 +2584,36 @@ static void end_bio_extent_readpage(struct bio *bio)
 
                if (tree->ops) {
                        ret = tree->ops->readpage_io_failed_hook(page, mirror);
-                       if (!ret && !bio->bi_error)
-                               uptodate = 1;
-               } else {
+                       if (ret == -EAGAIN) {
+                               /*
+                                * Data inode's readpage_io_failed_hook() always
+                                * returns -EAGAIN.
+                                *
+                                * The generic bio_readpage_error handles errors
+                                * the following way: If possible, new read
+                                * requests are created and submitted and will
+                                * end up in end_bio_extent_readpage as well (if
+                                * we're lucky, not in the !uptodate case). In
+                                * that case it returns 0 and we just go on with
+                                * the next page in our bio. If it can't handle
+                                * the error it will return -EIO and we remain
+                                * responsible for that page.
+                                */
+                               ret = bio_readpage_error(bio, offset, page,
+                                                        start, end, mirror);
+                               if (ret == 0) {
+                                       uptodate = !bio->bi_error;
+                                       offset += len;
+                                       continue;
+                               }
+                       }
+
                        /*
-                        * The generic bio_readpage_error handles errors the
-                        * following way: If possible, new read requests are
-                        * created and submitted and will end up in
-                        * end_bio_extent_readpage as well (if we're lucky, not
-                        * in the !uptodate case). In that case it returns 0 and
-                        * we just go on with the next page in our bio. If it
-                        * can't handle the error it will return -EIO and we
-                        * remain responsible for that page.
+                        * metadata's readpage_io_failed_hook() always returns
+                        * -EIO and fixes nothing.  -EIO is also returned if
+                        * data inode error could not be fixed.
                         */
-                       ret = bio_readpage_error(bio, offset, page, start, end,
-                                                mirror);
-                       if (ret == 0) {
-                               uptodate = !bio->bi_error;
-                               offset += len;
-                               continue;
-                       }
+                       ASSERT(ret == -EIO);
                }
 readpage_ok:
                if (likely(uptodate)) {
index c40060cc481f60440044d00ea4a76904cc4d9761..a18510be76c141e5d4b4d687c2eb5498cc273c56 100644 (file)
@@ -6709,6 +6709,20 @@ static noinline int uncompress_inline(struct btrfs_path *path,
        max_size = min_t(unsigned long, PAGE_SIZE, max_size);
        ret = btrfs_decompress(compress_type, tmp, page,
                               extent_offset, inline_size, max_size);
+
+       /*
+        * decompression code contains a memset to fill in any space between the end
+        * of the uncompressed data and the end of max_size in case the decompressed
+        * data ends up shorter than ram_bytes.  That doesn't cover the hole between
+        * the end of an inline extent and the beginning of the next block, so we
+        * cover that region here.
+        */
+
+       if (max_size + pg_offset < PAGE_SIZE) {
+               char *map = kmap(page);
+               memset(map + pg_offset + max_size, 0, PAGE_SIZE - max_size - pg_offset);
+               kunmap(page);
+       }
        kfree(tmp);
        return ret;
 }
@@ -10509,9 +10523,9 @@ out_inode:
 }
 
 __attribute__((const))
-static int dummy_readpage_io_failed_hook(struct page *page, int failed_mirror)
+static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror)
 {
-       return 0;
+       return -EAGAIN;
 }
 
 static const struct inode_operations btrfs_dir_inode_operations = {
@@ -10556,7 +10570,7 @@ static const struct extent_io_ops btrfs_extent_io_ops = {
        .submit_bio_hook = btrfs_submit_bio_hook,
        .readpage_end_io_hook = btrfs_readpage_end_io_hook,
        .merge_bio_hook = btrfs_merge_bio_hook,
-       .readpage_io_failed_hook = dummy_readpage_io_failed_hook,
+       .readpage_io_failed_hook = btrfs_readpage_io_failed_hook,
 
        /* optional callbacks */
        .fill_delalloc = run_delalloc_range,
index a5da750c1087fdc118e3ba696962260a9a761fc6..a59801dc2a340bcd3c5a34af9ef7277061967377 100644 (file)
@@ -2948,20 +2948,20 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
        ret = qgroup_reserve(root, num_bytes, enforce);
        if (ret < 0)
                return ret;
-       atomic_add(num_bytes, &root->qgroup_meta_rsv);
+       atomic64_add(num_bytes, &root->qgroup_meta_rsv);
        return ret;
 }
 
 void btrfs_qgroup_free_meta_all(struct btrfs_root *root)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
-       int reserved;
+       u64 reserved;
 
        if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
            !is_fstree(root->objectid))
                return;
 
-       reserved = atomic_xchg(&root->qgroup_meta_rsv, 0);
+       reserved = atomic64_xchg(&root->qgroup_meta_rsv, 0);
        if (reserved == 0)
                return;
        btrfs_qgroup_free_refroot(fs_info, root->objectid, reserved);
@@ -2976,8 +2976,8 @@ void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes)
                return;
 
        BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize));
-       WARN_ON(atomic_read(&root->qgroup_meta_rsv) < num_bytes);
-       atomic_sub(num_bytes, &root->qgroup_meta_rsv);
+       WARN_ON(atomic64_read(&root->qgroup_meta_rsv) < num_bytes);
+       atomic64_sub(num_bytes, &root->qgroup_meta_rsv);
        btrfs_qgroup_free_refroot(fs_info, root->objectid, num_bytes);
 }
 
index 456c8901489b6c6b468901854bcdcbc53cb5cf13..a60d5bfb8a49e2bfc3faef10f4ea353a9da5f8b8 100644 (file)
@@ -6305,8 +6305,13 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
                goto out;
        }
 
+       /*
+        * Check that we don't overflow at later allocations, we request
+        * clone_sources_count + 1 items, and compare to unsigned long inside
+        * access_ok.
+        */
        if (arg->clone_sources_count >
-           ULLONG_MAX / sizeof(*arg->clone_sources)) {
+           ULONG_MAX / sizeof(struct clone_root) - 1) {
                ret = -EINVAL;
                goto out;
        }
index 02a7a9286449d467741d64e8e817bb2902309926..6d6eca394d4d4107b8459b828b563acbbc9f082e 100644 (file)
@@ -327,7 +327,6 @@ EXPORT_SYMBOL(fscrypt_decrypt_page);
 static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct dentry *dir;
-       struct fscrypt_info *ci;
        int dir_has_key, cached_with_key;
 
        if (flags & LOOKUP_RCU)
@@ -339,18 +338,11 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
                return 0;
        }
 
-       ci = d_inode(dir)->i_crypt_info;
-       if (ci && ci->ci_keyring_key &&
-           (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
-                                         (1 << KEY_FLAG_REVOKED) |
-                                         (1 << KEY_FLAG_DEAD))))
-               ci = NULL;
-
        /* this should eventually be an flag in d_flags */
        spin_lock(&dentry->d_lock);
        cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
        spin_unlock(&dentry->d_lock);
-       dir_has_key = (ci != NULL);
+       dir_has_key = (d_inode(dir)->i_crypt_info != NULL);
        dput(dir);
 
        /*
index 13052b85c3930f071be764c5fbbeb091429002d3..37b49894c762344841117b2a0042c5e9ec8b7140 100644 (file)
@@ -350,7 +350,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
                fname->disk_name.len = iname->len;
                return 0;
        }
-       ret = fscrypt_get_crypt_info(dir);
+       ret = fscrypt_get_encryption_info(dir);
        if (ret && ret != -EOPNOTSUPP)
                return ret;
 
index fdbb8af32eafdb6bae492658d376abf15f8a3d69..e39696e644942a80d110035e2d49570840823af7 100644 (file)
@@ -67,7 +67,6 @@ struct fscrypt_info {
        u8 ci_filename_mode;
        u8 ci_flags;
        struct crypto_skcipher *ci_ctfm;
-       struct key *ci_keyring_key;
        u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
 };
 
@@ -101,7 +100,4 @@ extern int fscrypt_do_page_crypto(const struct inode *inode,
 extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
                                              gfp_t gfp_flags);
 
-/* keyinfo.c */
-extern int fscrypt_get_crypt_info(struct inode *);
-
 #endif /* _FSCRYPT_PRIVATE_H */
index d5d896fa5a71675272131d797919924b2398a85a..8cdfddce2b34868f0cfe3f71da55d64187172a38 100644 (file)
@@ -95,6 +95,7 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
        kfree(description);
        if (IS_ERR(keyring_key))
                return PTR_ERR(keyring_key);
+       down_read(&keyring_key->sem);
 
        if (keyring_key->type != &key_type_logon) {
                printk_once(KERN_WARNING
@@ -102,11 +103,9 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
                res = -ENOKEY;
                goto out;
        }
-       down_read(&keyring_key->sem);
        ukp = user_key_payload_locked(keyring_key);
        if (ukp->datalen != sizeof(struct fscrypt_key)) {
                res = -EINVAL;
-               up_read(&keyring_key->sem);
                goto out;
        }
        master_key = (struct fscrypt_key *)ukp->data;
@@ -117,17 +116,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
                                "%s: key size incorrect: %d\n",
                                __func__, master_key->size);
                res = -ENOKEY;
-               up_read(&keyring_key->sem);
                goto out;
        }
        res = derive_key_aes(ctx->nonce, master_key->raw, raw_key);
-       up_read(&keyring_key->sem);
-       if (res)
-               goto out;
-
-       crypt_info->ci_keyring_key = keyring_key;
-       return 0;
 out:
+       up_read(&keyring_key->sem);
        key_put(keyring_key);
        return res;
 }
@@ -169,12 +162,11 @@ static void put_crypt_info(struct fscrypt_info *ci)
        if (!ci)
                return;
 
-       key_put(ci->ci_keyring_key);
        crypto_free_skcipher(ci->ci_ctfm);
        kmem_cache_free(fscrypt_info_cachep, ci);
 }
 
-int fscrypt_get_crypt_info(struct inode *inode)
+int fscrypt_get_encryption_info(struct inode *inode)
 {
        struct fscrypt_info *crypt_info;
        struct fscrypt_context ctx;
@@ -184,21 +176,15 @@ int fscrypt_get_crypt_info(struct inode *inode)
        u8 *raw_key = NULL;
        int res;
 
+       if (inode->i_crypt_info)
+               return 0;
+
        res = fscrypt_initialize(inode->i_sb->s_cop->flags);
        if (res)
                return res;
 
        if (!inode->i_sb->s_cop->get_context)
                return -EOPNOTSUPP;
-retry:
-       crypt_info = ACCESS_ONCE(inode->i_crypt_info);
-       if (crypt_info) {
-               if (!crypt_info->ci_keyring_key ||
-                               key_validate(crypt_info->ci_keyring_key) == 0)
-                       return 0;
-               fscrypt_put_encryption_info(inode, crypt_info);
-               goto retry;
-       }
 
        res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
        if (res < 0) {
@@ -229,7 +215,6 @@ retry:
        crypt_info->ci_data_mode = ctx.contents_encryption_mode;
        crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
        crypt_info->ci_ctfm = NULL;
-       crypt_info->ci_keyring_key = NULL;
        memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
                                sizeof(crypt_info->ci_master_key));
 
@@ -273,14 +258,8 @@ retry:
        if (res)
                goto out;
 
-       kzfree(raw_key);
-       raw_key = NULL;
-       if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) {
-               put_crypt_info(crypt_info);
-               goto retry;
-       }
-       return 0;
-
+       if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL)
+               crypt_info = NULL;
 out:
        if (res == -ENOKEY)
                res = 0;
@@ -288,6 +267,7 @@ out:
        kzfree(raw_key);
        return res;
 }
+EXPORT_SYMBOL(fscrypt_get_encryption_info);
 
 void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
 {
@@ -305,17 +285,3 @@ void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
        put_crypt_info(ci);
 }
 EXPORT_SYMBOL(fscrypt_put_encryption_info);
-
-int fscrypt_get_encryption_info(struct inode *inode)
-{
-       struct fscrypt_info *ci = inode->i_crypt_info;
-
-       if (!ci ||
-               (ci->ci_keyring_key &&
-                (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
-                                              (1 << KEY_FLAG_REVOKED) |
-                                              (1 << KEY_FLAG_DEAD)))))
-               return fscrypt_get_crypt_info(inode);
-       return 0;
-}
-EXPORT_SYMBOL(fscrypt_get_encryption_info);
index 14b76da71269487f22b941f82dbf01d6adea07c7..4908906d54d562263093cd5245fcb14e36d18b8e 100644 (file)
@@ -33,17 +33,10 @@ static int create_encryption_context_from_policy(struct inode *inode,
                                const struct fscrypt_policy *policy)
 {
        struct fscrypt_context ctx;
-       int res;
 
        if (!inode->i_sb->s_cop->set_context)
                return -EOPNOTSUPP;
 
-       if (inode->i_sb->s_cop->prepare_context) {
-               res = inode->i_sb->s_cop->prepare_context(inode);
-               if (res)
-                       return res;
-       }
-
        ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
        memcpy(ctx.master_key_descriptor, policy->master_key_descriptor,
                                        FS_KEY_DESCRIPTOR_SIZE);
index 30a9f210d1e32c8a01635821b2937407d5b21773..375fb1c05d49ce87a287213720ca0ebf5e0deef1 100644 (file)
@@ -1169,10 +1169,9 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
        set_buffer_uptodate(dir_block);
        err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
        if (err)
-               goto out;
+               return err;
        set_buffer_verified(dir_block);
-out:
-       return err;
+       return ext4_mark_inode_dirty(handle, inode);
 }
 
 static int ext4_convert_inline_data_nolock(handle_t *handle,
index 7385e6a6b6cb549041d098a565c36c20794f7f14..4247d8d25687814dd1b844ea5555feeb43854d99 100644 (file)
@@ -5400,7 +5400,7 @@ int ext4_getattr(const struct path *path, struct kstat *stat,
         * If there is inline data in the inode, the inode will normally not
         * have data blocks allocated (it may have an external xattr block).
         * Report at least one sector for such files, so tools like tar, rsync,
-        * others doen't incorrectly think the file is completely sparse.
+        * others don't incorrectly think the file is completely sparse.
         */
        if (unlikely(ext4_has_inline_data(inode)))
                stat->blocks += (stat->size + 511) >> 9;
index 578f8c33fb44ad34062e978277f5def1d8aeebe1..c992ef2c2f94c0865d14de67e2c5b99857edf71f 100644 (file)
@@ -511,7 +511,7 @@ mext_check_arguments(struct inode *orig_inode,
        if ((orig_start & ~(PAGE_MASK >> orig_inode->i_blkbits)) !=
            (donor_start & ~(PAGE_MASK >> orig_inode->i_blkbits))) {
                ext4_debug("ext4 move extent: orig and donor's start "
-                       "offset are not alligned [ino:orig %lu, donor %lu]\n",
+                       "offsets are not aligned [ino:orig %lu, donor %lu]\n",
                        orig_inode->i_ino, donor_inode->i_ino);
                return -EINVAL;
        }
index 2e03a0a88d92f7731346a26cbdc934458549660f..a9448db1cf7e87c2bd41daac6fbab7729bc87ecc 100644 (file)
@@ -1120,17 +1120,16 @@ static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
                                 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len);
 }
 
-static int ext4_prepare_context(struct inode *inode)
-{
-       return ext4_convert_inline_data(inode);
-}
-
 static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
                                                        void *fs_data)
 {
        handle_t *handle = fs_data;
        int res, res2, retries = 0;
 
+       res = ext4_convert_inline_data(inode);
+       if (res)
+               return res;
+
        /*
         * If a journal handle was specified, then the encryption context is
         * being set on a new inode via inheritance and is part of a larger
@@ -1196,7 +1195,6 @@ static unsigned ext4_max_namelen(struct inode *inode)
 static const struct fscrypt_operations ext4_cryptops = {
        .key_prefix             = "ext4:",
        .get_context            = ext4_get_context,
-       .prepare_context        = ext4_prepare_context,
        .set_context            = ext4_set_context,
        .dummy_context          = ext4_dummy_context,
        .is_encrypted           = ext4_encrypted_inode,
index 67636acf762475e211a641f4720e862ba886a40a..996e7900d4c8ea2d16f65f47e3f1082552b2fc66 100644 (file)
@@ -131,31 +131,26 @@ static __le32 ext4_xattr_block_csum(struct inode *inode,
 }
 
 static int ext4_xattr_block_csum_verify(struct inode *inode,
-                                       sector_t block_nr,
-                                       struct ext4_xattr_header *hdr)
+                                       struct buffer_head *bh)
 {
-       if (ext4_has_metadata_csum(inode->i_sb) &&
-           (hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr)))
-               return 0;
-       return 1;
-}
-
-static void ext4_xattr_block_csum_set(struct inode *inode,
-                                     sector_t block_nr,
-                                     struct ext4_xattr_header *hdr)
-{
-       if (!ext4_has_metadata_csum(inode->i_sb))
-               return;
+       struct ext4_xattr_header *hdr = BHDR(bh);
+       int ret = 1;
 
-       hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr);
+       if (ext4_has_metadata_csum(inode->i_sb)) {
+               lock_buffer(bh);
+               ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
+                                                       bh->b_blocknr, hdr));
+               unlock_buffer(bh);
+       }
+       return ret;
 }
 
-static inline int ext4_handle_dirty_xattr_block(handle_t *handle,
-                                               struct inode *inode,
-                                               struct buffer_head *bh)
+static void ext4_xattr_block_csum_set(struct inode *inode,
+                                     struct buffer_head *bh)
 {
-       ext4_xattr_block_csum_set(inode, bh->b_blocknr, BHDR(bh));
-       return ext4_handle_dirty_metadata(handle, inode, bh);
+       if (ext4_has_metadata_csum(inode->i_sb))
+               BHDR(bh)->h_checksum = ext4_xattr_block_csum(inode,
+                                               bh->b_blocknr, BHDR(bh));
 }
 
 static inline const struct xattr_handler *
@@ -233,7 +228,7 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
        if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
            BHDR(bh)->h_blocks != cpu_to_le32(1))
                return -EFSCORRUPTED;
-       if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh)))
+       if (!ext4_xattr_block_csum_verify(inode, bh))
                return -EFSBADCRC;
        error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
                                       bh->b_data);
@@ -618,23 +613,22 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
                        }
                }
 
+               ext4_xattr_block_csum_set(inode, bh);
                /*
                 * Beware of this ugliness: Releasing of xattr block references
                 * from different inodes can race and so we have to protect
                 * from a race where someone else frees the block (and releases
                 * its journal_head) before we are done dirtying the buffer. In
                 * nojournal mode this race is harmless and we actually cannot
-                * call ext4_handle_dirty_xattr_block() with locked buffer as
+                * call ext4_handle_dirty_metadata() with locked buffer as
                 * that function can call sync_dirty_buffer() so for that case
                 * we handle the dirtying after unlocking the buffer.
                 */
                if (ext4_handle_valid(handle))
-                       error = ext4_handle_dirty_xattr_block(handle, inode,
-                                                             bh);
+                       error = ext4_handle_dirty_metadata(handle, inode, bh);
                unlock_buffer(bh);
                if (!ext4_handle_valid(handle))
-                       error = ext4_handle_dirty_xattr_block(handle, inode,
-                                                             bh);
+                       error = ext4_handle_dirty_metadata(handle, inode, bh);
                if (IS_SYNC(inode))
                        ext4_handle_sync(handle);
                dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
@@ -863,13 +857,14 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                                ext4_xattr_cache_insert(ext4_mb_cache,
                                        bs->bh);
                        }
+                       ext4_xattr_block_csum_set(inode, bs->bh);
                        unlock_buffer(bs->bh);
                        if (error == -EFSCORRUPTED)
                                goto bad_block;
                        if (!error)
-                               error = ext4_handle_dirty_xattr_block(handle,
-                                                                     inode,
-                                                                     bs->bh);
+                               error = ext4_handle_dirty_metadata(handle,
+                                                                  inode,
+                                                                  bs->bh);
                        if (error)
                                goto cleanup;
                        goto inserted;
@@ -967,10 +962,11 @@ inserted:
                                        ce->e_reusable = 0;
                                ea_bdebug(new_bh, "reusing; refcount now=%d",
                                          ref);
+                               ext4_xattr_block_csum_set(inode, new_bh);
                                unlock_buffer(new_bh);
-                               error = ext4_handle_dirty_xattr_block(handle,
-                                                                     inode,
-                                                                     new_bh);
+                               error = ext4_handle_dirty_metadata(handle,
+                                                                  inode,
+                                                                  new_bh);
                                if (error)
                                        goto cleanup_dquot;
                        }
@@ -1020,11 +1016,12 @@ getblk_failed:
                                goto getblk_failed;
                        }
                        memcpy(new_bh->b_data, s->base, new_bh->b_size);
+                       ext4_xattr_block_csum_set(inode, new_bh);
                        set_buffer_uptodate(new_bh);
                        unlock_buffer(new_bh);
                        ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
-                       error = ext4_handle_dirty_xattr_block(handle,
-                                                             inode, new_bh);
+                       error = ext4_handle_dirty_metadata(handle, inode,
+                                                          new_bh);
                        if (error)
                                goto cleanup;
                }
index a77df377e2e8197097912c9248948c7e729ce566..ee2d0a485fc3478fc5f93b5b85c6dad0431e8ea0 100644 (file)
@@ -196,6 +196,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
        si->base_mem += (NM_I(sbi)->nat_bits_blocks << F2FS_BLKSIZE_BITS);
        si->base_mem += NM_I(sbi)->nat_blocks * NAT_ENTRY_BITMAP_SIZE;
        si->base_mem += NM_I(sbi)->nat_blocks / 8;
+       si->base_mem += NM_I(sbi)->nat_blocks * sizeof(unsigned short);
 
 get_cache:
        si->cache_mem = 0;
index 4650c9b85de77679adaa275406512868671bb1bb..8d5c62b07b283f53e90ded2366c8bb9375409fa2 100644 (file)
@@ -750,7 +750,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
        dentry_blk = page_address(page);
        bit_pos = dentry - dentry_blk->dentry;
        for (i = 0; i < slots; i++)
-               clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
+               __clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
 
        /* Let's check and deallocate this dentry page */
        bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
index e849f83d611407b8968bec904c10f1939c40b4f1..0a6e115562f62edca5b60ee4c833e889a904c202 100644 (file)
@@ -561,6 +561,8 @@ struct f2fs_nm_info {
        struct mutex build_lock;        /* lock for build free nids */
        unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE];
        unsigned char *nat_block_bitmap;
+       unsigned short *free_nid_count; /* free nid count of NAT block */
+       spinlock_t free_nid_lock;       /* protect updating of nid count */
 
        /* for checkpoint */
        char *nat_bitmap;               /* NAT bitmap pointer */
index 94967171dee87a381655ede9190ff0f66b3ca4af..481aa8dc79f46f4c156cf67cca665e8160e36e6a 100644 (file)
@@ -338,9 +338,6 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
                set_nat_flag(e, IS_CHECKPOINTED, false);
        __set_nat_cache_dirty(nm_i, e);
 
-       if (enabled_nat_bits(sbi, NULL) && new_blkaddr == NEW_ADDR)
-               clear_bit_le(NAT_BLOCK_OFFSET(ni->nid), nm_i->empty_nat_bits);
-
        /* update fsync_mark if its inode nat entry is still alive */
        if (ni->nid != ni->ino)
                e = __lookup_nat_cache(nm_i, ni->ino);
@@ -1823,7 +1820,8 @@ static void remove_free_nid(struct f2fs_sb_info *sbi, nid_t nid)
                kmem_cache_free(free_nid_slab, i);
 }
 
-void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid, bool set)
+static void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid,
+                       bool set, bool build, bool locked)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        unsigned int nat_ofs = NAT_BLOCK_OFFSET(nid);
@@ -1833,9 +1831,18 @@ void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid, bool set)
                return;
 
        if (set)
-               set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
+               __set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
        else
-               clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
+               __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
+
+       if (!locked)
+               spin_lock(&nm_i->free_nid_lock);
+       if (set)
+               nm_i->free_nid_count[nat_ofs]++;
+       else if (!build)
+               nm_i->free_nid_count[nat_ofs]--;
+       if (!locked)
+               spin_unlock(&nm_i->free_nid_lock);
 }
 
 static void scan_nat_page(struct f2fs_sb_info *sbi,
@@ -1847,7 +1854,10 @@ static void scan_nat_page(struct f2fs_sb_info *sbi,
        unsigned int nat_ofs = NAT_BLOCK_OFFSET(start_nid);
        int i;
 
-       set_bit_le(nat_ofs, nm_i->nat_block_bitmap);
+       if (test_bit_le(nat_ofs, nm_i->nat_block_bitmap))
+               return;
+
+       __set_bit_le(nat_ofs, nm_i->nat_block_bitmap);
 
        i = start_nid % NAT_ENTRY_PER_BLOCK;
 
@@ -1861,7 +1871,7 @@ static void scan_nat_page(struct f2fs_sb_info *sbi,
                f2fs_bug_on(sbi, blk_addr == NEW_ADDR);
                if (blk_addr == NULL_ADDR)
                        freed = add_free_nid(sbi, start_nid, true);
-               update_free_nid_bitmap(sbi, start_nid, freed);
+               update_free_nid_bitmap(sbi, start_nid, freed, true, false);
        }
 }
 
@@ -1877,6 +1887,8 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi)
        for (i = 0; i < nm_i->nat_blocks; i++) {
                if (!test_bit_le(i, nm_i->nat_block_bitmap))
                        continue;
+               if (!nm_i->free_nid_count[i])
+                       continue;
                for (idx = 0; idx < NAT_ENTRY_PER_BLOCK; idx++) {
                        nid_t nid;
 
@@ -1907,58 +1919,6 @@ out:
        up_read(&nm_i->nat_tree_lock);
 }
 
-static int scan_nat_bits(struct f2fs_sb_info *sbi)
-{
-       struct f2fs_nm_info *nm_i = NM_I(sbi);
-       struct page *page;
-       unsigned int i = 0;
-       nid_t nid;
-
-       if (!enabled_nat_bits(sbi, NULL))
-               return -EAGAIN;
-
-       down_read(&nm_i->nat_tree_lock);
-check_empty:
-       i = find_next_bit_le(nm_i->empty_nat_bits, nm_i->nat_blocks, i);
-       if (i >= nm_i->nat_blocks) {
-               i = 0;
-               goto check_partial;
-       }
-
-       for (nid = i * NAT_ENTRY_PER_BLOCK; nid < (i + 1) * NAT_ENTRY_PER_BLOCK;
-                                                                       nid++) {
-               if (unlikely(nid >= nm_i->max_nid))
-                       break;
-               add_free_nid(sbi, nid, true);
-       }
-
-       if (nm_i->nid_cnt[FREE_NID_LIST] >= MAX_FREE_NIDS)
-               goto out;
-       i++;
-       goto check_empty;
-
-check_partial:
-       i = find_next_zero_bit_le(nm_i->full_nat_bits, nm_i->nat_blocks, i);
-       if (i >= nm_i->nat_blocks) {
-               disable_nat_bits(sbi, true);
-               up_read(&nm_i->nat_tree_lock);
-               return -EINVAL;
-       }
-
-       nid = i * NAT_ENTRY_PER_BLOCK;
-       page = get_current_nat_page(sbi, nid);
-       scan_nat_page(sbi, page, nid);
-       f2fs_put_page(page, 1);
-
-       if (nm_i->nid_cnt[FREE_NID_LIST] < MAX_FREE_NIDS) {
-               i++;
-               goto check_partial;
-       }
-out:
-       up_read(&nm_i->nat_tree_lock);
-       return 0;
-}
-
 static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
@@ -1980,21 +1940,6 @@ static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
 
                if (nm_i->nid_cnt[FREE_NID_LIST])
                        return;
-
-               /* try to find free nids with nat_bits */
-               if (!scan_nat_bits(sbi) && nm_i->nid_cnt[FREE_NID_LIST])
-                       return;
-       }
-
-       /* find next valid candidate */
-       if (enabled_nat_bits(sbi, NULL)) {
-               int idx = find_next_zero_bit_le(nm_i->full_nat_bits,
-                                       nm_i->nat_blocks, 0);
-
-               if (idx >= nm_i->nat_blocks)
-                       set_sbi_flag(sbi, SBI_NEED_FSCK);
-               else
-                       nid = idx * NAT_ENTRY_PER_BLOCK;
        }
 
        /* readahead nat pages to be scanned */
@@ -2081,7 +2026,7 @@ retry:
                __insert_nid_to_list(sbi, i, ALLOC_NID_LIST, false);
                nm_i->available_nids--;
 
-               update_free_nid_bitmap(sbi, *nid, false);
+               update_free_nid_bitmap(sbi, *nid, false, false, false);
 
                spin_unlock(&nm_i->nid_list_lock);
                return true;
@@ -2137,7 +2082,7 @@ void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid)
 
        nm_i->available_nids++;
 
-       update_free_nid_bitmap(sbi, nid, true);
+       update_free_nid_bitmap(sbi, nid, true, false, false);
 
        spin_unlock(&nm_i->nid_list_lock);
 
@@ -2383,7 +2328,7 @@ add_out:
        list_add_tail(&nes->set_list, head);
 }
 
-void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
+static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
                                                struct page *page)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
@@ -2402,16 +2347,16 @@ void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
                        valid++;
        }
        if (valid == 0) {
-               set_bit_le(nat_index, nm_i->empty_nat_bits);
-               clear_bit_le(nat_index, nm_i->full_nat_bits);
+               __set_bit_le(nat_index, nm_i->empty_nat_bits);
+               __clear_bit_le(nat_index, nm_i->full_nat_bits);
                return;
        }
 
-       clear_bit_le(nat_index, nm_i->empty_nat_bits);
+       __clear_bit_le(nat_index, nm_i->empty_nat_bits);
        if (valid == NAT_ENTRY_PER_BLOCK)
-               set_bit_le(nat_index, nm_i->full_nat_bits);
+               __set_bit_le(nat_index, nm_i->full_nat_bits);
        else
-               clear_bit_le(nat_index, nm_i->full_nat_bits);
+               __clear_bit_le(nat_index, nm_i->full_nat_bits);
 }
 
 static void __flush_nat_entry_set(struct f2fs_sb_info *sbi,
@@ -2467,11 +2412,11 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi,
                        add_free_nid(sbi, nid, false);
                        spin_lock(&NM_I(sbi)->nid_list_lock);
                        NM_I(sbi)->available_nids++;
-                       update_free_nid_bitmap(sbi, nid, true);
+                       update_free_nid_bitmap(sbi, nid, true, false, false);
                        spin_unlock(&NM_I(sbi)->nid_list_lock);
                } else {
                        spin_lock(&NM_I(sbi)->nid_list_lock);
-                       update_free_nid_bitmap(sbi, nid, false);
+                       update_free_nid_bitmap(sbi, nid, false, false, false);
                        spin_unlock(&NM_I(sbi)->nid_list_lock);
                }
        }
@@ -2577,6 +2522,40 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi)
        return 0;
 }
 
+inline void load_free_nid_bitmap(struct f2fs_sb_info *sbi)
+{
+       struct f2fs_nm_info *nm_i = NM_I(sbi);
+       unsigned int i = 0;
+       nid_t nid, last_nid;
+
+       if (!enabled_nat_bits(sbi, NULL))
+               return;
+
+       for (i = 0; i < nm_i->nat_blocks; i++) {
+               i = find_next_bit_le(nm_i->empty_nat_bits, nm_i->nat_blocks, i);
+               if (i >= nm_i->nat_blocks)
+                       break;
+
+               __set_bit_le(i, nm_i->nat_block_bitmap);
+
+               nid = i * NAT_ENTRY_PER_BLOCK;
+               last_nid = (i + 1) * NAT_ENTRY_PER_BLOCK;
+
+               spin_lock(&nm_i->free_nid_lock);
+               for (; nid < last_nid; nid++)
+                       update_free_nid_bitmap(sbi, nid, true, true, true);
+               spin_unlock(&nm_i->free_nid_lock);
+       }
+
+       for (i = 0; i < nm_i->nat_blocks; i++) {
+               i = find_next_bit_le(nm_i->full_nat_bits, nm_i->nat_blocks, i);
+               if (i >= nm_i->nat_blocks)
+                       break;
+
+               __set_bit_le(i, nm_i->nat_block_bitmap);
+       }
+}
+
 static int init_node_manager(struct f2fs_sb_info *sbi)
 {
        struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi);
@@ -2638,7 +2617,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
        return 0;
 }
 
-int init_free_nid_cache(struct f2fs_sb_info *sbi)
+static int init_free_nid_cache(struct f2fs_sb_info *sbi)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
 
@@ -2651,6 +2630,14 @@ int init_free_nid_cache(struct f2fs_sb_info *sbi)
                                                                GFP_KERNEL);
        if (!nm_i->nat_block_bitmap)
                return -ENOMEM;
+
+       nm_i->free_nid_count = f2fs_kvzalloc(nm_i->nat_blocks *
+                                       sizeof(unsigned short), GFP_KERNEL);
+       if (!nm_i->free_nid_count)
+               return -ENOMEM;
+
+       spin_lock_init(&nm_i->free_nid_lock);
+
        return 0;
 }
 
@@ -2670,6 +2657,9 @@ int build_node_manager(struct f2fs_sb_info *sbi)
        if (err)
                return err;
 
+       /* load free nid status from nat_bits table */
+       load_free_nid_bitmap(sbi);
+
        build_free_nids(sbi, true, true);
        return 0;
 }
@@ -2730,6 +2720,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
 
        kvfree(nm_i->nat_block_bitmap);
        kvfree(nm_i->free_nid_bitmap);
+       kvfree(nm_i->free_nid_count);
 
        kfree(nm_i->nat_bitmap);
        kfree(nm_i->nat_bits);
index 4bd7a8b19332d176d78b0a40c24e7bb12bbe2f5e..29ef7088c5582a480b6a1f7965fbbcca4f07e24e 100644 (file)
@@ -1163,6 +1163,12 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
                if (f2fs_discard_en(sbi) &&
                        !f2fs_test_and_set_bit(offset, se->discard_map))
                        sbi->discard_blks--;
+
+               /* don't overwrite by SSR to keep node chain */
+               if (se->type == CURSEG_WARM_NODE) {
+                       if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map))
+                               se->ckpt_valid_blocks++;
+               }
        } else {
                if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) {
 #ifdef CONFIG_F2FS_CHECK_FS
index 8f96461236f655c3eef66694d45d9c4381a58210..7163fe014b57f4e15813c1969958d5764b18e5af 100644 (file)
@@ -695,14 +695,11 @@ static struct inode *hugetlbfs_get_root(struct super_block *sb,
 
        inode = new_inode(sb);
        if (inode) {
-               struct hugetlbfs_inode_info *info;
                inode->i_ino = get_next_ino();
                inode->i_mode = S_IFDIR | config->mode;
                inode->i_uid = config->uid;
                inode->i_gid = config->gid;
                inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
-               info = HUGETLBFS_I(inode);
-               mpol_shared_policy_init(&info->policy, NULL);
                inode->i_op = &hugetlbfs_dir_inode_operations;
                inode->i_fop = &simple_dir_operations;
                /* directory inodes start off with i_nlink == 2 (for "." entry) */
@@ -733,7 +730,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,
 
        inode = new_inode(sb);
        if (inode) {
-               struct hugetlbfs_inode_info *info;
                inode->i_ino = get_next_ino();
                inode_init_owner(inode, dir, mode);
                lockdep_set_class(&inode->i_mapping->i_mmap_rwsem,
@@ -741,15 +737,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,
                inode->i_mapping->a_ops = &hugetlbfs_aops;
                inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
                inode->i_mapping->private_data = resv_map;
-               info = HUGETLBFS_I(inode);
-               /*
-                * The policy is initialized here even if we are creating a
-                * private inode because initialization simply creates an
-                * an empty rb tree and calls rwlock_init(), later when we
-                * call mpol_free_shared_policy() it will just return because
-                * the rb tree will still be empty.
-                */
-               mpol_shared_policy_init(&info->policy, NULL);
                switch (mode & S_IFMT) {
                default:
                        init_special_inode(inode, mode, dev);
@@ -937,6 +924,18 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
                hugetlbfs_inc_free_inodes(sbinfo);
                return NULL;
        }
+
+       /*
+        * Any time after allocation, hugetlbfs_destroy_inode can be called
+        * for the inode.  mpol_free_shared_policy is unconditionally called
+        * as part of hugetlbfs_destroy_inode.  So, initialize policy here
+        * in case of a quick call to destroy.
+        *
+        * Note that the policy is initialized even if we are creating a
+        * private inode.  This simplifies hugetlbfs_destroy_inode.
+        */
+       mpol_shared_policy_init(&p->policy, NULL);
+
        return &p->vfs_inode;
 }
 
index a1a359bfcc9cd4ff84254e464788ab3031dfe90f..5adc2fb62b0fab89899e5d0acba1e8019a73c766 100644 (file)
@@ -1125,10 +1125,8 @@ static journal_t *journal_init_common(struct block_device *bdev,
 
        /* Set up a default-sized revoke table for the new mount. */
        err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH);
-       if (err) {
-               kfree(journal);
-               return NULL;
-       }
+       if (err)
+               goto err_cleanup;
 
        spin_lock_init(&journal->j_history_lock);
 
@@ -1145,23 +1143,25 @@ static journal_t *journal_init_common(struct block_device *bdev,
        journal->j_wbufsize = n;
        journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *),
                                        GFP_KERNEL);
-       if (!journal->j_wbuf) {
-               kfree(journal);
-               return NULL;
-       }
+       if (!journal->j_wbuf)
+               goto err_cleanup;
 
        bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize);
        if (!bh) {
                pr_err("%s: Cannot get buffer for journal superblock\n",
                        __func__);
-               kfree(journal->j_wbuf);
-               kfree(journal);
-               return NULL;
+               goto err_cleanup;
        }
        journal->j_sb_buffer = bh;
        journal->j_superblock = (journal_superblock_t *)bh->b_data;
 
        return journal;
+
+err_cleanup:
+       kfree(journal->j_wbuf);
+       jbd2_journal_destroy_revoke(journal);
+       kfree(journal);
+       return NULL;
 }
 
 /* jbd2_journal_init_dev and jbd2_journal_init_inode:
index cfc38b5521189f8ff64330ff33aa6ac8c25794ec..f9aefcda585418abcc37e58226eb39f3ac883172 100644 (file)
@@ -280,6 +280,7 @@ int jbd2_journal_init_revoke(journal_t *journal, int hash_size)
 
 fail1:
        jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]);
+       journal->j_revoke_table[0] = NULL;
 fail0:
        return -ENOMEM;
 }
index 8e4dc7ab584c2df9bf802c2827dacb03ef534097..ac2dfe0c5a9c8520aa8b40c4bab97b710799cc78 100644 (file)
@@ -809,7 +809,8 @@ void kernfs_drain_open_files(struct kernfs_node *kn)
                if (kn->flags & KERNFS_HAS_MMAP)
                        unmap_mapping_range(inode->i_mapping, 0, 0, 1);
 
-               kernfs_release_file(kn, of);
+               if (kn->flags & KERNFS_HAS_RELEASE)
+                       kernfs_release_file(kn, of);
        }
 
        mutex_unlock(&kernfs_open_file_mutex);
index fb499a3f21b58ed341bbe17933bd5e191c850212..f92ba8d6c5569099f6c469eda92446ad0d7e148d 100644 (file)
@@ -2055,7 +2055,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 {
        struct inode *old_inode = d_inode(old_dentry);
        struct inode *new_inode = d_inode(new_dentry);
-       struct dentry *dentry = NULL, *rehash = NULL;
+       struct dentry *dentry = NULL;
        struct rpc_task *task;
        int error = -EBUSY;
 
@@ -2078,10 +2078,8 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                 * To prevent any new references to the target during the
                 * rename, we unhash the dentry in advance.
                 */
-               if (!d_unhashed(new_dentry)) {
+               if (!d_unhashed(new_dentry))
                        d_drop(new_dentry);
-                       rehash = new_dentry;
-               }
 
                if (d_count(new_dentry) > 2) {
                        int err;
@@ -2098,7 +2096,6 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                                goto out;
 
                        new_dentry = dentry;
-                       rehash = NULL;
                        new_inode = NULL;
                }
        }
@@ -2119,8 +2116,6 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                error = task->tk_status;
        rpc_put_task(task);
 out:
-       if (rehash)
-               d_rehash(rehash);
        trace_nfs_rename_exit(old_dir, old_dentry,
                        new_dir, new_dentry, error);
        /* new dentry created? */
index 44347f4bdc1516f54f030ca9f0d95332ab816116..acd30baca46166c902aa5dfae1663184cc30e235 100644 (file)
@@ -202,10 +202,10 @@ static int filelayout_async_handle_error(struct rpc_task *task,
                        task->tk_status);
                nfs4_mark_deviceid_unavailable(devid);
                pnfs_error_mark_layout_for_return(inode, lseg);
-               pnfs_set_lo_fail(lseg);
                rpc_wake_up(&tbl->slot_tbl_waitq);
                /* fall through */
        default:
+               pnfs_set_lo_fail(lseg);
 reset:
                dprintk("%s Retry through MDS. Error %d\n", __func__,
                        task->tk_status);
@@ -560,6 +560,50 @@ filelayout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
        return PNFS_ATTEMPTED;
 }
 
+static int
+filelayout_check_deviceid(struct pnfs_layout_hdr *lo,
+                         struct nfs4_filelayout_segment *fl,
+                         gfp_t gfp_flags)
+{
+       struct nfs4_deviceid_node *d;
+       struct nfs4_file_layout_dsaddr *dsaddr;
+       int status = -EINVAL;
+
+       /* find and reference the deviceid */
+       d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), &fl->deviceid,
+                       lo->plh_lc_cred, gfp_flags);
+       if (d == NULL)
+               goto out;
+
+       dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
+       /* Found deviceid is unavailable */
+       if (filelayout_test_devid_unavailable(&dsaddr->id_node))
+               goto out_put;
+
+       fl->dsaddr = dsaddr;
+
+       if (fl->first_stripe_index >= dsaddr->stripe_count) {
+               dprintk("%s Bad first_stripe_index %u\n",
+                               __func__, fl->first_stripe_index);
+               goto out_put;
+       }
+
+       if ((fl->stripe_type == STRIPE_SPARSE &&
+           fl->num_fh > 1 && fl->num_fh != dsaddr->ds_num) ||
+           (fl->stripe_type == STRIPE_DENSE &&
+           fl->num_fh != dsaddr->stripe_count)) {
+               dprintk("%s num_fh %u not valid for given packing\n",
+                       __func__, fl->num_fh);
+               goto out_put;
+       }
+       status = 0;
+out:
+       return status;
+out_put:
+       nfs4_fl_put_deviceid(dsaddr);
+       goto out;
+}
+
 /*
  * filelayout_check_layout()
  *
@@ -572,11 +616,8 @@ static int
 filelayout_check_layout(struct pnfs_layout_hdr *lo,
                        struct nfs4_filelayout_segment *fl,
                        struct nfs4_layoutget_res *lgr,
-                       struct nfs4_deviceid *id,
                        gfp_t gfp_flags)
 {
-       struct nfs4_deviceid_node *d;
-       struct nfs4_file_layout_dsaddr *dsaddr;
        int status = -EINVAL;
 
        dprintk("--> %s\n", __func__);
@@ -601,41 +642,10 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
                goto out;
        }
 
-       /* find and reference the deviceid */
-       d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), id,
-                       lo->plh_lc_cred, gfp_flags);
-       if (d == NULL)
-               goto out;
-
-       dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
-       /* Found deviceid is unavailable */
-       if (filelayout_test_devid_unavailable(&dsaddr->id_node))
-               goto out_put;
-
-       fl->dsaddr = dsaddr;
-
-       if (fl->first_stripe_index >= dsaddr->stripe_count) {
-               dprintk("%s Bad first_stripe_index %u\n",
-                               __func__, fl->first_stripe_index);
-               goto out_put;
-       }
-
-       if ((fl->stripe_type == STRIPE_SPARSE &&
-           fl->num_fh > 1 && fl->num_fh != dsaddr->ds_num) ||
-           (fl->stripe_type == STRIPE_DENSE &&
-           fl->num_fh != dsaddr->stripe_count)) {
-               dprintk("%s num_fh %u not valid for given packing\n",
-                       __func__, fl->num_fh);
-               goto out_put;
-       }
-
        status = 0;
 out:
        dprintk("--> %s returns %d\n", __func__, status);
        return status;
-out_put:
-       nfs4_fl_put_deviceid(dsaddr);
-       goto out;
 }
 
 static void _filelayout_free_lseg(struct nfs4_filelayout_segment *fl)
@@ -657,7 +667,6 @@ static int
 filelayout_decode_layout(struct pnfs_layout_hdr *flo,
                         struct nfs4_filelayout_segment *fl,
                         struct nfs4_layoutget_res *lgr,
-                        struct nfs4_deviceid *id,
                         gfp_t gfp_flags)
 {
        struct xdr_stream stream;
@@ -682,9 +691,9 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
        if (unlikely(!p))
                goto out_err;
 
-       memcpy(id, p, sizeof(*id));
+       memcpy(&fl->deviceid, p, sizeof(fl->deviceid));
        p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
-       nfs4_print_deviceid(id);
+       nfs4_print_deviceid(&fl->deviceid);
 
        nfl_util = be32_to_cpup(p++);
        if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS)
@@ -831,15 +840,14 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
 {
        struct nfs4_filelayout_segment *fl;
        int rc;
-       struct nfs4_deviceid id;
 
        dprintk("--> %s\n", __func__);
        fl = kzalloc(sizeof(*fl), gfp_flags);
        if (!fl)
                return NULL;
 
-       rc = filelayout_decode_layout(layoutid, fl, lgr, &id, gfp_flags);
-       if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id, gfp_flags)) {
+       rc = filelayout_decode_layout(layoutid, fl, lgr, gfp_flags);
+       if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, gfp_flags)) {
                _filelayout_free_lseg(fl);
                return NULL;
        }
@@ -888,18 +896,51 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
        return min(stripe_unit - (unsigned int)stripe_offset, size);
 }
 
+static struct pnfs_layout_segment *
+fl_pnfs_update_layout(struct inode *ino,
+                     struct nfs_open_context *ctx,
+                     loff_t pos,
+                     u64 count,
+                     enum pnfs_iomode iomode,
+                     bool strict_iomode,
+                     gfp_t gfp_flags)
+{
+       struct pnfs_layout_segment *lseg = NULL;
+       struct pnfs_layout_hdr *lo;
+       struct nfs4_filelayout_segment *fl;
+       int status;
+
+       lseg = pnfs_update_layout(ino, ctx, pos, count, iomode, strict_iomode,
+                                 gfp_flags);
+       if (!lseg)
+               lseg = ERR_PTR(-ENOMEM);
+       if (IS_ERR(lseg))
+               goto out;
+
+       lo = NFS_I(ino)->layout;
+       fl = FILELAYOUT_LSEG(lseg);
+
+       status = filelayout_check_deviceid(lo, fl, gfp_flags);
+       if (status)
+               lseg = ERR_PTR(status);
+out:
+       if (IS_ERR(lseg))
+               pnfs_put_lseg(lseg);
+       return lseg;
+}
+
 static void
 filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
                        struct nfs_page *req)
 {
        if (!pgio->pg_lseg) {
-               pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
-                                          req->wb_context,
-                                          0,
-                                          NFS4_MAX_UINT64,
-                                          IOMODE_READ,
-                                          false,
-                                          GFP_KERNEL);
+               pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
+                                                     req->wb_context,
+                                                     0,
+                                                     NFS4_MAX_UINT64,
+                                                     IOMODE_READ,
+                                                     false,
+                                                     GFP_KERNEL);
                if (IS_ERR(pgio->pg_lseg)) {
                        pgio->pg_error = PTR_ERR(pgio->pg_lseg);
                        pgio->pg_lseg = NULL;
@@ -919,13 +960,13 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
        int status;
 
        if (!pgio->pg_lseg) {
-               pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
-                                          req->wb_context,
-                                          0,
-                                          NFS4_MAX_UINT64,
-                                          IOMODE_RW,
-                                          false,
-                                          GFP_NOFS);
+               pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
+                                                     req->wb_context,
+                                                     0,
+                                                     NFS4_MAX_UINT64,
+                                                     IOMODE_RW,
+                                                     false,
+                                                     GFP_NOFS);
                if (IS_ERR(pgio->pg_lseg)) {
                        pgio->pg_error = PTR_ERR(pgio->pg_lseg);
                        pgio->pg_lseg = NULL;
index 2896cb833a11375e064f926c3a50b5cbfd499f39..79323b5dab0cb38a212318d774273cb7ce88187f 100644 (file)
@@ -55,15 +55,16 @@ struct nfs4_file_layout_dsaddr {
 };
 
 struct nfs4_filelayout_segment {
-       struct pnfs_layout_segment generic_hdr;
-       u32 stripe_type;
-       u32 commit_through_mds;
-       u32 stripe_unit;
-       u32 first_stripe_index;
-       u64 pattern_offset;
-       struct nfs4_file_layout_dsaddr *dsaddr; /* Point to GETDEVINFO data */
-       unsigned int num_fh;
-       struct nfs_fh **fh_array;
+       struct pnfs_layout_segment      generic_hdr;
+       u32                             stripe_type;
+       u32                             commit_through_mds;
+       u32                             stripe_unit;
+       u32                             first_stripe_index;
+       u64                             pattern_offset;
+       struct nfs4_deviceid            deviceid;
+       struct nfs4_file_layout_dsaddr  *dsaddr; /* Point to GETDEVINFO data */
+       unsigned int                    num_fh;
+       struct nfs_fh                   **fh_array;
 };
 
 struct nfs4_filelayout {
index 85fde93dff774e7edf619bffe43657b9c2346034..457cfeb1d5c162e4177450eb941460a2fe39f3b1 100644 (file)
@@ -208,6 +208,10 @@ static bool ff_layout_mirror_valid(struct pnfs_layout_segment *lseg,
                } else
                        goto outerr;
        }
+
+       if (IS_ERR(mirror->mirror_ds))
+               goto outerr;
+
        if (mirror->mirror_ds->ds == NULL) {
                struct nfs4_deviceid_node *devid;
                devid = &mirror->mirror_ds->id_node;
index c780d98035ccf79573c47ac8fb46b8f06a17653e..201ca3f2c4bac14986220fcdf6a6c37b734ffa96 100644 (file)
@@ -2442,17 +2442,14 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
        }
 
        nfs4_stateid_copy(&stateid, &delegation->stateid);
-       if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
+       if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) ||
+               !test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
+                       &delegation->flags)) {
                rcu_read_unlock();
                nfs_finish_clear_delegation_stateid(state, &stateid);
                return;
        }
 
-       if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags)) {
-               rcu_read_unlock();
-               return;
-       }
-
        cred = get_rpccred(delegation->cred);
        rcu_read_unlock();
        status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
index 73e75ac905258c17bdc107c0c071e8d14df739f0..8bf8f667a8cf2fe8359f74b41497bc9436ca0efb 100644 (file)
@@ -538,13 +538,21 @@ out_free:
 
 static ssize_t
 nfsd_print_version_support(char *buf, int remaining, const char *sep,
-               unsigned vers, unsigned minor)
+               unsigned vers, int minor)
 {
-       const char *format = (minor == 0) ? "%s%c%u" : "%s%c%u.%u";
+       const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
        bool supported = !!nfsd_vers(vers, NFSD_TEST);
 
-       if (vers == 4 && !nfsd_minorversion(minor, NFSD_TEST))
+       if (vers == 4 && minor >= 0 &&
+           !nfsd_minorversion(minor, NFSD_TEST))
                supported = false;
+       if (minor == 0 && supported)
+               /*
+                * special case for backward compatability.
+                * +4.0 is never reported, it is implied by
+                * +4, unless -4.0 is present.
+                */
+               return 0;
        return snprintf(buf, remaining, format, sep,
                        supported ? '+' : '-', vers, minor);
 }
@@ -554,7 +562,6 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
        char *mesg = buf;
        char *vers, *minorp, sign;
        int len, num, remaining;
-       unsigned minor;
        ssize_t tlen = 0;
        char *sep;
        struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
@@ -575,6 +582,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
                if (len <= 0) return -EINVAL;
                do {
                        enum vers_op cmd;
+                       unsigned minor;
                        sign = *vers;
                        if (sign == '+' || sign == '-')
                                num = simple_strtol((vers+1), &minorp, 0);
@@ -585,8 +593,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
                                        return -EINVAL;
                                if (kstrtouint(minorp+1, 0, &minor) < 0)
                                        return -EINVAL;
-                       } else
-                               minor = 0;
+                       }
+
                        cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
                        switch(num) {
                        case 2:
@@ -594,8 +602,20 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
                                nfsd_vers(num, cmd);
                                break;
                        case 4:
-                               if (nfsd_minorversion(minor, cmd) >= 0)
-                                       break;
+                               if (*minorp == '.') {
+                                       if (nfsd_minorversion(minor, cmd) < 0)
+                                               return -EINVAL;
+                               } else if ((cmd == NFSD_SET) != nfsd_vers(num, NFSD_TEST)) {
+                                       /*
+                                        * Either we have +4 and no minors are enabled,
+                                        * or we have -4 and at least one minor is enabled.
+                                        * In either case, propagate 'cmd' to all minors.
+                                        */
+                                       minor = 0;
+                                       while (nfsd_minorversion(minor, cmd) >= 0)
+                                               minor++;
+                               }
+                               break;
                        default:
                                return -EINVAL;
                        }
@@ -612,9 +632,11 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
        sep = "";
        remaining = SIMPLE_TRANSACTION_LIMIT;
        for (num=2 ; num <= 4 ; num++) {
+               int minor;
                if (!nfsd_vers(num, NFSD_AVAIL))
                        continue;
-               minor = 0;
+
+               minor = -1;
                do {
                        len = nfsd_print_version_support(buf, remaining,
                                        sep, num, minor);
@@ -624,7 +646,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
                        buf += len;
                        tlen += len;
                        minor++;
-                       sep = " ";
+                       if (len)
+                               sep = " ";
                } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION);
        }
 out:
index fa82b7707e8531f9b7e8065391c3f54387c2740d..03a7e9da4da0225e58fd53c4589ed682e0732141 100644 (file)
@@ -786,6 +786,7 @@ nfserrno (int errno)
                { nfserr_serverfault, -ESERVERFAULT },
                { nfserr_serverfault, -ENFILE },
                { nfserr_io, -EUCLEAN },
+               { nfserr_perm, -ENOKEY },
        };
        int     i;
 
index 786a4a2cb2d7a96cbde629c17b6ac58ab82bc84e..31e1f959345715a59f8f6b9d9ec00a0ec00fece5 100644 (file)
@@ -167,7 +167,8 @@ nfsd_adjust_nfsd_versions4(void)
 
 int nfsd_minorversion(u32 minorversion, enum vers_op change)
 {
-       if (minorversion > NFSD_SUPPORTED_MINOR_VERSION)
+       if (minorversion > NFSD_SUPPORTED_MINOR_VERSION &&
+           change != NFSD_AVAIL)
                return -1;
        switch(change) {
        case NFSD_SET:
@@ -415,23 +416,20 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
 
 void nfsd_reset_versions(void)
 {
-       int found_one = 0;
        int i;
 
-       for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
-               if (nfsd_program.pg_vers[i])
-                       found_one = 1;
-       }
+       for (i = 0; i < NFSD_NRVERS; i++)
+               if (nfsd_vers(i, NFSD_TEST))
+                       return;
 
-       if (!found_one) {
-               for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
-                       nfsd_program.pg_vers[i] = nfsd_version[i];
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
-               for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
-                       nfsd_acl_program.pg_vers[i] =
-                               nfsd_acl_version[i];
-#endif
-       }
+       for (i = 0; i < NFSD_NRVERS; i++)
+               if (i != 4)
+                       nfsd_vers(i, NFSD_SET);
+               else {
+                       int minor = 0;
+                       while (nfsd_minorversion(minor, NFSD_SET) >= 0)
+                               minor++;
+               }
 }
 
 /*
index 4df64a1fc09e7aab7f88cd4afe73928228930147..532372c6cf15c8084f4910072e96fd0360bad2cd 100644 (file)
@@ -14,8 +14,8 @@
  * [_sdata, _edata]: contains .data.* sections, may also contain .rodata.*
  *                   and/or .init.* sections.
  * [__start_rodata, __end_rodata]: contains .rodata.* sections
- * [__start_data_ro_after_init, __end_data_ro_after_init]:
- *                  contains data.ro_after_init section
+ * [__start_ro_after_init, __end_ro_after_init]:
+ *                  contains .data..ro_after_init section
  * [__init_begin, __init_end]: contains .init.* sections, but .init.text.*
  *                   may be out of this range on some architectures.
  * [_sinittext, _einittext]: contains .init.text.* sections
@@ -33,7 +33,7 @@ extern char _data[], _sdata[], _edata[];
 extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
 extern char _sinittext[], _einittext[];
-extern char __start_data_ro_after_init[], __end_data_ro_after_init[];
+extern char __start_ro_after_init[], __end_ro_after_init[];
 extern char _end[];
 extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
 extern char __kprobes_text_start[], __kprobes_text_end[];
index 0968d13b388591ae02b37f9dda0fe7a498cc7475..7cdfe167074f873a71dd51e04da3304864d2f063 100644 (file)
        KEEP(*(__##name##_of_table_end))
 
 #define CLKSRC_OF_TABLES()     OF_TABLE(CONFIG_CLKSRC_OF, clksrc)
+#define CLKEVT_OF_TABLES()     OF_TABLE(CONFIG_CLKEVT_OF, clkevt)
 #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)
 #define CLK_OF_TABLES()                OF_TABLE(CONFIG_COMMON_CLK, clk)
 #define IOMMU_OF_TABLES()      OF_TABLE(CONFIG_OF_IOMMU, iommu)
  */
 #ifndef RO_AFTER_INIT_DATA
 #define RO_AFTER_INIT_DATA                                             \
-       __start_data_ro_after_init = .;                                 \
+       __start_ro_after_init = .;                                      \
        *(.data..ro_after_init)                                         \
-       __end_data_ro_after_init = .;
+       __end_ro_after_init = .;
 #endif
 
 /*
        CLK_OF_TABLES()                                                 \
        RESERVEDMEM_OF_TABLES()                                         \
        CLKSRC_OF_TABLES()                                              \
+       CLKEVT_OF_TABLES()                                              \
        IOMMU_OF_TABLES()                                               \
        CPU_METHOD_OF_TABLES()                                          \
        CPUIDLE_METHOD_OF_TABLES()                                      \
index c71dd8fa57640eab059ca21b2847609340b6b506..c41b8d99dd0e7f352bc8e57e4e2ffc4dd08c63b7 100644 (file)
@@ -556,7 +556,7 @@ enum ccp_engine {
  * struct ccp_cmd - CCP operation request
  * @entry: list element (ccp driver use only)
  * @work: work element used for callbacks (ccp driver use only)
- * @ccp: CCP device to be run on (ccp driver use only)
+ * @ccp: CCP device to be run on
  * @ret: operation return code (ccp driver use only)
  * @flags: cmd processing flags
  * @engine: CCP operation to perform
index 5d3053c34fb3d5c365ad1f5a44e39a03fb6926c8..6d7edc3082f98466566cd1ae67640d7e0bd976d3 100644 (file)
@@ -229,7 +229,7 @@ static inline void tick_setup_hrtimer_broadcast(void) { }
 
 #ifdef CONFIG_CLKEVT_PROBE
 extern int clockevent_probe(void);
-#els
+#else
 static inline int clockevent_probe(void) { return 0; }
 #endif
 
index 9ca23fcfb5d73131b564ad81d887929abc0e954b..6fdfc884fdeb3d3cf81dcbd40c52c0b8c8d203b1 100644 (file)
@@ -20,6 +20,8 @@ struct sock_exterr_skb {
        struct sock_extended_err        ee;
        u16                             addr_offset;
        __be16                          port;
+       u8                              opt_stats:1,
+                                       unused:7;
 };
 
 #endif
index 547f81592ba134bce5d222a66405c782a91b80d8..10c1abfbac6c45d1049fdf9f1b1f133371521461 100644 (file)
@@ -87,7 +87,6 @@ struct fscrypt_operations {
        unsigned int flags;
        const char *key_prefix;
        int (*get_context)(struct inode *, void *, size_t);
-       int (*prepare_context)(struct inode *);
        int (*set_context)(struct inode *, const void *, size_t, void *);
        int (*dummy_context)(struct inode *);
        bool (*is_encrypted)(struct inode *);
index 2484b2fcc6eb58d0139605359fe97b285df8e5f5..933d936566055de430f9db64ae152eb31785b7ff 100644 (file)
@@ -143,15 +143,6 @@ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev,
                                                struct fwnode_handle *child,
                                                enum gpiod_flags flags,
                                                const char *label);
-/* FIXME: delete this helper when users are switched over */
-static inline struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
-                         const char *con_id, struct fwnode_handle *child)
-{
-       return devm_fwnode_get_index_gpiod_from_child(dev, con_id,
-                                                     0, child,
-                                                     GPIOD_ASIS,
-                                                     "?");
-}
 
 #else /* CONFIG_GPIOLIB */
 
@@ -444,13 +435,6 @@ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev,
        return ERR_PTR(-ENOSYS);
 }
 
-/* FIXME: delete this when all users are switched over */
-static inline struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
-                         const char *con_id, struct fwnode_handle *child)
-{
-       return ERR_PTR(-ENOSYS);
-}
-
 #endif /* CONFIG_GPIOLIB */
 
 static inline
index 78d59dba563e33e96f6658bfb764268e97f99573..88b6737491210aaf7a2ba66756672188992902ac 100644 (file)
@@ -88,6 +88,7 @@ enum hwmon_temp_attributes {
 #define HWMON_T_CRIT_HYST      BIT(hwmon_temp_crit_hyst)
 #define HWMON_T_EMERGENCY      BIT(hwmon_temp_emergency)
 #define HWMON_T_EMERGENCY_HYST BIT(hwmon_temp_emergency_hyst)
+#define HWMON_T_ALARM          BIT(hwmon_temp_alarm)
 #define HWMON_T_MIN_ALARM      BIT(hwmon_temp_min_alarm)
 #define HWMON_T_MAX_ALARM      BIT(hwmon_temp_max_alarm)
 #define HWMON_T_CRIT_ALARM     BIT(hwmon_temp_crit_alarm)
index 62bbf3c1aa4a04409fac1a001b03a87cf0162fd1..970771a5f7390268abb5c43ba1e1c8df48f2caa4 100644 (file)
@@ -845,6 +845,13 @@ struct vmbus_channel {
         * link up channels based on their CPU affinity.
         */
        struct list_head percpu_list;
+
+       /*
+        * Defer freeing channel until after all cpu's have
+        * gone through grace period.
+        */
+       struct rcu_head rcu;
+
        /*
         * For performance critical channels (storage, networking
         * etc,), Hyper-V has a mechanism to enhance the throughput
@@ -1430,9 +1437,6 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
                                const int *srv_version, int srv_vercnt,
                                int *nego_fw_version, int *nego_srv_version);
 
-void hv_event_tasklet_disable(struct vmbus_channel *channel);
-void hv_event_tasklet_enable(struct vmbus_channel *channel);
-
 void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
 
 void vmbus_setevent(struct vmbus_channel *channel);
index 23ca41515527965239a56e92b909d53e75055cd4..fa7931933067982b2bac57f4c73aac039db8f692 100644 (file)
@@ -62,7 +62,7 @@ void iio_swd_group_init_type_name(struct iio_sw_device *d,
                                  const char *name,
                                  struct config_item_type *type)
 {
-#ifdef CONFIG_CONFIGFS_FS
+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
        config_group_init_type_name(&d->group, name, type);
 #endif
 }
index 6a6de187ddc0ff1e0e737f94261211b7ea4408e9..2e4de0deee531adbd7c1cd8ff1d25e0d0eb98d47 100644 (file)
@@ -125,9 +125,16 @@ enum iommu_attr {
 };
 
 /* These are the possible reserved region types */
-#define IOMMU_RESV_DIRECT      (1 << 0)
-#define IOMMU_RESV_RESERVED    (1 << 1)
-#define IOMMU_RESV_MSI         (1 << 2)
+enum iommu_resv_type {
+       /* Memory regions which must be mapped 1:1 at all times */
+       IOMMU_RESV_DIRECT,
+       /* Arbitrary "never map this or give it to a device" address ranges */
+       IOMMU_RESV_RESERVED,
+       /* Hardware MSI region (untranslated) */
+       IOMMU_RESV_MSI,
+       /* Software-managed MSI translation window */
+       IOMMU_RESV_SW_MSI,
+};
 
 /**
  * struct iommu_resv_region - descriptor for a reserved memory region
@@ -142,7 +149,7 @@ struct iommu_resv_region {
        phys_addr_t             start;
        size_t                  length;
        int                     prot;
-       int                     type;
+       enum iommu_resv_type    type;
 };
 
 #ifdef CONFIG_IOMMU_API
@@ -288,7 +295,8 @@ extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
 extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
 extern int iommu_request_dm_for_dev(struct device *dev);
 extern struct iommu_resv_region *
-iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot, int type);
+iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
+                       enum iommu_resv_type type);
 extern int iommu_get_group_resv_regions(struct iommu_group *group,
                                        struct list_head *head);
 
index 5734480c9590946412ebd16b7752c5341c4600be..a5c7046f26b4b93f9199c2f4800b7a1da77791da 100644 (file)
@@ -76,6 +76,9 @@ size_t ksize(const void *);
 static inline void kasan_unpoison_slab(const void *ptr) { ksize(ptr); }
 size_t kasan_metadata_size(struct kmem_cache *cache);
 
+bool kasan_save_enable_multi_shot(void);
+void kasan_restore_multi_shot(bool enabled);
+
 #else /* CONFIG_KASAN */
 
 static inline void kasan_unpoison_shadow(const void *address, size_t size) {}
index 2c14ad9809da94bde727f3ebc744fabd47673f98..d0250744507a284138d0e7e702bb64e1d205e769 100644 (file)
@@ -162,8 +162,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
                    int len, void *val);
 int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
                            int len, struct kvm_io_device *dev);
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
-                             struct kvm_io_device *dev);
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+                              struct kvm_io_device *dev);
 struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
                                         gpa_t addr);
 
index 5af37730388074ff65d4e42143c40c2880b5aff7..bb7250c45cb8356b03df2d4b9f1325dc6e30069b 100644 (file)
@@ -740,6 +740,12 @@ static inline bool mem_cgroup_oom_synchronize(bool wait)
        return false;
 }
 
+static inline void mem_cgroup_update_page_stat(struct page *page,
+                                              enum mem_cgroup_stat_index idx,
+                                              int nr)
+{
+}
+
 static inline void mem_cgroup_inc_page_stat(struct page *page,
                                            enum mem_cgroup_stat_index idx)
 {
index 7e66e4f62858f395cd000226e9580785b03a4cf1..1beb1ec2fbdf339b34affc69508a5f5462b409b0 100644 (file)
@@ -476,6 +476,7 @@ enum {
 enum {
        MLX4_INTERFACE_STATE_UP         = 1 << 0,
        MLX4_INTERFACE_STATE_DELETION   = 1 << 1,
+       MLX4_INTERFACE_STATE_NOWAIT     = 1 << 2,
 };
 
 #define MSTR_SM_CHANGE_MASK (MLX4_EQ_PORT_INFO_MSTR_SM_SL_CHANGE_MASK | \
index 5f01c88f0800daaacca6f9b2a272e657552af4c9..00a8fa7e366a0320210941ca39dd53fed97d4e2c 100644 (file)
@@ -32,6 +32,8 @@ struct user_struct;
 struct writeback_control;
 struct bdi_writeback;
 
+void init_mm_internals(void);
+
 #ifndef CONFIG_NEED_MULTIPLE_NODES     /* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
 
index 35d0fd7a4948e6e49eb7e75512461d935cccd161..fd0de00c0d777ed72cfab3fdbeb54e885c14be77 100644 (file)
@@ -76,22 +76,12 @@ struct gpmc_timings;
 struct omap_nand_platform_data;
 struct omap_onenand_platform_data;
 
-#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
-extern int gpmc_nand_init(struct omap_nand_platform_data *d,
-                         struct gpmc_timings *gpmc_t);
-#else
-static inline int gpmc_nand_init(struct omap_nand_platform_data *d,
-                                struct gpmc_timings *gpmc_t)
-{
-       return 0;
-}
-#endif
-
 #if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
-extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
+extern int gpmc_onenand_init(struct omap_onenand_platform_data *d);
 #else
 #define board_onenand_data     NULL
-static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
+static inline int gpmc_onenand_init(struct omap_onenand_platform_data *d)
 {
+       return 0;
 }
 #endif
index 86b4ed75359e85345afb839483e5910bcf5fe6cb..96fb139bdd08fdec3ad83e689ad2808375473126 100644 (file)
@@ -31,31 +31,26 @@ static inline int device_reset_optional(struct device *dev)
 
 static inline int reset_control_reset(struct reset_control *rstc)
 {
-       WARN_ON(1);
        return 0;
 }
 
 static inline int reset_control_assert(struct reset_control *rstc)
 {
-       WARN_ON(1);
        return 0;
 }
 
 static inline int reset_control_deassert(struct reset_control *rstc)
 {
-       WARN_ON(1);
        return 0;
 }
 
 static inline int reset_control_status(struct reset_control *rstc)
 {
-       WARN_ON(1);
        return 0;
 }
 
 static inline void reset_control_put(struct reset_control *rstc)
 {
-       WARN_ON(1);
 }
 
 static inline int __must_check device_reset(struct device *dev)
@@ -74,14 +69,14 @@ static inline struct reset_control *__of_reset_control_get(
                                        const char *id, int index, bool shared,
                                        bool optional)
 {
-       return ERR_PTR(-ENOTSUPP);
+       return optional ? NULL : ERR_PTR(-ENOTSUPP);
 }
 
 static inline struct reset_control *__devm_reset_control_get(
                                        struct device *dev, const char *id,
                                        int index, bool shared, bool optional)
 {
-       return ERR_PTR(-ENOTSUPP);
+       return optional ? NULL : ERR_PTR(-ENOTSUPP);
 }
 
 #endif /* CONFIG_RESET_CONTROLLER */
index 4a68c67912078ec765e25ad59b88da70feacb0b6..34fe92ce1ebd7c6e9dfa0dac94ff4512deb6f95f 100644 (file)
@@ -54,15 +54,16 @@ static inline u64 local_clock(void)
 }
 #else
 extern void sched_clock_init_late(void);
-/*
- * Architectures can set this to 1 if they have specified
- * CONFIG_HAVE_UNSTABLE_SCHED_CLOCK in their arch Kconfig,
- * but then during bootup it turns out that sched_clock()
- * is reliable after all:
- */
 extern int sched_clock_stable(void);
 extern void clear_sched_clock_stable(void);
 
+/*
+ * When sched_clock_stable(), __sched_clock_offset provides the offset
+ * between local_clock() and sched_clock().
+ */
+extern u64 __sched_clock_offset;
+
+
 extern void sched_clock_tick(void);
 extern void sched_clock_idle_sleep_event(void);
 extern void sched_clock_idle_wakeup_event(u64 delta_ns);
index 1d0043dc34e427403a1c82458249bed83e87d3a0..de2a722fe3cf7c457352eb02548f0351a669ddf5 100644 (file)
 /* device can't handle Link Power Management */
 #define USB_QUIRK_NO_LPM                       BIT(10)
 
+/*
+ * Device reports its bInterval as linear frames instead of the
+ * USB 2.0 calculation.
+ */
+#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL  BIT(11)
+
 #endif /* __LINUX_USB_QUIRKS_H */
index 9638bfeb0d1f639ae310d1586b4e2fca567ba2f7..584f9a647ad4acca191ff6116a47c14da1385fa3 100644 (file)
@@ -48,6 +48,8 @@ struct virtio_vsock_pkt {
        struct virtio_vsock_hdr hdr;
        struct work_struct work;
        struct list_head list;
+       /* socket refcnt not held, only use for cancellation */
+       struct vsock_sock *vsk;
        void *buf;
        u32 len;
        u32 off;
@@ -56,6 +58,7 @@ struct virtio_vsock_pkt {
 
 struct virtio_vsock_pkt_info {
        u32 remote_cid, remote_port;
+       struct vsock_sock *vsk;
        struct msghdr *msg;
        u32 pkt_len;
        u16 type;
index f2758964ce6f890e3b11df5ba5bf2eefe636abd1..f32ed9ac181a47c00757596fc3b8c5733426c468 100644 (file)
@@ -100,6 +100,9 @@ struct vsock_transport {
        void (*destruct)(struct vsock_sock *);
        void (*release)(struct vsock_sock *);
 
+       /* Cancel all pending packets sent on vsock. */
+       int (*cancel_pkt)(struct vsock_sock *vsk);
+
        /* Connections. */
        int (*connect)(struct vsock_sock *);
 
index f540f9ad2af4f673a204875864ce73f423204a74..19605878da4739d04f0642b20f8641ed8601d2eb 100644 (file)
@@ -244,7 +244,7 @@ extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct,
                               u32 seq);
 
 /* Fake conntrack entry for untracked connections */
-DECLARE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
+DECLARE_PER_CPU_ALIGNED(struct nf_conn, nf_conntrack_untracked);
 static inline struct nf_conn *nf_ct_untracked_get(void)
 {
        return raw_cpu_ptr(&nf_conntrack_untracked);
index 2aa8a9d80fbe8263a4b0e1c65f44e1ee2d9295d4..0136028652bdb8b3c20813b01b2fa8cfb16ba012 100644 (file)
@@ -103,6 +103,35 @@ struct nft_regs {
        };
 };
 
+/* Store/load an u16 or u8 integer to/from the u32 data register.
+ *
+ * Note, when using concatenations, register allocation happens at 32-bit
+ * level. So for store instruction, pad the rest part with zero to avoid
+ * garbage values.
+ */
+
+static inline void nft_reg_store16(u32 *dreg, u16 val)
+{
+       *dreg = 0;
+       *(u16 *)dreg = val;
+}
+
+static inline void nft_reg_store8(u32 *dreg, u8 val)
+{
+       *dreg = 0;
+       *(u8 *)dreg = val;
+}
+
+static inline u16 nft_reg_load16(u32 *sreg)
+{
+       return *(u16 *)sreg;
+}
+
+static inline u8 nft_reg_load8(u32 *sreg)
+{
+       return *(u8 *)sreg;
+}
+
 static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
                                 unsigned int len)
 {
@@ -203,7 +232,6 @@ struct nft_set_elem {
 struct nft_set;
 struct nft_set_iter {
        u8              genmask;
-       bool            flush;
        unsigned int    count;
        unsigned int    skip;
        int             err;
index d150b50662017378644c8f3ccf0218ecceaa2331..97983d1c05e4d327147110440f4a3925b13f6951 100644 (file)
@@ -9,12 +9,13 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
                     struct sk_buff *skb,
                     const struct nf_hook_state *state)
 {
+       unsigned int flags = IP6_FH_F_AUTH;
        int protohdr, thoff = 0;
        unsigned short frag_off;
 
        nft_set_pktinfo(pkt, skb, state);
 
-       protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
+       protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
        if (protohdr < 0) {
                nft_set_pktinfo_proto_unspec(pkt, skb);
                return;
@@ -32,6 +33,7 @@ __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
                                const struct nf_hook_state *state)
 {
 #if IS_ENABLED(CONFIG_IPV6)
+       unsigned int flags = IP6_FH_F_AUTH;
        struct ipv6hdr *ip6h, _ip6h;
        unsigned int thoff = 0;
        unsigned short frag_off;
@@ -50,7 +52,7 @@ __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
        if (pkt_len + sizeof(*ip6h) > skb->len)
                return -1;
 
-       protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
+       protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
        if (protohdr < 0)
                return -1;
 
index 07a0b128625a4e24f9aa83019eff6eb17308eda3..592decebac752ffca16fddbc75cbf14f9283d125 100644 (file)
@@ -83,6 +83,7 @@ struct sctp_bind_addr;
 struct sctp_ulpq;
 struct sctp_ep_common;
 struct crypto_shash;
+struct sctp_stream;
 
 
 #include <net/sctp/tsnmap.h>
@@ -753,6 +754,8 @@ struct sctp_transport {
                /* Is the Path MTU update pending on this tranport */
                pmtu_pending:1,
 
+               dst_pending_confirm:1,  /* need to confirm neighbour */
+
                /* Has this transport moved the ctsn since we last sacked */
                sack_generation:1;
        u32 dst_cookie;
@@ -806,8 +809,6 @@ struct sctp_transport {
 
        __u32 burst_limited;    /* Holds old cwnd when max.burst is applied */
 
-       __u32 dst_pending_confirm;      /* need to confirm neighbour */
-
        /* Destination */
        struct dst_entry *dst;
        /* Source address. */
index 0f1813c1368795994e012d00c607499879c130aa..99e4423eb2b80b142024bed892ddc4a84ac5e576 100644 (file)
@@ -1863,6 +1863,9 @@ struct ib_port_immutable {
 };
 
 struct ib_device {
+       /* Do not access @dma_device directly from ULP nor from HW drivers. */
+       struct device                *dma_device;
+
        char                          name[IB_DEVICE_NAME_MAX];
 
        struct list_head              event_handler_list;
@@ -3007,7 +3010,7 @@ static inline int ib_req_ncomp_notif(struct ib_cq *cq, int wc_cnt)
  */
 static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
 {
-       return dma_mapping_error(&dev->dev, dma_addr);
+       return dma_mapping_error(dev->dma_device, dma_addr);
 }
 
 /**
@@ -3021,7 +3024,7 @@ static inline u64 ib_dma_map_single(struct ib_device *dev,
                                    void *cpu_addr, size_t size,
                                    enum dma_data_direction direction)
 {
-       return dma_map_single(&dev->dev, cpu_addr, size, direction);
+       return dma_map_single(dev->dma_device, cpu_addr, size, direction);
 }
 
 /**
@@ -3035,7 +3038,7 @@ static inline void ib_dma_unmap_single(struct ib_device *dev,
                                       u64 addr, size_t size,
                                       enum dma_data_direction direction)
 {
-       dma_unmap_single(&dev->dev, addr, size, direction);
+       dma_unmap_single(dev->dma_device, addr, size, direction);
 }
 
 /**
@@ -3052,7 +3055,7 @@ static inline u64 ib_dma_map_page(struct ib_device *dev,
                                  size_t size,
                                         enum dma_data_direction direction)
 {
-       return dma_map_page(&dev->dev, page, offset, size, direction);
+       return dma_map_page(dev->dma_device, page, offset, size, direction);
 }
 
 /**
@@ -3066,7 +3069,7 @@ static inline void ib_dma_unmap_page(struct ib_device *dev,
                                     u64 addr, size_t size,
                                     enum dma_data_direction direction)
 {
-       dma_unmap_page(&dev->dev, addr, size, direction);
+       dma_unmap_page(dev->dma_device, addr, size, direction);
 }
 
 /**
@@ -3080,7 +3083,7 @@ static inline int ib_dma_map_sg(struct ib_device *dev,
                                struct scatterlist *sg, int nents,
                                enum dma_data_direction direction)
 {
-       return dma_map_sg(&dev->dev, sg, nents, direction);
+       return dma_map_sg(dev->dma_device, sg, nents, direction);
 }
 
 /**
@@ -3094,7 +3097,7 @@ static inline void ib_dma_unmap_sg(struct ib_device *dev,
                                   struct scatterlist *sg, int nents,
                                   enum dma_data_direction direction)
 {
-       dma_unmap_sg(&dev->dev, sg, nents, direction);
+       dma_unmap_sg(dev->dma_device, sg, nents, direction);
 }
 
 static inline int ib_dma_map_sg_attrs(struct ib_device *dev,
@@ -3102,7 +3105,8 @@ static inline int ib_dma_map_sg_attrs(struct ib_device *dev,
                                      enum dma_data_direction direction,
                                      unsigned long dma_attrs)
 {
-       return dma_map_sg_attrs(&dev->dev, sg, nents, direction, dma_attrs);
+       return dma_map_sg_attrs(dev->dma_device, sg, nents, direction,
+                               dma_attrs);
 }
 
 static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev,
@@ -3110,7 +3114,7 @@ static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev,
                                         enum dma_data_direction direction,
                                         unsigned long dma_attrs)
 {
-       dma_unmap_sg_attrs(&dev->dev, sg, nents, direction, dma_attrs);
+       dma_unmap_sg_attrs(dev->dma_device, sg, nents, direction, dma_attrs);
 }
 /**
  * ib_sg_dma_address - Return the DMA address from a scatter/gather entry
@@ -3152,7 +3156,7 @@ static inline void ib_dma_sync_single_for_cpu(struct ib_device *dev,
                                              size_t size,
                                              enum dma_data_direction dir)
 {
-       dma_sync_single_for_cpu(&dev->dev, addr, size, dir);
+       dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
 }
 
 /**
@@ -3167,7 +3171,7 @@ static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
                                                 size_t size,
                                                 enum dma_data_direction dir)
 {
-       dma_sync_single_for_device(&dev->dev, addr, size, dir);
+       dma_sync_single_for_device(dev->dma_device, addr, size, dir);
 }
 
 /**
@@ -3182,7 +3186,7 @@ static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
                                           dma_addr_t *dma_handle,
                                           gfp_t flag)
 {
-       return dma_alloc_coherent(&dev->dev, size, dma_handle, flag);
+       return dma_alloc_coherent(dev->dma_device, size, dma_handle, flag);
 }
 
 /**
@@ -3196,7 +3200,7 @@ static inline void ib_dma_free_coherent(struct ib_device *dev,
                                        size_t size, void *cpu_addr,
                                        dma_addr_t dma_handle)
 {
-       dma_free_coherent(&dev->dev, size, cpu_addr, dma_handle);
+       dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
 }
 
 /**
index 9b1462e38b821a762b284b44a20a96de9f0930d9..a076cf1a3a23be2fbee73dab483e051b37b2370c 100644 (file)
@@ -730,9 +730,11 @@ __SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect)
 __SYSCALL(__NR_pkey_alloc,    sys_pkey_alloc)
 #define __NR_pkey_free 290
 __SYSCALL(__NR_pkey_free,     sys_pkey_free)
+#define __NR_statx 291
+__SYSCALL(__NR_statx,     sys_statx)
 
 #undef __NR_syscalls
-#define __NR_syscalls 291
+#define __NR_syscalls 292
 
 /*
  * All syscalls below here should go away really,
index db4c253f8011b2f483ddd1ffc09f4f04a93fdc0a..dcfc3a5a9cb1d20f29bbac00c6ef315006e9d208 100644 (file)
@@ -713,33 +713,6 @@ enum btrfs_err_code {
        BTRFS_ERROR_DEV_ONLY_WRITABLE,
        BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
 };
-/* An error code to error string mapping for the kernel
-*  error codes
-*/
-static inline char *btrfs_err_str(enum btrfs_err_code err_code)
-{
-       switch (err_code) {
-               case BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET:
-                       return "unable to go below two devices on raid1";
-               case BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET:
-                       return "unable to go below four devices on raid10";
-               case BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET:
-                       return "unable to go below two devices on raid5";
-               case BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET:
-                       return "unable to go below three devices on raid6";
-               case BTRFS_ERROR_DEV_TGT_REPLACE:
-                       return "unable to remove the dev_replace target dev";
-               case BTRFS_ERROR_DEV_MISSING_NOT_FOUND:
-                       return "no missing devices found to remove";
-               case BTRFS_ERROR_DEV_ONLY_WRITABLE:
-                       return "unable to remove the only writeable device";
-               case BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS:
-                       return "add/delete/balance/replace/resize operation "\
-                               "in progress";
-               default:
-                       return NULL;
-       }
-}
 
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
                                   struct btrfs_ioctl_vol_args)
index da7cd62bace746879e154829b5ecad5f6cd87c00..0b3d30837a9f6456aabe028f5f9931b3593d778c 100644 (file)
@@ -34,6 +34,7 @@
 #define MLX5_ABI_USER_H
 
 #include <linux/types.h>
+#include <linux/if_ether.h>    /* For ETH_ALEN. */
 
 enum {
        MLX5_QP_FLAG_SIGNATURE          = 1 << 0,
@@ -66,7 +67,7 @@ struct mlx5_ib_alloc_ucontext_req {
 };
 
 enum mlx5_lib_caps {
-       MLX5_LIB_CAP_4K_UAR     = (u64)1 << 0,
+       MLX5_LIB_CAP_4K_UAR     = (__u64)1 << 0,
 };
 
 struct mlx5_ib_alloc_ucontext_req_v2 {
index ef8e2a8ad0afc85da51bc3fca00a26fa3768ff16..6b083d327e982c0c5deb7895ce6e7c6b1094c8a6 100644 (file)
@@ -46,6 +46,7 @@
 #define DECON_FRAMEFIFO_STATUS         0x0524
 #define DECON_CMU                      0x1404
 #define DECON_UPDATE                   0x1410
+#define DECON_CRFMID                   0x1414
 #define DECON_UPDATE_SCHEME            0x1438
 #define DECON_VIDCON1                  0x2000
 #define DECON_VIDCON2                  0x2004
 
 /* VIDINTCON0 */
 #define VIDINTCON0_FRAMEDONE           (1 << 17)
+#define VIDINTCON0_FRAMESEL_BP         (0 << 15)
+#define VIDINTCON0_FRAMESEL_VS         (1 << 15)
+#define VIDINTCON0_FRAMESEL_AC         (2 << 15)
+#define VIDINTCON0_FRAMESEL_FP         (3 << 15)
 #define VIDINTCON0_INTFRMEN            (1 << 12)
 #define VIDINTCON0_INTEN               (1 << 0)
 
 #define STANDALONE_UPDATE_F            (1 << 0)
 
 /* DECON_VIDCON1 */
+#define VIDCON1_LINECNT_MASK           (0x0fff << 16)
+#define VIDCON1_I80_ACTIVE             (1 << 15)
+#define VIDCON1_VSTATUS_MASK           (0x3 << 13)
+#define VIDCON1_VSTATUS_VS             (0 << 13)
+#define VIDCON1_VSTATUS_BP             (1 << 13)
+#define VIDCON1_VSTATUS_AC             (2 << 13)
+#define VIDCON1_VSTATUS_FP             (3 << 13)
 #define VIDCON1_VCLK_MASK              (0x3 << 9)
 #define VIDCON1_VCLK_RUN_VDEN_DISABLE  (0x3 << 9)
 #define VIDCON1_VCLK_HOLD              (0x0 << 9)
index f9c9d994820327a3c23db348886fd535190b43e8..b0c11cbf5ddf8a55a3c832e4acbd72653d9c38f1 100644 (file)
@@ -1022,6 +1022,8 @@ static noinline void __init kernel_init_freeable(void)
 
        workqueue_init();
 
+       init_mm_internals();
+
        do_pre_smp_initcalls();
        lockup_detector_init();
 
index e794544f5e63334afccadf6cc70f5fb2541e1e2e..2f4964cfde0b4f142778c199e606dc3d519ebbf0 100644 (file)
 #include <linux/kthread.h>
 #include <linux/kernel.h>
 #include <linux/syscalls.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/mutex.h>
+#include <linux/gfp.h>
 
 #include <linux/audit.h>
 
@@ -90,13 +94,34 @@ static u32  audit_default;
 /* If auditing cannot proceed, audit_failure selects what happens. */
 static u32     audit_failure = AUDIT_FAIL_PRINTK;
 
-/*
- * If audit records are to be written to the netlink socket, audit_pid
- * contains the pid of the auditd process and audit_nlk_portid contains
- * the portid to use to send netlink messages to that process.
+/* private audit network namespace index */
+static unsigned int audit_net_id;
+
+/**
+ * struct audit_net - audit private network namespace data
+ * @sk: communication socket
+ */
+struct audit_net {
+       struct sock *sk;
+};
+
+/**
+ * struct auditd_connection - kernel/auditd connection state
+ * @pid: auditd PID
+ * @portid: netlink portid
+ * @net: the associated network namespace
+ * @lock: spinlock to protect write access
+ *
+ * Description:
+ * This struct is RCU protected; you must either hold the RCU lock for reading
+ * or the included spinlock for writing.
  */
-int            audit_pid;
-static __u32   audit_nlk_portid;
+static struct auditd_connection {
+       int pid;
+       u32 portid;
+       struct net *net;
+       spinlock_t lock;
+} auditd_conn;
 
 /* If audit_rate_limit is non-zero, limit the rate of sending audit records
  * to that number per second.  This prevents DoS attacks, but results in
@@ -123,10 +148,6 @@ u32                audit_sig_sid = 0;
 */
 static atomic_t        audit_lost = ATOMIC_INIT(0);
 
-/* The netlink socket. */
-static struct sock *audit_sock;
-static unsigned int audit_net_id;
-
 /* Hash for inode-based rules */
 struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
 
@@ -139,6 +160,7 @@ static LIST_HEAD(audit_freelist);
 
 /* queue msgs to send via kauditd_task */
 static struct sk_buff_head audit_queue;
+static void kauditd_hold_skb(struct sk_buff *skb);
 /* queue msgs due to temporary unicast send problems */
 static struct sk_buff_head audit_retry_queue;
 /* queue msgs waiting for new auditd connection */
@@ -192,6 +214,43 @@ struct audit_reply {
        struct sk_buff *skb;
 };
 
+/**
+ * auditd_test_task - Check to see if a given task is an audit daemon
+ * @task: the task to check
+ *
+ * Description:
+ * Return 1 if the task is a registered audit daemon, 0 otherwise.
+ */
+int auditd_test_task(const struct task_struct *task)
+{
+       int rc;
+
+       rcu_read_lock();
+       rc = (auditd_conn.pid && task->tgid == auditd_conn.pid ? 1 : 0);
+       rcu_read_unlock();
+
+       return rc;
+}
+
+/**
+ * audit_get_sk - Return the audit socket for the given network namespace
+ * @net: the destination network namespace
+ *
+ * Description:
+ * Returns the sock pointer if valid, NULL otherwise.  The caller must ensure
+ * that a reference is held for the network namespace while the sock is in use.
+ */
+static struct sock *audit_get_sk(const struct net *net)
+{
+       struct audit_net *aunet;
+
+       if (!net)
+               return NULL;
+
+       aunet = net_generic(net, audit_net_id);
+       return aunet->sk;
+}
+
 static void audit_set_portid(struct audit_buffer *ab, __u32 portid)
 {
        if (ab) {
@@ -210,9 +269,7 @@ void audit_panic(const char *message)
                        pr_err("%s\n", message);
                break;
        case AUDIT_FAIL_PANIC:
-               /* test audit_pid since printk is always losey, why bother? */
-               if (audit_pid)
-                       panic("audit: %s\n", message);
+               panic("audit: %s\n", message);
                break;
        }
 }
@@ -370,21 +427,87 @@ static int audit_set_failure(u32 state)
        return audit_do_config_change("audit_failure", &audit_failure, state);
 }
 
-/*
- * For one reason or another this nlh isn't getting delivered to the userspace
- * audit daemon, just send it to printk.
+/**
+ * auditd_set - Set/Reset the auditd connection state
+ * @pid: auditd PID
+ * @portid: auditd netlink portid
+ * @net: auditd network namespace pointer
+ *
+ * Description:
+ * This function will obtain and drop network namespace references as
+ * necessary.
+ */
+static void auditd_set(int pid, u32 portid, struct net *net)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&auditd_conn.lock, flags);
+       auditd_conn.pid = pid;
+       auditd_conn.portid = portid;
+       if (auditd_conn.net)
+               put_net(auditd_conn.net);
+       if (net)
+               auditd_conn.net = get_net(net);
+       else
+               auditd_conn.net = NULL;
+       spin_unlock_irqrestore(&auditd_conn.lock, flags);
+}
+
+/**
+ * auditd_reset - Disconnect the auditd connection
+ *
+ * Description:
+ * Break the auditd/kauditd connection and move all the queued records into the
+ * hold queue in case auditd reconnects.
+ */
+static void auditd_reset(void)
+{
+       struct sk_buff *skb;
+
+       /* if it isn't already broken, break the connection */
+       rcu_read_lock();
+       if (auditd_conn.pid)
+               auditd_set(0, 0, NULL);
+       rcu_read_unlock();
+
+       /* flush all of the main and retry queues to the hold queue */
+       while ((skb = skb_dequeue(&audit_retry_queue)))
+               kauditd_hold_skb(skb);
+       while ((skb = skb_dequeue(&audit_queue)))
+               kauditd_hold_skb(skb);
+}
+
+/**
+ * kauditd_print_skb - Print the audit record to the ring buffer
+ * @skb: audit record
+ *
+ * Whatever the reason, this packet may not make it to the auditd connection
+ * so write it via printk so the information isn't completely lost.
  */
 static void kauditd_printk_skb(struct sk_buff *skb)
 {
        struct nlmsghdr *nlh = nlmsg_hdr(skb);
        char *data = nlmsg_data(nlh);
 
-       if (nlh->nlmsg_type != AUDIT_EOE) {
-               if (printk_ratelimit())
-                       pr_notice("type=%d %s\n", nlh->nlmsg_type, data);
-               else
-                       audit_log_lost("printk limit exceeded");
-       }
+       if (nlh->nlmsg_type != AUDIT_EOE && printk_ratelimit())
+               pr_notice("type=%d %s\n", nlh->nlmsg_type, data);
+}
+
+/**
+ * kauditd_rehold_skb - Handle a audit record send failure in the hold queue
+ * @skb: audit record
+ *
+ * Description:
+ * This should only be used by the kauditd_thread when it fails to flush the
+ * hold queue.
+ */
+static void kauditd_rehold_skb(struct sk_buff *skb)
+{
+       /* put the record back in the queue at the same place */
+       skb_queue_head(&audit_hold_queue, skb);
+
+       /* fail the auditd connection */
+       auditd_reset();
 }
 
 /**
@@ -421,6 +544,9 @@ static void kauditd_hold_skb(struct sk_buff *skb)
        /* we have no other options - drop the message */
        audit_log_lost("kauditd hold queue overflow");
        kfree_skb(skb);
+
+       /* fail the auditd connection */
+       auditd_reset();
 }
 
 /**
@@ -441,51 +567,122 @@ static void kauditd_retry_skb(struct sk_buff *skb)
 }
 
 /**
- * auditd_reset - Disconnect the auditd connection
+ * auditd_send_unicast_skb - Send a record via unicast to auditd
+ * @skb: audit record
  *
  * Description:
- * Break the auditd/kauditd connection and move all the records in the retry
- * queue into the hold queue in case auditd reconnects.  The audit_cmd_mutex
- * must be held when calling this function.
+ * Send a skb to the audit daemon, returns positive/zero values on success and
+ * negative values on failure; in all cases the skb will be consumed by this
+ * function.  If the send results in -ECONNREFUSED the connection with auditd
+ * will be reset.  This function may sleep so callers should not hold any locks
+ * where this would cause a problem.
  */
-static void auditd_reset(void)
+static int auditd_send_unicast_skb(struct sk_buff *skb)
 {
-       struct sk_buff *skb;
-
-       /* break the connection */
-       if (audit_sock) {
-               sock_put(audit_sock);
-               audit_sock = NULL;
+       int rc;
+       u32 portid;
+       struct net *net;
+       struct sock *sk;
+
+       /* NOTE: we can't call netlink_unicast while in the RCU section so
+        *       take a reference to the network namespace and grab local
+        *       copies of the namespace, the sock, and the portid; the
+        *       namespace and sock aren't going to go away while we hold a
+        *       reference and if the portid does become invalid after the RCU
+        *       section netlink_unicast() should safely return an error */
+
+       rcu_read_lock();
+       if (!auditd_conn.pid) {
+               rcu_read_unlock();
+               rc = -ECONNREFUSED;
+               goto err;
        }
-       audit_pid = 0;
-       audit_nlk_portid = 0;
+       net = auditd_conn.net;
+       get_net(net);
+       sk = audit_get_sk(net);
+       portid = auditd_conn.portid;
+       rcu_read_unlock();
 
-       /* flush all of the retry queue to the hold queue */
-       while ((skb = skb_dequeue(&audit_retry_queue)))
-               kauditd_hold_skb(skb);
+       rc = netlink_unicast(sk, skb, portid, 0);
+       put_net(net);
+       if (rc < 0)
+               goto err;
+
+       return rc;
+
+err:
+       if (rc == -ECONNREFUSED)
+               auditd_reset();
+       return rc;
 }
 
 /**
- * kauditd_send_unicast_skb - Send a record via unicast to auditd
- * @skb: audit record
+ * kauditd_send_queue - Helper for kauditd_thread to flush skb queues
+ * @sk: the sending sock
+ * @portid: the netlink destination
+ * @queue: the skb queue to process
+ * @retry_limit: limit on number of netlink unicast failures
+ * @skb_hook: per-skb hook for additional processing
+ * @err_hook: hook called if the skb fails the netlink unicast send
+ *
+ * Description:
+ * Run through the given queue and attempt to send the audit records to auditd,
+ * returns zero on success, negative values on failure.  It is up to the caller
+ * to ensure that the @sk is valid for the duration of this function.
+ *
  */
-static int kauditd_send_unicast_skb(struct sk_buff *skb)
+static int kauditd_send_queue(struct sock *sk, u32 portid,
+                             struct sk_buff_head *queue,
+                             unsigned int retry_limit,
+                             void (*skb_hook)(struct sk_buff *skb),
+                             void (*err_hook)(struct sk_buff *skb))
 {
-       int rc;
+       int rc = 0;
+       struct sk_buff *skb;
+       static unsigned int failed = 0;
 
-       /* if we know nothing is connected, don't even try the netlink call */
-       if (!audit_pid)
-               return -ECONNREFUSED;
+       /* NOTE: kauditd_thread takes care of all our locking, we just use
+        *       the netlink info passed to us (e.g. sk and portid) */
+
+       while ((skb = skb_dequeue(queue))) {
+               /* call the skb_hook for each skb we touch */
+               if (skb_hook)
+                       (*skb_hook)(skb);
+
+               /* can we send to anyone via unicast? */
+               if (!sk) {
+                       if (err_hook)
+                               (*err_hook)(skb);
+                       continue;
+               }
 
-       /* get an extra skb reference in case we fail to send */
-       skb_get(skb);
-       rc = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
-       if (rc >= 0) {
-               consume_skb(skb);
-               rc = 0;
+               /* grab an extra skb reference in case of error */
+               skb_get(skb);
+               rc = netlink_unicast(sk, skb, portid, 0);
+               if (rc < 0) {
+                       /* fatal failure for our queue flush attempt? */
+                       if (++failed >= retry_limit ||
+                           rc == -ECONNREFUSED || rc == -EPERM) {
+                               /* yes - error processing for the queue */
+                               sk = NULL;
+                               if (err_hook)
+                                       (*err_hook)(skb);
+                               if (!skb_hook)
+                                       goto out;
+                               /* keep processing with the skb_hook */
+                               continue;
+                       } else
+                               /* no - requeue to preserve ordering */
+                               skb_queue_head(queue, skb);
+               } else {
+                       /* it worked - drop the extra reference and continue */
+                       consume_skb(skb);
+                       failed = 0;
+               }
        }
 
-       return rc;
+out:
+       return (rc >= 0 ? 0 : rc);
 }
 
 /*
@@ -493,16 +690,19 @@ static int kauditd_send_unicast_skb(struct sk_buff *skb)
  * @skb: audit record
  *
  * Description:
- * This function doesn't consume an skb as might be expected since it has to
- * copy it anyways.
+ * Write a multicast message to anyone listening in the initial network
+ * namespace.  This function doesn't consume an skb as might be expected since
+ * it has to copy it anyways.
  */
 static void kauditd_send_multicast_skb(struct sk_buff *skb)
 {
        struct sk_buff *copy;
-       struct audit_net *aunet = net_generic(&init_net, audit_net_id);
-       struct sock *sock = aunet->nlsk;
+       struct sock *sock = audit_get_sk(&init_net);
        struct nlmsghdr *nlh;
 
+       /* NOTE: we are not taking an additional reference for init_net since
+        *       we don't have to worry about it going away */
+
        if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
                return;
 
@@ -526,149 +726,75 @@ static void kauditd_send_multicast_skb(struct sk_buff *skb)
 }
 
 /**
- * kauditd_wake_condition - Return true when it is time to wake kauditd_thread
- *
- * Description:
- * This function is for use by the wait_event_freezable() call in
- * kauditd_thread().
+ * kauditd_thread - Worker thread to send audit records to userspace
+ * @dummy: unused
  */
-static int kauditd_wake_condition(void)
-{
-       static int pid_last = 0;
-       int rc;
-       int pid = audit_pid;
-
-       /* wake on new messages or a change in the connected auditd */
-       rc = skb_queue_len(&audit_queue) || (pid && pid != pid_last);
-       if (rc)
-               pid_last = pid;
-
-       return rc;
-}
-
 static int kauditd_thread(void *dummy)
 {
        int rc;
-       int auditd = 0;
-       int reschedule = 0;
-       struct sk_buff *skb;
-       struct nlmsghdr *nlh;
+       u32 portid = 0;
+       struct net *net = NULL;
+       struct sock *sk = NULL;
 
 #define UNICAST_RETRIES 5
-#define AUDITD_BAD(x,y) \
-       ((x) == -ECONNREFUSED || (x) == -EPERM || ++(y) >= UNICAST_RETRIES)
-
-       /* NOTE: we do invalidate the auditd connection flag on any sending
-        * errors, but we only "restore" the connection flag at specific places
-        * in the loop in order to help ensure proper ordering of audit
-        * records */
 
        set_freezable();
        while (!kthread_should_stop()) {
-               /* NOTE: possible area for future improvement is to look at
-                *       the hold and retry queues, since only this thread
-                *       has access to these queues we might be able to do
-                *       our own queuing and skip some/all of the locking */
-
-               /* NOTE: it might be a fun experiment to split the hold and
-                *       retry queue handling to another thread, but the
-                *       synchronization issues and other overhead might kill
-                *       any performance gains */
+               /* NOTE: see the lock comments in auditd_send_unicast_skb() */
+               rcu_read_lock();
+               if (!auditd_conn.pid) {
+                       rcu_read_unlock();
+                       goto main_queue;
+               }
+               net = auditd_conn.net;
+               get_net(net);
+               sk = audit_get_sk(net);
+               portid = auditd_conn.portid;
+               rcu_read_unlock();
 
                /* attempt to flush the hold queue */
-               while (auditd && (skb = skb_dequeue(&audit_hold_queue))) {
-                       rc = kauditd_send_unicast_skb(skb);
-                       if (rc) {
-                               /* requeue to the same spot */
-                               skb_queue_head(&audit_hold_queue, skb);
-
-                               auditd = 0;
-                               if (AUDITD_BAD(rc, reschedule)) {
-                                       mutex_lock(&audit_cmd_mutex);
-                                       auditd_reset();
-                                       mutex_unlock(&audit_cmd_mutex);
-                                       reschedule = 0;
-                               }
-                       } else
-                               /* we were able to send successfully */
-                               reschedule = 0;
+               rc = kauditd_send_queue(sk, portid,
+                                       &audit_hold_queue, UNICAST_RETRIES,
+                                       NULL, kauditd_rehold_skb);
+               if (rc < 0) {
+                       sk = NULL;
+                       goto main_queue;
                }
 
                /* attempt to flush the retry queue */
-               while (auditd && (skb = skb_dequeue(&audit_retry_queue))) {
-                       rc = kauditd_send_unicast_skb(skb);
-                       if (rc) {
-                               auditd = 0;
-                               if (AUDITD_BAD(rc, reschedule)) {
-                                       kauditd_hold_skb(skb);
-                                       mutex_lock(&audit_cmd_mutex);
-                                       auditd_reset();
-                                       mutex_unlock(&audit_cmd_mutex);
-                                       reschedule = 0;
-                               } else
-                                       /* temporary problem (we hope), queue
-                                        * to the same spot and retry */
-                                       skb_queue_head(&audit_retry_queue, skb);
-                       } else
-                               /* we were able to send successfully */
-                               reschedule = 0;
+               rc = kauditd_send_queue(sk, portid,
+                                       &audit_retry_queue, UNICAST_RETRIES,
+                                       NULL, kauditd_hold_skb);
+               if (rc < 0) {
+                       sk = NULL;
+                       goto main_queue;
                }
 
-               /* standard queue processing, try to be as quick as possible */
-quick_loop:
-               skb = skb_dequeue(&audit_queue);
-               if (skb) {
-                       /* setup the netlink header, see the comments in
-                        * kauditd_send_multicast_skb() for length quirks */
-                       nlh = nlmsg_hdr(skb);
-                       nlh->nlmsg_len = skb->len - NLMSG_HDRLEN;
-
-                       /* attempt to send to any multicast listeners */
-                       kauditd_send_multicast_skb(skb);
-
-                       /* attempt to send to auditd, queue on failure */
-                       if (auditd) {
-                               rc = kauditd_send_unicast_skb(skb);
-                               if (rc) {
-                                       auditd = 0;
-                                       if (AUDITD_BAD(rc, reschedule)) {
-                                               mutex_lock(&audit_cmd_mutex);
-                                               auditd_reset();
-                                               mutex_unlock(&audit_cmd_mutex);
-                                               reschedule = 0;
-                                       }
-
-                                       /* move to the retry queue */
-                                       kauditd_retry_skb(skb);
-                               } else
-                                       /* everything is working so go fast! */
-                                       goto quick_loop;
-                       } else if (reschedule)
-                               /* we are currently having problems, move to
-                                * the retry queue */
-                               kauditd_retry_skb(skb);
-                       else
-                               /* dump the message via printk and hold it */
-                               kauditd_hold_skb(skb);
-               } else {
-                       /* we have flushed the backlog so wake everyone */
-                       wake_up(&audit_backlog_wait);
-
-                       /* if everything is okay with auditd (if present), go
-                        * to sleep until there is something new in the queue
-                        * or we have a change in the connected auditd;
-                        * otherwise simply reschedule to give things a chance
-                        * to recover */
-                       if (reschedule) {
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule();
-                       } else
-                               wait_event_freezable(kauditd_wait,
-                                                    kauditd_wake_condition());
-
-                       /* update the auditd connection status */
-                       auditd = (audit_pid ? 1 : 0);
+main_queue:
+               /* process the main queue - do the multicast send and attempt
+                * unicast, dump failed record sends to the retry queue; if
+                * sk == NULL due to previous failures we will just do the
+                * multicast send and move the record to the retry queue */
+               kauditd_send_queue(sk, portid, &audit_queue, 1,
+                                  kauditd_send_multicast_skb,
+                                  kauditd_retry_skb);
+
+               /* drop our netns reference, no auditd sends past this line */
+               if (net) {
+                       put_net(net);
+                       net = NULL;
                }
+               sk = NULL;
+
+               /* we have processed all the queues so wake everyone */
+               wake_up(&audit_backlog_wait);
+
+               /* NOTE: we want to wake up if there is anything on the queue,
+                *       regardless of if an auditd is connected, as we need to
+                *       do the multicast send and rotate records from the
+                *       main queue to the retry/hold queues */
+               wait_event_freezable(kauditd_wait,
+                                    (skb_queue_len(&audit_queue) ? 1 : 0));
        }
 
        return 0;
@@ -678,17 +804,16 @@ int audit_send_list(void *_dest)
 {
        struct audit_netlink_list *dest = _dest;
        struct sk_buff *skb;
-       struct net *net = dest->net;
-       struct audit_net *aunet = net_generic(net, audit_net_id);
+       struct sock *sk = audit_get_sk(dest->net);
 
        /* wait for parent to finish and send an ACK */
        mutex_lock(&audit_cmd_mutex);
        mutex_unlock(&audit_cmd_mutex);
 
        while ((skb = __skb_dequeue(&dest->q)) != NULL)
-               netlink_unicast(aunet->nlsk, skb, dest->portid, 0);
+               netlink_unicast(sk, skb, dest->portid, 0);
 
-       put_net(net);
+       put_net(dest->net);
        kfree(dest);
 
        return 0;
@@ -722,16 +847,15 @@ out_kfree_skb:
 static int audit_send_reply_thread(void *arg)
 {
        struct audit_reply *reply = (struct audit_reply *)arg;
-       struct net *net = reply->net;
-       struct audit_net *aunet = net_generic(net, audit_net_id);
+       struct sock *sk = audit_get_sk(reply->net);
 
        mutex_lock(&audit_cmd_mutex);
        mutex_unlock(&audit_cmd_mutex);
 
        /* Ignore failure. It'll only happen if the sender goes away,
           because our timeout is set to infinite. */
-       netlink_unicast(aunet->nlsk , reply->skb, reply->portid, 0);
-       put_net(net);
+       netlink_unicast(sk, reply->skb, reply->portid, 0);
+       put_net(reply->net);
        kfree(reply);
        return 0;
 }
@@ -949,12 +1073,12 @@ static int audit_set_feature(struct sk_buff *skb)
 
 static int audit_replace(pid_t pid)
 {
-       struct sk_buff *skb = audit_make_reply(0, 0, AUDIT_REPLACE, 0, 0,
-                                              &pid, sizeof(pid));
+       struct sk_buff *skb;
 
+       skb = audit_make_reply(0, 0, AUDIT_REPLACE, 0, 0, &pid, sizeof(pid));
        if (!skb)
                return -ENOMEM;
-       return netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
+       return auditd_send_unicast_skb(skb);
 }
 
 static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
@@ -981,7 +1105,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                memset(&s, 0, sizeof(s));
                s.enabled               = audit_enabled;
                s.failure               = audit_failure;
-               s.pid                   = audit_pid;
+               rcu_read_lock();
+               s.pid                   = auditd_conn.pid;
+               rcu_read_unlock();
                s.rate_limit            = audit_rate_limit;
                s.backlog_limit         = audit_backlog_limit;
                s.lost                  = atomic_read(&audit_lost);
@@ -1014,30 +1140,44 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                         *       from the initial pid namespace, but something
                         *       to keep in mind if this changes */
                        int new_pid = s.pid;
+                       pid_t auditd_pid;
                        pid_t requesting_pid = task_tgid_vnr(current);
 
-                       if ((!new_pid) && (requesting_pid != audit_pid)) {
-                               audit_log_config_change("audit_pid", new_pid, audit_pid, 0);
+                       /* test the auditd connection */
+                       audit_replace(requesting_pid);
+
+                       rcu_read_lock();
+                       auditd_pid = auditd_conn.pid;
+                       /* only the current auditd can unregister itself */
+                       if ((!new_pid) && (requesting_pid != auditd_pid)) {
+                               rcu_read_unlock();
+                               audit_log_config_change("audit_pid", new_pid,
+                                                       auditd_pid, 0);
                                return -EACCES;
                        }
-                       if (audit_pid && new_pid &&
-                           audit_replace(requesting_pid) != -ECONNREFUSED) {
-                               audit_log_config_change("audit_pid", new_pid, audit_pid, 0);
+                       /* replacing a healthy auditd is not allowed */
+                       if (auditd_pid && new_pid) {
+                               rcu_read_unlock();
+                               audit_log_config_change("audit_pid", new_pid,
+                                                       auditd_pid, 0);
                                return -EEXIST;
                        }
+                       rcu_read_unlock();
+
                        if (audit_enabled != AUDIT_OFF)
-                               audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
+                               audit_log_config_change("audit_pid", new_pid,
+                                                       auditd_pid, 1);
+
                        if (new_pid) {
-                               if (audit_sock)
-                                       sock_put(audit_sock);
-                               audit_pid = new_pid;
-                               audit_nlk_portid = NETLINK_CB(skb).portid;
-                               sock_hold(skb->sk);
-                               audit_sock = skb->sk;
-                       } else {
+                               /* register a new auditd connection */
+                               auditd_set(new_pid,
+                                          NETLINK_CB(skb).portid,
+                                          sock_net(NETLINK_CB(skb).sk));
+                               /* try to process any backlog */
+                               wake_up_interruptible(&kauditd_wait);
+                       } else
+                               /* unregister the auditd connection */
                                auditd_reset();
-                       }
-                       wake_up_interruptible(&kauditd_wait);
                }
                if (s.mask & AUDIT_STATUS_RATE_LIMIT) {
                        err = audit_set_rate_limit(s.rate_limit);
@@ -1090,7 +1230,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                if (err)
                                        break;
                        }
-                       mutex_unlock(&audit_cmd_mutex);
                        audit_log_common_recv_msg(&ab, msg_type);
                        if (msg_type != AUDIT_USER_TTY)
                                audit_log_format(ab, " msg='%.*s'",
@@ -1108,7 +1247,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        }
                        audit_set_portid(ab, NETLINK_CB(skb).portid);
                        audit_log_end(ab);
-                       mutex_lock(&audit_cmd_mutex);
                }
                break;
        case AUDIT_ADD_RULE:
@@ -1298,26 +1436,26 @@ static int __net_init audit_net_init(struct net *net)
 
        struct audit_net *aunet = net_generic(net, audit_net_id);
 
-       aunet->nlsk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
-       if (aunet->nlsk == NULL) {
+       aunet->sk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
+       if (aunet->sk == NULL) {
                audit_panic("cannot initialize netlink socket in namespace");
                return -ENOMEM;
        }
-       aunet->nlsk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+       aunet->sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+
        return 0;
 }
 
 static void __net_exit audit_net_exit(struct net *net)
 {
        struct audit_net *aunet = net_generic(net, audit_net_id);
-       struct sock *sock = aunet->nlsk;
-       mutex_lock(&audit_cmd_mutex);
-       if (sock == audit_sock)
+
+       rcu_read_lock();
+       if (net == auditd_conn.net)
                auditd_reset();
-       mutex_unlock(&audit_cmd_mutex);
+       rcu_read_unlock();
 
-       netlink_kernel_release(sock);
-       aunet->nlsk = NULL;
+       netlink_kernel_release(aunet->sk);
 }
 
 static struct pernet_operations audit_net_ops __net_initdata = {
@@ -1335,20 +1473,24 @@ static int __init audit_init(void)
        if (audit_initialized == AUDIT_DISABLED)
                return 0;
 
-       pr_info("initializing netlink subsys (%s)\n",
-               audit_default ? "enabled" : "disabled");
-       register_pernet_subsys(&audit_net_ops);
+       memset(&auditd_conn, 0, sizeof(auditd_conn));
+       spin_lock_init(&auditd_conn.lock);
 
        skb_queue_head_init(&audit_queue);
        skb_queue_head_init(&audit_retry_queue);
        skb_queue_head_init(&audit_hold_queue);
-       audit_initialized = AUDIT_INITIALIZED;
-       audit_enabled = audit_default;
-       audit_ever_enabled |= !!audit_default;
 
        for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
                INIT_LIST_HEAD(&audit_inode_hash[i]);
 
+       pr_info("initializing netlink subsys (%s)\n",
+               audit_default ? "enabled" : "disabled");
+       register_pernet_subsys(&audit_net_ops);
+
+       audit_initialized = AUDIT_INITIALIZED;
+       audit_enabled = audit_default;
+       audit_ever_enabled |= !!audit_default;
+
        kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
        if (IS_ERR(kauditd_task)) {
                int err = PTR_ERR(kauditd_task);
@@ -1519,20 +1661,16 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
        if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
                return NULL;
 
-       /* don't ever fail/sleep on these two conditions:
+       /* NOTE: don't ever fail/sleep on these two conditions:
         * 1. auditd generated record - since we need auditd to drain the
         *    queue; also, when we are checking for auditd, compare PIDs using
         *    task_tgid_vnr() since auditd_pid is set in audit_receive_msg()
         *    using a PID anchored in the caller's namespace
-        * 2. audit command message - record types 1000 through 1099 inclusive
-        *    are command messages/records used to manage the kernel subsystem
-        *    and the audit userspace, blocking on these messages could cause
-        *    problems under load so don't do it (note: not all of these
-        *    command types are valid as record types, but it is quicker to
-        *    just check two ints than a series of ints in a if/switch stmt) */
-       if (!((audit_pid && audit_pid == task_tgid_vnr(current)) ||
-             (type >= 1000 && type <= 1099))) {
-               long sleep_time = audit_backlog_wait_time;
+        * 2. generator holding the audit_cmd_mutex - we don't want to block
+        *    while holding the mutex */
+       if (!(auditd_test_task(current) ||
+             (current == __mutex_owner(&audit_cmd_mutex)))) {
+               long stime = audit_backlog_wait_time;
 
                while (audit_backlog_limit &&
                       (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
@@ -1541,14 +1679,13 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 
                        /* sleep if we are allowed and we haven't exhausted our
                         * backlog wait limit */
-                       if ((gfp_mask & __GFP_DIRECT_RECLAIM) &&
-                           (sleep_time > 0)) {
+                       if (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) {
                                DECLARE_WAITQUEUE(wait, current);
 
                                add_wait_queue_exclusive(&audit_backlog_wait,
                                                         &wait);
                                set_current_state(TASK_UNINTERRUPTIBLE);
-                               sleep_time = schedule_timeout(sleep_time);
+                               stime = schedule_timeout(stime);
                                remove_wait_queue(&audit_backlog_wait, &wait);
                        } else {
                                if (audit_rate_check() && printk_ratelimit())
@@ -2127,15 +2264,27 @@ out:
  */
 void audit_log_end(struct audit_buffer *ab)
 {
+       struct sk_buff *skb;
+       struct nlmsghdr *nlh;
+
        if (!ab)
                return;
-       if (!audit_rate_check()) {
-               audit_log_lost("rate limit exceeded");
-       } else {
-               skb_queue_tail(&audit_queue, ab->skb);
-               wake_up_interruptible(&kauditd_wait);
+
+       if (audit_rate_check()) {
+               skb = ab->skb;
                ab->skb = NULL;
-       }
+
+               /* setup the netlink header, see the comments in
+                * kauditd_send_multicast_skb() for length quirks */
+               nlh = nlmsg_hdr(skb);
+               nlh->nlmsg_len = skb->len - NLMSG_HDRLEN;
+
+               /* queue the netlink packet and poke the kauditd thread */
+               skb_queue_tail(&audit_queue, skb);
+               wake_up_interruptible(&kauditd_wait);
+       } else
+               audit_log_lost("rate limit exceeded");
+
        audit_buffer_free(ab);
 }
 
index ca579880303ab475b2c81839a4948bdb128e92f8..0f1cf6d1878ab34a65d72644175ed50055df9a09 100644 (file)
@@ -218,7 +218,7 @@ extern void audit_log_name(struct audit_context *context,
                           struct audit_names *n, const struct path *path,
                           int record_num, int *call_panic);
 
-extern int audit_pid;
+extern int auditd_test_task(const struct task_struct *task);
 
 #define AUDIT_INODE_BUCKETS    32
 extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@ -250,10 +250,6 @@ struct audit_netlink_list {
 
 int audit_send_list(void *);
 
-struct audit_net {
-       struct sock *nlsk;
-};
-
 extern int selinux_audit_rule_update(void);
 
 extern struct mutex audit_filter_mutex;
@@ -340,8 +336,7 @@ extern int audit_filter(int msgtype, unsigned int listtype);
 extern int __audit_signal_info(int sig, struct task_struct *t);
 static inline int audit_signal_info(int sig, struct task_struct *t)
 {
-       if (unlikely((audit_pid && t->tgid == audit_pid) ||
-                    (audit_signals && !audit_dummy_context())))
+       if (auditd_test_task(t) || (audit_signals && !audit_dummy_context()))
                return __audit_signal_info(sig, t);
        return 0;
 }
index d6a8de5f8fa3d0ba33c14b20e6341e32d62dab2a..e59ffc7fc522ad9d057c34339807dfe35845d45e 100644 (file)
@@ -762,7 +762,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
        struct audit_entry *e;
        enum audit_state state;
 
-       if (audit_pid && tsk->tgid == audit_pid)
+       if (auditd_test_task(tsk))
                return AUDIT_DISABLED;
 
        rcu_read_lock();
@@ -816,7 +816,7 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
 {
        struct audit_names *n;
 
-       if (audit_pid && tsk->tgid == audit_pid)
+       if (auditd_test_task(tsk))
                return;
 
        rcu_read_lock();
@@ -2256,7 +2256,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
        struct audit_context *ctx = tsk->audit_context;
        kuid_t uid = current_uid(), t_uid = task_uid(t);
 
-       if (audit_pid && t->tgid == audit_pid) {
+       if (auditd_test_task(t)) {
                if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
                        audit_sig_pid = task_tgid_nr(tsk);
                        if (uid_valid(tsk->loginuid))
index afe5bab376c9811c7b82f56bc0b93ce69b6a579b..361a69dfe5434d6afb554477b899e91db90fb29f 100644 (file)
@@ -30,18 +30,12 @@ struct bpf_htab {
                struct pcpu_freelist freelist;
                struct bpf_lru lru;
        };
-       void __percpu *extra_elems;
+       struct htab_elem *__percpu *extra_elems;
        atomic_t count; /* number of elements in this hashtable */
        u32 n_buckets;  /* number of hash buckets */
        u32 elem_size;  /* size of each element in bytes */
 };
 
-enum extra_elem_state {
-       HTAB_NOT_AN_EXTRA_ELEM = 0,
-       HTAB_EXTRA_ELEM_FREE,
-       HTAB_EXTRA_ELEM_USED
-};
-
 /* each htab element is struct htab_elem + key + value */
 struct htab_elem {
        union {
@@ -56,7 +50,6 @@ struct htab_elem {
        };
        union {
                struct rcu_head rcu;
-               enum extra_elem_state state;
                struct bpf_lru_node lru_node;
        };
        u32 hash;
@@ -77,6 +70,11 @@ static bool htab_is_percpu(const struct bpf_htab *htab)
                htab->map.map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH;
 }
 
+static bool htab_is_prealloc(const struct bpf_htab *htab)
+{
+       return !(htab->map.map_flags & BPF_F_NO_PREALLOC);
+}
+
 static inline void htab_elem_set_ptr(struct htab_elem *l, u32 key_size,
                                     void __percpu *pptr)
 {
@@ -128,17 +126,20 @@ static struct htab_elem *prealloc_lru_pop(struct bpf_htab *htab, void *key,
 
 static int prealloc_init(struct bpf_htab *htab)
 {
+       u32 num_entries = htab->map.max_entries;
        int err = -ENOMEM, i;
 
-       htab->elems = bpf_map_area_alloc(htab->elem_size *
-                                        htab->map.max_entries);
+       if (!htab_is_percpu(htab) && !htab_is_lru(htab))
+               num_entries += num_possible_cpus();
+
+       htab->elems = bpf_map_area_alloc(htab->elem_size * num_entries);
        if (!htab->elems)
                return -ENOMEM;
 
        if (!htab_is_percpu(htab))
                goto skip_percpu_elems;
 
-       for (i = 0; i < htab->map.max_entries; i++) {
+       for (i = 0; i < num_entries; i++) {
                u32 size = round_up(htab->map.value_size, 8);
                void __percpu *pptr;
 
@@ -166,11 +167,11 @@ skip_percpu_elems:
        if (htab_is_lru(htab))
                bpf_lru_populate(&htab->lru, htab->elems,
                                 offsetof(struct htab_elem, lru_node),
-                                htab->elem_size, htab->map.max_entries);
+                                htab->elem_size, num_entries);
        else
                pcpu_freelist_populate(&htab->freelist,
                                       htab->elems + offsetof(struct htab_elem, fnode),
-                                      htab->elem_size, htab->map.max_entries);
+                                      htab->elem_size, num_entries);
 
        return 0;
 
@@ -191,16 +192,22 @@ static void prealloc_destroy(struct bpf_htab *htab)
 
 static int alloc_extra_elems(struct bpf_htab *htab)
 {
-       void __percpu *pptr;
+       struct htab_elem *__percpu *pptr, *l_new;
+       struct pcpu_freelist_node *l;
        int cpu;
 
-       pptr = __alloc_percpu_gfp(htab->elem_size, 8, GFP_USER | __GFP_NOWARN);
+       pptr = __alloc_percpu_gfp(sizeof(struct htab_elem *), 8,
+                                 GFP_USER | __GFP_NOWARN);
        if (!pptr)
                return -ENOMEM;
 
        for_each_possible_cpu(cpu) {
-               ((struct htab_elem *)per_cpu_ptr(pptr, cpu))->state =
-                       HTAB_EXTRA_ELEM_FREE;
+               l = pcpu_freelist_pop(&htab->freelist);
+               /* pop will succeed, since prealloc_init()
+                * preallocated extra num_possible_cpus elements
+                */
+               l_new = container_of(l, struct htab_elem, fnode);
+               *per_cpu_ptr(pptr, cpu) = l_new;
        }
        htab->extra_elems = pptr;
        return 0;
@@ -342,25 +349,25 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
                raw_spin_lock_init(&htab->buckets[i].lock);
        }
 
-       if (!percpu && !lru) {
-               /* lru itself can remove the least used element, so
-                * there is no need for an extra elem during map_update.
-                */
-               err = alloc_extra_elems(htab);
-               if (err)
-                       goto free_buckets;
-       }
-
        if (prealloc) {
                err = prealloc_init(htab);
                if (err)
-                       goto free_extra_elems;
+                       goto free_buckets;
+
+               if (!percpu && !lru) {
+                       /* lru itself can remove the least used element, so
+                        * there is no need for an extra elem during map_update.
+                        */
+                       err = alloc_extra_elems(htab);
+                       if (err)
+                               goto free_prealloc;
+               }
        }
 
        return &htab->map;
 
-free_extra_elems:
-       free_percpu(htab->extra_elems);
+free_prealloc:
+       prealloc_destroy(htab);
 free_buckets:
        bpf_map_area_free(htab->buckets);
 free_htab:
@@ -575,12 +582,7 @@ static void htab_elem_free_rcu(struct rcu_head *head)
 
 static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
 {
-       if (l->state == HTAB_EXTRA_ELEM_USED) {
-               l->state = HTAB_EXTRA_ELEM_FREE;
-               return;
-       }
-
-       if (!(htab->map.map_flags & BPF_F_NO_PREALLOC)) {
+       if (htab_is_prealloc(htab)) {
                pcpu_freelist_push(&htab->freelist, &l->fnode);
        } else {
                atomic_dec(&htab->count);
@@ -610,47 +612,43 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr,
 static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
                                         void *value, u32 key_size, u32 hash,
                                         bool percpu, bool onallcpus,
-                                        bool old_elem_exists)
+                                        struct htab_elem *old_elem)
 {
        u32 size = htab->map.value_size;
-       bool prealloc = !(htab->map.map_flags & BPF_F_NO_PREALLOC);
-       struct htab_elem *l_new;
+       bool prealloc = htab_is_prealloc(htab);
+       struct htab_elem *l_new, **pl_new;
        void __percpu *pptr;
-       int err = 0;
 
        if (prealloc) {
-               struct pcpu_freelist_node *l;
+               if (old_elem) {
+                       /* if we're updating the existing element,
+                        * use per-cpu extra elems to avoid freelist_pop/push
+                        */
+                       pl_new = this_cpu_ptr(htab->extra_elems);
+                       l_new = *pl_new;
+                       *pl_new = old_elem;
+               } else {
+                       struct pcpu_freelist_node *l;
 
-               l = pcpu_freelist_pop(&htab->freelist);
-               if (!l)
-                       err = -E2BIG;
-               else
+                       l = pcpu_freelist_pop(&htab->freelist);
+                       if (!l)
+                               return ERR_PTR(-E2BIG);
                        l_new = container_of(l, struct htab_elem, fnode);
-       } else {
-               if (atomic_inc_return(&htab->count) > htab->map.max_entries) {
-                       atomic_dec(&htab->count);
-                       err = -E2BIG;
-               } else {
-                       l_new = kmalloc(htab->elem_size,
-                                       GFP_ATOMIC | __GFP_NOWARN);
-                       if (!l_new)
-                               return ERR_PTR(-ENOMEM);
                }
-       }
-
-       if (err) {
-               if (!old_elem_exists)
-                       return ERR_PTR(err);
-
-               /* if we're updating the existing element and the hash table
-                * is full, use per-cpu extra elems
-                */
-               l_new = this_cpu_ptr(htab->extra_elems);
-               if (l_new->state != HTAB_EXTRA_ELEM_FREE)
-                       return ERR_PTR(-E2BIG);
-               l_new->state = HTAB_EXTRA_ELEM_USED;
        } else {
-               l_new->state = HTAB_NOT_AN_EXTRA_ELEM;
+               if (atomic_inc_return(&htab->count) > htab->map.max_entries)
+                       if (!old_elem) {
+                               /* when map is full and update() is replacing
+                                * old element, it's ok to allocate, since
+                                * old element will be freed immediately.
+                                * Otherwise return an error
+                                */
+                               atomic_dec(&htab->count);
+                               return ERR_PTR(-E2BIG);
+                       }
+               l_new = kmalloc(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN);
+               if (!l_new)
+                       return ERR_PTR(-ENOMEM);
        }
 
        memcpy(l_new->key, key, key_size);
@@ -731,7 +729,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
                goto err;
 
        l_new = alloc_htab_elem(htab, key, value, key_size, hash, false, false,
-                               !!l_old);
+                               l_old);
        if (IS_ERR(l_new)) {
                /* all pre-allocated elements are in use or memory exhausted */
                ret = PTR_ERR(l_new);
@@ -744,7 +742,8 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
        hlist_nulls_add_head_rcu(&l_new->hash_node, head);
        if (l_old) {
                hlist_nulls_del_rcu(&l_old->hash_node);
-               free_htab_elem(htab, l_old);
+               if (!htab_is_prealloc(htab))
+                       free_htab_elem(htab, l_old);
        }
        ret = 0;
 err:
@@ -856,7 +855,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
                                value, onallcpus);
        } else {
                l_new = alloc_htab_elem(htab, key, value, key_size,
-                                       hash, true, onallcpus, false);
+                                       hash, true, onallcpus, NULL);
                if (IS_ERR(l_new)) {
                        ret = PTR_ERR(l_new);
                        goto err;
@@ -1024,8 +1023,7 @@ static void delete_all_elements(struct bpf_htab *htab)
 
                hlist_nulls_for_each_entry_safe(l, n, head, hash_node) {
                        hlist_nulls_del_rcu(&l->hash_node);
-                       if (l->state != HTAB_EXTRA_ELEM_USED)
-                               htab_elem_free(htab, l);
+                       htab_elem_free(htab, l);
                }
        }
 }
@@ -1045,7 +1043,7 @@ static void htab_map_free(struct bpf_map *map)
         * not have executed. Wait for them.
         */
        rcu_barrier();
-       if (htab->map.map_flags & BPF_F_NO_PREALLOC)
+       if (!htab_is_prealloc(htab))
                delete_all_elements(htab);
        else
                prealloc_destroy(htab);
index 05316c9f32da9d0e20b3d3c92eeaf3eb49f1deef..3202aa17492c808af5331044de710a2f34e277a3 100644 (file)
@@ -186,19 +186,20 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd)
 
        reorder = &next_queue->reorder;
 
+       spin_lock(&reorder->lock);
        if (!list_empty(&reorder->list)) {
                padata = list_entry(reorder->list.next,
                                    struct padata_priv, list);
 
-               spin_lock(&reorder->lock);
                list_del_init(&padata->list);
                atomic_dec(&pd->reorder_objects);
-               spin_unlock(&reorder->lock);
 
                pd->processed++;
 
+               spin_unlock(&reorder->lock);
                goto out;
        }
+       spin_unlock(&reorder->lock);
 
        if (__this_cpu_read(pd->pqueue->cpu_index) == next_queue->cpu_index) {
                padata = ERR_PTR(-ENODATA);
index a08795e216283f1292f82720bb1ff758e6a2629c..00a45c45beca09829ad479aad9ba299f5498a42e 100644 (file)
@@ -96,10 +96,10 @@ static DEFINE_STATIC_KEY_FALSE(__sched_clock_stable);
 static int __sched_clock_stable_early = 1;
 
 /*
- * We want: ktime_get_ns() + gtod_offset == sched_clock() + raw_offset
+ * We want: ktime_get_ns() + __gtod_offset == sched_clock() + __sched_clock_offset
  */
-static __read_mostly u64 raw_offset;
-static __read_mostly u64 gtod_offset;
+__read_mostly u64 __sched_clock_offset;
+static __read_mostly u64 __gtod_offset;
 
 struct sched_clock_data {
        u64                     tick_raw;
@@ -131,17 +131,24 @@ static void __set_sched_clock_stable(void)
        /*
         * Attempt to make the (initial) unstable->stable transition continuous.
         */
-       raw_offset = (scd->tick_gtod + gtod_offset) - (scd->tick_raw);
+       __sched_clock_offset = (scd->tick_gtod + __gtod_offset) - (scd->tick_raw);
 
        printk(KERN_INFO "sched_clock: Marking stable (%lld, %lld)->(%lld, %lld)\n",
-                       scd->tick_gtod, gtod_offset,
-                       scd->tick_raw,  raw_offset);
+                       scd->tick_gtod, __gtod_offset,
+                       scd->tick_raw,  __sched_clock_offset);
 
        static_branch_enable(&__sched_clock_stable);
        tick_dep_clear(TICK_DEP_BIT_CLOCK_UNSTABLE);
 }
 
-static void __clear_sched_clock_stable(struct work_struct *work)
+static void __sched_clock_work(struct work_struct *work)
+{
+       static_branch_disable(&__sched_clock_stable);
+}
+
+static DECLARE_WORK(sched_clock_work, __sched_clock_work);
+
+static void __clear_sched_clock_stable(void)
 {
        struct sched_clock_data *scd = this_scd();
 
@@ -154,17 +161,17 @@ static void __clear_sched_clock_stable(struct work_struct *work)
         *
         * Still do what we can.
         */
-       gtod_offset = (scd->tick_raw + raw_offset) - (scd->tick_gtod);
+       __gtod_offset = (scd->tick_raw + __sched_clock_offset) - (scd->tick_gtod);
 
        printk(KERN_INFO "sched_clock: Marking unstable (%lld, %lld)<-(%lld, %lld)\n",
-                       scd->tick_gtod, gtod_offset,
-                       scd->tick_raw,  raw_offset);
+                       scd->tick_gtod, __gtod_offset,
+                       scd->tick_raw,  __sched_clock_offset);
 
-       static_branch_disable(&__sched_clock_stable);
        tick_dep_set(TICK_DEP_BIT_CLOCK_UNSTABLE);
-}
 
-static DECLARE_WORK(sched_clock_work, __clear_sched_clock_stable);
+       if (sched_clock_stable())
+               schedule_work(&sched_clock_work);
+}
 
 void clear_sched_clock_stable(void)
 {
@@ -173,7 +180,7 @@ void clear_sched_clock_stable(void)
        smp_mb(); /* matches sched_clock_init_late() */
 
        if (sched_clock_running == 2)
-               schedule_work(&sched_clock_work);
+               __clear_sched_clock_stable();
 }
 
 void sched_clock_init_late(void)
@@ -214,7 +221,7 @@ static inline u64 wrap_max(u64 x, u64 y)
  */
 static u64 sched_clock_local(struct sched_clock_data *scd)
 {
-       u64 now, clock, old_clock, min_clock, max_clock;
+       u64 now, clock, old_clock, min_clock, max_clock, gtod;
        s64 delta;
 
 again:
@@ -231,9 +238,10 @@ again:
         *                    scd->tick_gtod + TICK_NSEC);
         */
 
-       clock = scd->tick_gtod + gtod_offset + delta;
-       min_clock = wrap_max(scd->tick_gtod, old_clock);
-       max_clock = wrap_max(old_clock, scd->tick_gtod + TICK_NSEC);
+       gtod = scd->tick_gtod + __gtod_offset;
+       clock = gtod + delta;
+       min_clock = wrap_max(gtod, old_clock);
+       max_clock = wrap_max(old_clock, gtod + TICK_NSEC);
 
        clock = wrap_max(clock, min_clock);
        clock = wrap_min(clock, max_clock);
@@ -317,7 +325,7 @@ u64 sched_clock_cpu(int cpu)
        u64 clock;
 
        if (sched_clock_stable())
-               return sched_clock() + raw_offset;
+               return sched_clock() + __sched_clock_offset;
 
        if (unlikely(!sched_clock_running))
                return 0ull;
index cd7cd489f739817f07349e8526812eaa3e110075..54c577578da6899160cf4a611e87a386a2fd7db2 100644 (file)
@@ -584,20 +584,14 @@ static int sugov_start(struct cpufreq_policy *policy)
        for_each_cpu(cpu, policy->cpus) {
                struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu);
 
+               memset(sg_cpu, 0, sizeof(*sg_cpu));
                sg_cpu->sg_policy = sg_policy;
-               if (policy_is_shared(policy)) {
-                       sg_cpu->util = 0;
-                       sg_cpu->max = 0;
-                       sg_cpu->flags = SCHED_CPUFREQ_RT;
-                       sg_cpu->last_update = 0;
-                       sg_cpu->iowait_boost = 0;
-                       sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
-                       cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
-                                                    sugov_update_shared);
-               } else {
-                       cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
-                                                    sugov_update_single);
-               }
+               sg_cpu->flags = SCHED_CPUFREQ_RT;
+               sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
+               cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
+                                            policy_is_shared(policy) ?
+                                                       sugov_update_shared :
+                                                       sugov_update_single);
        }
        return 0;
 }
index 17d5ff5fa6a388c4dc947a47615608bca79b2c40..2c6cd1b5c3ea86668bc73196c4aa980c724ad34c 100644 (file)
@@ -12,6 +12,7 @@ static int collect_syscall(struct task_struct *target, long *callno,
 
        if (!try_get_task_stack(target)) {
                /* Task has no stack, so the task isn't in a syscall. */
+               *sp = *pc = 0;
                *callno = -1;
                return 0;
        }
index 0b1d3140fbb87738ec37031997075e50c5670575..a25c9763fce19f17c723b9db3645ae93ba47dcb6 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
+#include <linux/kasan.h>
 
 /*
  * Note: test functions are marked noinline so that their names appear in
@@ -474,6 +475,12 @@ static noinline void __init use_after_scope_test(void)
 
 static int __init kmalloc_tests_init(void)
 {
+       /*
+        * Temporarily enable multi-shot mode. Otherwise, we'd only get a
+        * report for the first case.
+        */
+       bool multishot = kasan_save_enable_multi_shot();
+
        kmalloc_oob_right();
        kmalloc_oob_left();
        kmalloc_node_oob_right();
@@ -499,6 +506,9 @@ static int __init kmalloc_tests_init(void)
        ksize_unpoisons_memory();
        copy_user_test();
        use_after_scope_test();
+
+       kasan_restore_multi_shot(multishot);
+
        return -EAGAIN;
 }
 
index 3d0aab9ee80d1f27e29074b95773649a48d7c7bf..e5828875f7bbd7a770d5c23334a0e3994ffe544f 100644 (file)
@@ -4403,7 +4403,9 @@ int hugetlb_reserve_pages(struct inode *inode,
        return 0;
 out_err:
        if (!vma || vma->vm_flags & VM_MAYSHARE)
-               region_abort(resv_map, from, to);
+               /* Don't call region_abort if region_chg failed */
+               if (chg >= 0)
+                       region_abort(resv_map, from, to);
        if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER))
                kref_put(&resv_map->refs, resv_map_release);
        return ret;
@@ -4651,6 +4653,7 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
 {
        struct page *page = NULL;
        spinlock_t *ptl;
+       pte_t pte;
 retry:
        ptl = pmd_lockptr(mm, pmd);
        spin_lock(ptl);
@@ -4660,12 +4663,13 @@ retry:
         */
        if (!pmd_huge(*pmd))
                goto out;
-       if (pmd_present(*pmd)) {
+       pte = huge_ptep_get((pte_t *)pmd);
+       if (pte_present(pte)) {
                page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT);
                if (flags & FOLL_GET)
                        get_page(page);
        } else {
-               if (is_hugetlb_entry_migration(huge_ptep_get((pte_t *)pmd))) {
+               if (is_hugetlb_entry_migration(pte)) {
                        spin_unlock(ptl);
                        __migration_entry_wait(mm, (pte_t *)pmd, ptl);
                        goto retry;
index 1c260e6b3b3c6a1f26fc1e13a0fdb39099bbbf68..dd2dea8eb0771a506c0b510efc79c3fc5253bda5 100644 (file)
@@ -96,11 +96,6 @@ static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
                << KASAN_SHADOW_SCALE_SHIFT);
 }
 
-static inline bool kasan_report_enabled(void)
-{
-       return !current->kasan_depth;
-}
-
 void kasan_report(unsigned long addr, size_t size,
                bool is_write, unsigned long ip);
 void kasan_report_double_free(struct kmem_cache *cache, void *object,
index f479365530b6484bbd5cae42064521fed362961e..ab42a0803f161c6834b1362aefd5ded1990eb04f 100644 (file)
@@ -13,7 +13,9 @@
  *
  */
 
+#include <linux/bitops.h>
 #include <linux/ftrace.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/printk.h>
@@ -293,6 +295,40 @@ static void kasan_report_error(struct kasan_access_info *info)
        kasan_end_report(&flags);
 }
 
+static unsigned long kasan_flags;
+
+#define KASAN_BIT_REPORTED     0
+#define KASAN_BIT_MULTI_SHOT   1
+
+bool kasan_save_enable_multi_shot(void)
+{
+       return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
+}
+EXPORT_SYMBOL_GPL(kasan_save_enable_multi_shot);
+
+void kasan_restore_multi_shot(bool enabled)
+{
+       if (!enabled)
+               clear_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
+}
+EXPORT_SYMBOL_GPL(kasan_restore_multi_shot);
+
+static int __init kasan_set_multi_shot(char *str)
+{
+       set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
+       return 1;
+}
+__setup("kasan_multi_shot", kasan_set_multi_shot);
+
+static inline bool kasan_report_enabled(void)
+{
+       if (current->kasan_depth)
+               return false;
+       if (test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
+               return true;
+       return !test_and_set_bit(KASAN_BIT_REPORTED, &kasan_flags);
+}
+
 void kasan_report(unsigned long addr, size_t size,
                bool is_write, unsigned long ip)
 {
index 26c874e90b12ef164d7b80171bb8bea979df5b1a..20036d4f9f13d4dc7b5b091e389b8a7b6b2ca32f 100644 (file)
@@ -1416,7 +1416,7 @@ static void kmemleak_scan(void)
        /* data/bss scanning */
        scan_large_block(_sdata, _edata);
        scan_large_block(__bss_start, __bss_stop);
-       scan_large_block(__start_data_ro_after_init, __end_data_ro_after_init);
+       scan_large_block(__start_ro_after_init, __end_ro_after_init);
 
 #ifdef CONFIG_SMP
        /* per-cpu sections scanning */
index 9a0897a14d37be3d7759d577f98060fa75c7be0f..ed97c2c14fa80b47ffbf7fa22ec6d4b9b57202b1 100644 (file)
@@ -209,8 +209,11 @@ static int remove_migration_pte(struct page *page, struct vm_area_struct *vma,
 
        VM_BUG_ON_PAGE(PageTail(page), page);
        while (page_vma_mapped_walk(&pvmw)) {
-               new = page - pvmw.page->index +
-                       linear_page_index(vma, pvmw.address);
+               if (PageKsm(page))
+                       new = page;
+               else
+                       new = page - pvmw.page->index +
+                               linear_page_index(vma, pvmw.address);
 
                get_page(new);
                pte = pte_mkold(mk_pte(new, READ_ONCE(vma->vm_page_prot)));
index 49ed681ccc7b01d5e2a73b48b62a1da4ac9731f2..f6838015810f5610abe039daec170aa1da634422 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1159,7 +1159,7 @@ void page_add_file_rmap(struct page *page, bool compound)
                        goto out;
        }
        __mod_node_page_state(page_pgdat(page), NR_FILE_MAPPED, nr);
-       mem_cgroup_inc_page_stat(page, MEM_CGROUP_STAT_FILE_MAPPED);
+       mem_cgroup_update_page_stat(page, MEM_CGROUP_STAT_FILE_MAPPED, nr);
 out:
        unlock_page_memcg(page);
 }
@@ -1199,7 +1199,7 @@ static void page_remove_file_rmap(struct page *page, bool compound)
         * pte lock(a spinlock) is held, which implies preemption disabled.
         */
        __mod_node_page_state(page_pgdat(page), NR_FILE_MAPPED, -nr);
-       mem_cgroup_dec_page_stat(page, MEM_CGROUP_STAT_FILE_MAPPED);
+       mem_cgroup_update_page_stat(page, MEM_CGROUP_STAT_FILE_MAPPED, -nr);
 
        if (unlikely(PageMlocked(page)))
                clear_page_mlock(page);
index 7ebb23836f689e766caa71bd775c0b919f658bb9..b1ccb58ad397403214a220e4a0ac7901a6b6ae1e 100644 (file)
@@ -267,8 +267,6 @@ int free_swap_slot(swp_entry_t entry)
 {
        struct swap_slots_cache *cache;
 
-       WARN_ON_ONCE(!swap_slot_cache_initialized);
-
        cache = &get_cpu_var(swp_slots);
        if (use_swap_slot_cache && cache->slots_ret) {
                spin_lock_irq(&cache->free_lock);
index b1947f0cbee2f97ce7ba7e5bd4ca4ea3dc205533..89f95396ec46be64055f1a658c9c0f7bdad90d5c 100644 (file)
@@ -1764,7 +1764,7 @@ static int vmstat_cpu_dead(unsigned int cpu)
 
 #endif
 
-static int __init setup_vmstat(void)
+void __init init_mm_internals(void)
 {
 #ifdef CONFIG_SMP
        int ret;
@@ -1792,9 +1792,7 @@ static int __init setup_vmstat(void)
        proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
        proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
 #endif
-       return 0;
 }
-module_init(setup_vmstat)
 
 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)
 
index ac839fca0e76ae3cc5a025684cb1516301922d92..eda05c71fa49e6e1e4f93a4029ddef04a4f8ab4c 100644 (file)
@@ -532,7 +532,7 @@ static int __init workingset_init(void)
        pr_info("workingset: timestamp_bits=%d max_order=%d bucket_order=%u\n",
               timestamp_bits, max_order, bucket_order);
 
-       ret = list_lru_init_key(&shadow_nodes, &shadow_nodes_key);
+       ret = __list_lru_init(&shadow_nodes, true, &shadow_nodes_key);
        if (ret)
                goto err;
        ret = register_shrinker(&workingset_shadow_shrinker);
index 7c3d994e90d87b868f2b1614cc5d26e2413e70ee..71343d0fec94b55f7318ec8578abc956148f7791 100644 (file)
@@ -2477,6 +2477,16 @@ static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
        batadv_iv_ogm_schedule(hard_iface);
 }
 
+/**
+ * batadv_iv_init_sel_class - initialize GW selection class
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
+{
+       /* set default TQ difference threshold to 20 */
+       atomic_set(&bat_priv->gw.sel_class, 20);
+}
+
 static struct batadv_gw_node *
 batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
 {
@@ -2823,6 +2833,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
                .del_if = batadv_iv_ogm_orig_del_if,
        },
        .gw = {
+               .init_sel_class = batadv_iv_init_sel_class,
                .get_best_gw_node = batadv_iv_gw_get_best_gw_node,
                .is_eligible = batadv_iv_gw_is_eligible,
 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
index 0acd081dd286996444d121b526f4530c4c1c0845..a36c8e7291d61f171cdb128dee865739d22cb00e 100644 (file)
@@ -668,6 +668,16 @@ err_ifinfo1:
        return ret;
 }
 
+/**
+ * batadv_v_init_sel_class - initialize GW selection class
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
+{
+       /* set default throughput difference threshold to 5Mbps */
+       atomic_set(&bat_priv->gw.sel_class, 50);
+}
+
 static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv,
                                        char *buff, size_t count)
 {
@@ -1052,6 +1062,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
                .dump = batadv_v_orig_dump,
        },
        .gw = {
+               .init_sel_class = batadv_v_init_sel_class,
                .store_sel_class = batadv_v_store_sel_class,
                .show_sel_class = batadv_v_show_sel_class,
                .get_best_gw_node = batadv_v_gw_get_best_gw_node,
@@ -1092,9 +1103,6 @@ int batadv_v_mesh_init(struct batadv_priv *bat_priv)
        if (ret < 0)
                return ret;
 
-       /* set default throughput difference threshold to 5Mbps */
-       atomic_set(&bat_priv->gw.sel_class, 50);
-
        return 0;
 }
 
index 11a23fd6e1a07fa0c541fa3ea0a13775f9933893..8f964beaac284905c487ecfc5babaf2dd72d822c 100644 (file)
@@ -404,7 +404,7 @@ out:
  * batadv_frag_create - create a fragment from skb
  * @skb: skb to create fragment from
  * @frag_head: header to use in new fragment
- * @mtu: size of new fragment
+ * @fragment_size: size of new fragment
  *
  * Split the passed skb into two fragments: A new one with size matching the
  * passed mtu and the old one with the rest. The new skb contains data from the
@@ -414,11 +414,11 @@ out:
  */
 static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
                                          struct batadv_frag_packet *frag_head,
-                                         unsigned int mtu)
+                                         unsigned int fragment_size)
 {
        struct sk_buff *skb_fragment;
        unsigned int header_size = sizeof(*frag_head);
-       unsigned int fragment_size = mtu - header_size;
+       unsigned int mtu = fragment_size + header_size;
 
        skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
        if (!skb_fragment)
@@ -456,7 +456,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
        struct sk_buff *skb_fragment;
        unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
        unsigned int header_size = sizeof(frag_header);
-       unsigned int max_fragment_size, max_packet_size;
+       unsigned int max_fragment_size, num_fragments;
        int ret;
 
        /* To avoid merge and refragmentation at next-hops we never send
@@ -464,10 +464,15 @@ int batadv_frag_send_packet(struct sk_buff *skb,
         */
        mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
        max_fragment_size = mtu - header_size;
-       max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS;
+
+       if (skb->len == 0 || max_fragment_size == 0)
+               return -EINVAL;
+
+       num_fragments = (skb->len - 1) / max_fragment_size + 1;
+       max_fragment_size = (skb->len - 1) / num_fragments + 1;
 
        /* Don't even try to fragment, if we need more than 16 fragments */
-       if (skb->len > max_packet_size) {
+       if (num_fragments > BATADV_FRAG_MAX_FRAGMENTS) {
                ret = -EAGAIN;
                goto free_skb;
        }
@@ -507,7 +512,8 @@ int batadv_frag_send_packet(struct sk_buff *skb,
                        goto put_primary_if;
                }
 
-               skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
+               skb_fragment = batadv_frag_create(skb, &frag_header,
+                                                 max_fragment_size);
                if (!skb_fragment) {
                        ret = -ENOMEM;
                        goto put_primary_if;
index 5db2e43e3775ef40fc3832984c93411c7f0dbb08..33940c5c74a8730c4ed3e06f7246e022cfb798da 100644 (file)
@@ -253,6 +253,11 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
  */
 void batadv_gw_init(struct batadv_priv *bat_priv)
 {
+       if (bat_priv->algo_ops->gw.init_sel_class)
+               bat_priv->algo_ops->gw.init_sel_class(bat_priv);
+       else
+               atomic_set(&bat_priv->gw.sel_class, 1);
+
        batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
                                     NULL, BATADV_TVLV_GW, 1,
                                     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
index 5d099b2e6cfccb8a436d98a10a6d513d89e31dc1..d042c99af028e2083307de1ba8978f2061fee45d 100644 (file)
@@ -819,7 +819,6 @@ static int batadv_softif_init_late(struct net_device *dev)
        atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
 #endif
        atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
-       atomic_set(&bat_priv->gw.sel_class, 20);
        atomic_set(&bat_priv->gw.bandwidth_down, 100);
        atomic_set(&bat_priv->gw.bandwidth_up, 20);
        atomic_set(&bat_priv->orig_interval, 1000);
index 66b25e410a41375e5c70bd7400a5b353bdff4520..246f21b4973bc39d0678273ad831da1f5b7e0df3 100644 (file)
@@ -1489,6 +1489,7 @@ struct batadv_algo_orig_ops {
 
 /**
  * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific)
+ * @init_sel_class: initialize GW selection class (optional)
  * @store_sel_class: parse and stores a new GW selection class (optional)
  * @show_sel_class: prints the current GW selection class (optional)
  * @get_best_gw_node: select the best GW from the list of available nodes
@@ -1499,6 +1500,7 @@ struct batadv_algo_orig_ops {
  * @dump: dump gateways to a netlink socket (optional)
  */
 struct batadv_algo_gw_ops {
+       void (*init_sel_class)(struct batadv_priv *bat_priv);
        ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff,
                                   size_t count);
        ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff);
index 4f598dc2d9168cd323a3027d77d601854aa35f04..6e08b7199dd7442acdbd4f85e5ef6315b121ca06 100644 (file)
@@ -106,7 +106,7 @@ static struct net_bridge_fdb_entry *br_fdb_find(struct net_bridge *br,
        struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
        struct net_bridge_fdb_entry *fdb;
 
-       WARN_ON_ONCE(!br_hash_lock_held(br));
+       lockdep_assert_held_once(&br->hash_lock);
 
        rcu_read_lock();
        fdb = fdb_find_rcu(head, addr, vid);
index fa87fbd62bb788a27b8fd749d59c292aedd4fb69..1f1e62095464f99eaca8de49a772289f057bd943 100644 (file)
@@ -706,18 +706,20 @@ static unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
 
 static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-       struct nf_bridge_info *nf_bridge;
-       unsigned int mtu_reserved;
+       struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+       unsigned int mtu, mtu_reserved;
 
        mtu_reserved = nf_bridge_mtu_reduction(skb);
+       mtu = skb->dev->mtu;
+
+       if (nf_bridge->frag_max_size && nf_bridge->frag_max_size < mtu)
+               mtu = nf_bridge->frag_max_size;
 
-       if (skb_is_gso(skb) || skb->len + mtu_reserved <= skb->dev->mtu) {
+       if (skb_is_gso(skb) || skb->len + mtu_reserved <= mtu) {
                nf_bridge_info_free(skb);
                return br_dev_queue_push_xmit(net, sk, skb);
        }
 
-       nf_bridge = nf_bridge_info_get(skb);
-
        /* This is wrong! We should preserve the original fragment
         * boundaries by preserving frag_list rather than refragmenting.
         */
index 2288fca7756c5103fc4e8420ad61a2f9e633c097..61368186edea53841b1f00b37ddaa0d26461aee3 100644 (file)
@@ -531,15 +531,6 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
 int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
                              const unsigned char *addr, u16 vid);
 
-static inline bool br_hash_lock_held(struct net_bridge *br)
-{
-#ifdef CONFIG_LOCKDEP
-       return lockdep_is_held(&br->hash_lock);
-#else
-       return true;
-#endif
-}
-
 /* br_forward.c */
 enum br_pkt_type {
        BR_PKT_UNICAST,
index 38dcf1eb427de562776934b1c2dfff2c46f3ca12..f76bb333261384257490b0f5125207028e8352aa 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kthread.h>
 #include <linux/net.h>
 #include <linux/nsproxy.h>
+#include <linux/sched/mm.h>
 #include <linux/slab.h>
 #include <linux/socket.h>
 #include <linux/string.h>
@@ -469,11 +470,16 @@ static int ceph_tcp_connect(struct ceph_connection *con)
 {
        struct sockaddr_storage *paddr = &con->peer_addr.in_addr;
        struct socket *sock;
+       unsigned int noio_flag;
        int ret;
 
        BUG_ON(con->sock);
+
+       /* sock_create_kern() allocates with GFP_KERNEL */
+       noio_flag = memalloc_noio_save();
        ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family,
                               SOCK_STREAM, IPPROTO_TCP, &sock);
+       memalloc_noio_restore(noio_flag);
        if (ret)
                return ret;
        sock->sk->sk_allocation = GFP_NOFS;
index 6ae56037bb1336d9cb6b6fc36043a203f3978202..029a61ac6cdd8a0b4dd54d2be3c5bdf047a82cb0 100644 (file)
@@ -71,27 +71,17 @@ static int update_classid_sock(const void *v, struct file *file, unsigned n)
        return 0;
 }
 
-static void update_classid(struct cgroup_subsys_state *css, void *v)
+static void cgrp_attach(struct cgroup_taskset *tset)
 {
-       struct css_task_iter it;
+       struct cgroup_subsys_state *css;
        struct task_struct *p;
 
-       css_task_iter_start(css, &it);
-       while ((p = css_task_iter_next(&it))) {
+       cgroup_taskset_for_each(p, css, tset) {
                task_lock(p);
-               iterate_fd(p->files, 0, update_classid_sock, v);
+               iterate_fd(p->files, 0, update_classid_sock,
+                          (void *)(unsigned long)css_cls_state(css)->classid);
                task_unlock(p);
        }
-       css_task_iter_end(&it);
-}
-
-static void cgrp_attach(struct cgroup_taskset *tset)
-{
-       struct cgroup_subsys_state *css;
-
-       cgroup_taskset_first(tset, &css);
-       update_classid(css,
-                      (void *)(unsigned long)css_cls_state(css)->classid);
 }
 
 static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
@@ -103,12 +93,22 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
                         u64 value)
 {
        struct cgroup_cls_state *cs = css_cls_state(css);
+       struct css_task_iter it;
+       struct task_struct *p;
 
        cgroup_sk_alloc_disable();
 
        cs->classid = (u32)value;
 
-       update_classid(css, (void *)(unsigned long)cs->classid);
+       css_task_iter_start(css, &it);
+       while ((p = css_task_iter_next(&it))) {
+               task_lock(p);
+               iterate_fd(p->files, 0, update_classid_sock,
+                          (void *)(unsigned long)cs->classid);
+               task_unlock(p);
+       }
+       css_task_iter_end(&it);
+
        return 0;
 }
 
index cd4ba8c6b6091651403cf74de8c60ccf69aa3e7b..9f781092fda9cb8cac22b0743b4bc7666a3bd91a 100644 (file)
@@ -3694,6 +3694,15 @@ static void sock_rmem_free(struct sk_buff *skb)
        atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
 }
 
+static void skb_set_err_queue(struct sk_buff *skb)
+{
+       /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+        * So, it is safe to (mis)use it to mark skbs on the error queue.
+        */
+       skb->pkt_type = PACKET_OUTGOING;
+       BUILD_BUG_ON(PACKET_OUTGOING == 0);
+}
+
 /*
  * Note: We dont mem charge error packets (no sk_forward_alloc changes)
  */
@@ -3707,6 +3716,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
        skb->sk = sk;
        skb->destructor = sock_rmem_free;
        atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+       skb_set_err_queue(skb);
 
        /* before exiting rcu section, make sure dst is refcounted */
        skb_dst_force(skb);
@@ -3783,16 +3793,20 @@ EXPORT_SYMBOL(skb_clone_sk);
 
 static void __skb_complete_tx_timestamp(struct sk_buff *skb,
                                        struct sock *sk,
-                                       int tstype)
+                                       int tstype,
+                                       bool opt_stats)
 {
        struct sock_exterr_skb *serr;
        int err;
 
+       BUILD_BUG_ON(sizeof(struct sock_exterr_skb) > sizeof(skb->cb));
+
        serr = SKB_EXT_ERR(skb);
        memset(serr, 0, sizeof(*serr));
        serr->ee.ee_errno = ENOMSG;
        serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
        serr->ee.ee_info = tstype;
+       serr->opt_stats = opt_stats;
        if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
                serr->ee.ee_data = skb_shinfo(skb)->tskey;
                if (sk->sk_protocol == IPPROTO_TCP &&
@@ -3833,7 +3847,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
         */
        if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
                *skb_hwtstamps(skb) = *hwtstamps;
-               __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
+               __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false);
                sock_put(sk);
        }
 }
@@ -3844,7 +3858,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
                     struct sock *sk, int tstype)
 {
        struct sk_buff *skb;
-       bool tsonly;
+       bool tsonly, opt_stats = false;
 
        if (!sk)
                return;
@@ -3857,9 +3871,10 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
 #ifdef CONFIG_INET
                if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
                    sk->sk_protocol == IPPROTO_TCP &&
-                   sk->sk_type == SOCK_STREAM)
+                   sk->sk_type == SOCK_STREAM) {
                        skb = tcp_get_timestamping_opt_stats(sk);
-               else
+                       opt_stats = true;
+               } else
 #endif
                        skb = alloc_skb(0, GFP_ATOMIC);
        } else {
@@ -3878,7 +3893,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
        else
                skb->tstamp = ktime_get_real();
 
-       __skb_complete_tx_timestamp(skb, sk, tstype);
+       __skb_complete_tx_timestamp(skb, sk, tstype, opt_stats);
 }
 EXPORT_SYMBOL_GPL(__skb_tstamp_tx);
 
index a96d5f7a5734a52dfd6a2df8490c7bd7f5f6599a..2c4f574168fbdcebc0cc82c0c8a36214992d6224 100644 (file)
@@ -1442,6 +1442,11 @@ static void __sk_destruct(struct rcu_head *head)
                pr_debug("%s: optmem leakage (%d bytes) detected\n",
                         __func__, atomic_read(&sk->sk_omem_alloc));
 
+       if (sk->sk_frag.page) {
+               put_page(sk->sk_frag.page);
+               sk->sk_frag.page = NULL;
+       }
+
        if (sk->sk_peer_cred)
                put_cred(sk->sk_peer_cred);
        put_pid(sk->sk_peer_pid);
@@ -1539,6 +1544,12 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                        is_charged = sk_filter_charge(newsk, filter);
 
                if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
+                       /* We need to make sure that we don't uncharge the new
+                        * socket if we couldn't charge it in the first place
+                        * as otherwise we uncharge the parent's filter.
+                        */
+                       if (!is_charged)
+                               RCU_INIT_POINTER(newsk->sk_filter, NULL);
                        sk_free_unlock_clone(newsk);
                        newsk = NULL;
                        goto out;
@@ -2787,11 +2798,6 @@ void sk_common_release(struct sock *sk)
 
        sk_refcnt_debug_release(sk);
 
-       if (sk->sk_frag.page) {
-               put_page(sk->sk_frag.page);
-               sk->sk_frag.page = NULL;
-       }
-
        sock_put(sk);
 }
 EXPORT_SYMBOL(sk_common_release);
index 42bfd08109dd78ab509493e8d2205d72845bb3eb..8f2133ffc2ff1b94871408a5f934cb938d3462b5 100644 (file)
@@ -1083,7 +1083,8 @@ static void nl_fib_input(struct sk_buff *skb)
 
        net = sock_net(skb->sk);
        nlh = nlmsg_hdr(skb);
-       if (skb->len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len ||
+       if (skb->len < nlmsg_total_size(sizeof(*frn)) ||
+           skb->len < nlh->nlmsg_len ||
            nlmsg_len(nlh) < sizeof(*frn))
                return;
 
index bbe7f72db9c157ba2d6c5292637c2f58ad39a123..b3cdeec85f1f2c612c362590e828f50596a5c247 100644 (file)
@@ -198,6 +198,7 @@ static void ip_expire(unsigned long arg)
        qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
        net = container_of(qp->q.net, struct net, ipv4.frags);
 
+       rcu_read_lock();
        spin_lock(&qp->q.lock);
 
        if (qp->q.flags & INET_FRAG_COMPLETE)
@@ -207,7 +208,7 @@ static void ip_expire(unsigned long arg)
        __IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
 
        if (!inet_frag_evicting(&qp->q)) {
-               struct sk_buff *head = qp->q.fragments;
+               struct sk_buff *clone, *head = qp->q.fragments;
                const struct iphdr *iph;
                int err;
 
@@ -216,32 +217,40 @@ static void ip_expire(unsigned long arg)
                if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !qp->q.fragments)
                        goto out;
 
-               rcu_read_lock();
                head->dev = dev_get_by_index_rcu(net, qp->iif);
                if (!head->dev)
-                       goto out_rcu_unlock;
+                       goto out;
+
 
                /* skb has no dst, perform route lookup again */
                iph = ip_hdr(head);
                err = ip_route_input_noref(head, iph->daddr, iph->saddr,
                                           iph->tos, head->dev);
                if (err)
-                       goto out_rcu_unlock;
+                       goto out;
 
                /* Only an end host needs to send an ICMP
                 * "Fragment Reassembly Timeout" message, per RFC792.
                 */
                if (frag_expire_skip_icmp(qp->user) &&
                    (skb_rtable(head)->rt_type != RTN_LOCAL))
-                       goto out_rcu_unlock;
+                       goto out;
+
+               clone = skb_clone(head, GFP_ATOMIC);
 
                /* Send an ICMP "Fragment Reassembly Timeout" message. */
-               icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
-out_rcu_unlock:
-               rcu_read_unlock();
+               if (clone) {
+                       spin_unlock(&qp->q.lock);
+                       icmp_send(clone, ICMP_TIME_EXCEEDED,
+                                 ICMP_EXC_FRAGTIME, 0);
+                       consume_skb(clone);
+                       goto out_rcu_unlock;
+               }
        }
 out:
        spin_unlock(&qp->q.lock);
+out_rcu_unlock:
+       rcu_read_unlock();
        ipq_put(qp);
 }
 
index bc1486f2c0643355ddac067cb79f075cafd788d1..2e14ed11a35cfc83db845e972521b2e8894f97c6 100644 (file)
@@ -165,6 +165,10 @@ static unsigned int ipv4_conntrack_local(void *priv,
        if (skb->len < sizeof(struct iphdr) ||
            ip_hdrlen(skb) < sizeof(struct iphdr))
                return NF_ACCEPT;
+
+       if (ip_is_fragment(ip_hdr(skb))) /* IP_NODEFRAG setsockopt set */
+               return NF_ACCEPT;
+
        return nf_conntrack_in(state->net, PF_INET, state->hook, skb);
 }
 
index f8aad03d674b05008edb5b9883b3a26b2fa7461f..6f5e8d01b876933a68e5f6cf8b2a48f8c4e17262 100644 (file)
@@ -255,11 +255,6 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
        /* maniptype == SRC for postrouting. */
        enum nf_nat_manip_type maniptype = HOOK2MANIP(state->hook);
 
-       /* We never see fragments: conntrack defrags on pre-routing
-        * and local-out, and nf_nat_out protects post-routing.
-        */
-       NF_CT_ASSERT(!ip_is_fragment(ip_hdr(skb)));
-
        ct = nf_ct_get(skb, &ctinfo);
        /* Can't track?  It's not due to stress, or conntrack would
         * have dropped it.  Hence it's the user's responsibilty to
index a0ea8aad1bf150bcb9e8e0aa2e6b45a5347599e4..f18677277119305aeea043d81deb4e6ee7d20b7c 100644 (file)
@@ -26,10 +26,10 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr,
        memset(&range, 0, sizeof(range));
        range.flags = priv->flags;
        if (priv->sreg_proto_min) {
-               range.min_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_min];
-               range.max_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_max];
+               range.min_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_min]);
+               range.max_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_max]);
        }
        regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, nft_hook(pkt),
                                                    &range, nft_out(pkt));
index 1650ed23c15dd00bb8e4bd741dc2d02d6cbf2c4e..5120be1d31185dd5c879419f8889d36ddb363591 100644 (file)
@@ -26,10 +26,10 @@ static void nft_redir_ipv4_eval(const struct nft_expr *expr,
 
        memset(&mr, 0, sizeof(mr));
        if (priv->sreg_proto_min) {
-               mr.range[0].min.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_min];
-               mr.range[0].max.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_max];
+               mr.range[0].min.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_min]);
+               mr.range[0].max.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_max]);
                mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
        }
 
index cf4555581282c608f920254078264e36e18584c6..1e319a525d51b0b603a5ccc5143381c752b9f2c7 100644 (file)
@@ -2770,7 +2770,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
 {
        const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */
        const struct inet_connection_sock *icsk = inet_csk(sk);
-       u32 now = tcp_time_stamp, intv;
+       u32 now, intv;
        u64 rate64;
        bool slow;
        u32 rate;
@@ -2839,6 +2839,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
        info->tcpi_retrans = tp->retrans_out;
        info->tcpi_fackets = tp->fackets_out;
 
+       now = tcp_time_stamp;
        info->tcpi_last_data_sent = jiffies_to_msecs(now - tp->lsndtime);
        info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime);
        info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp);
index 39c393cc0fd3c17130cd5d8d8b37f31ad3aeafd9..c43119726a62e494063fd940001b483215d0fe26 100644 (file)
@@ -5541,6 +5541,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
        struct inet_connection_sock *icsk = inet_csk(sk);
 
        tcp_set_state(sk, TCP_ESTABLISHED);
+       icsk->icsk_ack.lrcvtime = tcp_time_stamp;
 
        if (skb) {
                icsk->icsk_af_ops->sk_rx_dst_set(sk, skb);
@@ -5759,7 +5760,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                         * to stand against the temptation 8)     --ANK
                         */
                        inet_csk_schedule_ack(sk);
-                       icsk->icsk_ack.lrcvtime = tcp_time_stamp;
                        tcp_enter_quickack_mode(sk);
                        inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
                                                  TCP_DELACK_MAX, TCP_RTO_MAX);
index 7e16243cdb58c830f869fe483730e86400e2eb00..65c0f3d13eca47c6394c09925decf54287d01b48 100644 (file)
@@ -460,6 +460,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
                newtp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT);
                minmax_reset(&newtp->rtt_min, tcp_time_stamp, ~0U);
                newicsk->icsk_rto = TCP_TIMEOUT_INIT;
+               newicsk->icsk_ack.lrcvtime = tcp_time_stamp;
 
                newtp->packets_out = 0;
                newtp->retrans_out = 0;
index 6c5b5b1830a74f52e2dbc4f4f2bb8127a0ba2efb..4146536e9c1517fc5e2e0ad066a8e87154446dda 100644 (file)
@@ -27,10 +27,10 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr,
        memset(&range, 0, sizeof(range));
        range.flags = priv->flags;
        if (priv->sreg_proto_min) {
-               range.min_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_min];
-               range.max_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_max];
+               range.min_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_min]);
+               range.max_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_max]);
        }
        regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range,
                                                    nft_out(pkt));
index f5ac080fc0849b0f65751458432cf4e693353c8a..a27e424f690d699fafc5f2a7135637f36fb66388 100644 (file)
@@ -26,10 +26,10 @@ static void nft_redir_ipv6_eval(const struct nft_expr *expr,
 
        memset(&range, 0, sizeof(range));
        if (priv->sreg_proto_min) {
-               range.min_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_min],
-               range.max_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_max],
+               range.min_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_min]);
+               range.max_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_max]);
                range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
        }
 
index 35c58b669ebdfd73db32035bf4d6ccfdd01bbaaf..9db1418993f2b8a5b4194895f243441033d4729a 100644 (file)
@@ -3423,6 +3423,8 @@ static int rt6_fill_node(struct net *net,
        }
        else if (rt->rt6i_flags & RTF_LOCAL)
                rtm->rtm_type = RTN_LOCAL;
+       else if (rt->rt6i_flags & RTF_ANYCAST)
+               rtm->rtm_type = RTN_ANYCAST;
        else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
                rtm->rtm_type = RTN_LOCAL;
        else
index 4e4c401e3bc69020deaa4af1c10633288faedf13..e28082f0a307eb68ac13987580d8d9f65358212f 100644 (file)
@@ -1035,6 +1035,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        ipc6.hlimit = -1;
        ipc6.tclass = -1;
        ipc6.dontfrag = -1;
+       sockc.tsflags = sk->sk_tsflags;
 
        /* destination address check */
        if (sin6) {
@@ -1159,7 +1160,6 @@ do_udp_sendmsg:
 
        fl6.flowi6_mark = sk->sk_mark;
        fl6.flowi6_uid = sk->sk_uid;
-       sockc.tsflags = sk->sk_tsflags;
 
        if (msg->msg_controllen) {
                opt = &opt_space;
index 33211f9a265608c378848c97b4be36a1cec9736d..6414079aa7297eee8fbd6320fb4392c6d8865e34 100644 (file)
@@ -1269,6 +1269,8 @@ static void mpls_ifdown(struct net_device *dev, int event)
 {
        struct mpls_route __rcu **platform_label;
        struct net *net = dev_net(dev);
+       unsigned int nh_flags = RTNH_F_DEAD | RTNH_F_LINKDOWN;
+       unsigned int alive;
        unsigned index;
 
        platform_label = rtnl_dereference(net->mpls.platform_label);
@@ -1278,9 +1280,11 @@ static void mpls_ifdown(struct net_device *dev, int event)
                if (!rt)
                        continue;
 
+               alive = 0;
                change_nexthops(rt) {
                        if (rtnl_dereference(nh->nh_dev) != dev)
-                               continue;
+                               goto next;
+
                        switch (event) {
                        case NETDEV_DOWN:
                        case NETDEV_UNREGISTER:
@@ -1288,13 +1292,16 @@ static void mpls_ifdown(struct net_device *dev, int event)
                                /* fall through */
                        case NETDEV_CHANGE:
                                nh->nh_flags |= RTNH_F_LINKDOWN;
-                               if (event != NETDEV_UNREGISTER)
-                                       ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1;
                                break;
                        }
                        if (event == NETDEV_UNREGISTER)
                                RCU_INIT_POINTER(nh->nh_dev, NULL);
+next:
+                       if (!(nh->nh_flags & nh_flags))
+                               alive++;
                } endfor_nexthops(rt);
+
+               WRITE_ONCE(rt->rt_nhn_alive, alive);
        }
 }
 
index 071b97fcbefb083ded417e06e739a4622b237fe8..ffb78e5f7b70912a2bba608a7f32f0a2bc486adc 100644 (file)
@@ -181,7 +181,11 @@ EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
 unsigned int nf_conntrack_max __read_mostly;
 seqcount_t nf_conntrack_generation __read_mostly;
 
-DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
+/* nf_conn must be 8 bytes aligned, as the 3 LSB bits are used
+ * for the nfctinfo. We cheat by (ab)using the PER CPU cache line
+ * alignment to enforce this.
+ */
+DEFINE_PER_CPU_ALIGNED(struct nf_conn, nf_conntrack_untracked);
 EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
 
 static unsigned int nf_conntrack_hash_rnd __read_mostly;
index 31d358691af0963c664c742d180e79c664590005..804e8a0ab36ef56b120ea89be1994b39eca5bc36 100644 (file)
@@ -33,8 +33,16 @@ sctp_manip_pkt(struct sk_buff *skb,
               enum nf_nat_manip_type maniptype)
 {
        sctp_sctphdr_t *hdr;
+       int hdrsize = 8;
 
-       if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
+       /* This could be an inner header returned in imcp packet; in such
+        * cases we cannot update the checksum field since it is outside
+        * of the 8 bytes of transport layer headers we are guaranteed.
+        */
+       if (skb->len >= hdroff + sizeof(*hdr))
+               hdrsize = sizeof(*hdr);
+
+       if (!skb_make_writable(skb, hdroff + hdrsize))
                return false;
 
        hdr = (struct sctphdr *)(skb->data + hdroff);
@@ -47,6 +55,9 @@ sctp_manip_pkt(struct sk_buff *skb,
                hdr->dest = tuple->dst.u.sctp.port;
        }
 
+       if (hdrsize < sizeof(*hdr))
+               return true;
+
        if (skb->ip_summed != CHECKSUM_PARTIAL) {
                hdr->checksum = sctp_compute_cksum(skb, hdroff);
                skb->ip_summed = CHECKSUM_NONE;
index 5e0ccfd5bb37d1cbebb7e03b0998b7c24cca024d..434c739dfecaa8727dc193f8ad86e18133932660 100644 (file)
@@ -3145,7 +3145,6 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
                iter.count      = 0;
                iter.err        = 0;
                iter.fn         = nf_tables_bind_check_setelem;
-               iter.flush      = false;
 
                set->ops->walk(ctx, set, &iter);
                if (iter.err < 0)
@@ -3399,7 +3398,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
        args.iter.count         = 0;
        args.iter.err           = 0;
        args.iter.fn            = nf_tables_dump_setelem;
-       args.iter.flush         = false;
        set->ops->walk(&ctx, set, &args.iter);
 
        nla_nest_end(skb, nest);
@@ -3963,7 +3961,6 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
                struct nft_set_iter iter = {
                        .genmask        = genmask,
                        .fn             = nft_flush_set,
-                       .flush          = true,
                };
                set->ops->walk(&ctx, set, &iter);
 
@@ -5114,7 +5111,6 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
                        iter.count      = 0;
                        iter.err        = 0;
                        iter.fn         = nf_tables_loop_check_setelem;
-                       iter.flush      = false;
 
                        set->ops->walk(ctx, set, &iter);
                        if (iter.err < 0)
index bf548a7a71ec9b49cf308af041811d2eb5f33c8c..0264258c46feb5071a8eebcf9299b4b717fd0a32 100644 (file)
@@ -83,7 +83,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
 
        switch (priv->key) {
        case NFT_CT_DIRECTION:
-               *dest = CTINFO2DIR(ctinfo);
+               nft_reg_store8(dest, CTINFO2DIR(ctinfo));
                return;
        case NFT_CT_STATUS:
                *dest = ct->status;
@@ -151,20 +151,22 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
                return;
        }
        case NFT_CT_L3PROTOCOL:
-               *dest = nf_ct_l3num(ct);
+               nft_reg_store8(dest, nf_ct_l3num(ct));
                return;
        case NFT_CT_PROTOCOL:
-               *dest = nf_ct_protonum(ct);
+               nft_reg_store8(dest, nf_ct_protonum(ct));
                return;
 #ifdef CONFIG_NF_CONNTRACK_ZONES
        case NFT_CT_ZONE: {
                const struct nf_conntrack_zone *zone = nf_ct_zone(ct);
+               u16 zoneid;
 
                if (priv->dir < IP_CT_DIR_MAX)
-                       *dest = nf_ct_zone_id(zone, priv->dir);
+                       zoneid = nf_ct_zone_id(zone, priv->dir);
                else
-                       *dest = zone->id;
+                       zoneid = zone->id;
 
+               nft_reg_store16(dest, zoneid);
                return;
        }
 #endif
@@ -183,10 +185,10 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
                       nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
                return;
        case NFT_CT_PROTO_SRC:
-               *dest = (__force __u16)tuple->src.u.all;
+               nft_reg_store16(dest, (__force u16)tuple->src.u.all);
                return;
        case NFT_CT_PROTO_DST:
-               *dest = (__force __u16)tuple->dst.u.all;
+               nft_reg_store16(dest, (__force u16)tuple->dst.u.all);
                return;
        default:
                break;
@@ -205,7 +207,7 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr,
        const struct nft_ct *priv = nft_expr_priv(expr);
        struct sk_buff *skb = pkt->skb;
        enum ip_conntrack_info ctinfo;
-       u16 value = regs->data[priv->sreg];
+       u16 value = nft_reg_load16(&regs->data[priv->sreg]);
        struct nf_conn *ct;
 
        ct = nf_ct_get(skb, &ctinfo);
@@ -542,7 +544,8 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
                case IP_CT_DIR_REPLY:
                        break;
                default:
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto err1;
                }
        }
 
index e1f5ca9b423b5ffda43ec5519d4c8832ce695899..7b60e01f38ff9f2f9fa7d28f6f99b4f889d190d7 100644 (file)
@@ -45,16 +45,15 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                *dest = skb->len;
                break;
        case NFT_META_PROTOCOL:
-               *dest = 0;
-               *(__be16 *)dest = skb->protocol;
+               nft_reg_store16(dest, (__force u16)skb->protocol);
                break;
        case NFT_META_NFPROTO:
-               *dest = nft_pf(pkt);
+               nft_reg_store8(dest, nft_pf(pkt));
                break;
        case NFT_META_L4PROTO:
                if (!pkt->tprot_set)
                        goto err;
-               *dest = pkt->tprot;
+               nft_reg_store8(dest, pkt->tprot);
                break;
        case NFT_META_PRIORITY:
                *dest = skb->priority;
@@ -85,14 +84,12 @@ void nft_meta_get_eval(const struct nft_expr *expr,
        case NFT_META_IIFTYPE:
                if (in == NULL)
                        goto err;
-               *dest = 0;
-               *(u16 *)dest = in->type;
+               nft_reg_store16(dest, in->type);
                break;
        case NFT_META_OIFTYPE:
                if (out == NULL)
                        goto err;
-               *dest = 0;
-               *(u16 *)dest = out->type;
+               nft_reg_store16(dest, out->type);
                break;
        case NFT_META_SKUID:
                sk = skb_to_full_sk(skb);
@@ -142,19 +139,19 @@ void nft_meta_get_eval(const struct nft_expr *expr,
 #endif
        case NFT_META_PKTTYPE:
                if (skb->pkt_type != PACKET_LOOPBACK) {
-                       *dest = skb->pkt_type;
+                       nft_reg_store8(dest, skb->pkt_type);
                        break;
                }
 
                switch (nft_pf(pkt)) {
                case NFPROTO_IPV4:
                        if (ipv4_is_multicast(ip_hdr(skb)->daddr))
-                               *dest = PACKET_MULTICAST;
+                               nft_reg_store8(dest, PACKET_MULTICAST);
                        else
-                               *dest = PACKET_BROADCAST;
+                               nft_reg_store8(dest, PACKET_BROADCAST);
                        break;
                case NFPROTO_IPV6:
-                       *dest = PACKET_MULTICAST;
+                       nft_reg_store8(dest, PACKET_MULTICAST);
                        break;
                case NFPROTO_NETDEV:
                        switch (skb->protocol) {
@@ -168,14 +165,14 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                                        goto err;
 
                                if (ipv4_is_multicast(iph->daddr))
-                                       *dest = PACKET_MULTICAST;
+                                       nft_reg_store8(dest, PACKET_MULTICAST);
                                else
-                                       *dest = PACKET_BROADCAST;
+                                       nft_reg_store8(dest, PACKET_BROADCAST);
 
                                break;
                        }
                        case htons(ETH_P_IPV6):
-                               *dest = PACKET_MULTICAST;
+                               nft_reg_store8(dest, PACKET_MULTICAST);
                                break;
                        default:
                                WARN_ON_ONCE(1);
@@ -230,7 +227,9 @@ void nft_meta_set_eval(const struct nft_expr *expr,
 {
        const struct nft_meta *meta = nft_expr_priv(expr);
        struct sk_buff *skb = pkt->skb;
-       u32 value = regs->data[meta->sreg];
+       u32 *sreg = &regs->data[meta->sreg];
+       u32 value = *sreg;
+       u8 pkt_type;
 
        switch (meta->key) {
        case NFT_META_MARK:
@@ -240,9 +239,12 @@ void nft_meta_set_eval(const struct nft_expr *expr,
                skb->priority = value;
                break;
        case NFT_META_PKTTYPE:
-               if (skb->pkt_type != value &&
-                   skb_pkt_type_ok(value) && skb_pkt_type_ok(skb->pkt_type))
-                       skb->pkt_type = value;
+               pkt_type = nft_reg_load8(sreg);
+
+               if (skb->pkt_type != pkt_type &&
+                   skb_pkt_type_ok(pkt_type) &&
+                   skb_pkt_type_ok(skb->pkt_type))
+                       skb->pkt_type = pkt_type;
                break;
        case NFT_META_NFTRACE:
                skb->nf_trace = !!value;
index 19a7bf3236f968725a29e827012af301781802df..439e0bd152a004c98664a19ae6c920458fa6160a 100644 (file)
@@ -65,10 +65,10 @@ static void nft_nat_eval(const struct nft_expr *expr,
        }
 
        if (priv->sreg_proto_min) {
-               range.min_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_min];
-               range.max_proto.all =
-                       *(__be16 *)&regs->data[priv->sreg_proto_max];
+               range.min_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_min]);
+               range.max_proto.all = (__force __be16)nft_reg_load16(
+                       &regs->data[priv->sreg_proto_max]);
                range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
        }
 
index 152d226552c174929fd8973f023eaac888e4b0a9..8ebbc2940f4c593d393c65bd5674d90feb585d98 100644 (file)
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables.h>
 
+struct nft_bitmap_elem {
+       struct list_head        head;
+       struct nft_set_ext      ext;
+};
+
 /* This bitmap uses two bits to represent one element. These two bits determine
  * the element state in the current and the future generation.
  *
  *      restore its previous state.
  */
 struct nft_bitmap {
-       u16     bitmap_size;
-       u8      bitmap[];
+       struct  list_head       list;
+       u16                     bitmap_size;
+       u8                      bitmap[];
 };
 
-static inline void nft_bitmap_location(u32 key, u32 *idx, u32 *off)
+static inline void nft_bitmap_location(const struct nft_set *set,
+                                      const void *key,
+                                      u32 *idx, u32 *off)
 {
-       u32 k = (key << 1);
+       u32 k;
+
+       if (set->klen == 2)
+               k = *(u16 *)key;
+       else
+               k = *(u8 *)key;
+       k <<= 1;
 
        *idx = k / BITS_PER_BYTE;
        *off = k % BITS_PER_BYTE;
@@ -69,26 +83,48 @@ static bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
        u8 genmask = nft_genmask_cur(net);
        u32 idx, off;
 
-       nft_bitmap_location(*key, &idx, &off);
+       nft_bitmap_location(set, key, &idx, &off);
 
        return nft_bitmap_active(priv->bitmap, idx, off, genmask);
 }
 
+static struct nft_bitmap_elem *
+nft_bitmap_elem_find(const struct nft_set *set, struct nft_bitmap_elem *this,
+                    u8 genmask)
+{
+       const struct nft_bitmap *priv = nft_set_priv(set);
+       struct nft_bitmap_elem *be;
+
+       list_for_each_entry_rcu(be, &priv->list, head) {
+               if (memcmp(nft_set_ext_key(&be->ext),
+                          nft_set_ext_key(&this->ext), set->klen) ||
+                   !nft_set_elem_active(&be->ext, genmask))
+                       continue;
+
+               return be;
+       }
+       return NULL;
+}
+
 static int nft_bitmap_insert(const struct net *net, const struct nft_set *set,
                             const struct nft_set_elem *elem,
-                            struct nft_set_ext **_ext)
+                            struct nft_set_ext **ext)
 {
        struct nft_bitmap *priv = nft_set_priv(set);
-       struct nft_set_ext *ext = elem->priv;
+       struct nft_bitmap_elem *new = elem->priv, *be;
        u8 genmask = nft_genmask_next(net);
        u32 idx, off;
 
-       nft_bitmap_location(nft_set_ext_key(ext)->data[0], &idx, &off);
-       if (nft_bitmap_active(priv->bitmap, idx, off, genmask))
+       be = nft_bitmap_elem_find(set, new, genmask);
+       if (be) {
+               *ext = &be->ext;
                return -EEXIST;
+       }
 
+       nft_bitmap_location(set, nft_set_ext_key(&new->ext), &idx, &off);
        /* Enter 01 state. */
        priv->bitmap[idx] |= (genmask << off);
+       list_add_tail_rcu(&new->head, &priv->list);
 
        return 0;
 }
@@ -98,13 +134,14 @@ static void nft_bitmap_remove(const struct net *net,
                              const struct nft_set_elem *elem)
 {
        struct nft_bitmap *priv = nft_set_priv(set);
-       struct nft_set_ext *ext = elem->priv;
+       struct nft_bitmap_elem *be = elem->priv;
        u8 genmask = nft_genmask_next(net);
        u32 idx, off;
 
-       nft_bitmap_location(nft_set_ext_key(ext)->data[0], &idx, &off);
+       nft_bitmap_location(set, nft_set_ext_key(&be->ext), &idx, &off);
        /* Enter 00 state. */
        priv->bitmap[idx] &= ~(genmask << off);
+       list_del_rcu(&be->head);
 }
 
 static void nft_bitmap_activate(const struct net *net,
@@ -112,74 +149,52 @@ static void nft_bitmap_activate(const struct net *net,
                                const struct nft_set_elem *elem)
 {
        struct nft_bitmap *priv = nft_set_priv(set);
-       struct nft_set_ext *ext = elem->priv;
+       struct nft_bitmap_elem *be = elem->priv;
        u8 genmask = nft_genmask_next(net);
        u32 idx, off;
 
-       nft_bitmap_location(nft_set_ext_key(ext)->data[0], &idx, &off);
+       nft_bitmap_location(set, nft_set_ext_key(&be->ext), &idx, &off);
        /* Enter 11 state. */
        priv->bitmap[idx] |= (genmask << off);
+       nft_set_elem_change_active(net, set, &be->ext);
 }
 
 static bool nft_bitmap_flush(const struct net *net,
-                            const struct nft_set *set, void *ext)
+                            const struct nft_set *set, void *_be)
 {
        struct nft_bitmap *priv = nft_set_priv(set);
        u8 genmask = nft_genmask_next(net);
+       struct nft_bitmap_elem *be = _be;
        u32 idx, off;
 
-       nft_bitmap_location(nft_set_ext_key(ext)->data[0], &idx, &off);
+       nft_bitmap_location(set, nft_set_ext_key(&be->ext), &idx, &off);
        /* Enter 10 state, similar to deactivation. */
        priv->bitmap[idx] &= ~(genmask << off);
+       nft_set_elem_change_active(net, set, &be->ext);
 
        return true;
 }
 
-static struct nft_set_ext *nft_bitmap_ext_alloc(const struct nft_set *set,
-                                               const struct nft_set_elem *elem)
-{
-       struct nft_set_ext_tmpl tmpl;
-       struct nft_set_ext *ext;
-
-       nft_set_ext_prepare(&tmpl);
-       nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
-
-       ext = kzalloc(tmpl.len, GFP_KERNEL);
-       if (!ext)
-               return NULL;
-
-       nft_set_ext_init(ext, &tmpl);
-       memcpy(nft_set_ext_key(ext), elem->key.val.data, set->klen);
-
-       return ext;
-}
-
 static void *nft_bitmap_deactivate(const struct net *net,
                                   const struct nft_set *set,
                                   const struct nft_set_elem *elem)
 {
        struct nft_bitmap *priv = nft_set_priv(set);
+       struct nft_bitmap_elem *this = elem->priv, *be;
        u8 genmask = nft_genmask_next(net);
-       struct nft_set_ext *ext;
-       u32 idx, off, key = 0;
-
-       memcpy(&key, elem->key.val.data, set->klen);
-       nft_bitmap_location(key, &idx, &off);
+       u32 idx, off;
 
-       if (!nft_bitmap_active(priv->bitmap, idx, off, genmask))
-               return NULL;
+       nft_bitmap_location(set, elem->key.val.data, &idx, &off);
 
-       /* We have no real set extension since this is a bitmap, allocate this
-        * dummy object that is released from the commit/abort path.
-        */
-       ext = nft_bitmap_ext_alloc(set, elem);
-       if (!ext)
+       be = nft_bitmap_elem_find(set, this, genmask);
+       if (!be)
                return NULL;
 
        /* Enter 10 state. */
        priv->bitmap[idx] &= ~(genmask << off);
+       nft_set_elem_change_active(net, set, &be->ext);
 
-       return ext;
+       return be;
 }
 
 static void nft_bitmap_walk(const struct nft_ctx *ctx,
@@ -187,47 +202,23 @@ static void nft_bitmap_walk(const struct nft_ctx *ctx,
                            struct nft_set_iter *iter)
 {
        const struct nft_bitmap *priv = nft_set_priv(set);
-       struct nft_set_ext_tmpl tmpl;
+       struct nft_bitmap_elem *be;
        struct nft_set_elem elem;
-       struct nft_set_ext *ext;
-       int idx, off;
-       u16 key;
-
-       nft_set_ext_prepare(&tmpl);
-       nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
-
-       for (idx = 0; idx < priv->bitmap_size; idx++) {
-               for (off = 0; off < BITS_PER_BYTE; off += 2) {
-                       if (iter->count < iter->skip)
-                               goto cont;
-
-                       if (!nft_bitmap_active(priv->bitmap, idx, off,
-                                              iter->genmask))
-                               goto cont;
-
-                       ext = kzalloc(tmpl.len, GFP_KERNEL);
-                       if (!ext) {
-                               iter->err = -ENOMEM;
-                               return;
-                       }
-                       nft_set_ext_init(ext, &tmpl);
-                       key = ((idx * BITS_PER_BYTE) + off) >> 1;
-                       memcpy(nft_set_ext_key(ext), &key, set->klen);
-
-                       elem.priv = ext;
-                       iter->err = iter->fn(ctx, set, iter, &elem);
-
-                       /* On set flush, this dummy extension object is released
-                        * from the commit/abort path.
-                        */
-                       if (!iter->flush)
-                               kfree(ext);
-
-                       if (iter->err < 0)
-                               return;
+
+       list_for_each_entry_rcu(be, &priv->list, head) {
+               if (iter->count < iter->skip)
+                       goto cont;
+               if (!nft_set_elem_active(&be->ext, iter->genmask))
+                       goto cont;
+
+               elem.priv = be;
+
+               iter->err = iter->fn(ctx, set, iter, &elem);
+
+               if (iter->err < 0)
+                       return;
 cont:
-                       iter->count++;
-               }
+               iter->count++;
        }
 }
 
@@ -258,6 +249,7 @@ static int nft_bitmap_init(const struct nft_set *set,
 {
        struct nft_bitmap *priv = nft_set_priv(set);
 
+       INIT_LIST_HEAD(&priv->list);
        priv->bitmap_size = nft_bitmap_size(set->klen);
 
        return 0;
@@ -283,6 +275,7 @@ static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features,
 
 static struct nft_set_ops nft_bitmap_ops __read_mostly = {
        .privsize       = nft_bitmap_privsize,
+       .elemsize       = offsetof(struct nft_bitmap_elem, ext),
        .estimate       = nft_bitmap_estimate,
        .init           = nft_bitmap_init,
        .destroy        = nft_bitmap_destroy,
index 7b73c7c161a9680b8691a712c31073b7789620f7..596eaff66649e5955d6c0f349f062b6d8360dc2d 100644 (file)
@@ -96,6 +96,44 @@ EXPORT_SYMBOL_GPL(nl_table);
 
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
 
+static struct lock_class_key nlk_cb_mutex_keys[MAX_LINKS];
+
+static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = {
+       "nlk_cb_mutex-ROUTE",
+       "nlk_cb_mutex-1",
+       "nlk_cb_mutex-USERSOCK",
+       "nlk_cb_mutex-FIREWALL",
+       "nlk_cb_mutex-SOCK_DIAG",
+       "nlk_cb_mutex-NFLOG",
+       "nlk_cb_mutex-XFRM",
+       "nlk_cb_mutex-SELINUX",
+       "nlk_cb_mutex-ISCSI",
+       "nlk_cb_mutex-AUDIT",
+       "nlk_cb_mutex-FIB_LOOKUP",
+       "nlk_cb_mutex-CONNECTOR",
+       "nlk_cb_mutex-NETFILTER",
+       "nlk_cb_mutex-IP6_FW",
+       "nlk_cb_mutex-DNRTMSG",
+       "nlk_cb_mutex-KOBJECT_UEVENT",
+       "nlk_cb_mutex-GENERIC",
+       "nlk_cb_mutex-17",
+       "nlk_cb_mutex-SCSITRANSPORT",
+       "nlk_cb_mutex-ECRYPTFS",
+       "nlk_cb_mutex-RDMA",
+       "nlk_cb_mutex-CRYPTO",
+       "nlk_cb_mutex-SMC",
+       "nlk_cb_mutex-23",
+       "nlk_cb_mutex-24",
+       "nlk_cb_mutex-25",
+       "nlk_cb_mutex-26",
+       "nlk_cb_mutex-27",
+       "nlk_cb_mutex-28",
+       "nlk_cb_mutex-29",
+       "nlk_cb_mutex-30",
+       "nlk_cb_mutex-31",
+       "nlk_cb_mutex-MAX_LINKS"
+};
+
 static int netlink_dump(struct sock *sk);
 static void netlink_skb_destructor(struct sk_buff *skb);
 
@@ -585,6 +623,9 @@ static int __netlink_create(struct net *net, struct socket *sock,
        } else {
                nlk->cb_mutex = &nlk->cb_def_mutex;
                mutex_init(nlk->cb_mutex);
+               lockdep_set_class_and_name(nlk->cb_mutex,
+                                          nlk_cb_mutex_keys + protocol,
+                                          nlk_cb_mutex_key_strings[protocol]);
        }
        init_waitqueue_head(&nlk->wait);
 
index fb6e10fdb2174320c96608aea63d3c484d3625a0..92e0981f74040d7029b65863167b459322612024 100644 (file)
@@ -783,8 +783,10 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
 
                if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
                                   cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                  skb, CTRL_CMD_NEWFAMILY) < 0)
+                                  skb, CTRL_CMD_NEWFAMILY) < 0) {
+                       n--;
                        break;
+               }
        }
 
        cb->args[0] = n;
index 6f5fa50f716d066333b30edde43e5165b9fe94be..1105a838bab83f9fe647423060d08e4a415bab61 100644 (file)
@@ -604,7 +604,7 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
                        ipv4 = true;
                        break;
                case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
-                       SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
+                       SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.src,
                                        nla_get_in6_addr(a), is_mask);
                        ipv6 = true;
                        break;
@@ -665,6 +665,8 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
                        tun_flags |= TUNNEL_VXLAN_OPT;
                        opts_type = type;
                        break;
+               case OVS_TUNNEL_KEY_ATTR_PAD:
+                       break;
                default:
                        OVS_NLERR(log, "Unknown IP tunnel attribute %d",
                                  type);
index 3f9d8d7ec6323a95de3e08d01098abdfcf33ff4f..b099b64366f356c27dea0a4dd215cc1034e61b55 100644 (file)
@@ -275,6 +275,10 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
                rxrpc_conn_retransmit_call(conn, skb);
                return 0;
 
+       case RXRPC_PACKET_TYPE_BUSY:
+               /* Just ignore BUSY packets for now. */
+               return 0;
+
        case RXRPC_PACKET_TYPE_ABORT:
                if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
                                  &wtmp, sizeof(wtmp)) < 0)
index 802ac7c2e5e87eed1341ba4c09d3e5d70bc75876..5334e309f17f0ef4416dddcdc9278c14ecb5585d 100644 (file)
@@ -201,9 +201,13 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
        pr_debug("%s(skb %p,sch %p,[qdisc %p])\n", __func__, skb, sch, p);
 
        if (p->set_tc_index) {
+               int wlen = skb_network_offset(skb);
+
                switch (tc_skb_protocol(skb)) {
                case htons(ETH_P_IP):
-                       if (skb_cow_head(skb, sizeof(struct iphdr)))
+                       wlen += sizeof(struct iphdr);
+                       if (!pskb_may_pull(skb, wlen) ||
+                           skb_try_make_writable(skb, wlen))
                                goto drop;
 
                        skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
@@ -211,7 +215,9 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                        break;
 
                case htons(ETH_P_IPV6):
-                       if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
+                       wlen += sizeof(struct ipv6hdr);
+                       if (!pskb_may_pull(skb, wlen) ||
+                           skb_try_make_writable(skb, wlen))
                                goto drop;
 
                        skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
index 2a6835b4562b61cff52425a530524f1c48bc7919..0439a1a6836784fd5096d85a4217980cb5c49690 100644 (file)
@@ -71,9 +71,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 {
        struct net *net = sock_net(sk);
        struct sctp_sock *sp;
-       int i;
        sctp_paramhdr_t *p;
-       int err;
+       int i;
 
        /* Retrieve the SCTP per socket area.  */
        sp = sctp_sk((struct sock *)sk);
@@ -264,8 +263,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 
        /* AUTH related initializations */
        INIT_LIST_HEAD(&asoc->endpoint_shared_keys);
-       err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp);
-       if (err)
+       if (sctp_auth_asoc_copy_shkeys(ep, asoc, gfp))
                goto fail_init;
 
        asoc->active_key_id = ep->active_key_id;
index 71ce6b945dcb54d831425bdb02e315a14dae69ef..1224421036b3e59c4dba1dd5d672923b55c7923c 100644 (file)
@@ -546,7 +546,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
        struct sctp_association *asoc = tp->asoc;
        struct sctp_chunk *chunk, *tmp;
        int pkt_count, gso = 0;
-       int confirm;
        struct dst_entry *dst;
        struct sk_buff *head;
        struct sctphdr *sh;
@@ -625,13 +624,13 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
                        asoc->peer.last_sent_to = tp;
        }
        head->ignore_df = packet->ipfragok;
-       confirm = tp->dst_pending_confirm;
-       if (confirm)
+       if (tp->dst_pending_confirm)
                skb_set_dst_pending_confirm(head, 1);
        /* neighbour should be confirmed on successful transmission or
         * positive error
         */
-       if (tp->af_specific->sctp_xmit(head, tp) >= 0 && confirm)
+       if (tp->af_specific->sctp_xmit(head, tp) >= 0 &&
+           tp->dst_pending_confirm)
                tp->dst_pending_confirm = 0;
 
 out:
index db352e5d61f8980dc461a162959643d872997217..025ccff670720bd38b9cc9bd995b87e134c9f931 100644 (file)
@@ -382,17 +382,18 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
 }
 
 static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
-                                   struct sctp_sndrcvinfo *sinfo,
-                                   struct list_head *queue, int msg_len)
+                                   struct sctp_sndrcvinfo *sinfo, int msg_len)
 {
+       struct sctp_outq *q = &asoc->outqueue;
        struct sctp_chunk *chk, *temp;
 
-       list_for_each_entry_safe(chk, temp, queue, list) {
+       list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
                if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
                    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
                        continue;
 
                list_del_init(&chk->list);
+               q->out_qlen -= chk->skb->len;
                asoc->sent_cnt_removable--;
                asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
 
@@ -431,9 +432,7 @@ void sctp_prsctp_prune(struct sctp_association *asoc,
                        return;
        }
 
-       sctp_prsctp_prune_unsent(asoc, sinfo,
-                                &asoc->outqueue.out_chunk_list,
-                                msg_len);
+       sctp_prsctp_prune_unsent(asoc, sinfo, msg_len);
 }
 
 /* Mark all the eligible packets on a transport for retransmission.  */
index e034fe4164beec7731c68ba2bc6920627741561b..985ef06792d6e54c69d296f3e15baf89be972f9c 100644 (file)
@@ -652,6 +652,16 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
 }
 EXPORT_SYMBOL(kernel_sendmsg);
 
+static bool skb_is_err_queue(const struct sk_buff *skb)
+{
+       /* pkt_type of skbs enqueued on the error queue are set to
+        * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+        * in recvmsg, since skbs received on a local socket will never
+        * have a pkt_type of PACKET_OUTGOING.
+        */
+       return skb->pkt_type == PACKET_OUTGOING;
+}
+
 /*
  * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
  */
@@ -695,7 +705,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
                put_cmsg(msg, SOL_SOCKET,
                         SCM_TIMESTAMPING, sizeof(tss), &tss);
 
-               if (skb->len && (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS))
+               if (skb_is_err_queue(skb) && skb->len &&
+                   SKB_EXT_ERR(skb)->opt_stats)
                        put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
                                 skb->len, skb->data);
        }
index 8931e33b65412d7b8bbe8b3872e5f7d7b27d92d5..2b720fa35c4ff7c2ae906e9e76d13d27a2b2f008 100644 (file)
@@ -1635,6 +1635,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
 
        xprt = &svsk->sk_xprt;
        svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
+       set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
 
        serv->sv_bc_xprt = xprt;
 
index c13a5c35ce14d992515fa99e456976ed0cd1c382..fc8f14c7bfec60dc5828340861a747e49f06193e 100644 (file)
@@ -127,6 +127,7 @@ static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *serv,
        xprt = &cma_xprt->sc_xprt;
 
        svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv);
+       set_bit(XPT_CONG_CTRL, &xprt->xpt_flags);
        serv->sv_bc_xprt = xprt;
 
        dprintk("svcrdma: %s(%p)\n", __func__, xprt);
index 9d94e65d0894183b4af94ed24e84b94c0478b551..271cd66e4b3b66534d8686bec94132bc9737314e 100644 (file)
@@ -141,6 +141,11 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
 static void tipc_subscrp_timeout(unsigned long data)
 {
        struct tipc_subscription *sub = (struct tipc_subscription *)data;
+       struct tipc_subscriber *subscriber = sub->subscriber;
+
+       spin_lock_bh(&subscriber->lock);
+       tipc_nametbl_unsubscribe(sub);
+       spin_unlock_bh(&subscriber->lock);
 
        /* Notify subscriber of timeout */
        tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
@@ -173,7 +178,6 @@ static void tipc_subscrp_kref_release(struct kref *kref)
        struct tipc_subscriber *subscriber = sub->subscriber;
 
        spin_lock_bh(&subscriber->lock);
-       tipc_nametbl_unsubscribe(sub);
        list_del(&sub->subscrp_list);
        atomic_dec(&tn->subscription_count);
        spin_unlock_bh(&subscriber->lock);
@@ -205,6 +209,7 @@ static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber,
                if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr)))
                        continue;
 
+               tipc_nametbl_unsubscribe(sub);
                tipc_subscrp_get(sub);
                spin_unlock_bh(&subscriber->lock);
                tipc_subscrp_delete(sub);
index 6a0d48525fcf9a71f54bb43495b200b300f5341e..c36757e728442bb936c17f8a975b420f5f8a5972 100644 (file)
@@ -146,6 +146,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp)
        if (s) {
                struct unix_sock *u = unix_sk(s);
 
+               BUG_ON(!atomic_long_read(&u->inflight));
                BUG_ON(list_empty(&u->link));
 
                if (atomic_long_dec_and_test(&u->inflight))
@@ -341,6 +342,14 @@ void unix_gc(void)
        }
        list_del(&cursor);
 
+       /* Now gc_candidates contains only garbage.  Restore original
+        * inflight counters for these as well, and remove the skbuffs
+        * which are creating the cycle(s).
+        */
+       skb_queue_head_init(&hitlist);
+       list_for_each_entry(u, &gc_candidates, link)
+               scan_children(&u->sk, inc_inflight, &hitlist);
+
        /* not_cycle_list contains those sockets which do not make up a
         * cycle.  Restore these to the inflight list.
         */
@@ -350,14 +359,6 @@ void unix_gc(void)
                list_move_tail(&u->link, &gc_inflight_list);
        }
 
-       /* Now gc_candidates contains only garbage.  Restore original
-        * inflight counters for these as well, and remove the skbuffs
-        * which are creating the cycle(s).
-        */
-       skb_queue_head_init(&hitlist);
-       list_for_each_entry(u, &gc_candidates, link)
-       scan_children(&u->sk, inc_inflight, &hitlist);
-
        spin_unlock(&unix_gc_lock);
 
        /* Here we are. Hitlist is filled. Die. */
index 9f770f33c10098fd3fcccfd9c739ab9a28a6b6f5..6f7f6757ceefb500551fafbf40c462835c4baf88 100644 (file)
@@ -1102,10 +1102,19 @@ static const struct proto_ops vsock_dgram_ops = {
        .sendpage = sock_no_sendpage,
 };
 
+static int vsock_transport_cancel_pkt(struct vsock_sock *vsk)
+{
+       if (!transport->cancel_pkt)
+               return -EOPNOTSUPP;
+
+       return transport->cancel_pkt(vsk);
+}
+
 static void vsock_connect_timeout(struct work_struct *work)
 {
        struct sock *sk;
        struct vsock_sock *vsk;
+       int cancel = 0;
 
        vsk = container_of(work, struct vsock_sock, dwork.work);
        sk = sk_vsock(vsk);
@@ -1116,8 +1125,11 @@ static void vsock_connect_timeout(struct work_struct *work)
                sk->sk_state = SS_UNCONNECTED;
                sk->sk_err = ETIMEDOUT;
                sk->sk_error_report(sk);
+               cancel = 1;
        }
        release_sock(sk);
+       if (cancel)
+               vsock_transport_cancel_pkt(vsk);
 
        sock_put(sk);
 }
@@ -1224,11 +1236,13 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
                        err = sock_intr_errno(timeout);
                        sk->sk_state = SS_UNCONNECTED;
                        sock->state = SS_UNCONNECTED;
+                       vsock_transport_cancel_pkt(vsk);
                        goto out_wait;
                } else if (timeout == 0) {
                        err = -ETIMEDOUT;
                        sk->sk_state = SS_UNCONNECTED;
                        sock->state = SS_UNCONNECTED;
+                       vsock_transport_cancel_pkt(vsk);
                        goto out_wait;
                }
 
index 9d24c0e958b18e614e30b24c0fcfbbe2152941f3..68675a151f22b8b63c02b25a67b833d9a6046d84 100644 (file)
@@ -213,6 +213,47 @@ virtio_transport_send_pkt(struct virtio_vsock_pkt *pkt)
        return len;
 }
 
+static int
+virtio_transport_cancel_pkt(struct vsock_sock *vsk)
+{
+       struct virtio_vsock *vsock;
+       struct virtio_vsock_pkt *pkt, *n;
+       int cnt = 0;
+       LIST_HEAD(freeme);
+
+       vsock = virtio_vsock_get();
+       if (!vsock) {
+               return -ENODEV;
+       }
+
+       spin_lock_bh(&vsock->send_pkt_list_lock);
+       list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) {
+               if (pkt->vsk != vsk)
+                       continue;
+               list_move(&pkt->list, &freeme);
+       }
+       spin_unlock_bh(&vsock->send_pkt_list_lock);
+
+       list_for_each_entry_safe(pkt, n, &freeme, list) {
+               if (pkt->reply)
+                       cnt++;
+               list_del(&pkt->list);
+               virtio_transport_free_pkt(pkt);
+       }
+
+       if (cnt) {
+               struct virtqueue *rx_vq = vsock->vqs[VSOCK_VQ_RX];
+               int new_cnt;
+
+               new_cnt = atomic_sub_return(cnt, &vsock->queued_replies);
+               if (new_cnt + cnt >= virtqueue_get_vring_size(rx_vq) &&
+                   new_cnt < virtqueue_get_vring_size(rx_vq))
+                       queue_work(virtio_vsock_workqueue, &vsock->rx_work);
+       }
+
+       return 0;
+}
+
 static void virtio_vsock_rx_fill(struct virtio_vsock *vsock)
 {
        int buf_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
@@ -462,6 +503,7 @@ static struct virtio_transport virtio_transport = {
                .release                  = virtio_transport_release,
                .connect                  = virtio_transport_connect,
                .shutdown                 = virtio_transport_shutdown,
+               .cancel_pkt               = virtio_transport_cancel_pkt,
 
                .dgram_bind               = virtio_transport_dgram_bind,
                .dgram_dequeue            = virtio_transport_dgram_dequeue,
index 8d592a45b59786746d186e12d0c362d07c30bdac..af087b44ceea2311e53060e2442b4af2024bb037 100644 (file)
@@ -58,6 +58,7 @@ virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info,
        pkt->len                = len;
        pkt->hdr.len            = cpu_to_le32(len);
        pkt->reply              = info->reply;
+       pkt->vsk                = info->vsk;
 
        if (info->msg && len > 0) {
                pkt->buf = kmalloc(len, GFP_KERNEL);
@@ -180,6 +181,7 @@ static int virtio_transport_send_credit_update(struct vsock_sock *vsk,
        struct virtio_vsock_pkt_info info = {
                .op = VIRTIO_VSOCK_OP_CREDIT_UPDATE,
                .type = type,
+               .vsk = vsk,
        };
 
        return virtio_transport_send_pkt_info(vsk, &info);
@@ -519,6 +521,7 @@ int virtio_transport_connect(struct vsock_sock *vsk)
        struct virtio_vsock_pkt_info info = {
                .op = VIRTIO_VSOCK_OP_REQUEST,
                .type = VIRTIO_VSOCK_TYPE_STREAM,
+               .vsk = vsk,
        };
 
        return virtio_transport_send_pkt_info(vsk, &info);
@@ -534,6 +537,7 @@ int virtio_transport_shutdown(struct vsock_sock *vsk, int mode)
                          VIRTIO_VSOCK_SHUTDOWN_RCV : 0) |
                         (mode & SEND_SHUTDOWN ?
                          VIRTIO_VSOCK_SHUTDOWN_SEND : 0),
+               .vsk = vsk,
        };
 
        return virtio_transport_send_pkt_info(vsk, &info);
@@ -560,6 +564,7 @@ virtio_transport_stream_enqueue(struct vsock_sock *vsk,
                .type = VIRTIO_VSOCK_TYPE_STREAM,
                .msg = msg,
                .pkt_len = len,
+               .vsk = vsk,
        };
 
        return virtio_transport_send_pkt_info(vsk, &info);
@@ -581,6 +586,7 @@ static int virtio_transport_reset(struct vsock_sock *vsk,
                .op = VIRTIO_VSOCK_OP_RST,
                .type = VIRTIO_VSOCK_TYPE_STREAM,
                .reply = !!pkt,
+               .vsk = vsk,
        };
 
        /* Send RST only if the original pkt is not a RST pkt */
@@ -826,6 +832,7 @@ virtio_transport_send_response(struct vsock_sock *vsk,
                .remote_cid = le64_to_cpu(pkt->hdr.src_cid),
                .remote_port = le32_to_cpu(pkt->hdr.src_port),
                .reply = true,
+               .vsk = vsk,
        };
 
        return virtio_transport_send_pkt_info(vsk, &info);
index d7f8be4e321a32eba3a615aa69a860c212511625..2312dc2ffdb98b37b2909274c57eed68935267d7 100644 (file)
@@ -545,22 +545,18 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
 {
        int err;
 
-       rtnl_lock();
-
        if (!cb->args[0]) {
                err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
                                  genl_family_attrbuf(&nl80211_fam),
                                  nl80211_fam.maxattr, nl80211_policy);
                if (err)
-                       goto out_unlock;
+                       return err;
 
                *wdev = __cfg80211_wdev_from_attrs(
                                        sock_net(skb->sk),
                                        genl_family_attrbuf(&nl80211_fam));
-               if (IS_ERR(*wdev)) {
-                       err = PTR_ERR(*wdev);
-                       goto out_unlock;
-               }
+               if (IS_ERR(*wdev))
+                       return PTR_ERR(*wdev);
                *rdev = wiphy_to_rdev((*wdev)->wiphy);
                /* 0 is the first index - add 1 to parse only once */
                cb->args[0] = (*rdev)->wiphy_idx + 1;
@@ -570,10 +566,8 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
                struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
                struct wireless_dev *tmp;
 
-               if (!wiphy) {
-                       err = -ENODEV;
-                       goto out_unlock;
-               }
+               if (!wiphy)
+                       return -ENODEV;
                *rdev = wiphy_to_rdev(wiphy);
                *wdev = NULL;
 
@@ -584,21 +578,11 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
                        }
                }
 
-               if (!*wdev) {
-                       err = -ENODEV;
-                       goto out_unlock;
-               }
+               if (!*wdev)
+                       return -ENODEV;
        }
 
        return 0;
- out_unlock:
-       rtnl_unlock();
-       return err;
-}
-
-static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
-{
-       rtnl_unlock();
 }
 
 /* IE validation */
@@ -2608,17 +2592,17 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
        int filter_wiphy = -1;
        struct cfg80211_registered_device *rdev;
        struct wireless_dev *wdev;
+       int ret;
 
        rtnl_lock();
        if (!cb->args[2]) {
                struct nl80211_dump_wiphy_state state = {
                        .filter_wiphy = -1,
                };
-               int ret;
 
                ret = nl80211_dump_wiphy_parse(skb, cb, &state);
                if (ret)
-                       return ret;
+                       goto out_unlock;
 
                filter_wiphy = state.filter_wiphy;
 
@@ -2663,12 +2647,14 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
                wp_idx++;
        }
  out:
-       rtnl_unlock();
-
        cb->args[0] = wp_idx;
        cb->args[1] = if_idx;
 
-       return skb->len;
+       ret = skb->len;
+ out_unlock:
+       rtnl_unlock();
+
+       return ret;
 }
 
 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
@@ -4452,9 +4438,10 @@ static int nl80211_dump_station(struct sk_buff *skb,
        int sta_idx = cb->args[2];
        int err;
 
+       rtnl_lock();
        err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
        if (err)
-               return err;
+               goto out_err;
 
        if (!wdev->netdev) {
                err = -EINVAL;
@@ -4489,7 +4476,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
        cb->args[2] = sta_idx;
        err = skb->len;
  out_err:
-       nl80211_finish_wdev_dump(rdev);
+       rtnl_unlock();
 
        return err;
 }
@@ -5275,9 +5262,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
        int path_idx = cb->args[2];
        int err;
 
+       rtnl_lock();
        err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
        if (err)
-               return err;
+               goto out_err;
 
        if (!rdev->ops->dump_mpath) {
                err = -EOPNOTSUPP;
@@ -5310,7 +5298,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
        cb->args[2] = path_idx;
        err = skb->len;
  out_err:
-       nl80211_finish_wdev_dump(rdev);
+       rtnl_unlock();
        return err;
 }
 
@@ -5470,9 +5458,10 @@ static int nl80211_dump_mpp(struct sk_buff *skb,
        int path_idx = cb->args[2];
        int err;
 
+       rtnl_lock();
        err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
        if (err)
-               return err;
+               goto out_err;
 
        if (!rdev->ops->dump_mpp) {
                err = -EOPNOTSUPP;
@@ -5505,7 +5494,7 @@ static int nl80211_dump_mpp(struct sk_buff *skb,
        cb->args[2] = path_idx;
        err = skb->len;
  out_err:
-       nl80211_finish_wdev_dump(rdev);
+       rtnl_unlock();
        return err;
 }
 
@@ -7674,9 +7663,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
        int start = cb->args[2], idx = 0;
        int err;
 
+       rtnl_lock();
        err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
-       if (err)
+       if (err) {
+               rtnl_unlock();
                return err;
+       }
 
        wdev_lock(wdev);
        spin_lock_bh(&rdev->bss_lock);
@@ -7699,7 +7691,7 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
        wdev_unlock(wdev);
 
        cb->args[2] = idx;
-       nl80211_finish_wdev_dump(rdev);
+       rtnl_unlock();
 
        return skb->len;
 }
@@ -7784,9 +7776,10 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
        int res;
        bool radio_stats;
 
+       rtnl_lock();
        res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
        if (res)
-               return res;
+               goto out_err;
 
        /* prepare_wdev_dump parsed the attributes */
        radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
@@ -7827,7 +7820,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
        cb->args[2] = survey_idx;
        res = skb->len;
  out_err:
-       nl80211_finish_wdev_dump(rdev);
+       rtnl_unlock();
        return res;
 }
 
@@ -11508,17 +11501,13 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
        void *data = NULL;
        unsigned int data_len = 0;
 
-       rtnl_lock();
-
        if (cb->args[0]) {
                /* subtract the 1 again here */
                struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
                struct wireless_dev *tmp;
 
-               if (!wiphy) {
-                       err = -ENODEV;
-                       goto out_unlock;
-               }
+               if (!wiphy)
+                       return -ENODEV;
                *rdev = wiphy_to_rdev(wiphy);
                *wdev = NULL;
 
@@ -11538,23 +11527,19 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
        err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
                          attrbuf, nl80211_fam.maxattr, nl80211_policy);
        if (err)
-               goto out_unlock;
+               return err;
 
        if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
-           !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
-               err = -EINVAL;
-               goto out_unlock;
-       }
+           !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
+               return -EINVAL;
 
        *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
        if (IS_ERR(*wdev))
                *wdev = NULL;
 
        *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
-       if (IS_ERR(*rdev)) {
-               err = PTR_ERR(*rdev);
-               goto out_unlock;
-       }
+       if (IS_ERR(*rdev))
+               return PTR_ERR(*rdev);
 
        vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
        subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
@@ -11567,19 +11552,15 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
                if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
                        continue;
 
-               if (!vcmd->dumpit) {
-                       err = -EOPNOTSUPP;
-                       goto out_unlock;
-               }
+               if (!vcmd->dumpit)
+                       return -EOPNOTSUPP;
 
                vcmd_idx = i;
                break;
        }
 
-       if (vcmd_idx < 0) {
-               err = -EOPNOTSUPP;
-               goto out_unlock;
-       }
+       if (vcmd_idx < 0)
+               return -EOPNOTSUPP;
 
        if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
                data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
@@ -11596,9 +11577,6 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
 
        /* keep rtnl locked in successful case */
        return 0;
- out_unlock:
-       rtnl_unlock();
-       return err;
 }
 
 static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
@@ -11613,9 +11591,10 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
        int err;
        struct nlattr *vendor_data;
 
+       rtnl_lock();
        err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
        if (err)
-               return err;
+               goto out;
 
        vcmd_idx = cb->args[2];
        data = (void *)cb->args[3];
@@ -11624,15 +11603,21 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
 
        if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
                           WIPHY_VENDOR_CMD_NEED_NETDEV)) {
-               if (!wdev)
-                       return -EINVAL;
+               if (!wdev) {
+                       err = -EINVAL;
+                       goto out;
+               }
                if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
-                   !wdev->netdev)
-                       return -EINVAL;
+                   !wdev->netdev) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
-                       if (!wdev_running(wdev))
-                               return -ENETDOWN;
+                       if (!wdev_running(wdev)) {
+                               err = -ENETDOWN;
+                               goto out;
+                       }
                }
        }
 
index 9705c279494b248b759155d671cfbc778fa25058..40a8aa39220d67d349c36f80ab1628d0e90c3fa7 100644 (file)
@@ -412,7 +412,14 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
        up = nla_data(rp);
        ulen = xfrm_replay_state_esn_len(up);
 
-       if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
+       /* Check the overall length and the internal bitmap length to avoid
+        * potential overflow. */
+       if (nla_len(rp) < ulen ||
+           xfrm_replay_state_esn_len(replay_esn) != ulen ||
+           replay_esn->bmp_len != up->bmp_len)
+               return -EINVAL;
+
+       if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
                return -EINVAL;
 
        return 0;
index d6ca649cb0e96d4d91a4980048912544b8183e06..afe3fd3af1e40616857b3e6c425be632c1fa2667 100644 (file)
@@ -148,6 +148,10 @@ cc-fullversion = $(shell $(CONFIG_SHELL) \
 # Usage:  EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
 cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4))
 
+# cc-if-fullversion
+# Usage:  EXTRA_CFLAGS += $(call cc-if-fullversion, -lt, 040502, -O1)
+cc-if-fullversion = $(shell [ $(cc-fullversion) $(1) $(2) ] && echo $(3) || echo $(4))
+
 # cc-ldoption
 # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
 cc-ldoption = $(call try-run,\
index 4c935202ce23be4fc57c9d79c3fe0a160d9b8a89..f3b1d7f50b81156d4c29c5c0958a884e9292bbae 100644 (file)
@@ -1832,6 +1832,7 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
             info->output_pool != client->pool->size)) {
                if (snd_seq_write_pool_allocated(client)) {
                        /* remove all existing cells */
+                       snd_seq_pool_mark_closing(client->pool);
                        snd_seq_queue_client_leave_cells(client->number);
                        snd_seq_pool_done(client->pool);
                }
index 448efd4e980edf97138b43b6263a9909d07c076a..01c4cfe30c9feffd4fa24c7223e58d9a604cb026 100644 (file)
@@ -72,6 +72,9 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
                return;
        *fifo = NULL;
 
+       if (f->pool)
+               snd_seq_pool_mark_closing(f->pool);
+
        snd_seq_fifo_clear(f);
 
        /* wake up clients if any */
@@ -264,6 +267,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
        /* NOTE: overflow flag is not cleared */
        spin_unlock_irqrestore(&f->lock, flags);
 
+       /* close the old pool and wait until all users are gone */
+       snd_seq_pool_mark_closing(oldpool);
+       snd_use_lock_sync(&f->use_lock);
+
        /* release cells in old pool */
        for (cell = oldhead; cell; cell = next) {
                next = cell->next;
index 1a1acf3ddda4c9aeb022548b9438498e0f036762..d4c61ec9be13d7389addd27bc70acf58bda2eecc 100644 (file)
@@ -415,6 +415,18 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
        return 0;
 }
 
+/* refuse the further insertion to the pool */
+void snd_seq_pool_mark_closing(struct snd_seq_pool *pool)
+{
+       unsigned long flags;
+
+       if (snd_BUG_ON(!pool))
+               return;
+       spin_lock_irqsave(&pool->lock, flags);
+       pool->closing = 1;
+       spin_unlock_irqrestore(&pool->lock, flags);
+}
+
 /* remove events */
 int snd_seq_pool_done(struct snd_seq_pool *pool)
 {
@@ -425,10 +437,6 @@ int snd_seq_pool_done(struct snd_seq_pool *pool)
                return -EINVAL;
 
        /* wait for closing all threads */
-       spin_lock_irqsave(&pool->lock, flags);
-       pool->closing = 1;
-       spin_unlock_irqrestore(&pool->lock, flags);
-
        if (waitqueue_active(&pool->output_sleep))
                wake_up(&pool->output_sleep);
 
@@ -485,6 +493,7 @@ int snd_seq_pool_delete(struct snd_seq_pool **ppool)
        *ppool = NULL;
        if (pool == NULL)
                return 0;
+       snd_seq_pool_mark_closing(pool);
        snd_seq_pool_done(pool);
        kfree(pool);
        return 0;
index 4a2ec779b8a701b1aba2402e9de583878f7a39ca..32f959c17786d9ac8c071ba0e6fd070dc06da78b 100644 (file)
@@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(struct snd_seq_pool *pool)
 int snd_seq_pool_init(struct snd_seq_pool *pool);
 
 /* done pool - free events */
+void snd_seq_pool_mark_closing(struct snd_seq_pool *pool);
 int snd_seq_pool_done(struct snd_seq_pool *pool);
 
 /* create pool */
index ab4cdab5cfa57abf3db2a8da806d0bf7031fed67..79edd88d5cd08398afb86c63b3d32b025162164e 100644 (file)
@@ -1905,7 +1905,7 @@ static int hw_card_start(struct hw *hw)
                return err;
 
        /* Set DMA transfer mask */
-       if (dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
+       if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
                dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
        } else {
                dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
index c15c51bea26d0afdcc6d8c806993754eaaa2e031..69266b8ea2ad7b498097c4bc231fbad6e55ff37e 100644 (file)
@@ -261,6 +261,7 @@ enum {
        CXT_FIXUP_HP_530,
        CXT_FIXUP_CAP_MIX_AMP_5047,
        CXT_FIXUP_MUTE_LED_EAPD,
+       CXT_FIXUP_HP_DOCK,
        CXT_FIXUP_HP_SPECTRE,
        CXT_FIXUP_HP_GATE_MIC,
 };
@@ -778,6 +779,14 @@ static const struct hda_fixup cxt_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cxt_fixup_mute_led_eapd,
        },
+       [CXT_FIXUP_HP_DOCK] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x16, 0x21011020 }, /* line-out */
+                       { 0x18, 0x2181103f }, /* line-in */
+                       { }
+               }
+       },
        [CXT_FIXUP_HP_SPECTRE] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -839,6 +848,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
        SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
+       SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
        SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
        SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
        SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
@@ -871,6 +881,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
        { .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" },
        { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" },
        { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" },
+       { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" },
        {}
 };
 
index 4e112221d825462ef7e1ae38c092e40e58667f38..299835d1fbaadb5f312ee86502deacd4f7643603 100644 (file)
@@ -4847,6 +4847,7 @@ enum {
        ALC286_FIXUP_HP_GPIO_LED,
        ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
        ALC280_FIXUP_HP_DOCK_PINS,
+       ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
        ALC280_FIXUP_HP_9480M,
        ALC288_FIXUP_DELL_HEADSET_MODE,
        ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
@@ -4857,6 +4858,7 @@ enum {
        ALC292_FIXUP_DISABLE_AAMIX,
        ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
        ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
        ALC275_FIXUP_DELL_XPS,
        ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
        ALC293_FIXUP_LENOVO_SPK_NOISE,
@@ -5388,6 +5390,16 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC280_FIXUP_HP_GPIO4
        },
+       [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x1b, 0x21011020 }, /* line-out */
+                       { 0x18, 0x2181103f }, /* line-in */
+                       { },
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
+       },
        [ALC280_FIXUP_HP_9480M] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc280_fixup_hp_9480m,
@@ -5459,6 +5471,15 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MODE
        },
+       [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE
+       },
        [ALC275_FIXUP_DELL_XPS] = {
                .type = HDA_FIXUP_VERBS,
                .v.verbs = (const struct hda_verb[]) {
@@ -5531,7 +5552,7 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc298_fixup_speaker_volume,
                .chained = true,
-               .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+               .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
        },
        [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
                .type = HDA_FIXUP_PINS,
@@ -5647,7 +5668,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
        SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
        SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
-       SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
+       SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
        SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -5816,6 +5837,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
        {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
        {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
+       {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
        {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
        {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
        {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
@@ -6090,6 +6112,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
                ALC295_STANDARD_PINS,
                {0x17, 0x21014040},
                {0x18, 0x21a19050}),
+       SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+               ALC295_STANDARD_PINS),
        SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC298_STANDARD_PINS,
                {0x17, 0x90170110}),
index 89ac5f5a93eb31f510d8ab189badc781fd319e6f..7ae46c2647d453bcad1176b6877fcbbae110416b 100644 (file)
@@ -349,7 +349,7 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
 }
 
 #define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
-#define CLASSD_ACLK_RATE_12M288_MPY_8  (12228 * 1000 * 8)
+#define CLASSD_ACLK_RATE_12M288_MPY_8  (12288 * 1000 * 8)
 
 static struct {
        int rate;
index 78fca8acd3ec0a2209876bf5b20a1363a03c6336..fd272a40485b077039c68f786671218a7f4204e2 100644 (file)
@@ -1534,21 +1534,20 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
                        pin->mst_capable = false;
                        /* if not MST, default is port[0] */
                        hport = &pin->ports[0];
-                       goto out;
                } else {
                        for (i = 0; i < pin->num_ports; i++) {
                                pin->mst_capable = true;
                                if (pin->ports[i].id == pipe) {
                                        hport = &pin->ports[i];
-                                       goto out;
+                                       break;
                                }
                        }
                }
+
+               if (hport)
+                       hdac_hdmi_present_sense(pin, hport);
        }
 
-out:
-       if (pin && hport)
-               hdac_hdmi_present_sense(pin, hport);
 }
 
 static struct i915_audio_component_audio_ops aops = {
@@ -1998,7 +1997,7 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
        struct hdac_hdmi_pin *pin, *pin_next;
        struct hdac_hdmi_cvt *cvt, *cvt_next;
        struct hdac_hdmi_pcm *pcm, *pcm_next;
-       struct hdac_hdmi_port *port;
+       struct hdac_hdmi_port *port, *port_next;
        int i;
 
        snd_soc_unregister_codec(&edev->hdac.dev);
@@ -2008,8 +2007,9 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
                if (list_empty(&pcm->port_list))
                        continue;
 
-               list_for_each_entry(port, &pcm->port_list, head)
-                       port = NULL;
+               list_for_each_entry_safe(port, port_next,
+                                       &pcm->port_list, head)
+                       list_del(&port->head);
 
                list_del(&pcm->head);
                kfree(pcm);
index 324461e985b3918211ad29052a5142a6560e26af..476135ec57268cf6863e9792d5fb027c6383e190 100644 (file)
@@ -1241,7 +1241,7 @@ static irqreturn_t rt5665_irq(int irq, void *data)
 static void rt5665_jd_check_handler(struct work_struct *work)
 {
        struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
-               calibrate_work.work);
+               jd_check_work.work);
 
        if (snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010) {
                /* jack out */
@@ -2252,7 +2252,7 @@ static const char * const rt5665_if2_1_adc_in_src[] = {
 
 static const SOC_ENUM_SINGLE_DECL(
        rt5665_if2_1_adc_in_enum, RT5665_DIG_INF2_DATA,
-       RT5665_IF3_ADC_IN_SFT, rt5665_if2_1_adc_in_src);
+       RT5665_IF2_1_ADC_IN_SFT, rt5665_if2_1_adc_in_src);
 
 static const struct snd_kcontrol_new rt5665_if2_1_adc_in_mux =
        SOC_DAPM_ENUM("IF2_1 ADC IN Source", rt5665_if2_1_adc_in_enum);
@@ -3178,6 +3178,9 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
        {"DAC Mono Right Filter", NULL, "DAC Mono R ASRC", is_using_asrc},
        {"DAC Stereo1 Filter", NULL, "DAC STO1 ASRC", is_using_asrc},
        {"DAC Stereo2 Filter", NULL, "DAC STO2 ASRC", is_using_asrc},
+       {"I2S1 ASRC", NULL, "CLKDET"},
+       {"I2S2 ASRC", NULL, "CLKDET"},
+       {"I2S3 ASRC", NULL, "CLKDET"},
 
        /*Vref*/
        {"Mic Det Power", NULL, "Vref2"},
@@ -3912,6 +3915,7 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
        {"Mono MIX", "MONOVOL Switch", "MONOVOL"},
        {"Mono Amp", NULL, "Mono MIX"},
        {"Mono Amp", NULL, "Vref2"},
+       {"Mono Amp", NULL, "Vref3"},
        {"Mono Amp", NULL, "CLKDET SYS"},
        {"Mono Amp", NULL, "CLKDET MONO"},
        {"Mono Playback", "Switch", "Mono Amp"},
@@ -4798,7 +4802,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
        /* Enhance performance*/
        regmap_update_bits(rt5665->regmap, RT5665_PWR_ANLG_1,
                RT5665_HP_DRIVER_MASK | RT5665_LDO1_DVO_MASK,
-               RT5665_HP_DRIVER_5X | RT5665_LDO1_DVO_09);
+               RT5665_HP_DRIVER_5X | RT5665_LDO1_DVO_12);
 
        INIT_DELAYED_WORK(&rt5665->jack_detect_work,
                                rt5665_jack_detect_handler);
index 12f7080a0d3c3f1eeab2e3083020cffe98599891..a30f5e6d062882724230e2bf2f2d1157ee823a9b 100644 (file)
 #define RT5665_HP_DRIVER_MASK                  (0x3 << 2)
 #define RT5665_HP_DRIVER_1X                    (0x0 << 2)
 #define RT5665_HP_DRIVER_3X                    (0x1 << 2)
-#define RT5665_HP_DRIVER_5X                    (0x2 << 2)
+#define RT5665_HP_DRIVER_5X                    (0x3 << 2)
 #define RT5665_LDO1_DVO_MASK                   (0x3)
 #define RT5665_LDO1_DVO_09                     (0x0)
 #define RT5665_LDO1_DVO_10                     (0x1)
index d151224ffcca411a5685b2076c43748fd2134790..bbdb72f73df19ddf954daab19d3deb222208dc7c 100644 (file)
@@ -899,7 +899,10 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
 
        mutex_lock(&ctl->dsp->pwr_lock);
 
-       memcpy(ctl->cache, p, ctl->len);
+       if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
+               ret = -EPERM;
+       else
+               memcpy(ctl->cache, p, ctl->len);
 
        ctl->set = 1;
        if (ctl->enabled && ctl->dsp->running)
@@ -926,6 +929,8 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
                ctl->set = 1;
                if (ctl->enabled && ctl->dsp->running)
                        ret = wm_coeff_write_control(ctl, ctl->cache, size);
+               else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
+                       ret = -EPERM;
        }
 
        mutex_unlock(&ctl->dsp->pwr_lock);
@@ -947,7 +952,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl,
 
        mutex_lock(&ctl->dsp->pwr_lock);
 
-       if (ctl->enabled)
+       if (ctl->enabled && ctl->dsp->running)
                ret = wm_coeff_write_acked_control(ctl, val);
        else
                ret = -EPERM;
index 4924575d2e95d3d49c0bdad57bc8691c472da5b2..343b291fc3725f46b4d5270b65d5100ca083ef61 100644 (file)
@@ -115,6 +115,7 @@ int asoc_simple_card_parse_clk(struct device *dev,
        clk = devm_get_clk_from_child(dev, node, NULL);
        if (!IS_ERR(clk)) {
                simple_dai->sysclk = clk_get_rate(clk);
+               simple_dai->clk = clk;
        } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
                simple_dai->sysclk = val;
        } else {
index ed58b5b3555a869ff91772689b761369873d6c89..2dbfb1b24ef4a629ecdac8004630fc66aeb529fc 100644 (file)
@@ -512,7 +512,7 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
                        if (bc->set_params != SKL_PARAM_INIT)
                                continue;
 
-                       mconfig->formats_config.caps = (u32 *)&bc->params;
+                       mconfig->formats_config.caps = (u32 *)bc->params;
                        mconfig->formats_config.caps_size = bc->size;
 
                        break;
index 05cf809cf9e1467dca19e4f02433f6e6b34532a3..d7013bde6f45fc7ed82db8ea0e92ae81226705f1 100644 (file)
@@ -13,7 +13,7 @@ config SND_SOC_MT2701
 
 config SND_SOC_MT2701_CS42448
        tristate "ASoc Audio driver for MT2701 with CS42448 codec"
-       depends on SND_SOC_MT2701
+       depends on SND_SOC_MT2701 && I2C
        select SND_SOC_CS42XX8_I2C
        select SND_SOC_BT_SCO
        help
index abb5eaac854a9b9c47027e278cd5204c18aceace..7d92a24b7cfa558afbb8331401c974c59d5f1ae5 100644 (file)
@@ -31,23 +31,24 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
        struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
        struct device *dev = rsnd_priv_to_dev(priv);
        u32 data;
+       u32 path[] = {
+               [1] = 1 << 0,
+               [5] = 1 << 8,
+               [6] = 1 << 12,
+               [9] = 1 << 15,
+       };
 
        if (!mix && !dvc)
                return 0;
 
+       if (ARRAY_SIZE(path) < rsnd_mod_id(mod) + 1)
+               return -ENXIO;
+
        if (mix) {
                struct rsnd_dai *rdai;
                struct rsnd_mod *src;
                struct rsnd_dai_stream *tio;
                int i;
-               u32 path[] = {
-                       [0] = 0,
-                       [1] = 1 << 0,
-                       [2] = 0,
-                       [3] = 0,
-                       [4] = 0,
-                       [5] = 1 << 8
-               };
 
                /*
                 * it is assuming that integrater is well understanding about
@@ -70,16 +71,19 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
        } else {
                struct rsnd_mod *src = rsnd_io_to_mod_src(io);
 
-               u32 path[] = {
-                       [0] = 0x30000,
-                       [1] = 0x30001,
-                       [2] = 0x40000,
-                       [3] = 0x10000,
-                       [4] = 0x20000,
-                       [5] = 0x40100
+               u8 cmd_case[] = {
+                       [0] = 0x3,
+                       [1] = 0x3,
+                       [2] = 0x4,
+                       [3] = 0x1,
+                       [4] = 0x2,
+                       [5] = 0x4,
+                       [6] = 0x1,
+                       [9] = 0x2,
                };
 
-               data = path[rsnd_mod_id(src)];
+               data = path[rsnd_mod_id(src)] |
+                       cmd_case[rsnd_mod_id(src)] << 16;
        }
 
        dev_dbg(dev, "ctu/mix path = 0x%08x", data);
index 1f405c83386759a1bfc7dbfd3ff51dba2ee33614..241cb3b08a0755dc93c06034cca814e9c509c090 100644 (file)
@@ -454,6 +454,20 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
        return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
 }
 
+static void rsnd_dmapp_bset(struct rsnd_dma *dma, u32 data, u32 mask, u32 reg)
+{
+       struct rsnd_mod *mod = rsnd_mod_get(dma);
+       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+       struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
+       void __iomem *addr = rsnd_dmapp_addr(dmac, dma, reg);
+       u32 val = ioread32(addr);
+
+       val &= ~mask;
+       val |= (data & mask);
+
+       iowrite32(val, addr);
+}
+
 static int rsnd_dmapp_stop(struct rsnd_mod *mod,
                           struct rsnd_dai_stream *io,
                           struct rsnd_priv *priv)
@@ -461,10 +475,10 @@ static int rsnd_dmapp_stop(struct rsnd_mod *mod,
        struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
        int i;
 
-       rsnd_dmapp_write(dma, 0, PDMACHCR);
+       rsnd_dmapp_bset(dma, 0,  PDMACHCR_DE, PDMACHCR);
 
        for (i = 0; i < 1024; i++) {
-               if (0 == rsnd_dmapp_read(dma, PDMACHCR))
+               if (0 == (rsnd_dmapp_read(dma, PDMACHCR) & PDMACHCR_DE))
                        return 0;
                udelay(1);
        }
index 4e817c8a18c0bbe899374028ae56ef0754042d59..14fafdaf1395f9737191df18599ee58fc4f858fd 100644 (file)
@@ -64,7 +64,11 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
        mask1 = (1 << 4) | (1 << 20);   /* mask sync bit */
        mask2 = (1 << 4);               /* mask sync bit */
        val1  = val2  = 0;
-       if (rsnd_ssi_is_pin_sharing(io)) {
+       if (id == 8) {
+               /*
+                * SSI8 pin is sharing with SSI7, nothing to do.
+                */
+       } else if (rsnd_ssi_is_pin_sharing(io)) {
                int shift = -1;
 
                switch (id) {
index 6dca408faae334d223494c33e14d503518b497d7..2722bb0c557310d97816cfa7857b24d7c9bd4948 100644 (file)
@@ -3326,7 +3326,10 @@ static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_platform *platform = rtd->platform;
 
-       return platform->driver->pcm_new(rtd);
+       if (platform->driver->pcm_new)
+               return platform->driver->pcm_new(rtd);
+       else
+               return 0;
 }
 
 static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
@@ -3334,7 +3337,8 @@ static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
        struct snd_soc_pcm_runtime *rtd = pcm->private_data;
        struct snd_soc_platform *platform = rtd->platform;
 
-       platform->driver->pcm_free(pcm);
+       if (platform->driver->pcm_free)
+               platform->driver->pcm_free(pcm);
 }
 
 /**
index 5992c6ab3833ef60c15e21656fd7f5731b43c2d3..93a8df6ed880ea8cc32b62f94ab0b44befbe06ef 100644 (file)
@@ -349,6 +349,8 @@ static int uni_reader_startup(struct snd_pcm_substream *substream,
        struct uniperif *reader = priv->dai_data.uni;
        int ret;
 
+       reader->substream = substream;
+
        if (!UNIPERIF_TYPE_IS_TDM(reader))
                return 0;
 
@@ -378,6 +380,7 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream,
                /* Stop the reader */
                uni_reader_stop(reader);
        }
+       reader->substream = NULL;
 }
 
 static const struct snd_soc_dai_ops uni_reader_dai_ops = {
index b92bdc8361af3a118b0d944585e3076ae1e8c947..7527ba29a5a0ea6eb9c6498d8d0293ad4aead18a 100644 (file)
@@ -259,25 +259,20 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = {
-       SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC,
-                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0),
-       SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC,
-                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
-       SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
-                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
-       SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
-                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
-};
-
-static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
-       SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
+static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
+       SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
+                       SUN8I_DAC_MXR_SRC,
+                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L,
                        SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
-       SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC,
+       SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
+                       SUN8I_DAC_MXR_SRC,
+                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L,
                        SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
-       SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC,
+       SOC_DAPM_DOUBLE("AIF2 Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
+                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL,
                        SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
-       SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC,
+       SOC_DAPM_DOUBLE("ADC Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
+                       SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL,
                        SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
 };
 
@@ -286,19 +281,21 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
                            0, NULL, 0),
 
-       /* Analog DAC */
-       SND_SOC_DAPM_DAC("Digital Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
-                        SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
-       SND_SOC_DAPM_DAC("Digital Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
-                        SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
+       /* Analog DAC AIF */
+       SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left", "Playback", 0,
+                           SUN8I_AIF1_DACDAT_CTRL,
+                           SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
+       SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Right", "Playback", 0,
+                           SUN8I_AIF1_DACDAT_CTRL,
+                           SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
 
        /* DAC Mixers */
-       SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0,
-                          sun8i_output_left_mixer_controls,
-                          ARRAY_SIZE(sun8i_output_left_mixer_controls)),
-       SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0,
-                          sun8i_output_right_mixer_controls,
-                          ARRAY_SIZE(sun8i_output_right_mixer_controls)),
+       SND_SOC_DAPM_MIXER("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
+                          sun8i_dac_mixer_controls,
+                          ARRAY_SIZE(sun8i_dac_mixer_controls)),
+       SND_SOC_DAPM_MIXER("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
+                          sun8i_dac_mixer_controls,
+                          ARRAY_SIZE(sun8i_dac_mixer_controls)),
 
        /* Clocks */
        SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
@@ -321,8 +318,6 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
                            SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
        SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
                            SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
-
-       SND_SOC_DAPM_OUTPUT("HP"),
 };
 
 static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
@@ -338,16 +333,14 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
        { "DAC", NULL, "MODCLK DAC" },
 
        /* DAC Routes */
-       { "Digital Left DAC", NULL, "DAC" },
-       { "Digital Right DAC", NULL, "DAC" },
+       { "AIF1 Slot 0 Right", NULL, "DAC" },
+       { "AIF1 Slot 0 Left", NULL, "DAC" },
 
        /* DAC Mixer Routes */
-       { "Left DAC Mixer", "LSlot 0", "Digital Left DAC"},
-       { "Right DAC Mixer", "RSlot 0", "Digital Right DAC"},
-
-       /* End of route : HP out */
-       { "HP", NULL, "Left DAC Mixer" },
-       { "HP", NULL, "Right DAC Mixer" },
+       { "Left Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
+         "AIF1 Slot 0 Left"},
+       { "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
+         "AIF1 Slot 0 Right"},
 };
 
 static struct snd_soc_dai_ops sun8i_codec_dai_ops = {
index 84c8f8fc597cd6046d17ee27839024b98329e33d..8adf4d1bd46e71237e6827f0eda8fc89e7b40ea1 100644 (file)
@@ -1,6 +1,7 @@
 menuconfig SND_X86
-       tristate "X86 sound devices"
+       bool "X86 sound devices"
        depends on X86
+       default y
        ---help---
          X86 sound devices that don't fall under SoC or PCI categories
 
index 67531f47781b4069a33557f2f5a832b3aa57492a..6a1ad58cb66f4ae6faaf4837e29c5f8b487f000c 100644 (file)
@@ -1,22 +1,23 @@
 LIBDIR := ../../../lib
-BPFOBJ := $(LIBDIR)/bpf/bpf.o
+BPFDIR := $(LIBDIR)/bpf
 
-CFLAGS += -Wall -O2 -lcap -I../../../include/uapi -I$(LIBDIR) $(BPFOBJ)
+CFLAGS += -Wall -O2 -I../../../include/uapi -I$(LIBDIR)
+LDLIBS += -lcap
 
 TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map
 
 TEST_PROGS := test_kmod.sh
 
-all: $(TEST_GEN_PROGS)
+include ../lib.mk
+
+BPFOBJ := $(OUTPUT)/bpf.o
+
+$(TEST_GEN_PROGS): $(BPFOBJ)
 
-.PHONY: all clean force
+.PHONY: force
 
 # force a rebuild of BPFOBJ when its dependencies are updated
 force:
 
 $(BPFOBJ): force
-       $(MAKE) -C $(dir $(BPFOBJ))
-
-$(test_objs): $(BPFOBJ)
-
-include ../lib.mk
+       $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/
index cada17ac00b8e6b5af37554ea8489be6ffc873a2..a0aa2009b0e0a81e65672eb795039a2172484c55 100644 (file)
@@ -80,8 +80,9 @@ static void test_hashmap(int task, void *data)
        assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
        key = 2;
        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
-       key = 1;
-       assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
+       key = 3;
+       assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
+              errno == E2BIG);
 
        /* Check that key = 0 doesn't exist. */
        key = 0;
@@ -110,6 +111,24 @@ static void test_hashmap(int task, void *data)
        close(fd);
 }
 
+static void test_hashmap_sizes(int task, void *data)
+{
+       int fd, i, j;
+
+       for (i = 1; i <= 512; i <<= 1)
+               for (j = 1; j <= 1 << 18; j <<= 1) {
+                       fd = bpf_create_map(BPF_MAP_TYPE_HASH, i, j,
+                                           2, map_flags);
+                       if (fd < 0) {
+                               printf("Failed to create hashmap key=%d value=%d '%s'\n",
+                                      i, j, strerror(errno));
+                               exit(1);
+                       }
+                       close(fd);
+                       usleep(10); /* give kernel time to destroy */
+               }
+}
+
 static void test_hashmap_percpu(int task, void *data)
 {
        unsigned int nr_cpus = bpf_num_possible_cpus();
@@ -317,7 +336,10 @@ static void test_arraymap_percpu(int task, void *data)
 static void test_arraymap_percpu_many_keys(void)
 {
        unsigned int nr_cpus = bpf_num_possible_cpus();
-       unsigned int nr_keys = 20000;
+       /* nr_keys is not too large otherwise the test stresses percpu
+        * allocator more than anything else
+        */
+       unsigned int nr_keys = 2000;
        long values[nr_cpus];
        int key, fd, i;
 
@@ -419,6 +441,7 @@ static void test_map_stress(void)
 {
        run_parallel(100, test_hashmap, NULL);
        run_parallel(100, test_hashmap_percpu, NULL);
+       run_parallel(100, test_hashmap_sizes, NULL);
 
        run_parallel(100, test_arraymap, NULL);
        run_parallel(100, test_arraymap_percpu, NULL);
index a29786dd95221017b141a060b031c5c899dac2e5..4d28a9ddbee01077fea01beeeae5523917822da9 100644 (file)
@@ -870,7 +870,8 @@ kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
                        continue;
 
                kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
-               kvm->buses[bus_idx]->ioeventfd_count--;
+               if (kvm->buses[bus_idx])
+                       kvm->buses[bus_idx]->ioeventfd_count--;
                ioeventfd_release(p);
                ret = 0;
                break;
index a17d78759727f352991a97b4c2bed21266657760..88257b311cb579b5b720330456f99fbec97a58ac 100644 (file)
@@ -727,8 +727,11 @@ static void kvm_destroy_vm(struct kvm *kvm)
        list_del(&kvm->vm_list);
        spin_unlock(&kvm_lock);
        kvm_free_irq_routing(kvm);
-       for (i = 0; i < KVM_NR_BUSES; i++)
-               kvm_io_bus_destroy(kvm->buses[i]);
+       for (i = 0; i < KVM_NR_BUSES; i++) {
+               if (kvm->buses[i])
+                       kvm_io_bus_destroy(kvm->buses[i]);
+               kvm->buses[i] = NULL;
+       }
        kvm_coalesced_mmio_free(kvm);
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
        mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
@@ -1062,7 +1065,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
         * changes) is disallowed above, so any other attribute changes getting
         * here can be skipped.
         */
-       if ((change == KVM_MR_CREATE) || (change == KVM_MR_MOVE)) {
+       if (as_id == 0 && (change == KVM_MR_CREATE || change == KVM_MR_MOVE)) {
                r = kvm_iommu_map_pages(kvm, &new);
                return r;
        }
@@ -3474,6 +3477,8 @@ int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
        };
 
        bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu);
+       if (!bus)
+               return -ENOMEM;
        r = __kvm_io_bus_write(vcpu, bus, &range, val);
        return r < 0 ? r : 0;
 }
@@ -3491,6 +3496,8 @@ int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx,
        };
 
        bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu);
+       if (!bus)
+               return -ENOMEM;
 
        /* First try the device referenced by cookie. */
        if ((cookie >= 0) && (cookie < bus->dev_count) &&
@@ -3541,6 +3548,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
        };
 
        bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu);
+       if (!bus)
+               return -ENOMEM;
        r = __kvm_io_bus_read(vcpu, bus, &range, val);
        return r < 0 ? r : 0;
 }
@@ -3553,6 +3562,9 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
        struct kvm_io_bus *new_bus, *bus;
 
        bus = kvm->buses[bus_idx];
+       if (!bus)
+               return -ENOMEM;
+
        /* exclude ioeventfd which is limited by maximum fd */
        if (bus->dev_count - bus->ioeventfd_count > NR_IOBUS_DEVS - 1)
                return -ENOSPC;
@@ -3572,37 +3584,41 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
 }
 
 /* Caller must hold slots_lock. */
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
-                             struct kvm_io_device *dev)
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+                              struct kvm_io_device *dev)
 {
-       int i, r;
+       int i;
        struct kvm_io_bus *new_bus, *bus;
 
        bus = kvm->buses[bus_idx];
-       r = -ENOENT;
+       if (!bus)
+               return;
+
        for (i = 0; i < bus->dev_count; i++)
                if (bus->range[i].dev == dev) {
-                       r = 0;
                        break;
                }
 
-       if (r)
-               return r;
+       if (i == bus->dev_count)
+               return;
 
        new_bus = kmalloc(sizeof(*bus) + ((bus->dev_count - 1) *
                          sizeof(struct kvm_io_range)), GFP_KERNEL);
-       if (!new_bus)
-               return -ENOMEM;
+       if (!new_bus)  {
+               pr_err("kvm: failed to shrink bus, removing it completely\n");
+               goto broken;
+       }
 
        memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range));
        new_bus->dev_count--;
        memcpy(new_bus->range + i, bus->range + i + 1,
               (new_bus->dev_count - i) * sizeof(struct kvm_io_range));
 
+broken:
        rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
        synchronize_srcu_expedited(&kvm->srcu);
        kfree(bus);
-       return r;
+       return;
 }
 
 struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
@@ -3615,6 +3631,8 @@ struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
        srcu_idx = srcu_read_lock(&kvm->srcu);
 
        bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
+       if (!bus)
+               goto out_unlock;
 
        dev_idx = kvm_io_bus_get_first_dev(bus, addr, 1);
        if (dev_idx < 0)