Merge tag 'for-4.12/dm-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Jun 2017 21:23:02 +0000 (14:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Jun 2017 21:23:02 +0000 (14:23 -0700)
Pull device mapper fixes from Mike Snitzer:

 - dm thinp fix for crash that will occur when metadata device failure
   races with discard passdown to the underlying data device.

 - dm raid fix to not access the superblock's >= 1.9.0 'sectors' member
   unconditionally.

* tag 'for-4.12/dm-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm thin: do not queue freed thin mapping for next stage processing
  dm raid: fix oops on upgrading to extended superblock format

530 files changed:
Documentation/admin-guide/kernel-parameters.txt
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
Documentation/devicetree/bindings/mfd/stm32-timers.txt
Documentation/devicetree/bindings/net/dsa/b53.txt
Documentation/devicetree/bindings/net/smsc911x.txt
Documentation/networking/scaling.txt
MAINTAINERS
Makefile
arch/arc/include/asm/processor.h
arch/arc/mm/mmap.c
arch/arm/Kconfig
arch/arm/boot/compressed/efi-header.S
arch/arm/boot/dts/am335x-sl50.dts
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/kernel/setup.c
arch/arm/mm/mmap.c
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi [deleted symlink]
arch/arm64/kernel/vdso.c
arch/arm64/kernel/vdso/gettimeofday.S
arch/arm64/net/bpf_jit_comp.c
arch/blackfin/include/asm/processor.h
arch/c6x/include/asm/processor.h
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v32/kernel/process.c
arch/cris/include/asm/processor.h
arch/frv/include/asm/processor.h
arch/frv/kernel/process.c
arch/frv/mm/elf-fdpic.c
arch/h8300/include/asm/processor.h
arch/h8300/kernel/process.c
arch/hexagon/include/asm/processor.h
arch/hexagon/kernel/process.c
arch/ia64/include/asm/processor.h
arch/m32r/include/asm/processor.h
arch/m32r/kernel/process.c
arch/m68k/include/asm/processor.h
arch/m68k/kernel/process.c
arch/microblaze/include/asm/processor.h
arch/microblaze/kernel/process.c
arch/mips/boot/Makefile
arch/mips/include/asm/highmem.h
arch/mips/include/asm/kprobes.h
arch/mips/include/asm/pgtable-32.h
arch/mips/kernel/branch.c
arch/mips/kernel/ftrace.c
arch/mips/kernel/perf_event_mipsxx.c
arch/mips/kvm/tlb.c
arch/mips/mm/mmap.c
arch/mips/mm/pgtable-32.c
arch/mn10300/include/asm/processor.h
arch/mn10300/kernel/process.c
arch/nios2/include/asm/processor.h
arch/openrisc/include/asm/processor.h
arch/openrisc/kernel/process.c
arch/parisc/include/asm/processor.h
arch/parisc/kernel/process.c
arch/parisc/kernel/sys_parisc.c
arch/powerpc/include/asm/bug.h
arch/powerpc/include/asm/kprobes.h
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/xive.h
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/trace/ftrace_64_mprofile.S
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_interrupts.S
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_xive_template.c
arch/powerpc/mm/hugetlbpage-radix.c
arch/powerpc/mm/mmap.c
arch/powerpc/mm/slice.c
arch/powerpc/perf/perf_regs.c
arch/powerpc/platforms/powernv/npu-dma.c
arch/powerpc/sysdev/xive/common.c
arch/s390/configs/default_defconfig
arch/s390/configs/gcov_defconfig
arch/s390/configs/performance_defconfig
arch/s390/configs/zfcpdump_defconfig
arch/s390/defconfig
arch/s390/include/asm/processor.h
arch/s390/kernel/entry.S
arch/s390/kernel/ipl.c
arch/s390/kernel/process.c
arch/s390/kvm/gaccess.c
arch/s390/mm/mmap.c
arch/score/include/asm/processor.h
arch/score/kernel/process.c
arch/sh/mm/mmap.c
arch/sparc/include/asm/processor_32.h
arch/sparc/include/asm/processor_64.h
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/mm/hugetlbpage.c
arch/tile/include/asm/processor.h
arch/tile/mm/hugetlbpage.c
arch/um/include/asm/processor-generic.h
arch/um/kernel/um_arch.c
arch/x86/events/intel/core.c
arch/x86/include/asm/extable.h
arch/x86/include/asm/kvm_emulate.h
arch/x86/include/asm/mshyperv.h
arch/x86/include/asm/processor.h
arch/x86/kernel/process.c
arch/x86/kernel/sys_x86_64.c
arch/x86/kernel/traps.c
arch/x86/kvm/emulate.c
arch/x86/kvm/x86.c
arch/x86/mm/extable.c
arch/x86/mm/hugetlbpage.c
arch/x86/mm/init.c
arch/xtensa/include/asm/irq.h
arch/xtensa/include/asm/processor.h
arch/xtensa/kernel/irq.c
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/syscall.c
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/platforms/iss/simdisk.c
arch/xtensa/platforms/xtfpga/include/platform/hardware.h
arch/xtensa/platforms/xtfpga/setup.c
block/bio.c
block/blk-mq-sched.c
block/blk-mq-sched.h
block/blk-mq.c
block/blk-sysfs.c
drivers/acpi/acpica/tbutils.c
drivers/acpi/acpica/utresrc.c
drivers/acpi/scan.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/char/random.c
drivers/clk/meson/Kconfig
drivers/clk/sunxi-ng/Kconfig
drivers/clk/sunxi-ng/ccu-sun50i-a64.h
drivers/clk/sunxi-ng/ccu-sun5i.c
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/sunxi-ng/ccu-sun8i-h3.h
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
drivers/clocksource/arm_arch_timer.c
drivers/clocksource/cadence_ttc_timer.c
drivers/clocksource/timer-sun5i.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpuidle/dt_idle_states.c
drivers/devfreq/event/exynos-nocp.c
drivers/devfreq/event/exynos-ppmu.c
drivers/firmware/dmi-id.c
drivers/firmware/dmi_scan.c
drivers/gpio/gpio-mvebu.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/atombios_crtc.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/bridge/synopsys/Kconfig
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/etnaviv/etnaviv_gem.h
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_guc_submission.c
drivers/gpu/drm/i915/i915_pvinfo.h
drivers/gpu/drm/i915/i915_vgpu.c
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp_aux_backlight.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/mgag200/mgag200_mode.c
drivers/gpu/drm/mxsfb/mxsfb_crtc.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_uvd.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
drivers/gpu/host1x/dev.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-magicmouse.c
drivers/hid/usbhid/hid-quirks.c
drivers/hsi/clients/ssi_protocol.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-rcar.c
drivers/iio/adc/meson_saradc.c
drivers/iio/adc/mxs-lradc-adc.c
drivers/iio/buffer/industrialio-buffer-dma.c
drivers/iio/buffer/industrialio-buffer-dmaengine.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
drivers/infiniband/core/addr.c
drivers/infiniband/hw/bnxt_re/bnxt_re.h
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_fp.h
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
drivers/infiniband/hw/bnxt_re/qplib_res.h
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/qplib_sp.h
drivers/infiniband/hw/cxgb4/device.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/qedr/qedr.h
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/sw/rxe/rxe.h
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/input/misc/soc_button_array.c
drivers/input/rmi4/rmi_f54.c
drivers/input/serio/i8042-x86ia64io.h
drivers/irqchip/irq-mips-gic.c
drivers/irqchip/irq-xtensa-mx.c
drivers/irqchip/irq-xtensa-pic.c
drivers/leds/leds-bcm6328.c
drivers/leds/trigger/ledtrig-heartbeat.c
drivers/media/cec/Kconfig
drivers/media/cec/cec-api.c
drivers/media/i2c/tc358743.c
drivers/media/rc/sir_ir.c
drivers/media/usb/rainshadow-cec/rainshadow-cec.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/mfd/arizona-core.c
drivers/mmc/host/meson-gx-mmc.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_main.c
drivers/net/caif/caif_hsi.c
drivers/net/caif/caif_serial.c
drivers/net/caif/caif_spi.c
drivers/net/caif/caif_virtio.c
drivers/net/can/dev.c
drivers/net/can/peak_canfd/peak_canfd.c
drivers/net/can/slcan.c
drivers/net/can/usb/gs_usb.c
drivers/net/can/usb/peak_usb/pcan_usb_core.c
drivers/net/can/vcan.c
drivers/net/can/vxcan.c
drivers/net/dummy.c
drivers/net/ethernet/amazon/ena/ena_com.c
drivers/net/ethernet/amazon/ena/ena_ethtool.c
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/amazon/ena/ena_netdev.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/freescale/fman/mac.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/marvell/mvpp2.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
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_am.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/health.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/qlogic/qed/qed_debug.c
drivers/net/ethernet/sfc/ef10_sriov.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
drivers/net/geneve.c
drivers/net/gtp.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/bpqether.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/ifb.c
drivers/net/ipvlan/ipvlan_main.c
drivers/net/loopback.c
drivers/net/macsec.c
drivers/net/macvlan.c
drivers/net/netconsole.c
drivers/net/nlmon.c
drivers/net/phy/Kconfig
drivers/net/phy/phy.c
drivers/net/slip/slip.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/cdc-phonet.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/veth.c
drivers/net/vrf.c
drivers/net/vsockmon.c
drivers/net/vxlan.c
drivers/net/wan/dlci.c
drivers/net/wan/hdlc_fr.c
drivers/net/wan/lapbether.c
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
drivers/net/wireless/intersil/hostap/hostap_main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/marvell/mwifiex/main.c
drivers/ntb/hw/intel/ntb_hw_intel.c
drivers/ntb/ntb_transport.c
drivers/ntb/test/ntb_perf.c
drivers/nvme/host/pci.c
drivers/pci/access.c
drivers/pci/endpoint/functions/Kconfig
drivers/pinctrl/pinctrl-amd.c
drivers/pinctrl/stm32/pinctrl-stm32.c
drivers/platform/x86/intel_telemetry_debugfs.c
drivers/s390/cio/vfio_ccw_ops.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_card.c
drivers/s390/crypto/ap_queue.c
drivers/s390/net/netiucv.c
drivers/scsi/qedi/qedi_fw.c
drivers/scsi/qedi/qedi_main.c
drivers/staging/iio/cdc/ad7152.c
drivers/staging/rtl8188eu/os_dep/mon.c
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
drivers/staging/rtl8723bs/os_dep/os_intfs.c
drivers/staging/rtl8723bs/os_dep/osdep_service.c
drivers/target/iscsi/iscsi_target.c
drivers/target/target_core_internal.h
drivers/target/target_core_tmr.c
drivers/target/target_core_transport.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_phonet.c
drivers/usb/gadget/legacy/inode.c
drivers/usb/gadget/udc/dummy_hcd.c
drivers/usb/gadget/udc/net2280.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/video/fbdev/core/fbmon.c
drivers/video/fbdev/smscufx.c
drivers/video/fbdev/udlfb.c
drivers/video/fbdev/via/viafbdev.c
drivers/virtio/virtio_balloon.c
fs/autofs4/dev-ioctl.c
fs/block_dev.c
fs/btrfs/hash.c
fs/ceph/acl.c
fs/ceph/export.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/cifs/file.c
fs/cifs/misc.c
fs/cifs/smb1ops.c
fs/cifs/smb2ops.c
fs/cifs/xattr.c
fs/configfs/item.c
fs/configfs/symlink.c
fs/dax.c
fs/dcache.c
fs/exec.c
fs/f2fs/f2fs.h
fs/hugetlbfs/inode.c
fs/namespace.c
fs/nfs/callback_xdr.c
fs/nfs/dir.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/ocfs2/dlmglue.c
fs/ocfs2/xattr.c
fs/proc/task_mmu.c
fs/read_write.c
fs/ufs/balloc.c
fs/ufs/inode.c
fs/ufs/super.c
fs/ufs/ufs_fs.h
fs/ufs/util.c
fs/ufs/util.h
fs/userfaultfd.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_icache.c
include/acpi/acpi_bus.h
include/acpi/actbl.h
include/dt-bindings/clock/sun50i-a64-ccu.h
include/dt-bindings/clock/sun8i-h3-ccu.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/configfs.h
include/linux/dmi.h
include/linux/mm.h
include/linux/netdevice.h
include/linux/slub_def.h
include/linux/timekeeper_internal.h
include/media/cec-notifier.h
include/media/cec.h
include/net/wext.h
include/uapi/linux/ethtool.h
include/uapi/linux/openvswitch.h
kernel/events/ring_buffer.c
kernel/irq/manage.c
kernel/livepatch/patch.c
kernel/livepatch/transition.c
kernel/sched/core.c
kernel/sched/cpufreq_schedutil.c
kernel/sched/fair.c
kernel/signal.c
kernel/time/alarmtimer.c
kernel/time/tick-broadcast.c
kernel/time/tick-internal.h
kernel/time/timekeeping.c
lib/cmdline.c
lib/libcrc32c.c
mm/gup.c
mm/huge_memory.c
mm/khugepaged.c
mm/memory-failure.c
mm/memory.c
mm/mmap.c
mm/slub.c
mm/swap_cgroup.c
mm/vmalloc.c
mm/vmpressure.c
net/8021q/vlan.c
net/8021q/vlan_dev.c
net/batman-adv/distributed-arp-table.c
net/batman-adv/routing.c
net/batman-adv/soft-interface.c
net/bluetooth/6lowpan.c
net/bridge/br_device.c
net/caif/caif_socket.c
net/caif/cfpkt_skbuff.c
net/caif/chnl_net.c
net/can/af_can.c
net/core/dev.c
net/core/dev_ioctl.c
net/core/dst.c
net/core/fib_rules.c
net/core/rtnetlink.c
net/decnet/dn_route.c
net/decnet/netfilter/dn_rtmsg.c
net/hsr/hsr_device.c
net/hsr/hsr_forward.c
net/hsr/hsr_framereg.c
net/hsr/hsr_framereg.h
net/ieee802154/6lowpan/core.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/ip_tunnel.c
net/ipv4/ipmr.c
net/ipv6/addrconf.c
net/ipv6/fib6_rules.c
net/ipv6/icmp.c
net/ipv6/ila/ila_xlat.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/ip6mr.c
net/ipv6/proc.c
net/ipv6/route.c
net/ipv6/sit.c
net/irda/irlan/irlan_eth.c
net/l2tp/l2tp_eth.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/wpa.c
net/mac802154/iface.c
net/openvswitch/vport-internal_dev.c
net/phonet/pep-gprs.c
net/rxrpc/key.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sctp/endpointola.c
net/sctp/sctp_diag.c
net/sctp/socket.c
net/tipc/msg.c
net/unix/af_unix.c
net/wireless/wext-core.c
scripts/Makefile.headersinst
scripts/genksyms/genksyms.h
scripts/kconfig/Makefile
scripts/kconfig/nconf.c
scripts/kconfig/nconf.gui.c
scripts/tags.sh
security/selinux/hooks.c
sound/core/pcm_lib.c
sound/firewire/amdtp-stream.c
sound/firewire/amdtp-stream.h
sound/pci/hda/hda_intel.c
tools/objtool/builtin-check.c
tools/perf/Makefile.config
tools/perf/Makefile.perf
tools/perf/arch/Build
tools/perf/pmu-events/Build
tools/perf/tests/Build
tools/perf/tests/task-exit.c
tools/perf/util/evsel.c
tools/perf/util/header.c
tools/perf/util/probe-event.c
tools/perf/util/unwind-libdw.c
tools/testing/selftests/bpf/bpf_endian.h
tools/testing/selftests/ntb/ntb_test.sh

index 0f5c3b4347c6f94a82385f193e76bc99dba19db5..7737ab5d04b2941621df23b7fc83a4cdba36e5ba 100644 (file)
                        expediting.  Set to zero to disable automatic
                        expediting.
 
+       stack_guard_gap=        [MM]
+                       override the default stack gap protection. The value
+                       is in page units and it defines how many pages prior
+                       to (for stacks growing down) resp. after (for stacks
+                       growing up) the main stack are reserved for no other
+                       mapping. Default value is 256 pages.
+
        stacktrace      [FTRACE]
                        Enabled the stack tracer on boot up.
 
index e9c5a1d9834af600de55821bc0077e6235ff0bff..f465647a4dd219a7718c26c88725a42dc5106f0d 100644 (file)
@@ -22,7 +22,8 @@ Required properties :
 - #clock-cells : must contain 1
 - #reset-cells : must contain 1
 
-For the PRCM CCUs on H3/A64, one more clock is needed:
+For the PRCM CCUs on H3/A64, two more clocks are needed:
+- "pll-periph": the SoC's peripheral PLL from the main CCU
 - "iosc": the SoC's internal frequency oscillator
 
 Example for generic CCU:
@@ -39,8 +40,8 @@ Example for PRCM CCU:
 r_ccu: clock@01f01400 {
        compatible = "allwinner,sun50i-a64-r-ccu";
        reg = <0x01f01400 0x100>;
-       clocks = <&osc24M>, <&osc32k>, <&iosc>;
-       clock-names = "hosc", "losc", "iosc";
+       clocks = <&osc24M>, <&osc32k>, <&iosc>, <&ccu CLK_PLL_PERIPH0>;
+       clock-names = "hosc", "losc", "iosc", "pll-periph";
        #clock-cells = <1>;
        #reset-cells = <1>;
 };
index 42c3bb2d53e88b651a7d39efe00e278c24d9c9b3..01e331a5f3e7491fba25188b5a12e91722057e42 100644 (file)
@@ -41,9 +41,9 @@ Required properties:
 Optional properties:
 
 In order to use the GPIO lines in PWM mode, some additional optional
-properties are required. Only Armada 370 and XP support these properties.
+properties are required.
 
-- compatible: Must contain "marvell,armada-370-xp-gpio"
+- compatible: Must contain "marvell,armada-370-gpio"
 
 - reg: an additional register set is needed, for the GPIO Blink
   Counter on/off registers.
@@ -71,7 +71,7 @@ Example:
                };
 
                gpio1: gpio@18140 {
-                       compatible = "marvell,armada-370-xp-gpio";
+                       compatible = "marvell,armada-370-gpio";
                        reg = <0x18140 0x40>, <0x181c8 0x08>;
                        reg-names = "gpio", "pwm";
                        ngpios = <17>;
index bbd083f5600a786b23a0ec821f384e8e8a6a3553..1db6e0057a638e09a5346956a70620c31276fdf6 100644 (file)
@@ -31,7 +31,7 @@ Example:
                compatible = "st,stm32-timers";
                reg = <0x40010000 0x400>;
                clocks = <&rcc 0 160>;
-               clock-names = "clk_int";
+               clock-names = "int";
 
                pwm {
                        compatible = "st,stm32-pwm";
index d6c6e41648d4f17814ea43775e8591a40a4c0786..8ec2ca21adeb6ca840a7fd5d660a57748919af42 100644 (file)
@@ -34,7 +34,7 @@ Required properties:
       "brcm,bcm6328-switch"
       "brcm,bcm6368-switch" and the mandatory "brcm,bcm63xx-switch"
 
-See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional
+See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional
 required and optional properties.
 
 Examples:
index 16c3a9501f5d689431451c52b91c86b8ae1395b8..acfafc8e143c4c8599510eb7d2cbcb35af7e6f9f 100644 (file)
@@ -27,6 +27,7 @@ Optional properties:
   of the device. On many systems this is wired high so the device goes
   out of reset at power-on, but if it is under program control, this
   optional GPIO can wake up in response to it.
+- vdd33a-supply, vddvario-supply : 3.3V analog and IO logic power supplies
 
 Examples:
 
index 59f4db2a0c85c02df4f6cee3176ceb173333cac1..f55639d71d35b8c466252808cf9b0e58d42b7f30 100644 (file)
@@ -122,7 +122,7 @@ associated flow of the packet. The hash is either provided by hardware
 or will be computed in the stack. Capable hardware can pass the hash in
 the receive descriptor for the packet; this would usually be the same
 hash used for RSS (e.g. computed Toeplitz hash). The hash is saved in
-skb->rx_hash and can be used elsewhere in the stack as a hash of the
+skb->hash and can be used elsewhere in the stack as a hash of the
 packet’s flow.
 
 Each receive hardware queue has an associated list of CPUs to which
index 09b5ab6a8a5ce8fd66bed85f30b9ca7db26c14c2..767e9d202adf889d5ae0a746dc6dd7a9561c4a83 100644 (file)
@@ -2964,7 +2964,7 @@ F:        sound/pci/oxygen/
 
 C6X ARCHITECTURE
 M:     Mark Salter <msalter@redhat.com>
-M:     Aurelien Jacquiot <a-jacquiot@ti.com>
+M:     Aurelien Jacquiot <jacquiot.aurelien@gmail.com>
 L:     linux-c6x-dev@linux-c6x.org
 W:     http://www.linux-c6x.org/wiki/index.php/Main_Page
 S:     Maintained
index 83f6d9972cab0028038d95d0d34b728e754ca0ad..6d8a984ed9c975e8867b151e8e6e9424f85dea87 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 12
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc7
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
@@ -1437,7 +1437,7 @@ help:
        @echo  '  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
        @echo  '  make V=2   [targets] 2 => give reason for rebuild of target'
        @echo  '  make O=dir [targets] Locate all output files in "dir", including .config'
-       @echo  '  make C=1   [targets] Check all c source with $$CHECK (sparse by default)'
+       @echo  '  make C=1   [targets] Check re-compiled c source with $$CHECK (sparse by default)'
        @echo  '  make C=2   [targets] Force check of all c source with $$CHECK'
        @echo  '  make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections'
        @echo  '  make W=n   [targets] Enable extra gcc checks, n=1,2,3 where'
index 6e1242da0159e274b7e161f9648e031cbddd7ef4..4104a08392146f6c479710557010135aa4774a15 100644 (file)
@@ -86,8 +86,6 @@ struct task_struct;
 #define TSK_K_BLINK(tsk)       TSK_K_REG(tsk, 4)
 #define TSK_K_FP(tsk)          TSK_K_REG(tsk, 0)
 
-#define thread_saved_pc(tsk)   TSK_K_BLINK(tsk)
-
 extern void start_thread(struct pt_regs * regs, unsigned long pc,
                         unsigned long usp);
 
index 3e25e8d6486ba258c8fa07ae52214af5e845decb..2e13683dfb24ba68363a08e88e019e4753977179 100644 (file)
@@ -65,7 +65,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index 4c1a35f1583872d2ce39db5c1cacce28be48ccb1..c0fcab6a550473859b4a2ca525cefc16624e1710 100644 (file)
@@ -1416,6 +1416,7 @@ choice
        config VMSPLIT_3G
                bool "3G/1G user/kernel split"
        config VMSPLIT_3G_OPT
+               depends on !ARM_LPAE
                bool "3G/1G user/kernel split (for full 1G low memory)"
        config VMSPLIT_2G
                bool "2G/2G user/kernel split"
index 3f7d1b74c5e02bd46730c58b0a66756c89b904ab..a17ca8d78656d1012910ffb8a37b3433720a8d44 100644 (file)
@@ -17,7 +17,8 @@
                @ there.
                .inst   'M' | ('Z' << 8) | (0x1310 << 16)   @ tstne r0, #0x4d000
 #else
-               W(mov)  r0, r0
+ AR_CLASS(     mov     r0, r0          )
+  M_CLASS(     nop.w                   )
 #endif
                .endm
 
index c5d2589c55fc3ddfab5909413e7bbfe59aba50f7..fc864a8559918992401f2db3594bd5f28a7b7b28 100644 (file)
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7)              /* spi0_cs1.gpio0_6 */
+                       AM33XX_IOPAD(0x96c, PIN_INPUT | MUX_MODE7)              /* uart0_rtsn.gpio1_9 */
                >;
        };
 
                        AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE7)       /* nKbdReset - gpmc_ad13.gpio1_13 */
                        AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE7)       /* nDispReset - gpmc_ad14.gpio1_14 */
                        AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE7)       /* USB1_enPower - gpmc_a1.gpio1_17 */
-                       /* AVR Programming - SPI Bus (bit bang) - Screen and Keyboard */
-                       AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE7)       /* Kbd/Disp/BattMOSI spi0_d0.gpio0_3 */
-                       AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE7)       /* Kbd/Disp/BattMISO spi0_d1.gpio0_4 */
-                       AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE7)       /* Kbd/Disp/BattSCLK spi0_clk.gpio0_2 */
                        /* PDI Bus - Battery system */
                        AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE7)       /* nBattReset  gpmc_a0.gpio1_16 */
                        AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE7)       /* BattPDIData gpmc_ad15.gpio1_15 */
        pinctrl-names = "default";
        pinctrl-0 = <&mmc1_pins>;
        bus-width = <4>;
-       cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+       cd-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
        vmmc-supply = <&vmmcsd_fixed>;
 };
 
index 1aeeacb3a8849b63b9c21796612f9a870084ce34..d4f600dbb7eb8dc7b5f922e9334c5dddf3528296 100644 (file)
                };
 
                r_ccu: clock@1f01400 {
-                       compatible = "allwinner,sun50i-a64-r-ccu";
+                       compatible = "allwinner,sun8i-h3-r-ccu";
                        reg = <0x01f01400 0x100>;
-                       clocks = <&osc24M>, <&osc32k>, <&iosc>;
-                       clock-names = "hosc", "losc", "iosc";
+                       clocks = <&osc24M>, <&osc32k>, <&iosc>,
+                                <&ccu 9>;
+                       clock-names = "hosc", "losc", "iosc", "pll-periph";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                };
index 32e1a9513dc70eba4787ca1af0ba3e32b9f29d7e..4e80bf7420d4e65fb30e0c68e7bef53932f765b3 100644 (file)
@@ -315,7 +315,7 @@ static void __init cacheid_init(void)
        if (arch >= CPU_ARCH_ARMv6) {
                unsigned int cachetype = read_cpuid_cachetype();
 
-               if ((arch == CPU_ARCH_ARMv7M) && !cachetype) {
+               if ((arch == CPU_ARCH_ARMv7M) && !(cachetype & 0xf000f)) {
                        cacheid = 0;
                } else if ((cachetype & (7 << 29)) == 4 << 29) {
                        /* ARMv7 register format */
index 2239fde10b808d7985bba83f42984dda35871901..f0701d8d24df5a8edd151055402c0cdf05e8a8e3 100644 (file)
@@ -90,7 +90,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
@@ -141,7 +141,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                        addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                               (!vma || addr + len <= vma->vm_start))
+                               (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index c7f669f5884f910c6e4be44ac1dd09a216cb97f0..166c9ef884dc6e52432e0030d06f1b7036d2c428 100644 (file)
                r_ccu: clock@1f01400 {
                        compatible = "allwinner,sun50i-a64-r-ccu";
                        reg = <0x01f01400 0x100>;
-                       clocks = <&osc24M>, <&osc32k>, <&iosc>;
-                       clock-names = "hosc", "losc", "iosc";
+                       clocks = <&osc24M>, <&osc32k>, <&iosc>,
+                                <&ccu 11>;
+                       clock-names = "hosc", "losc", "iosc", "pll-periph";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                };
index 4d314a253fd9e08bd4e0f6db6b1677c2e2e2fb05..732e2e06f503c83e42c0c4925b06295e6e47dc64 100644 (file)
@@ -40,7 +40,7 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "sunxi-h3-h5.dtsi"
+#include <arm/sunxi-h3-h5.dtsi>
 
 / {
        cpus {
diff --git a/arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi b/arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi
deleted file mode 120000 (symlink)
index 036f01d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../arm/boot/dts/sunxi-h3-h5.dtsi
\ No newline at end of file
index 41b6e31f8f556f4d4af8ecdafd3867e540a8ed10..d0cb007fa4823791be514b8a5ac65d8d408f099d 100644 (file)
@@ -221,10 +221,11 @@ void update_vsyscall(struct timekeeper *tk)
                /* tkr_mono.cycle_last == tkr_raw.cycle_last */
                vdso_data->cs_cycle_last        = tk->tkr_mono.cycle_last;
                vdso_data->raw_time_sec         = tk->raw_time.tv_sec;
-               vdso_data->raw_time_nsec        = tk->raw_time.tv_nsec;
+               vdso_data->raw_time_nsec        = (tk->raw_time.tv_nsec <<
+                                                  tk->tkr_raw.shift) +
+                                                 tk->tkr_raw.xtime_nsec;
                vdso_data->xtime_clock_sec      = tk->xtime_sec;
                vdso_data->xtime_clock_nsec     = tk->tkr_mono.xtime_nsec;
-               /* tkr_raw.xtime_nsec == 0 */
                vdso_data->cs_mono_mult         = tk->tkr_mono.mult;
                vdso_data->cs_raw_mult          = tk->tkr_raw.mult;
                /* tkr_mono.shift == tkr_raw.shift */
index e00b4671bd7c4af5516b95da00409c7296df1963..76320e9209651fd307659dcbab8092ff7c1c09e2 100644 (file)
@@ -256,7 +256,6 @@ monotonic_raw:
        seqcnt_check fail=monotonic_raw
 
        /* All computations are done with left-shifted nsecs. */
-       lsl     x14, x14, x12
        get_nsec_per_sec res=x9
        lsl     x9, x9, x12
 
index 71f930501ade7cec2d1f230aa638ad3fc9112ee8..c870d6f01ac217e0dc80bf4ee0d3549e6fa1c658 100644 (file)
@@ -36,6 +36,7 @@ int bpf_jit_enable __read_mostly;
 #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
 #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
 #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
+#define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
 
 /* Map BPF registers to A64 registers */
 static const int bpf2a64[] = {
@@ -57,6 +58,7 @@ static const int bpf2a64[] = {
        /* temporary registers for internal BPF JIT */
        [TMP_REG_1] = A64_R(10),
        [TMP_REG_2] = A64_R(11),
+       [TMP_REG_3] = A64_R(12),
        /* tail_call_cnt */
        [TCALL_CNT] = A64_R(26),
        /* temporary register for blinding constants */
@@ -319,6 +321,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
        const u8 src = bpf2a64[insn->src_reg];
        const u8 tmp = bpf2a64[TMP_REG_1];
        const u8 tmp2 = bpf2a64[TMP_REG_2];
+       const u8 tmp3 = bpf2a64[TMP_REG_3];
        const s16 off = insn->off;
        const s32 imm = insn->imm;
        const int i = insn - ctx->prog->insnsi;
@@ -689,10 +692,10 @@ emit_cond_jmp:
                emit(A64_PRFM(tmp, PST, L1, STRM), ctx);
                emit(A64_LDXR(isdw, tmp2, tmp), ctx);
                emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
-               emit(A64_STXR(isdw, tmp2, tmp, tmp2), ctx);
+               emit(A64_STXR(isdw, tmp2, tmp, tmp3), ctx);
                jmp_offset = -3;
                check_imm19(jmp_offset);
-               emit(A64_CBNZ(0, tmp2, jmp_offset), ctx);
+               emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
                break;
 
        /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */
index 85d4af97c986aee4a7eff90b4347aca444ee1ed9..dbdbb8a558df4acb548b71dbc52f63b3e7373d7f 100644 (file)
@@ -75,11 +75,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-#define thread_saved_pc(tsk)   (tsk->thread.pc)
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define        KSTK_EIP(tsk)                                                   \
index b9eb3da7f278dac858bfb2191094f9fc837ac5c8..7c87b5be53b5b74c76fbe03829034b1e96ac3c7c 100644 (file)
@@ -95,11 +95,6 @@ static inline void release_thread(struct task_struct *dead_task)
 #define copy_segments(tsk, mm)         do { } while (0)
 #define release_segments(mm)           do { } while (0)
 
-/*
- * saved PC of a blocked thread.
- */
-#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc)
-
 /*
  * saved kernel SP and DP of a blocked thread.
  */
index e299d30105b53bf5ad0e8b8df7f036f39267ad66..a2cdb1521aca4db4069d449f56094ee822e0313d 100644 (file)
@@ -69,14 +69,6 @@ void hard_reset_now (void)
        while(1) /* waiting for RETRIBUTION! */ ;
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-       return task_pt_regs(t)->irp;
-}
-
 /* setup the child's kernel stack with a pt_regs and switch_stack on it.
  * it will be un-nested during _resume and _ret_from_sys_call when the
  * new thread is scheduled.
index c530a8fa87ceb751a0c275885e34852dbcd5b6c2..fe87b383fbf3fc45522d8ce74a122c8469347993 100644 (file)
@@ -84,14 +84,6 @@ hard_reset_now(void)
                ; /* Wait for reset. */
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-       return task_pt_regs(t)->erp;
-}
-
 /*
  * Setup the child's kernel stack with a pt_regs and call switch_stack() on it.
  * It will be unnested during _resume and _ret_from_sys_call when the new thread
index 15b815df29c165809c4e6e229ede6a077d9e8e71..bc2729e4b2c97e89b5a9dd3daf30df555dee1e0f 100644 (file)
@@ -52,8 +52,6 @@ unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 /* Free all resources held by a thread. */
 static inline void release_thread(struct task_struct *dead_task)
 {
index ddaeb9cc9143333d8f00de60291298f6dce5530c..e4d08d74ed9f8dc4f81140fcf60442378f02cf58 100644 (file)
@@ -96,11 +96,6 @@ extern asmlinkage void *restore_user_regs(const struct user_context *target, ...
 #define release_segments(mm)           do { } while (0)
 #define forget_segments()              do { } while (0)
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define        KSTK_EIP(tsk)   ((tsk)->thread.frame0->pc)
index 5a4c92abc99ec320b54ef80841bc6f3333a9d3dd..a957b374e3a66b28a30bf5d30b623bfccbc2fb0a 100644 (file)
@@ -198,15 +198,6 @@ unsigned long get_wchan(struct task_struct *p)
        return 0;
 }
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       /* Check whether the thread is blocked in resume() */
-       if (in_sched_functions(tsk->thread.pc))
-               return ((unsigned long *)tsk->thread.fp)[2];
-       else
-               return tsk->thread.pc;
-}
-
 int elf_check_arch(const struct elf32_hdr *hdr)
 {
        unsigned long hsr0 = __get_HSR(0);
index da82c25301e7774bcbe3058129b574c7496efba8..46aa289c5102baf8a1b841e693316538ee901f8b 100644 (file)
@@ -75,7 +75,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
                addr = PAGE_ALIGN(addr);
                vma = find_vma(current->mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        goto success;
        }
 
index 65132d7ae9e5b66fb484014f7930fd91f75cc944..afa53147e66a82e24d8d9e100b4706a9ce2ee760 100644 (file)
@@ -110,10 +110,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk);
 unsigned long get_wchan(struct task_struct *p);
 
 #define        KSTK_EIP(tsk)   \
index 0f5db5bb561b75cb30bb2871ffa7c00545f84539..d1ddcabbbe8383fc6160db3946a334286676b5ae 100644 (file)
@@ -129,11 +129,6 @@ int copy_thread(unsigned long clone_flags,
        return 0;
 }
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       return ((struct pt_regs *)tsk->thread.esp0)->pc;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        unsigned long fp, pc;
index 45a825402f634ee4b650a08a60efc5c60d50e261..ce67940860a536dce66bea9b59daeab1fcaa103e 100644 (file)
@@ -33,9 +33,6 @@
 /*  task_struct, defined elsewhere, is the "process descriptor" */
 struct task_struct;
 
-/*  this is defined in arch/process.c  */
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
 
 /*
index de715bab7956c7e38df0b8ab689d11cca8fceb16..656050c2e6a06ab7f60ad6c1a65351dfd29f544f 100644 (file)
@@ -60,14 +60,6 @@ void arch_cpu_idle(void)
        local_irq_enable();
 }
 
-/*
- *  Return saved PC of a blocked thread
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       return 0;
-}
-
 /*
  * Copy architecture-specific thread state
  */
index 26a63d69c599addab0486c2fa08d548dd229ccf9..ab982f07ea681253d42f351c230c976a83258f95 100644 (file)
@@ -601,23 +601,6 @@ ia64_set_unat (__u64 *unat, void *spill_addr, unsigned long nat)
        *unat = (*unat & ~mask) | (nat << bit);
 }
 
-/*
- * Return saved PC of a blocked thread.
- * Note that the only way T can block is through a call to schedule() -> switch_to().
- */
-static inline unsigned long
-thread_saved_pc (struct task_struct *t)
-{
-       struct unw_frame_info info;
-       unsigned long ip;
-
-       unw_init_from_blocked_task(&info, t);
-       if (unw_unwind(&info) < 0)
-               return 0;
-       unw_get_ip(&info, &ip);
-       return ip;
-}
-
 /*
  * Get the current instruction/program counter value.
  */
index 5767367550c69637a0b51c7a037b7a5e0c4fbfb4..657874eeeccc262c11268094e0f0ba530e05dd92 100644 (file)
@@ -122,8 +122,6 @@ extern void release_thread(struct task_struct *);
 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
 extern void release_segments(struct mm_struct * mm);
 
-extern unsigned long thread_saved_pc(struct task_struct *);
-
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(p, mm)  do { } while (0)
 #define release_segments(mm)  do { } while (0)
index d8ffcfec599cb6a10a6eb649f15d628a97a377f9..8cd7e03f4370c06a633d2a12b5db70299ffa41ae 100644 (file)
 
 #include <linux/err.h>
 
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       return tsk->thread.lr;
-}
-
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
index 77239e81379b16b52e39cff979d1da4ceb2e1965..94c36030440cc825c4688244a0b973ba60be3863 100644 (file)
@@ -130,8 +130,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define        KSTK_EIP(tsk)   \
index e475c945c8b2bf199e6147a16fcf42c2d7c0d714..7df92f8b0781dd2651096f83f8c45185a26be803 100644 (file)
 asmlinkage void ret_from_fork(void);
 asmlinkage void ret_from_kernel_thread(void);
 
-
-/*
- * Return saved PC from a blocked thread
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
-       /* Check whether the thread is blocked in resume() */
-       if (in_sched_functions(sw->retpc))
-               return ((unsigned long *)sw->a6)[1];
-       else
-               return sw->retpc;
-}
-
 void arch_cpu_idle(void)
 {
 #if defined(MACH_ATARI_ONLY)
index 37ef196e45191adb481450c8648e9e9acbb05106..330d556860ba7a8211b767cd4ac03275adcab9f0 100644 (file)
@@ -69,8 +69,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 extern unsigned long get_wchan(struct task_struct *p);
 
 # define KSTK_EIP(tsk) (0)
@@ -121,10 +119,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-/* Return saved (kernel) PC of a blocked thread.  */
-#  define thread_saved_pc(tsk) \
-       ((tsk)->thread.regs ? (tsk)->thread.regs->r15 : 0)
-
 unsigned long get_wchan(struct task_struct *p);
 
 /* The size allocated for kernel stacks. This _must_ be a power of two! */
index e92a817e645fac7bf8782e782b2525429572d5b3..6527ec22f158f16acef89a0b78310c518866ae73 100644 (file)
@@ -119,23 +119,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        return 0;
 }
 
-#ifndef CONFIG_MMU
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       struct cpu_context *ctx =
-               &(((struct thread_info *)(tsk->stack))->cpu_context);
-
-       /* Check whether the thread is blocked in resume() */
-       if (in_sched_functions(ctx->r15))
-               return (unsigned long)ctx->r15;
-       else
-               return ctx->r14;
-}
-#endif
-
 unsigned long get_wchan(struct task_struct *p)
 {
 /* TBD (used by procfs) */
index 2728a9a9c7c5bc4f822ab6788e1f889cb39c0a51..145b5ce8eb7e660dda67f6a53aa472f74a413af0 100644 (file)
@@ -128,19 +128,19 @@ quiet_cmd_cpp_its_S = ITS     $@
                        -DADDR_BITS=$(ADDR_BITS) \
                        -DADDR_CELLS=$(itb_addr_cells)
 
-$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
        $(call if_changed_dep,cpp_its_S,none,vmlinux.bin)
 
-$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
        $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz)
 
-$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX)  FORCE
        $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2)
 
-$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
        $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma)
 
-$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
        $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo)
 
 quiet_cmd_itb-image = ITB     $@
index d34536e7653f6a29fe85b5b1e15b67c19a8c9b3e..279b6d14ffeb7c5af5b54152292b70dd5581d88c 100644 (file)
@@ -35,7 +35,12 @@ extern pte_t *pkmap_page_table;
  * easily, subsequent pte tables have to be allocated in one physical
  * chunk of RAM.
  */
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+#define LAST_PKMAP 512
+#else
 #define LAST_PKMAP 1024
+#endif
+
 #define LAST_PKMAP_MASK (LAST_PKMAP-1)
 #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
 #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
index 291846d9ba8346ca915879ff6b7c1162cde67df8..ad1a99948f2795c0608c32e3dc213c46e171d162 100644 (file)
@@ -43,7 +43,8 @@ typedef union mips_instruction kprobe_opcode_t;
 
 #define flush_insn_slot(p)                                             \
 do {                                                                   \
-       flush_icache_range((unsigned long)p->addr,                      \
+       if (p->addr)                                                    \
+               flush_icache_range((unsigned long)p->addr,              \
                           (unsigned long)p->addr +                     \
                           (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));  \
 } while (0)
index 6f94bed571c4416b917a52fe364172243a3a9fe6..74afe8c76bdd01a9a0351208ab05f54f4d43160a 100644 (file)
 #define __ARCH_USE_5LEVEL_HACK
 #include <asm-generic/pgtable-nopmd.h>
 
+#ifdef CONFIG_HIGHMEM
+#include <asm/highmem.h>
+#endif
+
 extern int temp_tlb_entry;
 
 /*
@@ -62,7 +66,8 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
 
 #define VMALLOC_START    MAP_BASE
 
-#define PKMAP_BASE             (0xfe000000UL)
+#define PKMAP_END      ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
+#define PKMAP_BASE     (PKMAP_END - PAGE_SIZE * LAST_PKMAP)
 
 #ifdef CONFIG_HIGHMEM
 # define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
index b11facd11c9d05dfae733094359da713c948ad84..f702a459a830060f6aa77fe09eda28c03a3d4f4c 100644 (file)
@@ -804,8 +804,10 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
                        break;
                }
                /* Compact branch: BNEZC || JIALC */
-               if (insn.i_format.rs)
+               if (!insn.i_format.rs) {
+                       /* JIALC: set $31/ra */
                        regs->regs[31] = epc + 4;
+               }
                regs->cp0_epc += 8;
                break;
 #endif
index 30a3b75e88eb6a3310808d8c743739efa3f98fb7..9d9b8fbae2022a426f0bcd9c7e134c4c33b67034 100644 (file)
@@ -38,20 +38,6 @@ void arch_ftrace_update_code(int command)
 
 #endif
 
-/*
- * Check if the address is in kernel space
- *
- * Clone core_kernel_text() from kernel/extable.c, but doesn't call
- * init_kernel_text() for Ftrace doesn't trace functions in init sections.
- */
-static inline int in_kernel_space(unsigned long ip)
-{
-       if (ip >= (unsigned long)_stext &&
-           ip <= (unsigned long)_etext)
-               return 1;
-       return 0;
-}
-
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 #define JAL 0x0c000000         /* jump & link: ip --> ra, jump to target */
@@ -198,7 +184,7 @@ int ftrace_make_nop(struct module *mod,
         * If ip is in kernel space, no long call, otherwise, long call is
         * needed.
         */
-       new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F;
+       new = core_kernel_text(ip) ? INSN_NOP : INSN_B_1F;
 #ifdef CONFIG_64BIT
        return ftrace_modify_code(ip, new);
 #else
@@ -218,12 +204,12 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
        unsigned int new;
        unsigned long ip = rec->ip;
 
-       new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
+       new = core_kernel_text(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
 
 #ifdef CONFIG_64BIT
        return ftrace_modify_code(ip, new);
 #else
-       return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ?
+       return ftrace_modify_code_2r(ip, new, core_kernel_text(ip) ?
                                                INSN_NOP : insn_la_mcount[1]);
 #endif
 }
@@ -289,7 +275,7 @@ unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
         * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for
         * kernel, move after the instruction "move ra, at"(offset is 16)
         */
-       ip = self_ra - (in_kernel_space(self_ra) ? 16 : 24);
+       ip = self_ra - (core_kernel_text(self_ra) ? 16 : 24);
 
        /*
         * search the text until finding the non-store instruction or "s{d,w}
@@ -394,7 +380,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
         * entries configured through the tracing/set_graph_function interface.
         */
 
-       insns = in_kernel_space(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
+       insns = core_kernel_text(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
        trace.func = self_ra - (MCOUNT_INSN_SIZE * insns);
 
        /* Only trace if the calling function expects to */
index 313a88b2973f673f0fac0998c36517fd2139504b..f3e301f95aef7edb160e122fa722d8cb6840a9a7 100644 (file)
@@ -1597,7 +1597,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
                break;
        case CPU_P5600:
        case CPU_P6600:
-       case CPU_I6400:
                /* 8-bit event numbers */
                raw_id = config & 0x1ff;
                base_id = raw_id & 0xff;
@@ -1610,6 +1609,11 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
                raw_event.range = P;
 #endif
                break;
+       case CPU_I6400:
+               /* 8-bit event numbers */
+               base_id = config & 0xff;
+               raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+               break;
        case CPU_1004K:
                if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
                        raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
index 7c6336dd2638ce9c12c4ff8be566ff6acb856137..7cd92166a0b9a9bf3c14fe1df33442442ac668ac 100644 (file)
@@ -166,7 +166,11 @@ static int _kvm_mips_host_tlb_inv(unsigned long entryhi)
 int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va,
                          bool user, bool kernel)
 {
-       int idx_user, idx_kernel;
+       /*
+        * Initialize idx_user and idx_kernel to workaround bogus
+        * maybe-initialized warning when using GCC 6.
+        */
+       int idx_user = 0, idx_kernel = 0;
        unsigned long flags, old_entryhi;
 
        local_irq_save(flags);
index 64dd8bdd92c3390ba0c5df29e57e955293dbac9a..28adeabe851ff22dbea2da9d701208dadcc4925d 100644 (file)
@@ -93,7 +93,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index adc6911ba748915bda5b2575fc03b76891f1fb21..b19a3c506b1e9d203cbacb0da71513d8f21868b1 100644 (file)
@@ -51,15 +51,15 @@ void __init pagetable_init(void)
        /*
         * Fixed mappings:
         */
-       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-       fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
+       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
+       fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
 
 #ifdef CONFIG_HIGHMEM
        /*
         * Permanent kmaps:
         */
        vaddr = PKMAP_BASE;
-       fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+       fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
 
        pgd = swapper_pg_dir + __pgd_offset(vaddr);
        pud = pud_offset(pgd, vaddr);
index 18e17abf7664e51c807e3d5649b0585bfd89a3be..3ae479117b42efd07d719282ee1dd287abecb1a4 100644 (file)
@@ -132,11 +132,6 @@ static inline void start_thread(struct pt_regs *regs,
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define task_pt_regs(task) ((task)->thread.uregs)
index c9fa42619c6a9aa4f5fa3244b3ce45efdfaeea11..89e8027e07fb327d39de0170c0da61af177c7160 100644 (file)
 #include <asm/gdb-stub.h>
 #include "internal.h"
 
-/*
- * return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       return ((unsigned long *) tsk->thread.sp)[3];
-}
-
 /*
  * power off function, if any
  */
index 3bbbc3d798e5f4738548690eb8511834050baa76..4944e2e1d8b0677d48c30ebba98629d43db90933 100644 (file)
@@ -75,9 +75,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-/* Return saved PC of a blocked thread. */
-#define thread_saved_pc(tsk)   ((tsk)->thread.kregs->ea)
-
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define task_pt_regs(p) \
index a908e6c30a001e14860fe70f174f1451c6e4ae09..396d8f306c21b6c24f872780b9500cb8ebc1b963 100644 (file)
@@ -84,11 +84,6 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
 void release_thread(struct task_struct *);
 unsigned long get_wchan(struct task_struct *p);
 
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 #define init_stack      (init_thread_union.stack)
 
 #define cpu_relax()     barrier()
index 106859ae27ffba114f9f4b0011151db0f65f98d4..f9b77003f1138ce42dff841814cb280d562481e0 100644 (file)
@@ -110,11 +110,6 @@ void show_regs(struct pt_regs *regs)
        show_registers(regs);
 }
 
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-       return (unsigned long)user_regs(t->stack)->pc;
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 }
index a3661ee6b060c1d258ab740e5468cfffb665f8d5..4c6694b4e77e0dd12ef6aed95508ea035ccdb10c 100644 (file)
@@ -163,12 +163,7 @@ struct thread_struct {
        .flags          = 0 \
        }
 
-/*
- * Return saved PC of a blocked thread.  This is used by ps mostly.
- */
-
 struct task_struct;
-unsigned long thread_saved_pc(struct task_struct *t);
 void show_trace(struct task_struct *task, unsigned long *stack);
 
 /*
index 4516a5b53f38ef651c038e4231effa00fd6db19d..b64d7d21646ed50c4a5c1f046b0f8ca758abfcc6 100644 (file)
@@ -239,11 +239,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
        return 0;
 }
 
-unsigned long thread_saved_pc(struct task_struct *t)
-{
-       return t->thread.regs.kpc;
-}
-
 unsigned long
 get_wchan(struct task_struct *p)
 {
index e5288638a1d9ad713c03fa4fc0d439efd012c470..378a754ca1867fb17d48625150a707dd95675b87 100644 (file)
@@ -90,7 +90,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
                unsigned long len, unsigned long pgoff, unsigned long flags)
 {
        struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
+       struct vm_area_struct *vma, *prev;
        unsigned long task_size = TASK_SIZE;
        int do_color_align, last_mmap;
        struct vm_unmapped_area_info info;
@@ -117,9 +117,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
                else
                        addr = PAGE_ALIGN(addr);
 
-               vma = find_vma(mm, addr);
+               vma = find_vma_prev(mm, addr, &prev);
                if (task_size - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)) &&
+                   (!prev || addr >= vm_end_gap(prev)))
                        goto found_addr;
        }
 
@@ -143,7 +144,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                          const unsigned long len, const unsigned long pgoff,
                          const unsigned long flags)
 {
-       struct vm_area_struct *vma;
+       struct vm_area_struct *vma, *prev;
        struct mm_struct *mm = current->mm;
        unsigned long addr = addr0;
        int do_color_align, last_mmap;
@@ -177,9 +178,11 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                        addr = COLOR_ALIGN(addr, last_mmap, pgoff);
                else
                        addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
+
+               vma = find_vma_prev(mm, addr, &prev);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)) &&
+                   (!prev || addr >= vm_end_gap(prev)))
                        goto found_addr;
        }
 
index f2c562a0a427dda2c774acb1e13c7eda8514e21e..0151af6c2a505a77c512110271e73f0c9c3fcd6e 100644 (file)
                "1:     "PPC_TLNEI"     %4,0\n"                 \
                _EMIT_BUG_ENTRY                                 \
                : : "i" (__FILE__), "i" (__LINE__),             \
-                 "i" (BUGFLAG_TAINT(TAINT_WARN)),              \
+                 "i" (BUGFLAG_WARNING|BUGFLAG_TAINT(TAINT_WARN)),\
                  "i" (sizeof(struct bug_entry)),               \
                  "r" (__ret_warn_on));                         \
        }                                                       \
index a83821f33ea36f8c005dab8e80dfdfcfd26a7058..8814a7249cebe29852dd8b4588a61052decac88c 100644 (file)
@@ -103,6 +103,7 @@ extern int kprobe_exceptions_notify(struct notifier_block *self,
 extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_handler(struct pt_regs *regs);
 extern int kprobe_post_handler(struct pt_regs *regs);
+extern int is_current_kprobe_addr(unsigned long addr);
 #ifdef CONFIG_KPROBES_ON_FTRACE
 extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
                           struct kprobe_ctlblk *kcb);
index bb99b651085aaf292e5f98ee23c7cdc53d443cd2..1189d04f3bd1ce6db0f6ed5da3414f25dc3f4c38 100644 (file)
@@ -378,12 +378,6 @@ struct thread_struct {
 }
 #endif
 
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-#define thread_saved_pc(tsk)    \
-        ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-
 #define task_pt_regs(tsk)      ((struct pt_regs *)(tsk)->thread.regs)
 
 unsigned long get_wchan(struct task_struct *p);
index c8a822acf962ab95d3ef36c37abe70cc82f1c76e..c23ff4389ca236c43994fe4279b7f151e80fe5e7 100644 (file)
@@ -94,11 +94,13 @@ struct xive_q {
  * store at 0 and some ESBs support doing a trigger via a
  * separate trigger page.
  */
-#define XIVE_ESB_GET           0x800
-#define XIVE_ESB_SET_PQ_00     0xc00
-#define XIVE_ESB_SET_PQ_01     0xd00
-#define XIVE_ESB_SET_PQ_10     0xe00
-#define XIVE_ESB_SET_PQ_11     0xf00
+#define XIVE_ESB_STORE_EOI     0x400 /* Store */
+#define XIVE_ESB_LOAD_EOI      0x000 /* Load */
+#define XIVE_ESB_GET           0x800 /* Load */
+#define XIVE_ESB_SET_PQ_00     0xc00 /* Load */
+#define XIVE_ESB_SET_PQ_01     0xd00 /* Load */
+#define XIVE_ESB_SET_PQ_10     0xe00 /* Load */
+#define XIVE_ESB_SET_PQ_11     0xf00 /* Load */
 
 #define XIVE_ESB_VAL_P         0x2
 #define XIVE_ESB_VAL_Q         0x1
index ae418b85c17c4bce805227a82350d322259cf06e..b886795060fd2dba727c54d8c7b5e2b47a888f8d 100644 (file)
@@ -1411,10 +1411,8 @@ USE_TEXT_SECTION()
        .balign IFETCH_ALIGN_BYTES
 do_hash_page:
 #ifdef CONFIG_PPC_STD_MMU_64
-       andis.  r0,r4,0xa410            /* weird error? */
+       andis.  r0,r4,0xa450            /* weird error? */
        bne-    handle_page_fault       /* if not, try to insert a HPTE */
-       andis.  r0,r4,DSISR_DABRMATCH@h
-       bne-    handle_dabr_fault
        CURRENT_THREAD_INFO(r11, r1)
        lwz     r0,TI_PREEMPT(r11)      /* If we're in an "NMI" */
        andis.  r0,r0,NMI_MASK@h        /* (i.e. an irq when soft-disabled) */
@@ -1438,11 +1436,16 @@ do_hash_page:
 
        /* Error */
        blt-    13f
+
+       /* Reload DSISR into r4 for the DABR check below */
+       ld      r4,_DSISR(r1)
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
 /* Here we have a page fault that hash_page can't handle. */
 handle_page_fault:
-11:    ld      r4,_DAR(r1)
+11:    andis.  r0,r4,DSISR_DABRMATCH@h
+       bne-    handle_dabr_fault
+       ld      r4,_DAR(r1)
        ld      r5,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_page_fault
index fc4343514bed8b0f05a88e64caf0285c44ee8ea0..01addfb0ed0a42216d64c7692c3fea4694c528fb 100644 (file)
@@ -43,6 +43,12 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
 
+int is_current_kprobe_addr(unsigned long addr)
+{
+       struct kprobe *p = kprobe_running();
+       return (p && (unsigned long)p->addr == addr) ? 1 : 0;
+}
+
 bool arch_within_kprobe_blacklist(unsigned long addr)
 {
        return  (addr >= (unsigned long)__kprobes_text_start &&
@@ -617,6 +623,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
        regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
 #endif
 
+       /*
+        * jprobes use jprobe_return() which skips the normal return
+        * path of the function, and this messes up the accounting of the
+        * function graph tracer.
+        *
+        * Pause function graph tracing while performing the jprobe function.
+        */
+       pause_graph_tracing();
+
        return 1;
 }
 NOKPROBE_SYMBOL(setjmp_pre_handler);
@@ -642,6 +657,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
         * saved regs...
         */
        memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+       /* It's OK to start function graph tracing again */
+       unpause_graph_tracing();
        preempt_enable_no_resched();
        return 1;
 }
index a8c1f99e96072530cb1f2d9ed702dffd78665720..4640f6d64f8b406a636d60c4ea2263658dde5be6 100644 (file)
@@ -615,6 +615,24 @@ void __init exc_lvl_early_init(void)
 }
 #endif
 
+/*
+ * Emergency stacks are used for a range of things, from asynchronous
+ * NMIs (system reset, machine check) to synchronous, process context.
+ * We set preempt_count to zero, even though that isn't necessarily correct. To
+ * get the right value we'd need to copy it from the previous thread_info, but
+ * doing that might fault causing more problems.
+ * TODO: what to do with accounting?
+ */
+static void emerg_stack_init_thread_info(struct thread_info *ti, int cpu)
+{
+       ti->task = NULL;
+       ti->cpu = cpu;
+       ti->preempt_count = 0;
+       ti->local_flags = 0;
+       ti->flags = 0;
+       klp_init_thread_info(ti);
+}
+
 /*
  * Stack space used when we detect a bad kernel stack pointer, and
  * early in SMP boots before relocation is enabled. Exclusive emergency
@@ -633,24 +651,31 @@ void __init emergency_stack_init(void)
         * Since we use these as temporary stacks during secondary CPU
         * bringup, we need to get at them in real mode. This means they
         * must also be within the RMO region.
+        *
+        * The IRQ stacks allocated elsewhere in this file are zeroed and
+        * initialized in kernel/irq.c. These are initialized here in order
+        * to have emergency stacks available as early as possible.
         */
        limit = min(safe_stack_limit(), ppc64_rma_size);
 
        for_each_possible_cpu(i) {
                struct thread_info *ti;
                ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
-               klp_init_thread_info(ti);
+               memset(ti, 0, THREAD_SIZE);
+               emerg_stack_init_thread_info(ti, i);
                paca[i].emergency_sp = (void *)ti + THREAD_SIZE;
 
 #ifdef CONFIG_PPC_BOOK3S_64
                /* emergency stack for NMI exception handling. */
                ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
-               klp_init_thread_info(ti);
+               memset(ti, 0, THREAD_SIZE);
+               emerg_stack_init_thread_info(ti, i);
                paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE;
 
                /* emergency stack for machine check exception handling. */
                ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
-               klp_init_thread_info(ti);
+               memset(ti, 0, THREAD_SIZE);
+               emerg_stack_init_thread_info(ti, i);
                paca[i].mc_emergency_sp = (void *)ti + THREAD_SIZE;
 #endif
        }
index 7c933a99f5d578bdfd1408b16d4e7fe33e95e4a9..c98e90b4ea7b1f15a2dd7157300376e370774cf2 100644 (file)
@@ -45,10 +45,14 @@ _GLOBAL(ftrace_caller)
        stdu    r1,-SWITCH_FRAME_SIZE(r1)
 
        /* Save all gprs to pt_regs */
-       SAVE_8GPRS(0,r1)
-       SAVE_8GPRS(8,r1)
-       SAVE_8GPRS(16,r1)
-       SAVE_8GPRS(24,r1)
+       SAVE_GPR(0, r1)
+       SAVE_10GPRS(2, r1)
+       SAVE_10GPRS(12, r1)
+       SAVE_10GPRS(22, r1)
+
+       /* Save previous stack pointer (r1) */
+       addi    r8, r1, SWITCH_FRAME_SIZE
+       std     r8, GPR1(r1)
 
        /* Load special regs for save below */
        mfmsr   r8
@@ -95,18 +99,44 @@ ftrace_call:
        bl      ftrace_stub
        nop
 
-       /* Load ctr with the possibly modified NIP */
-       ld      r3, _NIP(r1)
-       mtctr   r3
+       /* Load the possibly modified NIP */
+       ld      r15, _NIP(r1)
+
 #ifdef CONFIG_LIVEPATCH
-       cmpd    r14,r3          /* has NIP been altered? */
+       cmpd    r14, r15        /* has NIP been altered? */
+#endif
+
+#if defined(CONFIG_LIVEPATCH) && defined(CONFIG_KPROBES_ON_FTRACE)
+       /* NIP has not been altered, skip over further checks */
+       beq     1f
+
+       /* Check if there is an active kprobe on us */
+       subi    r3, r14, 4
+       bl      is_current_kprobe_addr
+       nop
+
+       /*
+        * If r3 == 1, then this is a kprobe/jprobe.
+        * else, this is livepatched function.
+        *
+        * The conditional branch for livepatch_handler below will use the
+        * result of this comparison. For kprobe/jprobe, we just need to branch to
+        * the new NIP, not call livepatch_handler. The branch below is bne, so we
+        * want CR0[EQ] to be true if this is a kprobe/jprobe. Which means we want
+        * CR0[EQ] = (r3 == 1).
+        */
+       cmpdi   r3, 1
+1:
 #endif
 
+       /* Load CTR with the possibly modified NIP */
+       mtctr   r15
+
        /* Restore gprs */
-       REST_8GPRS(0,r1)
-       REST_8GPRS(8,r1)
-       REST_8GPRS(16,r1)
-       REST_8GPRS(24,r1)
+       REST_GPR(0,r1)
+       REST_10GPRS(2,r1)
+       REST_10GPRS(12,r1)
+       REST_10GPRS(22,r1)
 
        /* Restore possibly modified LR */
        ld      r0, _LINK(r1)
@@ -119,7 +149,10 @@ ftrace_call:
        addi r1, r1, SWITCH_FRAME_SIZE
 
 #ifdef CONFIG_LIVEPATCH
-        /* Based on the cmpd above, if the NIP was altered handle livepatch */
+        /*
+        * Based on the cmpd or cmpdi above, if the NIP was altered and we're
+        * not on a kprobe/jprobe, then handle livepatch.
+        */
        bne-    livepatch_handler
 #endif
 
index 42b7a4fd57d9a557f8278a9f9a8c228f2758a1e8..8d1a365b8edc45fa9f655b77789a0d8602b462fd 100644 (file)
@@ -1486,6 +1486,14 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
                r = set_vpa(vcpu, &vcpu->arch.dtl, addr, len);
                break;
        case KVM_REG_PPC_TB_OFFSET:
+               /*
+                * POWER9 DD1 has an erratum where writing TBU40 causes
+                * the timebase to lose ticks.  So we don't let the
+                * timebase offset be changed on P9 DD1.  (It is
+                * initialized to zero.)
+                */
+               if (cpu_has_feature(CPU_FTR_POWER9_DD1))
+                       break;
                /* round up to multiple of 2^24 */
                vcpu->arch.vcore->tb_offset =
                        ALIGN(set_reg_val(id, *val), 1UL << 24);
@@ -2907,12 +2915,36 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
 {
        int r;
        int srcu_idx;
+       unsigned long ebb_regs[3] = {}; /* shut up GCC */
+       unsigned long user_tar = 0;
+       unsigned int user_vrsave;
 
        if (!vcpu->arch.sane) {
                run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
                return -EINVAL;
        }
 
+       /*
+        * Don't allow entry with a suspended transaction, because
+        * the guest entry/exit code will lose it.
+        * If the guest has TM enabled, save away their TM-related SPRs
+        * (they will get restored by the TM unavailable interrupt).
+        */
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       if (cpu_has_feature(CPU_FTR_TM) && current->thread.regs &&
+           (current->thread.regs->msr & MSR_TM)) {
+               if (MSR_TM_ACTIVE(current->thread.regs->msr)) {
+                       run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+                       run->fail_entry.hardware_entry_failure_reason = 0;
+                       return -EINVAL;
+               }
+               current->thread.tm_tfhar = mfspr(SPRN_TFHAR);
+               current->thread.tm_tfiar = mfspr(SPRN_TFIAR);
+               current->thread.tm_texasr = mfspr(SPRN_TEXASR);
+               current->thread.regs->msr &= ~MSR_TM;
+       }
+#endif
+
        kvmppc_core_prepare_to_enter(vcpu);
 
        /* No need to go into the guest when all we'll do is come back out */
@@ -2934,6 +2966,15 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
 
        flush_all_to_thread(current);
 
+       /* Save userspace EBB and other register values */
+       if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
+               ebb_regs[0] = mfspr(SPRN_EBBHR);
+               ebb_regs[1] = mfspr(SPRN_EBBRR);
+               ebb_regs[2] = mfspr(SPRN_BESCR);
+               user_tar = mfspr(SPRN_TAR);
+       }
+       user_vrsave = mfspr(SPRN_VRSAVE);
+
        vcpu->arch.wqp = &vcpu->arch.vcore->wq;
        vcpu->arch.pgdir = current->mm->pgd;
        vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;
@@ -2960,6 +3001,16 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
                }
        } while (is_kvmppc_resume_guest(r));
 
+       /* Restore userspace EBB and other register values */
+       if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
+               mtspr(SPRN_EBBHR, ebb_regs[0]);
+               mtspr(SPRN_EBBRR, ebb_regs[1]);
+               mtspr(SPRN_BESCR, ebb_regs[2]);
+               mtspr(SPRN_TAR, user_tar);
+               mtspr(SPRN_FSCR, current->thread.fscr);
+       }
+       mtspr(SPRN_VRSAVE, user_vrsave);
+
  out:
        vcpu->arch.state = KVMPPC_VCPU_NOTREADY;
        atomic_dec(&vcpu->kvm->arch.vcpus_running);
index 0fdc4a28970b3c53d821088dae8eec5e2282dca4..404deb512844424d07bba8ead5bd77e70aee82af 100644 (file)
@@ -121,10 +121,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
         * Put whatever is in the decrementer into the
         * hypervisor decrementer.
         */
+BEGIN_FTR_SECTION
+       ld      r5, HSTATE_KVM_VCORE(r13)
+       ld      r6, VCORE_KVM(r5)
+       ld      r9, KVM_HOST_LPCR(r6)
+       andis.  r9, r9, LPCR_LD@h
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        mfspr   r8,SPRN_DEC
        mftb    r7
-       mtspr   SPRN_HDEC,r8
+BEGIN_FTR_SECTION
+       /* On POWER9, don't sign-extend if host LPCR[LD] bit is set */
+       bne     32f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        extsw   r8,r8
+32:    mtspr   SPRN_HDEC,r8
        add     r8,r8,r7
        std     r8,HSTATE_DECEXP(r13)
 
index bdb3f76ceb6b9ff0e25e5b3b56c3be48dd6f65cc..4888dd494604f101a194a51ff168c44d85c4354d 100644 (file)
 #include <asm/opal.h>
 #include <asm/xive-regs.h>
 
+/* Sign-extend HDEC if not on POWER9 */
+#define EXTEND_HDEC(reg)                       \
+BEGIN_FTR_SECTION;                             \
+       extsw   reg, reg;                       \
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
+
 #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM)
 
 /* Values in HSTATE_NAPPING(r13) */
 #define NAPPING_CEDE   1
 #define NAPPING_NOVCPU 2
 
+/* Stack frame offsets for kvmppc_hv_entry */
+#define SFS                    144
+#define STACK_SLOT_TRAP                (SFS-4)
+#define STACK_SLOT_TID         (SFS-16)
+#define STACK_SLOT_PSSCR       (SFS-24)
+#define STACK_SLOT_PID         (SFS-32)
+#define STACK_SLOT_IAMR                (SFS-40)
+#define STACK_SLOT_CIABR       (SFS-48)
+#define STACK_SLOT_DAWR                (SFS-56)
+#define STACK_SLOT_DAWRX       (SFS-64)
+
 /*
  * Call kvmppc_hv_entry in real mode.
  * Must be called with interrupts hard-disabled.
@@ -214,6 +231,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 kvmppc_primary_no_guest:
        /* We handle this much like a ceded vcpu */
        /* put the HDEC into the DEC, since HDEC interrupts don't wake us */
+       /* HDEC may be larger than DEC for arch >= v3.00, but since the */
+       /* HDEC value came from DEC in the first place, it will fit */
        mfspr   r3, SPRN_HDEC
        mtspr   SPRN_DEC, r3
        /*
@@ -295,8 +314,9 @@ kvm_novcpu_wakeup:
 
        /* See if our timeslice has expired (HDEC is negative) */
        mfspr   r0, SPRN_HDEC
+       EXTEND_HDEC(r0)
        li      r12, BOOK3S_INTERRUPT_HV_DECREMENTER
-       cmpwi   r0, 0
+       cmpdi   r0, 0
        blt     kvm_novcpu_exit
 
        /* Got an IPI but other vcpus aren't yet exiting, must be a latecomer */
@@ -319,10 +339,10 @@ kvm_novcpu_exit:
        bl      kvmhv_accumulate_time
 #endif
 13:    mr      r3, r12
-       stw     r12, 112-4(r1)
+       stw     r12, STACK_SLOT_TRAP(r1)
        bl      kvmhv_commence_exit
        nop
-       lwz     r12, 112-4(r1)
+       lwz     r12, STACK_SLOT_TRAP(r1)
        b       kvmhv_switch_to_host
 
 /*
@@ -390,8 +410,8 @@ kvm_secondary_got_guest:
        lbz     r4, HSTATE_PTID(r13)
        cmpwi   r4, 0
        bne     63f
-       lis     r6, 0x7fff
-       ori     r6, r6, 0xffff
+       LOAD_REG_ADDR(r6, decrementer_max)
+       ld      r6, 0(r6)
        mtspr   SPRN_HDEC, r6
        /* and set per-LPAR registers, if doing dynamic micro-threading */
        ld      r6, HSTATE_SPLIT_MODE(r13)
@@ -545,11 +565,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
  *                                                                            *
  *****************************************************************************/
 
-/* Stack frame offsets */
-#define STACK_SLOT_TID         (112-16)
-#define STACK_SLOT_PSSCR       (112-24)
-#define STACK_SLOT_PID         (112-32)
-
 .global kvmppc_hv_entry
 kvmppc_hv_entry:
 
@@ -565,7 +580,7 @@ kvmppc_hv_entry:
         */
        mflr    r0
        std     r0, PPC_LR_STKOFF(r1)
-       stdu    r1, -112(r1)
+       stdu    r1, -SFS(r1)
 
        /* Save R1 in the PACA */
        std     r1, HSTATE_HOST_R1(r13)
@@ -749,10 +764,20 @@ BEGIN_FTR_SECTION
        mfspr   r5, SPRN_TIDR
        mfspr   r6, SPRN_PSSCR
        mfspr   r7, SPRN_PID
+       mfspr   r8, SPRN_IAMR
        std     r5, STACK_SLOT_TID(r1)
        std     r6, STACK_SLOT_PSSCR(r1)
        std     r7, STACK_SLOT_PID(r1)
+       std     r8, STACK_SLOT_IAMR(r1)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+BEGIN_FTR_SECTION
+       mfspr   r5, SPRN_CIABR
+       mfspr   r6, SPRN_DAWR
+       mfspr   r7, SPRN_DAWRX
+       std     r5, STACK_SLOT_CIABR(r1)
+       std     r6, STACK_SLOT_DAWR(r1)
+       std     r7, STACK_SLOT_DAWRX(r1)
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
 BEGIN_FTR_SECTION
        /* Set partition DABR */
@@ -968,7 +993,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
 
        /* Check if HDEC expires soon */
        mfspr   r3, SPRN_HDEC
-       cmpwi   r3, 512         /* 1 microsecond */
+       EXTEND_HDEC(r3)
+       cmpdi   r3, 512         /* 1 microsecond */
        blt     hdec_soon
 
 #ifdef CONFIG_KVM_XICS
@@ -1505,11 +1531,10 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
         * set by the guest could disrupt the host.
         */
        li      r0, 0
-       mtspr   SPRN_IAMR, r0
-       mtspr   SPRN_CIABR, r0
-       mtspr   SPRN_DAWRX, r0
+       mtspr   SPRN_PSPB, r0
        mtspr   SPRN_WORT, r0
 BEGIN_FTR_SECTION
+       mtspr   SPRN_IAMR, r0
        mtspr   SPRN_TCSCR, r0
        /* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */
        li      r0, 1
@@ -1525,6 +1550,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
        std     r6,VCPU_UAMOR(r9)
        li      r6,0
        mtspr   SPRN_AMR,r6
+       mtspr   SPRN_UAMOR, r6
 
        /* Switch DSCR back to host value */
        mfspr   r8, SPRN_DSCR
@@ -1669,13 +1695,23 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        ptesync
 
        /* Restore host values of some registers */
+BEGIN_FTR_SECTION
+       ld      r5, STACK_SLOT_CIABR(r1)
+       ld      r6, STACK_SLOT_DAWR(r1)
+       ld      r7, STACK_SLOT_DAWRX(r1)
+       mtspr   SPRN_CIABR, r5
+       mtspr   SPRN_DAWR, r6
+       mtspr   SPRN_DAWRX, r7
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 BEGIN_FTR_SECTION
        ld      r5, STACK_SLOT_TID(r1)
        ld      r6, STACK_SLOT_PSSCR(r1)
        ld      r7, STACK_SLOT_PID(r1)
+       ld      r8, STACK_SLOT_IAMR(r1)
        mtspr   SPRN_TIDR, r5
        mtspr   SPRN_PSSCR, r6
        mtspr   SPRN_PID, r7
+       mtspr   SPRN_IAMR, r8
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 BEGIN_FTR_SECTION
        PPC_INVALIDATE_ERAT
@@ -1819,8 +1855,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
        li      r0, KVM_GUEST_MODE_NONE
        stb     r0, HSTATE_IN_GUEST(r13)
 
-       ld      r0, 112+PPC_LR_STKOFF(r1)
-       addi    r1, r1, 112
+       ld      r0, SFS+PPC_LR_STKOFF(r1)
+       addi    r1, r1, SFS
        mtlr    r0
        blr
 
@@ -2366,12 +2402,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
        mfspr   r3, SPRN_DEC
        mfspr   r4, SPRN_HDEC
        mftb    r5
-       cmpw    r3, r4
+       extsw   r3, r3
+       EXTEND_HDEC(r4)
+       cmpd    r3, r4
        ble     67f
        mtspr   SPRN_DEC, r4
 67:
        /* save expiry time of guest decrementer */
-       extsw   r3, r3
        add     r3, r3, r5
        ld      r4, HSTATE_KVM_VCPU(r13)
        ld      r5, HSTATE_KVM_VCORE(r13)
index 023a31133c37ce0714fc4457a5ff73062ce8abbc..4636ca6e7d383b7d3ce26b18df01152b8087a8ec 100644 (file)
@@ -69,7 +69,7 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd)
 {
        /* If the XIVE supports the new "store EOI facility, use it */
        if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
-               __x_writeq(0, __x_eoi_page(xd));
+               __x_writeq(0, __x_eoi_page(xd) + XIVE_ESB_STORE_EOI);
        else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) {
                opal_int_eoi(hw_irq);
        } else {
@@ -89,7 +89,7 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd)
                 * properly.
                 */
                if (xd->flags & XIVE_IRQ_FLAG_LSI)
-                       __x_readq(__x_eoi_page(xd));
+                       __x_readq(__x_eoi_page(xd) + XIVE_ESB_LOAD_EOI);
                else {
                        eoi_val = GLUE(X_PFX,esb_load)(xd, XIVE_ESB_SET_PQ_00);
 
index 6575b9aabef4df3f0e8903417d121b47c1f2f2a4..a12e86395025f9c7fcdb8a12c76ae642a1ef7cb8 100644 (file)
@@ -68,7 +68,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                addr = ALIGN(addr, huge_page_size(h));
                vma = find_vma(mm, addr);
                if (mm->task_size - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
        /*
index 9dbd2a733d6b12401ee9157cd6309cd835b2b87b..0ee6be4f1ba44e231da18c7e38d217610ac4bcd5 100644 (file)
@@ -112,7 +112,7 @@ radix__arch_get_unmapped_area(struct file *filp, unsigned long addr,
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (mm->task_size - len >= addr && addr >= mmap_min_addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
@@ -157,7 +157,7 @@ radix__arch_get_unmapped_area_topdown(struct file *filp,
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (mm->task_size - len >= addr && addr >= mmap_min_addr &&
-                               (!vma || addr + len <= vma->vm_start))
+                               (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index 966b9fccfa66b4268c5421252364bf2af6d6253f..45f6740dd407dae752c25a19ad2ae4a804a19858 100644 (file)
@@ -99,7 +99,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr,
        if ((mm->task_size - len) < addr)
                return 0;
        vma = find_vma(mm, addr);
-       return (!vma || (addr + len) <= vma->vm_start);
+       return (!vma || (addr + len) <= vm_start_gap(vma));
 }
 
 static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
index cbd82fde57702e2a210608dc2e1800ae574465e0..09ceea6175ba9dc1d99b8b56eadae1367138b166 100644 (file)
@@ -101,5 +101,6 @@ void perf_get_regs_user(struct perf_regs *regs_user,
                        struct pt_regs *regs_user_copy)
 {
        regs_user->regs = task_pt_regs(current);
-       regs_user->abi  = perf_reg_abi(current);
+       regs_user->abi = (regs_user->regs) ? perf_reg_abi(current) :
+                        PERF_SAMPLE_REGS_ABI_NONE;
 }
index 78fa9395b8c55c3dab2c10e1a245f5a7a04be8a2..b5d960d6db3d0b18d33273b31ac67e03caebd02b 100644 (file)
@@ -75,7 +75,8 @@ struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index)
        if (WARN_ON(!gpdev))
                return NULL;
 
-       if (WARN_ON(!gpdev->dev.of_node))
+       /* Not all PCI devices have device-tree nodes */
+       if (!gpdev->dev.of_node)
                return NULL;
 
        /* Get assoicated PCI device */
@@ -448,7 +449,7 @@ static int mmio_launch_invalidate(struct npu *npu, unsigned long launch,
        return mmio_atsd_reg;
 }
 
-static int mmio_invalidate_pid(struct npu *npu, unsigned long pid)
+static int mmio_invalidate_pid(struct npu *npu, unsigned long pid, bool flush)
 {
        unsigned long launch;
 
@@ -464,12 +465,15 @@ static int mmio_invalidate_pid(struct npu *npu, unsigned long pid)
        /* PID */
        launch |= pid << PPC_BITLSHIFT(38);
 
+       /* No flush */
+       launch |= !flush << PPC_BITLSHIFT(39);
+
        /* Invalidating the entire process doesn't use a va */
        return mmio_launch_invalidate(npu, launch, 0);
 }
 
 static int mmio_invalidate_va(struct npu *npu, unsigned long va,
-                       unsigned long pid)
+                       unsigned long pid, bool flush)
 {
        unsigned long launch;
 
@@ -485,26 +489,60 @@ static int mmio_invalidate_va(struct npu *npu, unsigned long va,
        /* PID */
        launch |= pid << PPC_BITLSHIFT(38);
 
+       /* No flush */
+       launch |= !flush << PPC_BITLSHIFT(39);
+
        return mmio_launch_invalidate(npu, launch, va);
 }
 
 #define mn_to_npu_context(x) container_of(x, struct npu_context, mn)
 
+struct mmio_atsd_reg {
+       struct npu *npu;
+       int reg;
+};
+
+static void mmio_invalidate_wait(
+       struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS], bool flush)
+{
+       struct npu *npu;
+       int i, reg;
+
+       /* Wait for all invalidations to complete */
+       for (i = 0; i <= max_npu2_index; i++) {
+               if (mmio_atsd_reg[i].reg < 0)
+                       continue;
+
+               /* Wait for completion */
+               npu = mmio_atsd_reg[i].npu;
+               reg = mmio_atsd_reg[i].reg;
+               while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT))
+                       cpu_relax();
+
+               put_mmio_atsd_reg(npu, reg);
+
+               /*
+                * The GPU requires two flush ATSDs to ensure all entries have
+                * been flushed. We use PID 0 as it will never be used for a
+                * process on the GPU.
+                */
+               if (flush)
+                       mmio_invalidate_pid(npu, 0, true);
+       }
+}
+
 /*
  * Invalidate either a single address or an entire PID depending on
  * the value of va.
  */
 static void mmio_invalidate(struct npu_context *npu_context, int va,
-                       unsigned long address)
+                       unsigned long address, bool flush)
 {
-       int i, j, reg;
+       int i, j;
        struct npu *npu;
        struct pnv_phb *nphb;
        struct pci_dev *npdev;
-       struct {
-               struct npu *npu;
-               int reg;
-       } mmio_atsd_reg[NV_MAX_NPUS];
+       struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS];
        unsigned long pid = npu_context->mm->context.id;
 
        /*
@@ -524,10 +562,11 @@ static void mmio_invalidate(struct npu_context *npu_context, int va,
 
                        if (va)
                                mmio_atsd_reg[i].reg =
-                                       mmio_invalidate_va(npu, address, pid);
+                                       mmio_invalidate_va(npu, address, pid,
+                                                       flush);
                        else
                                mmio_atsd_reg[i].reg =
-                                       mmio_invalidate_pid(npu, pid);
+                                       mmio_invalidate_pid(npu, pid, flush);
 
                        /*
                         * The NPU hardware forwards the shootdown to all GPUs
@@ -543,18 +582,10 @@ static void mmio_invalidate(struct npu_context *npu_context, int va,
         */
        flush_tlb_mm(npu_context->mm);
 
-       /* Wait for all invalidations to complete */
-       for (i = 0; i <= max_npu2_index; i++) {
-               if (mmio_atsd_reg[i].reg < 0)
-                       continue;
-
-               /* Wait for completion */
-               npu = mmio_atsd_reg[i].npu;
-               reg = mmio_atsd_reg[i].reg;
-               while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT))
-                       cpu_relax();
-               put_mmio_atsd_reg(npu, reg);
-       }
+       mmio_invalidate_wait(mmio_atsd_reg, flush);
+       if (flush)
+               /* Wait for the flush to complete */
+               mmio_invalidate_wait(mmio_atsd_reg, false);
 }
 
 static void pnv_npu2_mn_release(struct mmu_notifier *mn,
@@ -570,7 +601,7 @@ static void pnv_npu2_mn_release(struct mmu_notifier *mn,
         * There should be no more translation requests for this PID, but we
         * need to ensure any entries for it are removed from the TLB.
         */
-       mmio_invalidate(npu_context, 0, 0);
+       mmio_invalidate(npu_context, 0, 0, true);
 }
 
 static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn,
@@ -580,7 +611,7 @@ static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn,
 {
        struct npu_context *npu_context = mn_to_npu_context(mn);
 
-       mmio_invalidate(npu_context, 1, address);
+       mmio_invalidate(npu_context, 1, address, true);
 }
 
 static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn,
@@ -589,7 +620,7 @@ static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn,
 {
        struct npu_context *npu_context = mn_to_npu_context(mn);
 
-       mmio_invalidate(npu_context, 1, address);
+       mmio_invalidate(npu_context, 1, address, true);
 }
 
 static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
@@ -599,8 +630,11 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
        struct npu_context *npu_context = mn_to_npu_context(mn);
        unsigned long address;
 
-       for (address = start; address <= end; address += PAGE_SIZE)
-               mmio_invalidate(npu_context, 1, address);
+       for (address = start; address < end; address += PAGE_SIZE)
+               mmio_invalidate(npu_context, 1, address, false);
+
+       /* Do the flush only on the final addess == end */
+       mmio_invalidate(npu_context, 1, address, true);
 }
 
 static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
@@ -650,8 +684,11 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                /* No nvlink associated with this GPU device */
                return ERR_PTR(-ENODEV);
 
-       if (!mm) {
-               /* kernel thread contexts are not supported */
+       if (!mm || mm->context.id == 0) {
+               /*
+                * Kernel thread contexts are not supported and context id 0 is
+                * reserved on the GPU.
+                */
                return ERR_PTR(-EINVAL);
        }
 
index 913825086b8df675f68f69a0b993934c3b607104..8f5e3035483bc3fac3b552f793ac358344774661 100644 (file)
@@ -297,7 +297,7 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd)
 {
        /* If the XIVE supports the new "store EOI facility, use it */
        if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
-               out_be64(xd->eoi_mmio, 0);
+               out_be64(xd->eoi_mmio + XIVE_ESB_STORE_EOI, 0);
        else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) {
                /*
                 * The FW told us to call it. This happens for some
index a5039fa8931442a5c5b35c77fbee22fe86e78131..282072206df7076e732b8fcd121ca49b1693634a 100644 (file)
@@ -30,6 +30,7 @@ CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -44,7 +45,10 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_SQ=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_BSD_DISKLABEL=y
@@ -90,6 +94,8 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=m
 CONFIG_XFRM_USER=m
 CONFIG_NET_KEY=m
+CONFIG_SMC=m
+CONFIG_SMC_DIAG=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -359,6 +365,7 @@ CONFIG_NET_ACT_SIMP=m
 CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
+CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
@@ -367,16 +374,19 @@ CONFIG_DEVTMPFS=y
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
 CONFIG_CONNECTOR=y
+CONFIG_ZRAM=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_OSD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_ATA_OVER_ETH=m
+CONFIG_BLK_DEV_RAM_DAX=y
 CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_RBD=m
 CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_GENWQE=m
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
@@ -442,6 +452,8 @@ CONFIG_NLMON=m
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
 CONFIG_MLX4_EN=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
 # CONFIG_NET_VENDOR_NATSEMI is not set
 CONFIG_PPP=m
 CONFIG_PPP_BSDCOMP=m
@@ -452,7 +464,6 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
@@ -471,6 +482,7 @@ CONFIG_DIAG288_WATCHDOG=m
 CONFIG_INFINIBAND=m
 CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_INFINIBAND=m
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
@@ -487,12 +499,18 @@ CONFIG_XFS_POSIX_ACL=y
 CONFIG_XFS_RT=y
 CONFIG_XFS_DEBUG=y
 CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
 CONFIG_OCFS2_FS=m
 CONFIG_BTRFS_FS=y
 CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_BTRFS_DEBUG=y
 CONFIG_NILFS2_FS=m
+CONFIG_FS_DAX=y
+CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QUOTA_DEBUG=y
 CONFIG_QFMT_V1=m
 CONFIG_QFMT_V2=m
 CONFIG_AUTOFS4_FS=m
@@ -558,6 +576,7 @@ CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_RODATA_TEST=y
 CONFIG_DEBUG_OBJECTS=y
 CONFIG_DEBUG_OBJECTS_SELFTEST=y
 CONFIG_DEBUG_OBJECTS_FREE=y
@@ -580,7 +599,6 @@ CONFIG_DETECT_HUNG_TASK=y
 CONFIG_WQ_WATCHDOG=y
 CONFIG_PANIC_ON_OOPS=y
 CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
 CONFIG_PROVE_LOCKING=y
@@ -595,6 +613,7 @@ CONFIG_RCU_TORTURE_TEST=m
 CONFIG_RCU_CPU_STALL_TIMEOUT=300
 CONFIG_NOTIFIER_ERROR_INJECTION=m
 CONFIG_PM_NOTIFIER_ERROR_INJECT=m
+CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
 CONFIG_FAULT_INJECTION=y
 CONFIG_FAILSLAB=y
 CONFIG_FAIL_PAGE_ALLOC=y
@@ -616,13 +635,12 @@ CONFIG_HIST_TRIGGERS=y
 CONFIG_TRACE_ENUM_MAP_FILE=y
 CONFIG_LKDTM=m
 CONFIG_TEST_LIST_SORT=y
+CONFIG_TEST_SORT=y
 CONFIG_KPROBES_SANITY_TEST=y
 CONFIG_RBTREE_TEST=y
 CONFIG_INTERVAL_TREE_TEST=m
 CONFIG_PERCPU_TEST=m
 CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_TEST_STRING_HELPERS=y
-CONFIG_TEST_KSTRTOX=y
 CONFIG_DMA_API_DEBUG=y
 CONFIG_TEST_BPF=m
 CONFIG_BUG_ON_DATA_CORRUPTION=y
@@ -630,6 +648,7 @@ CONFIG_S390_PTDUMP=y
 CONFIG_ENCRYPTED_KEYS=m
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
@@ -640,7 +659,9 @@ CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_DH=m
 CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_USER=m
+CONFIG_CRYPTO_PCRYPT=m
 CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
@@ -648,6 +669,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_CRC32=m
@@ -657,8 +679,10 @@ CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
 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
@@ -674,6 +698,7 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
 CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
@@ -685,6 +710,7 @@ CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_DES_S390=m
 CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_PAES_S390=m
 CONFIG_CRYPTO_GHASH_S390=m
 CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_ASYMMETRIC_KEY_TYPE=y
@@ -692,6 +718,7 @@ CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
 CONFIG_X509_CERTIFICATE_PARSER=m
 CONFIG_CRC7=m
 CONFIG_CRC8=m
+CONFIG_RANDOM32_SELFTEST=y
 CONFIG_CORDIC=m
 CONFIG_CMM=m
 CONFIG_APPLDATA_BASE=y
index 83970b5afb2bc32f8ca86545c6eea31ece2d0001..3c6b78189fbcc805225b9b2e05d5812c5a5f9b67 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -46,7 +47,10 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_SQ=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_BSD_DISKLABEL=y
@@ -88,6 +92,8 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=m
 CONFIG_XFRM_USER=m
 CONFIG_NET_KEY=m
+CONFIG_SMC=m
+CONFIG_SMC_DIAG=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -356,6 +362,7 @@ CONFIG_NET_ACT_SIMP=m
 CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
+CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
@@ -364,16 +371,18 @@ CONFIG_DEVTMPFS=y
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
 CONFIG_CONNECTOR=y
+CONFIG_ZRAM=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_OSD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_ATA_OVER_ETH=m
+CONFIG_BLK_DEV_RAM_DAX=y
 CONFIG_VIRTIO_BLK=y
 CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_GENWQE=m
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
@@ -439,6 +448,8 @@ CONFIG_NLMON=m
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
 CONFIG_MLX4_EN=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
 # CONFIG_NET_VENDOR_NATSEMI is not set
 CONFIG_PPP=m
 CONFIG_PPP_BSDCOMP=m
@@ -449,7 +460,6 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
@@ -468,6 +478,7 @@ CONFIG_DIAG288_WATCHDOG=m
 CONFIG_INFINIBAND=m
 CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_INFINIBAND=m
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
@@ -483,11 +494,15 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_POSIX_ACL=y
 CONFIG_XFS_RT=y
 CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
 CONFIG_OCFS2_FS=m
 CONFIG_BTRFS_FS=y
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_NILFS2_FS=m
+CONFIG_FS_DAX=y
+CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 CONFIG_QFMT_V1=m
 CONFIG_QFMT_V2=m
@@ -553,7 +568,6 @@ CONFIG_UNUSED_SYMBOLS=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_PANIC_ON_OOPS=y
-CONFIG_TIMER_STATS=y
 CONFIG_RCU_TORTURE_TEST=m
 CONFIG_RCU_CPU_STALL_TIMEOUT=60
 CONFIG_LATENCYTOP=y
@@ -576,6 +590,7 @@ CONFIG_BIG_KEYS=y
 CONFIG_ENCRYPTED_KEYS=m
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
@@ -599,6 +614,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_CRC32=m
@@ -611,6 +627,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
@@ -626,16 +643,19 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
 CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 CONFIG_ZCRYPT=m
+CONFIG_PKEY=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_DES_S390=m
 CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_PAES_S390=m
 CONFIG_CRYPTO_GHASH_S390=m
 CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_CRC7=m
index fbc6542aaf5955bdeb839fbf03496d2b39113688..653d72bcc007db3b2e39aa7225b447c18c9d9cb2 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -44,7 +45,10 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_SQ=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_BSD_DISKLABEL=y
@@ -86,6 +90,8 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=m
 CONFIG_XFRM_USER=m
 CONFIG_NET_KEY=m
+CONFIG_SMC=m
+CONFIG_SMC_DIAG=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -354,6 +360,7 @@ CONFIG_NET_ACT_SIMP=m
 CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
+CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
@@ -362,16 +369,18 @@ CONFIG_DEVTMPFS=y
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
 CONFIG_CONNECTOR=y
+CONFIG_ZRAM=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_OSD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_ATA_OVER_ETH=m
+CONFIG_BLK_DEV_RAM_DAX=y
 CONFIG_VIRTIO_BLK=y
 CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_GENWQE=m
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
@@ -437,6 +446,8 @@ CONFIG_NLMON=m
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
 CONFIG_MLX4_EN=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
 # CONFIG_NET_VENDOR_NATSEMI is not set
 CONFIG_PPP=m
 CONFIG_PPP_BSDCOMP=m
@@ -447,7 +458,6 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
@@ -466,6 +476,7 @@ CONFIG_DIAG288_WATCHDOG=m
 CONFIG_INFINIBAND=m
 CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_INFINIBAND=m
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
@@ -481,11 +492,15 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_POSIX_ACL=y
 CONFIG_XFS_RT=y
 CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
 CONFIG_OCFS2_FS=m
 CONFIG_BTRFS_FS=y
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_NILFS2_FS=m
+CONFIG_FS_DAX=y
+CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 CONFIG_QFMT_V1=m
 CONFIG_QFMT_V2=m
@@ -551,7 +566,6 @@ CONFIG_UNUSED_SYMBOLS=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_PANIC_ON_OOPS=y
-CONFIG_TIMER_STATS=y
 CONFIG_RCU_TORTURE_TEST=m
 CONFIG_RCU_CPU_STALL_TIMEOUT=60
 CONFIG_LATENCYTOP=y
@@ -574,6 +588,7 @@ CONFIG_BIG_KEYS=y
 CONFIG_ENCRYPTED_KEYS=m
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
@@ -597,6 +612,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_CRC32=m
@@ -609,6 +625,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
@@ -624,6 +641,7 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
 CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
@@ -635,6 +653,7 @@ CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_DES_S390=m
 CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_PAES_S390=m
 CONFIG_CRYPTO_GHASH_S390=m
 CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_CRC7=m
index e23d97c13735b94e43bb965341b93766413a5502..afa46a7406eaeddbbf70bbaf384f49ffa0535874 100644 (file)
@@ -12,8 +12,10 @@ CONFIG_TUNE_ZEC12=y
 CONFIG_NR_CPUS=2
 # CONFIG_HOTPLUG_CPU is not set
 CONFIG_HZ_100=y
+# CONFIG_ARCH_RANDOM is not set
 # CONFIG_COMPACTION is not set
 # CONFIG_MIGRATION is not set
+# CONFIG_BOUNCE is not set
 # CONFIG_CHECK_STACK is not set
 # CONFIG_CHSC_SCH is not set
 # CONFIG_SCM_BUS is not set
@@ -36,11 +38,11 @@ CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_ZFCP=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_HVC_IUCV is not set
+# CONFIG_HW_RANDOM_S390 is not set
 CONFIG_RAW_DRIVER=y
 # CONFIG_SCLP_ASYNC is not set
 # CONFIG_HMC_DRV is not set
@@ -54,9 +56,9 @@ CONFIG_RAW_DRIVER=y
 # CONFIG_INOTIFY_USER is not set
 CONFIG_CONFIGFS_FS=y
 # CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_PANIC_ON_OOPS=y
 # CONFIG_SCHED_DEBUG is not set
index 97189dbaf34b2a36dade0738a64eb65bae38aafc..20244a38c88698f887e002bce2423afeb199ace3 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -108,7 +109,6 @@ CONFIG_ZFCP=y
 CONFIG_SCSI_VIRTIO=y
 CONFIG_MD=y
 CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=m
@@ -131,6 +131,7 @@ CONFIG_TUN=m
 CONFIG_VIRTIO_NET=y
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 CONFIG_DEVKMEM=y
@@ -162,7 +163,6 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_PANIC_ON_OOPS=y
-CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_LOCK_STAT=y
@@ -172,14 +172,12 @@ CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_NOTIFIERS=y
 CONFIG_RCU_CPU_STALL_TIMEOUT=60
-CONFIG_RCU_TRACE=y
 CONFIG_LATENCYTOP=y
 CONFIG_SCHED_TRACER=y
 CONFIG_FTRACE_SYSCALLS=y
 CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_UPROBE_EVENTS=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_TRACE_ENUM_MAP_FILE=y
 CONFIG_KPROBES_SANITY_TEST=y
@@ -190,7 +188,6 @@ CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_CTS=m
-CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
@@ -230,6 +227,7 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_ZCRYPT=m
 CONFIG_PKEY=m
+CONFIG_CRYPTO_PAES_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA512_S390=m
index 60d395fdc86438e55f49ddf853dca7b6f99582b3..aeac013968f2a00fd0050e772d50a8959dd57e04 100644 (file)
@@ -221,11 +221,6 @@ extern void release_thread(struct task_struct *);
 /* Free guarded storage control block for current */
 void exit_thread_gs(void);
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 unsigned long get_wchan(struct task_struct *p);
 #define task_pt_regs(tsk) ((struct pt_regs *) \
         (task_stack_page(tsk) + THREAD_SIZE) - 1)
index e408d9cc5b96adf40b873d8aabb3235793cd1b16..6315037335ba9365a198859de579c6fdcfb683cf 100644 (file)
@@ -231,12 +231,17 @@ ENTRY(sie64a)
        lctlg   %c1,%c1,__LC_USER_ASCE          # load primary asce
 .Lsie_done:
 # some program checks are suppressing. C code (e.g. do_protection_exception)
-# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
-# instructions between sie64a and .Lsie_done should not cause program
-# interrupts. So lets use a nop (47 00 00 00) as a landing pad.
+# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
+# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
+# Other instructions between sie64a and .Lsie_done should not cause program
+# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
 # See also .Lcleanup_sie
-.Lrewind_pad:
-       nop     0
+.Lrewind_pad6:
+       nopr    7
+.Lrewind_pad4:
+       nopr    7
+.Lrewind_pad2:
+       nopr    7
        .globl sie_exit
 sie_exit:
        lg      %r14,__SF_EMPTY+8(%r15)         # load guest register save area
@@ -249,7 +254,9 @@ sie_exit:
        stg     %r14,__SF_EMPTY+16(%r15)        # set exit reason code
        j       sie_exit
 
-       EX_TABLE(.Lrewind_pad,.Lsie_fault)
+       EX_TABLE(.Lrewind_pad6,.Lsie_fault)
+       EX_TABLE(.Lrewind_pad4,.Lsie_fault)
+       EX_TABLE(.Lrewind_pad2,.Lsie_fault)
        EX_TABLE(sie_exit,.Lsie_fault)
 EXPORT_SYMBOL(sie64a)
 EXPORT_SYMBOL(sie_exit)
index e545ffe5155ab0179327cfe4f9f66e677c604041..8e622bb52f7a95fd59c2f89aec95f04c616633cf 100644 (file)
@@ -564,8 +564,6 @@ static struct kset *ipl_kset;
 
 static void __ipl_run(void *unused)
 {
-       if (MACHINE_IS_LPAR && ipl_info.type == IPL_TYPE_CCW)
-               diag308(DIAG308_LOAD_NORMAL_DUMP, NULL);
        diag308(DIAG308_LOAD_CLEAR, NULL);
        if (MACHINE_IS_VM)
                __cpcmd("IPL", NULL, 0, NULL);
@@ -1088,10 +1086,7 @@ static void __reipl_run(void *unused)
                break;
        case REIPL_METHOD_CCW_DIAG:
                diag308(DIAG308_SET, reipl_block_ccw);
-               if (MACHINE_IS_LPAR)
-                       diag308(DIAG308_LOAD_NORMAL_DUMP, NULL);
-               else
-                       diag308(DIAG308_LOAD_CLEAR, NULL);
+               diag308(DIAG308_LOAD_CLEAR, NULL);
                break;
        case REIPL_METHOD_FCP_RW_DIAG:
                diag308(DIAG308_SET, reipl_block_fcp);
index 999d7154bbdcd0891f6e2d5e6c55ea4ab62d0554..bb32b8618bf61836888d383c5b3fe1c9a352c0d2 100644 (file)
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
 
-/*
- * Return saved PC of a blocked thread. used in kernel/sched.
- * resume in entry.S does not create a new stack frame, it
- * just stores the registers %r6-%r15 to the frame given by
- * schedule. We want to return the address of the caller of
- * schedule, so we have to walk the backchain one time to
- * find the frame schedule() store its return address.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       struct stack_frame *sf, *low, *high;
-
-       if (!tsk || !task_stack_page(tsk))
-               return 0;
-       low = task_stack_page(tsk);
-       high = (struct stack_frame *) task_pt_regs(tsk);
-       sf = (struct stack_frame *) tsk->thread.ksp;
-       if (sf <= low || sf > high)
-               return 0;
-       sf = (struct stack_frame *) sf->back_chain;
-       if (sf <= low || sf > high)
-               return 0;
-       return sf->gprs[8];
-}
-
 extern void kernel_thread_starter(void);
 
 /*
index 9da243d94cc3286c5e1dabcfae5e563f991326a0..3b297fa3aa67c59be7fdb2fd2953f431adfbc1d4 100644 (file)
@@ -977,11 +977,12 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
        ptr = asce.origin * 4096;
        if (asce.r) {
                *fake = 1;
+               ptr = 0;
                asce.dt = ASCE_TYPE_REGION1;
        }
        switch (asce.dt) {
        case ASCE_TYPE_REGION1:
-               if (vaddr.rfx01 > asce.tl && !asce.r)
+               if (vaddr.rfx01 > asce.tl && !*fake)
                        return PGM_REGION_FIRST_TRANS;
                break;
        case ASCE_TYPE_REGION2:
@@ -1009,8 +1010,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
                union region1_table_entry rfte;
 
                if (*fake) {
-                       /* offset in 16EB guest memory block */
-                       ptr = ptr + ((unsigned long) vaddr.rsx << 53UL);
+                       ptr += (unsigned long) vaddr.rfx << 53;
                        rfte.val = ptr;
                        goto shadow_r2t;
                }
@@ -1036,8 +1036,7 @@ shadow_r2t:
                union region2_table_entry rste;
 
                if (*fake) {
-                       /* offset in 8PB guest memory block */
-                       ptr = ptr + ((unsigned long) vaddr.rtx << 42UL);
+                       ptr += (unsigned long) vaddr.rsx << 42;
                        rste.val = ptr;
                        goto shadow_r3t;
                }
@@ -1064,8 +1063,7 @@ shadow_r3t:
                union region3_table_entry rtte;
 
                if (*fake) {
-                       /* offset in 4TB guest memory block */
-                       ptr = ptr + ((unsigned long) vaddr.sx << 31UL);
+                       ptr += (unsigned long) vaddr.rtx << 31;
                        rtte.val = ptr;
                        goto shadow_sgt;
                }
@@ -1101,8 +1099,7 @@ shadow_sgt:
                union segment_table_entry ste;
 
                if (*fake) {
-                       /* offset in 2G guest memory block */
-                       ptr = ptr + ((unsigned long) vaddr.sx << 20UL);
+                       ptr += (unsigned long) vaddr.sx << 20;
                        ste.val = ptr;
                        goto shadow_pgt;
                }
index b017daed6887847c8eb025e146ae22b37dedfb2c..b854b1da281a3bd4473e9b62bbad03197b540ff3 100644 (file)
@@ -101,7 +101,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        goto check_asce_limit;
        }
 
@@ -151,7 +151,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-                               (!vma || addr + len <= vma->vm_start))
+                               (!vma || addr + len <= vm_start_gap(vma)))
                        goto check_asce_limit;
        }
 
index d9a922d8711b2155a2225699e5958236dbb70adb..299274581968d1c850f56341615d81bddae19003 100644 (file)
@@ -13,7 +13,6 @@ struct task_struct;
  */
 extern void (*cpu_wait)(void);
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
 extern void start_thread(struct pt_regs *regs,
                        unsigned long pc, unsigned long sp);
 extern unsigned long get_wchan(struct task_struct *p);
index eb64d7a677cb9525afc874a1cb3a21872ad4bddb..6e20241a1ed45c428d7f5bfe9e76c55ecd5e0d07 100644 (file)
@@ -101,11 +101,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
        return 1;
 }
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       return task_pt_regs(tsk)->cp0_epc;
-}
-
 unsigned long get_wchan(struct task_struct *task)
 {
        if (!task || task == current || task->state == TASK_RUNNING)
index 08e7af0be4a77b021ebc1b9736a93748cb2c5b5d..6a1a1297baaeee75ded9e04bc89a402f5c2ef2f0 100644 (file)
@@ -64,7 +64,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
@@ -114,7 +114,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index dd27159819ebedce4d0479ec800e91d56706311f..b395e5620c0b986ec808675ccf3062e9a534ae43 100644 (file)
@@ -67,9 +67,6 @@ struct thread_struct {
        .current_ds = KERNEL_DS, \
 }
 
-/* Return saved PC of a blocked thread. */
-unsigned long thread_saved_pc(struct task_struct *t);
-
 /* Do necessary setup to start up a newly executed thread. */
 static inline void start_thread(struct pt_regs * regs, unsigned long pc,
                                    unsigned long sp)
index b58ee90184334224b756360e769c47a0d10e088a..f04dc5a4306245ffc0b53b3c88707332b8a25a0f 100644 (file)
@@ -89,9 +89,7 @@ struct thread_struct {
 #include <linux/types.h>
 #include <asm/fpumacro.h>
 
-/* Return saved PC of a blocked thread. */
 struct task_struct;
-unsigned long thread_saved_pc(struct task_struct *);
 
 /* On Uniprocessor, even in RMO processes see TSO semantics */
 #ifdef CONFIG_SMP
index b6dac8e980f07183f9ea300abcfb033d0251b5c0..9245f93398c76a59a073963253609c1fc54bfeec 100644 (file)
@@ -176,14 +176,6 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
        printk("\n");
 }
 
-/*
- * Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       return task_thread_info(tsk)->kpc;
-}
-
 /*
  * Free current thread data structures etc..
  */
index 1badc493e62ee71c2e538758aec3c446780ea671..b96104da5bd6116b119872eaa79e013636aa328c 100644 (file)
@@ -400,25 +400,6 @@ core_initcall(sparc_sysrq_init);
 
 #endif
 
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       struct thread_info *ti = task_thread_info(tsk);
-       unsigned long ret = 0xdeadbeefUL;
-       
-       if (ti && ti->ksp) {
-               unsigned long *sp;
-               sp = (unsigned long *)(ti->ksp + STACK_BIAS);
-               if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL &&
-                   sp[14]) {
-                       unsigned long *fp;
-                       fp = (unsigned long *)(sp[14] + STACK_BIAS);
-                       if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL)
-                               ret = fp[15];
-               }
-       }
-       return ret;
-}
-
 /* Free current thread data structures etc.. */
 void exit_thread(struct task_struct *tsk)
 {
index ef4520efc8130c1aeef8a36d4de24fdecf78c883..043544d0cda3f000ffca1a1c1f2f00680218d8d9 100644 (file)
@@ -120,7 +120,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
 
                vma = find_vma(mm, addr);
                if (task_size - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
@@ -183,7 +183,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
                vma = find_vma(mm, addr);
                if (task_size - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index 7c29d38e6b99c68c5ac746eb3d3a3fe1da8394a5..88855e383b34c16a8960b1ff89ae207a1ad50b07 100644 (file)
@@ -120,7 +120,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                addr = ALIGN(addr, huge_page_size(h));
                vma = find_vma(mm, addr);
                if (task_size - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
        if (mm->get_unmapped_area == arch_get_unmapped_area)
index 0bc9968b97a19296a48d4dfb215cd3464b69f9a6..f71e5206650bf91578677720a7701a3d766d0436 100644 (file)
@@ -214,13 +214,6 @@ static inline void release_thread(struct task_struct *dead_task)
 
 extern void prepare_exit_to_usermode(struct pt_regs *regs, u32 flags);
 
-
-/*
- * Return saved (kernel) PC of a blocked thread.
- * Only used in a printk() in kernel/sched/core.c, so don't work too hard.
- */
-#define thread_saved_pc(t)   ((t)->thread.pc)
-
 unsigned long get_wchan(struct task_struct *p);
 
 /* Return initial ksp value for given task. */
index cb10153b5c9fb4307b92359a8118be91895715db..03e5cc4e76e4e67548c8ea396012d66d8ab89752 100644 (file)
@@ -233,7 +233,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                addr = ALIGN(addr, huge_page_size(h));
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
        if (current->mm->get_unmapped_area == arch_get_unmapped_area)
index 2d1e0dd5bb0bf55a7e543f9f7f9e0eefd6ab4cac..f6d1a3f747a9b58b3f33ce0ee25c3bf889985c0b 100644 (file)
@@ -58,8 +58,6 @@ static inline void release_thread(struct task_struct *task)
 {
 }
 
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
 static inline void mm_copy_segments(struct mm_struct *from_mm,
                                    struct mm_struct *new_mm)
 {
index 64a1fd06f3fde02d964c4fedcb9e73328085c94d..7b56401173250e1dbb61208106c35c58e324812b 100644 (file)
@@ -56,12 +56,6 @@ union thread_union cpu0_irqstack
        __attribute__((__section__(".data..init_irqstack"))) =
                { INIT_THREAD_INFO(init_task) };
 
-unsigned long thread_saved_pc(struct task_struct *task)
-{
-       /* FIXME: Need to look up userspace_pid by cpu */
-       return os_process_pc(userspace_pid[0]);
-}
-
 /* Changed in setup_arch, which is called in early boot */
 static char host_info[(__NEW_UTS_LEN + 1) * 5];
 
index a6d91d4e37a1f1dadae588a1c084e31e65d08f5d..110ce8238466f7e404d8312dd8d9297fa09355c9 100644 (file)
@@ -431,11 +431,11 @@ static __initconst const u64 skl_hw_cache_event_ids
  [ C(DTLB) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = 0x81d0,  /* MEM_INST_RETIRED.ALL_LOADS */
-               [ C(RESULT_MISS)   ] = 0x608,   /* DTLB_LOAD_MISSES.WALK_COMPLETED */
+               [ C(RESULT_MISS)   ] = 0xe08,   /* DTLB_LOAD_MISSES.WALK_COMPLETED */
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = 0x82d0,  /* MEM_INST_RETIRED.ALL_STORES */
-               [ C(RESULT_MISS)   ] = 0x649,   /* DTLB_STORE_MISSES.WALK_COMPLETED */
+               [ C(RESULT_MISS)   ] = 0xe49,   /* DTLB_STORE_MISSES.WALK_COMPLETED */
        },
        [ C(OP_PREFETCH) ] = {
                [ C(RESULT_ACCESS) ] = 0x0,
index b8ad261d11dce0d5f196efdc71e9f2b5e837d4bf..c66d19e3c23e8c6e31630c5c06f8a90539025695 100644 (file)
@@ -29,6 +29,7 @@ struct pt_regs;
        } while (0)
 
 extern int fixup_exception(struct pt_regs *regs, int trapnr);
+extern int fixup_bug(struct pt_regs *regs, int trapnr);
 extern bool ex_has_fault_handler(unsigned long ip);
 extern void early_fixup_exception(struct pt_regs *regs, int trapnr);
 
index 05596261577937d65afcad75574bab676a7effe9..722d0e56886342a3a9f65d7f419d0e240a9cc6ab 100644 (file)
@@ -296,6 +296,7 @@ struct x86_emulate_ctxt {
 
        bool perm_ok; /* do not check permissions if true */
        bool ud;        /* inject an #UD if host doesn't support insn */
+       bool tf;        /* TF value before instruction (after for syscall/sysret) */
 
        bool have_exception;
        struct x86_exception exception;
index fba1007139243b21081b6bfa114bed588e6f4e8e..d5acc27ed1cc79ab7bc621ae0d85ad4076cbc4cc 100644 (file)
@@ -2,8 +2,7 @@
 #define _ASM_X86_MSHYPER_H
 
 #include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/clocksource.h>
+#include <linux/atomic.h>
 #include <asm/hyperv.h>
 
 /*
index 3cada998a402a7893ffd2fc709916f4fcbc3f970..a28b671f15499590d3b7243eb7909436aa27b814 100644 (file)
@@ -860,8 +860,6 @@ extern unsigned long KSTK_ESP(struct task_struct *task);
 
 #endif /* CONFIG_X86_64 */
 
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
 extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
                                               unsigned long new_sp);
 
index 0bb88428cbf2697c89a60311051cc5351ea55fde..3ca198080ea9294486ae9a1121e7815dfba7cb19 100644 (file)
@@ -544,17 +544,6 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
        return randomize_page(mm->brk, 0x02000000);
 }
 
-/*
- * Return saved PC of a blocked thread.
- * What is this good for? it will be always the scheduler or ret_from_fork.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
-       struct inactive_task_frame *frame =
-               (struct inactive_task_frame *) READ_ONCE(tsk->thread.sp);
-       return READ_ONCE_NOCHECK(frame->ret_addr);
-}
-
 /*
  * Called from fs/proc with a reference on @p to find the function
  * which called into schedule(). This needs to be done carefully
index 207b8f2582c75b7c80a882ffc92a720071c8277e..213ddf3e937d800577514a3677f742813298555e 100644 (file)
@@ -144,7 +144,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (end - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
@@ -187,7 +187,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                               (!vma || addr + len <= vma->vm_start))
+                               (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index 3995d3a777d49c569e3ba79e3eca5d2206ab1b0a..bf54309b85da279147d6dbae5bff34381fa789a8 100644 (file)
@@ -182,7 +182,7 @@ int is_valid_bugaddr(unsigned long addr)
        return ud == INSN_UD0 || ud == INSN_UD2;
 }
 
-static int fixup_bug(struct pt_regs *regs, int trapnr)
+int fixup_bug(struct pt_regs *regs, int trapnr)
 {
        if (trapnr != X86_TRAP_UD)
                return 0;
index 0816ab2e8adcae2b45f83c95c51e8b95a245b07e..80890dee66cebf370a3815e28f7bd7c34025b0d4 100644 (file)
@@ -2742,6 +2742,7 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
                ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF);
        }
 
+       ctxt->tf = (ctxt->eflags & X86_EFLAGS_TF) != 0;
        return X86EMUL_CONTINUE;
 }
 
index 87d3cb901935f2b251857f54ed53ca73567f10ef..0e846f0cb83bb214811d0a12d2f700cc96a455f9 100644 (file)
@@ -5313,6 +5313,8 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
        kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
 
        ctxt->eflags = kvm_get_rflags(vcpu);
+       ctxt->tf = (ctxt->eflags & X86_EFLAGS_TF) != 0;
+
        ctxt->eip = kvm_rip_read(vcpu);
        ctxt->mode = (!is_protmode(vcpu))               ? X86EMUL_MODE_REAL :
                     (ctxt->eflags & X86_EFLAGS_VM)     ? X86EMUL_MODE_VM86 :
@@ -5528,36 +5530,25 @@ static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7,
        return dr6;
 }
 
-static void kvm_vcpu_check_singlestep(struct kvm_vcpu *vcpu, unsigned long rflags, int *r)
+static void kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu, int *r)
 {
        struct kvm_run *kvm_run = vcpu->run;
 
-       /*
-        * rflags is the old, "raw" value of the flags.  The new value has
-        * not been saved yet.
-        *
-        * This is correct even for TF set by the guest, because "the
-        * processor will not generate this exception after the instruction
-        * that sets the TF flag".
-        */
-       if (unlikely(rflags & X86_EFLAGS_TF)) {
-               if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
-                       kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 |
-                                                 DR6_RTM;
-                       kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip;
-                       kvm_run->debug.arch.exception = DB_VECTOR;
-                       kvm_run->exit_reason = KVM_EXIT_DEBUG;
-                       *r = EMULATE_USER_EXIT;
-               } else {
-                       /*
-                        * "Certain debug exceptions may clear bit 0-3.  The
-                        * remaining contents of the DR6 register are never
-                        * cleared by the processor".
-                        */
-                       vcpu->arch.dr6 &= ~15;
-                       vcpu->arch.dr6 |= DR6_BS | DR6_RTM;
-                       kvm_queue_exception(vcpu, DB_VECTOR);
-               }
+       if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+               kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | DR6_RTM;
+               kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip;
+               kvm_run->debug.arch.exception = DB_VECTOR;
+               kvm_run->exit_reason = KVM_EXIT_DEBUG;
+               *r = EMULATE_USER_EXIT;
+       } else {
+               /*
+                * "Certain debug exceptions may clear bit 0-3.  The
+                * remaining contents of the DR6 register are never
+                * cleared by the processor".
+                */
+               vcpu->arch.dr6 &= ~15;
+               vcpu->arch.dr6 |= DR6_BS | DR6_RTM;
+               kvm_queue_exception(vcpu, DB_VECTOR);
        }
 }
 
@@ -5567,7 +5558,17 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
        int r = EMULATE_DONE;
 
        kvm_x86_ops->skip_emulated_instruction(vcpu);
-       kvm_vcpu_check_singlestep(vcpu, rflags, &r);
+
+       /*
+        * rflags is the old, "raw" value of the flags.  The new value has
+        * not been saved yet.
+        *
+        * This is correct even for TF set by the guest, because "the
+        * processor will not generate this exception after the instruction
+        * that sets the TF flag".
+        */
+       if (unlikely(rflags & X86_EFLAGS_TF))
+               kvm_vcpu_do_singlestep(vcpu, &r);
        return r == EMULATE_DONE;
 }
 EXPORT_SYMBOL_GPL(kvm_skip_emulated_instruction);
@@ -5726,8 +5727,9 @@ restart:
                toggle_interruptibility(vcpu, ctxt->interruptibility);
                vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
                kvm_rip_write(vcpu, ctxt->eip);
-               if (r == EMULATE_DONE)
-                       kvm_vcpu_check_singlestep(vcpu, rflags, &r);
+               if (r == EMULATE_DONE &&
+                   (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
+                       kvm_vcpu_do_singlestep(vcpu, &r);
                if (!ctxt->have_exception ||
                    exception_type(ctxt->exception.vector) == EXCPT_TRAP)
                        __kvm_set_rflags(vcpu, ctxt->eflags);
index 35ea061010a1a51f743bda3ca7cfe1be468670e1..0ea8afcb929c031fdac01681ac277dcf74887e4e 100644 (file)
@@ -162,6 +162,9 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
        if (fixup_exception(regs, trapnr))
                return;
 
+       if (fixup_bug(regs, trapnr))
+               return;
+
 fail:
        early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
                     (unsigned)trapnr, (unsigned long)regs->cs, regs->ip,
index 302f43fd9c28c6d14652981d672569d57e3dea35..adad702b39cd473218d373e7d1b452b96d9816be 100644 (file)
@@ -148,7 +148,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                addr = ALIGN(addr, huge_page_size(h));
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
        if (mm->get_unmapped_area == arch_get_unmapped_area)
index cbc87ea9875109b79b70a17ea6c130d8803ff207..9b3f9fa5b283acb12ba38a42824e1b872a9560b9 100644 (file)
@@ -161,16 +161,16 @@ static int page_size_mask;
 
 static void __init probe_page_size_mask(void)
 {
-#if !defined(CONFIG_KMEMCHECK)
        /*
         * For CONFIG_KMEMCHECK or pagealloc debugging, identity mapping will
         * use small pages.
         * This will simplify cpa(), which otherwise needs to support splitting
         * large pages into small in interrupt context, etc.
         */
-       if (boot_cpu_has(X86_FEATURE_PSE) && !debug_pagealloc_enabled())
+       if (boot_cpu_has(X86_FEATURE_PSE) && !debug_pagealloc_enabled() && !IS_ENABLED(CONFIG_KMEMCHECK))
                page_size_mask |= 1 << PG_LEVEL_2M;
-#endif
+       else
+               direct_gbpages = 0;
 
        /* Enable PSE if available */
        if (boot_cpu_has(X86_FEATURE_PSE))
index f71f88ea7646dcc798067e984dddefa8a659037d..19707db966f1393017bcf9528ff64d2951089d20 100644 (file)
@@ -29,7 +29,8 @@ static inline void variant_irq_disable(unsigned int irq) { }
 # define PLATFORM_NR_IRQS 0
 #endif
 #define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS
-#define NR_IRQS (XTENSA_NR_IRQS + VARIANT_NR_IRQS + PLATFORM_NR_IRQS)
+#define NR_IRQS (XTENSA_NR_IRQS + VARIANT_NR_IRQS + PLATFORM_NR_IRQS + 1)
+#define XTENSA_PIC_LINUX_IRQ(hwirq) ((hwirq) + 1)
 
 #if VARIANT_NR_IRQS == 0
 static inline void variant_init_irq(void) { }
index 003eeee3fbc636d91aed849aaa39bb0c24370227..30ee8c608853d4fb4b238a01319589d38ce018b7 100644 (file)
@@ -213,8 +213,6 @@ struct mm_struct;
 #define release_segments(mm)   do { } while(0)
 #define forget_segments()      do { } while (0)
 
-#define thread_saved_pc(tsk)   (task_pt_regs(tsk)->pc)
-
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)          (task_pt_regs(tsk)->pc)
index a265edd6ac37b423e7227f095201fcd8e1685538..99341028cc77c5d24f10ee1ec6b1cb534137cc84 100644 (file)
@@ -34,11 +34,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
 {
        int irq = irq_find_mapping(NULL, hwirq);
 
-       if (hwirq >= NR_IRQS) {
-               printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
-                               __func__, hwirq);
-       }
-
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        /* Debugging check for stack overflow: is there less than 1KB free? */
        {
index 394ef08300b6a3188b196155e0863bf2360fef93..33bfa5270d95440cd44c95674073608797e1d131 100644 (file)
@@ -593,8 +593,7 @@ c_show(struct seq_file *f, void *slot)
                      (ccount_freq/10000) % 100,
                      loops_per_jiffy/(500000/HZ),
                      (loops_per_jiffy/(5000/HZ)) % 100);
-
-       seq_printf(f,"flags\t\t: "
+       seq_puts(f, "flags\t\t: "
 #if XCHAL_HAVE_NMI
                     "nmi "
 #endif
index 06937928cb72dc1ac66d1bb18543d49daaf511ec..74afbf02d07e8b3a7539235eeb2d5cfabe791230 100644 (file)
@@ -88,7 +88,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
                /* At this point:  (!vmm || addr < vmm->vm_end). */
                if (TASK_SIZE - len < addr)
                        return -ENOMEM;
-               if (!vmm || addr + len <= vmm->vm_start)
+               if (!vmm || addr + len <= vm_start_gap(vmm))
                        return addr;
                addr = vmm->vm_end;
                if (flags & MAP_SHARED)
index 30d9fc21e0763c4115f7f5c74b78aba46ead1109..162c77e53ca845bf26ba9ab40ce4cd606f5a7060 100644 (file)
@@ -118,7 +118,7 @@ SECTIONS
   SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
   SECTION_VECTOR (.UserExceptionVector.literal, USER_VECTOR_VADDR - 4)
   SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR)
-  SECTION_VECTOR (.DoubleExceptionVector.literal, DOUBLEEXC_VECTOR_VADDR - 48)
+  SECTION_VECTOR (.DoubleExceptionVector.literal, DOUBLEEXC_VECTOR_VADDR - 20)
   SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
 #endif
 
@@ -306,13 +306,13 @@ SECTIONS
                  .UserExceptionVector.literal)
   SECTION_VECTOR (_DoubleExceptionVector_literal,
                  .DoubleExceptionVector.literal,
-                 DOUBLEEXC_VECTOR_VADDR - 48,
+                 DOUBLEEXC_VECTOR_VADDR - 20,
                  SIZEOF(.UserExceptionVector.text),
                  .UserExceptionVector.text)
   SECTION_VECTOR (_DoubleExceptionVector_text,
                  .DoubleExceptionVector.text,
                  DOUBLEEXC_VECTOR_VADDR,
-                 48,
+                 20,
                  .DoubleExceptionVector.literal)
 
   . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
index 02e94bb3ad3e088e65eef692873cf86447eccf16..c45b90bb93393bf58c20ab279bc8e63981b7dc02 100644 (file)
@@ -317,8 +317,7 @@ static int __init simdisk_init(void)
        if (simdisk_count > MAX_SIMDISK_COUNT)
                simdisk_count = MAX_SIMDISK_COUNT;
 
-       sddev = kmalloc(simdisk_count * sizeof(struct simdisk),
-                       GFP_KERNEL);
+       sddev = kmalloc_array(simdisk_count, sizeof(*sddev), GFP_KERNEL);
        if (sddev == NULL)
                goto out_unregister;
 
index dbeea2b440a1b50bd3e6a1eea85dcb7626244a91..1fda7e20dfcbff79849e5aae29ac8a6529c43e39 100644 (file)
 
 /* Interrupt configuration. */
 
-#define PLATFORM_NR_IRQS       10
+#define PLATFORM_NR_IRQS       0
 
 /* Default assignment of LX60 devices to external interrupts. */
 
 #ifdef CONFIG_XTENSA_MX
 #define DUART16552_INTNUM      XCHAL_EXTINT3_NUM
 #define OETH_IRQ               XCHAL_EXTINT4_NUM
+#define C67X00_IRQ             XCHAL_EXTINT8_NUM
 #else
 #define DUART16552_INTNUM      XCHAL_EXTINT0_NUM
 #define OETH_IRQ               XCHAL_EXTINT1_NUM
+#define C67X00_IRQ             XCHAL_EXTINT5_NUM
 #endif
 
 /*
@@ -63,5 +65,5 @@
 
 #define C67X00_PADDR           (XCHAL_KIO_PADDR + 0x0D0D0000)
 #define C67X00_SIZE            0x10
-#define C67X00_IRQ             5
+
 #endif /* __XTENSA_XTAVNET_HARDWARE_H */
index 779be723eb2bdd4fa03c6b30abd553e948df9991..42285f35d3135a0a6d58b5b9e2eea7f5fcaa4019 100644 (file)
@@ -175,8 +175,8 @@ static struct resource ethoc_res[] = {
                .flags = IORESOURCE_MEM,
        },
        [2] = { /* IRQ number */
-               .start = OETH_IRQ,
-               .end   = OETH_IRQ,
+               .start = XTENSA_PIC_LINUX_IRQ(OETH_IRQ),
+               .end   = XTENSA_PIC_LINUX_IRQ(OETH_IRQ),
                .flags = IORESOURCE_IRQ,
        },
 };
@@ -213,8 +213,8 @@ static struct resource c67x00_res[] = {
                .flags = IORESOURCE_MEM,
        },
        [1] = { /* IRQ number */
-               .start = C67X00_IRQ,
-               .end   = C67X00_IRQ,
+               .start = XTENSA_PIC_LINUX_IRQ(C67X00_IRQ),
+               .end   = XTENSA_PIC_LINUX_IRQ(C67X00_IRQ),
                .flags = IORESOURCE_IRQ,
        },
 };
@@ -247,7 +247,7 @@ static struct resource serial_resource = {
 static struct plat_serial8250_port serial_platform_data[] = {
        [0] = {
                .mapbase        = DUART16552_PADDR,
-               .irq            = DUART16552_INTNUM,
+               .irq            = XTENSA_PIC_LINUX_IRQ(DUART16552_INTNUM),
                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
                                  UPF_IOREMAP,
                .iotype         = XCHAL_HAVE_BE ? UPIO_MEM32BE : UPIO_MEM32,
index 888e7801c6381edd8d995503643917b2f452282e..26b0810fb8eac14b0a39c27bdf53f2398c767fb3 100644 (file)
@@ -240,20 +240,21 @@ fallback:
        return bvl;
 }
 
-static void __bio_free(struct bio *bio)
+void bio_uninit(struct bio *bio)
 {
        bio_disassociate_task(bio);
 
        if (bio_integrity(bio))
                bio_integrity_free(bio);
 }
+EXPORT_SYMBOL(bio_uninit);
 
 static void bio_free(struct bio *bio)
 {
        struct bio_set *bs = bio->bi_pool;
        void *p;
 
-       __bio_free(bio);
+       bio_uninit(bio);
 
        if (bs) {
                bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio));
@@ -271,6 +272,11 @@ static void bio_free(struct bio *bio)
        }
 }
 
+/*
+ * Users of this function have their own bio allocation. Subsequently,
+ * they must remember to pair any call to bio_init() with bio_uninit()
+ * when IO has completed, or when the bio is released.
+ */
 void bio_init(struct bio *bio, struct bio_vec *table,
              unsigned short max_vecs)
 {
@@ -297,7 +303,7 @@ void bio_reset(struct bio *bio)
 {
        unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS);
 
-       __bio_free(bio);
+       bio_uninit(bio);
 
        memset(bio, 0, BIO_RESET_BYTES);
        bio->bi_flags = flags;
index 1f5b692526ae1a7199ee9bbaef305c4b0a42e696..0ded5e846335667406d58ce08e8439360baeb312 100644 (file)
@@ -68,6 +68,45 @@ static void blk_mq_sched_assign_ioc(struct request_queue *q,
                __blk_mq_sched_assign_ioc(q, rq, bio, ioc);
 }
 
+/*
+ * Mark a hardware queue as needing a restart. For shared queues, maintain
+ * a count of how many hardware queues are marked for restart.
+ */
+static void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx)
+{
+       if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+               return;
+
+       if (hctx->flags & BLK_MQ_F_TAG_SHARED) {
+               struct request_queue *q = hctx->queue;
+
+               if (!test_and_set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+                       atomic_inc(&q->shared_hctx_restart);
+       } else
+               set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
+}
+
+static bool blk_mq_sched_restart_hctx(struct blk_mq_hw_ctx *hctx)
+{
+       if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+               return false;
+
+       if (hctx->flags & BLK_MQ_F_TAG_SHARED) {
+               struct request_queue *q = hctx->queue;
+
+               if (test_and_clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+                       atomic_dec(&q->shared_hctx_restart);
+       } else
+               clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
+
+       if (blk_mq_hctx_has_pending(hctx)) {
+               blk_mq_run_hw_queue(hctx, true);
+               return true;
+       }
+
+       return false;
+}
+
 struct request *blk_mq_sched_get_request(struct request_queue *q,
                                         struct bio *bio,
                                         unsigned int op,
@@ -266,18 +305,6 @@ static bool blk_mq_sched_bypass_insert(struct blk_mq_hw_ctx *hctx,
        return true;
 }
 
-static bool blk_mq_sched_restart_hctx(struct blk_mq_hw_ctx *hctx)
-{
-       if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) {
-               clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
-               if (blk_mq_hctx_has_pending(hctx)) {
-                       blk_mq_run_hw_queue(hctx, true);
-                       return true;
-               }
-       }
-       return false;
-}
-
 /**
  * list_for_each_entry_rcu_rr - iterate in a round-robin fashion over rcu list
  * @pos:    loop cursor.
@@ -309,6 +336,13 @@ void blk_mq_sched_restart(struct blk_mq_hw_ctx *const hctx)
        unsigned int i, j;
 
        if (set->flags & BLK_MQ_F_TAG_SHARED) {
+               /*
+                * If this is 0, then we know that no hardware queues
+                * have RESTART marked. We're done.
+                */
+               if (!atomic_read(&queue->shared_hctx_restart))
+                       return;
+
                rcu_read_lock();
                list_for_each_entry_rcu_rr(q, queue, &set->tag_list,
                                           tag_set_list) {
index edafb5383b7bbdedfd5365ed38f9a5c373ec96ab..5007edece51aced038d3db8f0adbc722c49e3d38 100644 (file)
@@ -115,15 +115,6 @@ static inline bool blk_mq_sched_has_work(struct blk_mq_hw_ctx *hctx)
        return false;
 }
 
-/*
- * Mark a hardware queue as needing a restart.
- */
-static inline void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx)
-{
-       if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
-               set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
-}
-
 static inline bool blk_mq_sched_needs_restart(struct blk_mq_hw_ctx *hctx)
 {
        return test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
index bb66c96850b18cb419b0e44aab1894169352f9af..958cedaff8b829ceb4c724dbf1c6f6d30d883aeb 100644 (file)
@@ -2103,20 +2103,30 @@ static void blk_mq_map_swqueue(struct request_queue *q,
        }
 }
 
+/*
+ * Caller needs to ensure that we're either frozen/quiesced, or that
+ * the queue isn't live yet.
+ */
 static void queue_set_hctx_shared(struct request_queue *q, bool shared)
 {
        struct blk_mq_hw_ctx *hctx;
        int i;
 
        queue_for_each_hw_ctx(q, hctx, i) {
-               if (shared)
+               if (shared) {
+                       if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+                               atomic_inc(&q->shared_hctx_restart);
                        hctx->flags |= BLK_MQ_F_TAG_SHARED;
-               else
+               } else {
+                       if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+                               atomic_dec(&q->shared_hctx_restart);
                        hctx->flags &= ~BLK_MQ_F_TAG_SHARED;
+               }
        }
 }
 
-static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set, bool shared)
+static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set,
+                                       bool shared)
 {
        struct request_queue *q;
 
index 283da7fbe03408d9eef71ba3e1a4f863671d761b..27aceab1cc31484423524caae9d6970cef9274ec 100644 (file)
@@ -777,24 +777,25 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
 }
 
 /**
- * blk_release_queue: - release a &struct request_queue when it is no longer needed
- * @kobj:    the kobj belonging to the request queue to be released
+ * __blk_release_queue - release a request queue when it is no longer needed
+ * @work: pointer to the release_work member of the request queue to be released
  *
  * Description:
- *     blk_release_queue is the pair to blk_init_queue() or
- *     blk_queue_make_request().  It should be called when a request queue is
- *     being released; typically when a block device is being de-registered.
- *     Currently, its primary task it to free all the &struct request
- *     structures that were allocated to the queue and the queue itself.
+ *     blk_release_queue is the counterpart of blk_init_queue(). It should be
+ *     called when a request queue is being released; typically when a block
+ *     device is being de-registered. Its primary task it to free the queue
+ *     itself.
  *
- * Note:
+ * Notes:
  *     The low level driver must have finished any outstanding requests first
  *     via blk_cleanup_queue().
- **/
-static void blk_release_queue(struct kobject *kobj)
+ *
+ *     Although blk_release_queue() may be called with preemption disabled,
+ *     __blk_release_queue() may sleep.
+ */
+static void __blk_release_queue(struct work_struct *work)
 {
-       struct request_queue *q =
-               container_of(kobj, struct request_queue, kobj);
+       struct request_queue *q = container_of(work, typeof(*q), release_work);
 
        if (test_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags))
                blk_stat_remove_callback(q, q->poll_cb);
@@ -834,6 +835,15 @@ static void blk_release_queue(struct kobject *kobj)
        call_rcu(&q->rcu_head, blk_free_queue_rcu);
 }
 
+static void blk_release_queue(struct kobject *kobj)
+{
+       struct request_queue *q =
+               container_of(kobj, struct request_queue, kobj);
+
+       INIT_WORK(&q->release_work, __blk_release_queue);
+       schedule_work(&q->release_work);
+}
+
 static const struct sysfs_ops queue_sysfs_ops = {
        .show   = queue_attr_show,
        .store  = queue_attr_store,
index 7abe6650573950674ce41a7511fd9abe2736c451..0d2e98920069cf97ee323c8f9c3df543f8d6407a 100644 (file)
@@ -416,9 +416,18 @@ acpi_tb_get_table(struct acpi_table_desc *table_desc,
                }
        }
 
-       table_desc->validation_count++;
-       if (table_desc->validation_count == 0) {
-               table_desc->validation_count--;
+       if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
+               table_desc->validation_count++;
+
+               /*
+                * Detect validation_count overflows to ensure that the warning
+                * message will only be printed once.
+                */
+               if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
+                       ACPI_WARNING((AE_INFO,
+                                     "Table %p, Validation count overflows\n",
+                                     table_desc));
+               }
        }
 
        *out_table = table_desc->pointer;
@@ -445,13 +454,20 @@ void acpi_tb_put_table(struct acpi_table_desc *table_desc)
 
        ACPI_FUNCTION_TRACE(acpi_tb_put_table);
 
-       if (table_desc->validation_count == 0) {
-               ACPI_WARNING((AE_INFO,
-                             "Table %p, Validation count is zero before decrement\n",
-                             table_desc));
-               return_VOID;
+       if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
+               table_desc->validation_count--;
+
+               /*
+                * Detect validation_count underflows to ensure that the warning
+                * message will only be printed once.
+                */
+               if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
+                       ACPI_WARNING((AE_INFO,
+                                     "Table %p, Validation count underflows\n",
+                                     table_desc));
+                       return_VOID;
+               }
        }
-       table_desc->validation_count--;
 
        if (table_desc->validation_count == 0) {
 
index e0587c85bafdf73a299c40d531eefa27deab4761..ff096d9755b925d9f72105f42993ebcc7c0522e1 100644 (file)
@@ -474,15 +474,6 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
                                return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
                        }
 
-                       /*
-                        * The end_tag opcode must be followed by a zero byte.
-                        * Although this byte is technically defined to be a checksum,
-                        * in practice, all ASL compilers set this byte to zero.
-                        */
-                       if (*(aml + 1) != 0) {
-                               return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
-                       }
-
                        /* Return the pointer to the end_tag if requested */
 
                        if (!user_function) {
index 3a10d7573477e7dea0139c5f885e9514a1886a7a..d53162997f32002828a6db353bcd1926f2a8dc97 100644 (file)
@@ -1428,6 +1428,37 @@ static void acpi_init_coherency(struct acpi_device *adev)
        adev->flags.coherent_dma = cca;
 }
 
+static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data)
+{
+       bool *is_spi_i2c_slave_p = data;
+
+       if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+               return 1;
+
+       /*
+        * devices that are connected to UART still need to be enumerated to
+        * platform bus
+        */
+       if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
+               *is_spi_i2c_slave_p = true;
+
+        /* no need to do more checking */
+       return -1;
+}
+
+static bool acpi_is_spi_i2c_slave(struct acpi_device *device)
+{
+       struct list_head resource_list;
+       bool is_spi_i2c_slave = false;
+
+       INIT_LIST_HEAD(&resource_list);
+       acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
+                              &is_spi_i2c_slave);
+       acpi_dev_free_resource_list(&resource_list);
+
+       return is_spi_i2c_slave;
+}
+
 void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
                             int type, unsigned long long sta)
 {
@@ -1443,6 +1474,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
        acpi_bus_get_flags(device);
        device->flags.match_driver = false;
        device->flags.initialized = true;
+       device->flags.spi_i2c_slave = acpi_is_spi_i2c_slave(device);
        acpi_device_clear_enumerated(device);
        device_initialize(&device->dev);
        dev_set_uevent_suppress(&device->dev, true);
@@ -1727,38 +1759,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
        return AE_OK;
 }
 
-static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data)
-{
-       bool *is_spi_i2c_slave_p = data;
-
-       if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
-               return 1;
-
-       /*
-        * devices that are connected to UART still need to be enumerated to
-        * platform bus
-        */
-       if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
-               *is_spi_i2c_slave_p = true;
-
-        /* no need to do more checking */
-       return -1;
-}
-
 static void acpi_default_enumeration(struct acpi_device *device)
 {
-       struct list_head resource_list;
-       bool is_spi_i2c_slave = false;
-
        /*
         * Do not enumerate SPI/I2C slaves as they will be enumerated by their
         * respective parents.
         */
-       INIT_LIST_HEAD(&resource_list);
-       acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
-                              &is_spi_i2c_slave);
-       acpi_dev_free_resource_list(&resource_list);
-       if (!is_spi_i2c_slave) {
+       if (!device->flags.spi_i2c_slave) {
                acpi_create_platform_device(device, NULL);
                acpi_device_set_enumerated(device);
        } else {
@@ -1854,7 +1861,7 @@ static void acpi_bus_attach(struct acpi_device *device)
                return;
 
        device->flags.match_driver = true;
-       if (ret > 0) {
+       if (ret > 0 && !device->flags.spi_i2c_slave) {
                acpi_device_set_enumerated(device);
                goto ok;
        }
@@ -1863,10 +1870,10 @@ static void acpi_bus_attach(struct acpi_device *device)
        if (ret < 0)
                return;
 
-       if (device->pnp.type.platform_id)
-               acpi_default_enumeration(device);
-       else
+       if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave)
                acpi_device_set_enumerated(device);
+       else
+               acpi_default_enumeration(device);
 
  ok:
        list_for_each_entry(child, &device->children, node)
index 726c32e35db9c542e6f050ff0a04e31e10fc2b7d..0e824091a12fac8757c2ade5d4e5dae6a1470cbd 100644 (file)
@@ -609,8 +609,6 @@ int xen_blkif_schedule(void *arg)
        unsigned long timeout;
        int ret;
 
-       xen_blkif_get(blkif);
-
        set_freezable();
        while (!kthread_should_stop()) {
                if (try_to_freeze())
@@ -665,7 +663,6 @@ purge_gnt_list:
                print_stats(ring);
 
        ring->xenblkd = NULL;
-       xen_blkif_put(blkif);
 
        return 0;
 }
@@ -1436,34 +1433,35 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
 static void make_response(struct xen_blkif_ring *ring, u64 id,
                          unsigned short op, int st)
 {
-       struct blkif_response  resp;
+       struct blkif_response *resp;
        unsigned long     flags;
        union blkif_back_rings *blk_rings;
        int notify;
 
-       resp.id        = id;
-       resp.operation = op;
-       resp.status    = st;
-
        spin_lock_irqsave(&ring->blk_ring_lock, flags);
        blk_rings = &ring->blk_rings;
        /* Place on the response ring for the relevant domain. */
        switch (ring->blkif->blk_protocol) {
        case BLKIF_PROTOCOL_NATIVE:
-               memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt),
-                      &resp, sizeof(resp));
+               resp = RING_GET_RESPONSE(&blk_rings->native,
+                                        blk_rings->native.rsp_prod_pvt);
                break;
        case BLKIF_PROTOCOL_X86_32:
-               memcpy(RING_GET_RESPONSE(&blk_rings->x86_32, blk_rings->x86_32.rsp_prod_pvt),
-                      &resp, sizeof(resp));
+               resp = RING_GET_RESPONSE(&blk_rings->x86_32,
+                                        blk_rings->x86_32.rsp_prod_pvt);
                break;
        case BLKIF_PROTOCOL_X86_64:
-               memcpy(RING_GET_RESPONSE(&blk_rings->x86_64, blk_rings->x86_64.rsp_prod_pvt),
-                      &resp, sizeof(resp));
+               resp = RING_GET_RESPONSE(&blk_rings->x86_64,
+                                        blk_rings->x86_64.rsp_prod_pvt);
                break;
        default:
                BUG();
        }
+
+       resp->id        = id;
+       resp->operation = op;
+       resp->status    = st;
+
        blk_rings->common.rsp_prod_pvt++;
        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify);
        spin_unlock_irqrestore(&ring->blk_ring_lock, flags);
index dea61f6ab8cbdbaffedceb4c64bda239b51a63a4..ecb35fe8ca8dbb54f36a85513a09064819acd67a 100644 (file)
@@ -75,9 +75,8 @@ extern unsigned int xenblk_max_queues;
 struct blkif_common_request {
        char dummy;
 };
-struct blkif_common_response {
-       char dummy;
-};
+
+/* i386 protocol version */
 
 struct blkif_x86_32_request_rw {
        uint8_t        nr_segments;  /* number of segments                   */
@@ -129,14 +128,6 @@ struct blkif_x86_32_request {
        } u;
 } __attribute__((__packed__));
 
-/* i386 protocol version */
-#pragma pack(push, 4)
-struct blkif_x86_32_response {
-       uint64_t        id;              /* copied from request */
-       uint8_t         operation;       /* copied from request */
-       int16_t         status;          /* BLKIF_RSP_???       */
-};
-#pragma pack(pop)
 /* x86_64 protocol version */
 
 struct blkif_x86_64_request_rw {
@@ -193,18 +184,12 @@ struct blkif_x86_64_request {
        } u;
 } __attribute__((__packed__));
 
-struct blkif_x86_64_response {
-       uint64_t       __attribute__((__aligned__(8))) id;
-       uint8_t         operation;       /* copied from request */
-       int16_t         status;          /* BLKIF_RSP_???       */
-};
-
 DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
-                 struct blkif_common_response);
+                 struct blkif_response);
 DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
-                 struct blkif_x86_32_response);
+                 struct blkif_response __packed);
 DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
-                 struct blkif_x86_64_response);
+                 struct blkif_response);
 
 union blkif_back_rings {
        struct blkif_back_ring        native;
@@ -281,6 +266,7 @@ struct xen_blkif_ring {
 
        wait_queue_head_t       wq;
        atomic_t                inflight;
+       bool                    active;
        /* One thread per blkif ring. */
        struct task_struct      *xenblkd;
        unsigned int            waiting_reqs;
index 1f3dfaa54d871a36897408898c1e0e9f22100bb1..792da683e70dafafa6f69e224b8e57272d3e6be1 100644 (file)
@@ -159,7 +159,7 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif)
                init_waitqueue_head(&ring->shutdown_wq);
                ring->blkif = blkif;
                ring->st_print = jiffies;
-               xen_blkif_get(blkif);
+               ring->active = true;
        }
 
        return 0;
@@ -249,10 +249,12 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
                struct xen_blkif_ring *ring = &blkif->rings[r];
                unsigned int i = 0;
 
+               if (!ring->active)
+                       continue;
+
                if (ring->xenblkd) {
                        kthread_stop(ring->xenblkd);
                        wake_up(&ring->shutdown_wq);
-                       ring->xenblkd = NULL;
                }
 
                /* The above kthread_stop() guarantees that at this point we
@@ -296,7 +298,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
                BUG_ON(ring->free_pages_num != 0);
                BUG_ON(ring->persistent_gnt_c != 0);
                WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
-               xen_blkif_put(blkif);
+               ring->active = false;
        }
        blkif->nr_ring_pages = 0;
        /*
@@ -312,9 +314,10 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
 
 static void xen_blkif_free(struct xen_blkif *blkif)
 {
-
-       xen_blkif_disconnect(blkif);
+       WARN_ON(xen_blkif_disconnect(blkif));
        xen_vbd_free(&blkif->vbd);
+       kfree(blkif->be->mode);
+       kfree(blkif->be);
 
        /* Make sure everything is drained before shutting down */
        kmem_cache_free(xen_blkif_cachep, blkif);
@@ -511,8 +514,6 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
                xen_blkif_put(be->blkif);
        }
 
-       kfree(be->mode);
-       kfree(be);
        return 0;
 }
 
index e870f329db888c58e06bb854e7cf55d78a8bd313..01a260f67437488b425372c12d33142fce699f84 100644 (file)
@@ -803,13 +803,13 @@ static int crng_fast_load(const char *cp, size_t len)
                p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp;
                cp++; crng_init_cnt++; len--;
        }
+       spin_unlock_irqrestore(&primary_crng.lock, flags);
        if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
                invalidate_batched_entropy();
                crng_init = 1;
                wake_up_interruptible(&crng_init_wait);
                pr_notice("random: fast init done\n");
        }
-       spin_unlock_irqrestore(&primary_crng.lock, flags);
        return 1;
 }
 
@@ -841,6 +841,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
        }
        memzero_explicit(&buf, sizeof(buf));
        crng->init_time = jiffies;
+       spin_unlock_irqrestore(&primary_crng.lock, flags);
        if (crng == &primary_crng && crng_init < 2) {
                invalidate_batched_entropy();
                crng_init = 2;
@@ -848,7 +849,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
                wake_up_interruptible(&crng_init_wait);
                pr_notice("random: crng init done\n");
        }
-       spin_unlock_irqrestore(&primary_crng.lock, flags);
 }
 
 static inline void crng_wait_ready(void)
@@ -2041,8 +2041,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
 u64 get_random_u64(void)
 {
        u64 ret;
-       bool use_lock = crng_init < 2;
-       unsigned long flags;
+       bool use_lock = READ_ONCE(crng_init) < 2;
+       unsigned long flags = 0;
        struct batched_entropy *batch;
 
 #if BITS_PER_LONG == 64
@@ -2073,8 +2073,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
 u32 get_random_u32(void)
 {
        u32 ret;
-       bool use_lock = crng_init < 2;
-       unsigned long flags;
+       bool use_lock = READ_ONCE(crng_init) < 2;
+       unsigned long flags = 0;
        struct batched_entropy *batch;
 
        if (arch_get_random_int(&ret))
index 19480bcc704630bc2e7e084fb4cb586f0ac3c254..2f29ee1a4d005422a087de38efc3b5274b8f7a04 100644 (file)
@@ -14,6 +14,7 @@ config COMMON_CLK_MESON8B
 config COMMON_CLK_GXBB
        bool
        depends on COMMON_CLK_AMLOGIC
+       select RESET_CONTROLLER
        help
          Support for the clock controller on AmLogic S905 devices, aka gxbb.
          Say Y if you want peripherals and CPU frequency scaling to work.
index b0d551a8efe4d6d31114bc4f2cb3347173606cd9..eb89c7801f001b4a0ea0fde521fe695a298036b9 100644 (file)
@@ -156,6 +156,7 @@ config SUN8I_R_CCU
        bool "Support for Allwinner SoCs' PRCM CCUs"
        select SUNXI_CCU_DIV
        select SUNXI_CCU_GATE
+       select SUNXI_CCU_MP
        default MACH_SUN8I || (ARCH_SUNXI && ARM64)
 
 endif
index 9b3cd24b78d2326a06672555555f9752ebcf6b78..061b6fbb4f9591c0b77a54e8aa6a4ac0bb993e66 100644 (file)
@@ -31,7 +31,9 @@
 #define CLK_PLL_VIDEO0_2X              8
 #define CLK_PLL_VE                     9
 #define CLK_PLL_DDR0                   10
-#define CLK_PLL_PERIPH0                        11
+
+/* PLL_PERIPH0 exported for PRCM */
+
 #define CLK_PLL_PERIPH0_2X             12
 #define CLK_PLL_PERIPH1                        13
 #define CLK_PLL_PERIPH1_2X             14
index 5c476f966a7220c468799f5011b9994eb23c3ad4..5372bf8be5e6fb8b0a43185279d33cc1cc30bd3b 100644 (file)
@@ -243,7 +243,7 @@ static SUNXI_CCU_GATE(ahb_ss_clk,   "ahb-ss",       "ahb",
 static SUNXI_CCU_GATE(ahb_dma_clk,     "ahb-dma",      "ahb",
                      0x060, BIT(6), 0);
 static SUNXI_CCU_GATE(ahb_bist_clk,    "ahb-bist",     "ahb",
-                     0x060, BIT(6), 0);
+                     0x060, BIT(7), 0);
 static SUNXI_CCU_GATE(ahb_mmc0_clk,    "ahb-mmc0",     "ahb",
                      0x060, BIT(8), 0);
 static SUNXI_CCU_GATE(ahb_mmc1_clk,    "ahb-mmc1",     "ahb",
index 89e68d29bf456ab3d682f7d2ba7d35ad4a21bb58..df97e25aec76b505ddb88ab7d4b3dc76475fb035 100644 (file)
@@ -556,7 +556,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents,
                                 0x12c, 0, 4, 24, 3, BIT(31),
                                 CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents,
-                                0x12c, 0, 4, 24, 3, BIT(31),
+                                0x130, 0, 4, 24, 3, BIT(31),
                                 CLK_SET_RATE_PARENT);
 
 static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1",
index 85973d1e8165f9a085d9e574cc1f822430802c68..1b4baea37d810351d541d0b0a91d8a78a8524a95 100644 (file)
@@ -29,7 +29,9 @@
 #define CLK_PLL_VIDEO          6
 #define CLK_PLL_VE             7
 #define CLK_PLL_DDR            8
-#define CLK_PLL_PERIPH0                9
+
+/* PLL_PERIPH0 exported for PRCM */
+
 #define CLK_PLL_PERIPH0_2X     10
 #define CLK_PLL_GPU            11
 #define CLK_PLL_PERIPH1                12
index e58706b40ae98281d281b117f447e07c15546444..6297add857b53112a851f9bc0f1205db5996fe1b 100644 (file)
@@ -537,7 +537,7 @@ static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
        [RST_BUS_EMAC]          =  { 0x2c0, BIT(17) },
        [RST_BUS_HSTIMER]       =  { 0x2c0, BIT(19) },
        [RST_BUS_SPI0]          =  { 0x2c0, BIT(20) },
-       [RST_BUS_OTG]           =  { 0x2c0, BIT(23) },
+       [RST_BUS_OTG]           =  { 0x2c0, BIT(24) },
        [RST_BUS_EHCI0]         =  { 0x2c0, BIT(26) },
        [RST_BUS_OHCI0]         =  { 0x2c0, BIT(29) },
 
index 4bed671e490e0b15d79fd432f3d85dacfd094a96..8b5c30062d995968cc83e6c0511bcccab721873c 100644 (file)
@@ -1209,9 +1209,9 @@ arch_timer_mem_frame_get_cntfrq(struct arch_timer_mem_frame *frame)
                return 0;
        }
 
-       rate = readl_relaxed(frame + CNTFRQ);
+       rate = readl_relaxed(base + CNTFRQ);
 
-       iounmap(frame);
+       iounmap(base);
 
        return rate;
 }
index 44e5e951583bc38fc8c4a6a9b89ea91f7587af34..8e64b8460f113f56e829f69a414e229fea3c722a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
+#include <linux/clocksource.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/slab.h>
index 2e9c830ae1cd52d61e38dbb3620b2eb53dd4eb7e..c4656c4d44a6715a25b0b9ddaf432451f31ad32c 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/clk.h>
 #include <linux/clockchips.h>
+#include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
index 992f7c20760f3c69a07b9f4558d8774fc39520ed..88220ff3e1c226277e7ef8895317a5a1314ddee6 100644 (file)
@@ -185,8 +185,8 @@ static ssize_t store_down_threshold(struct gov_attr_set *attr_set,
        int ret;
        ret = sscanf(buf, "%u", &input);
 
-       /* cannot be lower than 11 otherwise freq will not fall */
-       if (ret != 1 || input < 11 || input > 100 ||
+       /* cannot be lower than 1 otherwise freq will not fall */
+       if (ret != 1 || input < 1 || input > 100 ||
                        input >= dbs_data->up_threshold)
                return -EINVAL;
 
index ffca4fc0061d6dad4de3c0d8ce4724461d7a13da..ae8eb03598892d18155d71161b4ea699d614ce97 100644 (file)
@@ -180,8 +180,10 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
                if (!state_node)
                        break;
 
-               if (!of_device_is_available(state_node))
+               if (!of_device_is_available(state_node)) {
+                       of_node_put(state_node);
                        continue;
+               }
 
                if (!idle_state_valid(state_node, i, cpumask)) {
                        pr_warn("%s idle state not valid, bailing out\n",
index 5c3e7b11e8a66c4853a1aabf9850537eea26767a..f6e7956fc91a212538b0ce937fe34f17aa73f073 100644 (file)
@@ -267,7 +267,11 @@ static int exynos_nocp_probe(struct platform_device *pdev)
        }
        platform_set_drvdata(pdev, nocp);
 
-       clk_prepare_enable(nocp->clk);
+       ret = clk_prepare_enable(nocp->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to prepare ppmu clock\n");
+               return ret;
+       }
 
        pr_info("exynos-nocp: new NoC Probe device registered: %s\n",
                        dev_name(dev));
index 9b7350935b73259828a897a7eea6d4fc9b2e4c4f..d96e3dc71cf8ba74fa92078d97c79d434344c949 100644 (file)
@@ -44,7 +44,7 @@ struct exynos_ppmu {
        { "ppmu-event2-"#name, PPMU_PMNCNT2 },  \
        { "ppmu-event3-"#name, PPMU_PMNCNT3 }
 
-struct __exynos_ppmu_events {
+static struct __exynos_ppmu_events {
        char *name;
        int id;
 } ppmu_events[] = {
@@ -648,7 +648,11 @@ static int exynos_ppmu_probe(struct platform_device *pdev)
                        dev_name(&pdev->dev), desc[i].name);
        }
 
-       clk_prepare_enable(info->ppmu.clk);
+       ret = clk_prepare_enable(info->ppmu.clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to prepare ppmu clock\n");
+               return ret;
+       }
 
        return 0;
 }
index dc269cb288c209d60e780eff287af2930fb4c477..951b6c79f166a7d2b4ec14e12096559df9aed684 100644 (file)
@@ -47,7 +47,7 @@ DEFINE_DMI_ATTR_WITH_SHOW(product_name,               0444, DMI_PRODUCT_NAME);
 DEFINE_DMI_ATTR_WITH_SHOW(product_version,     0444, DMI_PRODUCT_VERSION);
 DEFINE_DMI_ATTR_WITH_SHOW(product_serial,      0400, DMI_PRODUCT_SERIAL);
 DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,                0400, DMI_PRODUCT_UUID);
-DEFINE_DMI_ATTR_WITH_SHOW(product_family,      0400, DMI_PRODUCT_FAMILY);
+DEFINE_DMI_ATTR_WITH_SHOW(product_family,      0444, DMI_PRODUCT_FAMILY);
 DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,                0444, DMI_BOARD_VENDOR);
 DEFINE_DMI_ATTR_WITH_SHOW(board_name,          0444, DMI_BOARD_NAME);
 DEFINE_DMI_ATTR_WITH_SHOW(board_version,       0444, DMI_BOARD_VERSION);
@@ -192,7 +192,7 @@ static void __init dmi_id_init_attr_table(void)
        ADD_DMI_ATTR(product_version,   DMI_PRODUCT_VERSION);
        ADD_DMI_ATTR(product_serial,    DMI_PRODUCT_SERIAL);
        ADD_DMI_ATTR(product_uuid,      DMI_PRODUCT_UUID);
-       ADD_DMI_ATTR(product_family,      DMI_PRODUCT_FAMILY);
+       ADD_DMI_ATTR(product_family,    DMI_PRODUCT_FAMILY);
        ADD_DMI_ATTR(board_vendor,      DMI_BOARD_VENDOR);
        ADD_DMI_ATTR(board_name,        DMI_BOARD_NAME);
        ADD_DMI_ATTR(board_version,     DMI_BOARD_VERSION);
index 93f7acdaac7ac19c057fc6b98a76c270a4646f24..783041964439acaa60c80eac80df24080579d036 100644 (file)
@@ -144,7 +144,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
 
        buf = dmi_early_remap(dmi_base, orig_dmi_len);
        if (buf == NULL)
-               return -1;
+               return -ENOMEM;
 
        dmi_decode_table(buf, decode, NULL);
 
@@ -178,7 +178,7 @@ static void __init dmi_save_ident(const struct dmi_header *dm, int slot,
        const char *d = (const char *) dm;
        const char *p;
 
-       if (dmi_ident[slot])
+       if (dmi_ident[slot] || dm->length <= string)
                return;
 
        p = dmi_string(dm, d[string]);
@@ -191,13 +191,14 @@ static void __init dmi_save_ident(const struct dmi_header *dm, int slot,
 static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
                int index)
 {
-       const u8 *d = (u8 *) dm + index;
+       const u8 *d;
        char *s;
        int is_ff = 1, is_00 = 1, i;
 
-       if (dmi_ident[slot])
+       if (dmi_ident[slot] || dm->length <= index + 16)
                return;
 
+       d = (u8 *) dm + index;
        for (i = 0; i < 16 && (is_ff || is_00); i++) {
                if (d[i] != 0x00)
                        is_00 = 0;
@@ -228,16 +229,17 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
 static void __init dmi_save_type(const struct dmi_header *dm, int slot,
                int index)
 {
-       const u8 *d = (u8 *) dm + index;
+       const u8 *d;
        char *s;
 
-       if (dmi_ident[slot])
+       if (dmi_ident[slot] || dm->length <= index)
                return;
 
        s = dmi_alloc(4);
        if (!s)
                return;
 
+       d = (u8 *) dm + index;
        sprintf(s, "%u", *d & 0x7F);
        dmi_ident[slot] = s;
 }
@@ -278,9 +280,13 @@ static void __init dmi_save_devices(const struct dmi_header *dm)
 
 static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm)
 {
-       int i, count = *(u8 *)(dm + 1);
+       int i, count;
        struct dmi_device *dev;
 
+       if (dm->length < 0x05)
+               return;
+
+       count = *(u8 *)(dm + 1);
        for (i = 1; i <= count; i++) {
                const char *devname = dmi_string(dm, i);
 
@@ -353,6 +359,9 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
        const char *name;
        const u8 *d = (u8 *)dm;
 
+       if (dm->length < 0x0B)
+               return;
+
        /* Skip disabled device */
        if ((d[0x5] & 0x80) == 0)
                return;
@@ -387,7 +396,7 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v)
        const char *d = (const char *)dm;
        static int nr;
 
-       if (dm->type != DMI_ENTRY_MEM_DEVICE)
+       if (dm->type != DMI_ENTRY_MEM_DEVICE || dm->length < 0x12)
                return;
        if (nr >= dmi_memdev_nr) {
                pr_warn(FW_BUG "Too many DIMM entries in SMBIOS table\n");
@@ -649,6 +658,21 @@ void __init dmi_scan_machine(void)
                if (p == NULL)
                        goto error;
 
+               /*
+                * Same logic as above, look for a 64-bit entry point
+                * first, and if not found, fall back to 32-bit entry point.
+                */
+               memcpy_fromio(buf, p, 16);
+               for (q = p + 16; q < p + 0x10000; q += 16) {
+                       memcpy_fromio(buf + 16, q, 16);
+                       if (!dmi_smbios3_present(buf)) {
+                               dmi_available = 1;
+                               dmi_early_unmap(p, 0x10000);
+                               goto out;
+                       }
+                       memcpy(buf, buf + 16, 16);
+               }
+
                /*
                 * Iterate over all possible DMI header addresses q.
                 * Maintain the 32 bytes around q in buf.  On the
@@ -659,7 +683,7 @@ void __init dmi_scan_machine(void)
                memset(buf, 0, 16);
                for (q = p; q < p + 0x10000; q += 16) {
                        memcpy_fromio(buf + 16, q, 16);
-                       if (!dmi_smbios3_present(buf) || !dmi_present(buf)) {
+                       if (!dmi_present(buf)) {
                                dmi_available = 1;
                                dmi_early_unmap(p, 0x10000);
                                goto out;
@@ -993,7 +1017,8 @@ EXPORT_SYMBOL(dmi_get_date);
  *     @decode: Callback function
  *     @private_data: Private data to be passed to the callback function
  *
- *     Returns -1 when the DMI table can't be reached, 0 on success.
+ *     Returns 0 on success, -ENXIO if DMI is not selected or not present,
+ *     or a different negative error code if DMI walking fails.
  */
 int dmi_walk(void (*decode)(const struct dmi_header *, void *),
             void *private_data)
@@ -1001,11 +1026,11 @@ int dmi_walk(void (*decode)(const struct dmi_header *, void *),
        u8 *buf;
 
        if (!dmi_available)
-               return -1;
+               return -ENXIO;
 
        buf = dmi_remap(dmi_base, dmi_len);
        if (buf == NULL)
-               return -1;
+               return -ENOMEM;
 
        dmi_decode_table(buf, decode, private_data);
 
index 5104b63981390adb878ed27f4ca2d0d758c65307..c83ea68be792df45a354f38dee2438a866a1f29d 100644 (file)
@@ -721,7 +721,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
        u32 set;
 
        if (!of_device_is_compatible(mvchip->chip.of_node,
-                                    "marvell,armada-370-xp-gpio"))
+                                    "marvell,armada-370-gpio"))
                return 0;
 
        if (IS_ERR(mvchip->clk))
@@ -852,7 +852,7 @@ static const struct of_device_id mvebu_gpio_of_match[] = {
                .data       = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
        },
        {
-               .compatible = "marvell,armada-370-xp-gpio",
+               .compatible = "marvell,armada-370-gpio",
                .data       = (void *) MVEBU_GPIO_SOC_VARIANT_ORION,
        },
        {
@@ -1128,7 +1128,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
                                                 mvchip);
        }
 
-       /* Armada 370/XP has simple PWM support for GPIO lines */
+       /* Some MVEBU SoCs have simple PWM support for GPIO lines */
        if (IS_ENABLED(CONFIG_PWM))
                return mvebu_pwm_probe(pdev, mvchip, id);
 
index 1cf78f4dd339f93ddd971088ec42a5146b9820fe..1e8e1123ddf416f18176cbc6e82fa791b3df9fb5 100644 (file)
@@ -693,6 +693,10 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)
                        DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n",
                                 adev->clock.default_dispclk / 100);
                        adev->clock.default_dispclk = 60000;
+               } else if (adev->clock.default_dispclk <= 60000) {
+                       DRM_INFO("Changing default dispclk from %dMhz to 625Mhz\n",
+                                adev->clock.default_dispclk / 100);
+                       adev->clock.default_dispclk = 62500;
                }
                adev->clock.dp_extclk =
                        le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
index f2d705e6a75aa4f092d3d98ff739927e15b6f26b..ab6b0d0febab810ba4941e5a527435dd5d3161d8 100644 (file)
@@ -449,6 +449,7 @@ static const struct pci_device_id pciidlist[] = {
        {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, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
        {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
        /* Vega 10 */
        {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT},
index 8c9bc75a9c2db63288f2c6765b02f68f63875194..8a0818b23ea40fadde57f6b469b2153330b710ab 100644 (file)
@@ -165,7 +165,7 @@ void amdgpu_atombios_crtc_powergate(struct drm_crtc *crtc, int state)
        struct drm_device *dev = crtc->dev;
        struct amdgpu_device *adev = dev->dev_private;
        int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
-       ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
+       ENABLE_DISP_POWER_GATING_PS_ALLOCATION args;
 
        memset(&args, 0, sizeof(args));
 
@@ -178,7 +178,7 @@ void amdgpu_atombios_crtc_powergate(struct drm_crtc *crtc, int state)
 void amdgpu_atombios_crtc_powergate_init(struct amdgpu_device *adev)
 {
        int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
-       ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
+       ENABLE_DISP_POWER_GATING_PS_ALLOCATION args;
 
        memset(&args, 0, sizeof(args));
 
index 0cdeb6a2e4a0166d8f33a542e950e7c87abc11fa..5dffa27afa45a2dff164d46b53f6af2e24ca00ab 100644 (file)
@@ -1207,8 +1207,11 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
        u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
 
                /* watermark for high clocks */
                if (adev->pm.dpm_enabled) {
index 773654a19749fa7594250c6683d688e50bb12172..47bbc87f96d2bbf291db431e964b0dc9b0c5424e 100644 (file)
@@ -1176,8 +1176,11 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
        u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
 
                /* watermark for high clocks */
                if (adev->pm.dpm_enabled) {
index 1f3552967ba374c2e5677a742b70e2040f867d65..d8c9a959493ed512104e8b8414ffb1742c9566e3 100644 (file)
@@ -983,8 +983,11 @@ static void dce_v6_0_program_watermarks(struct amdgpu_device *adev,
        fixed20_12 a, b, c;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
                priority_a_cnt = 0;
                priority_b_cnt = 0;
 
index 3c558c170e5e685ad58aafa8dc6df301e879f264..db30c6ba563a4a2362e3fde4545ed92d35b1bae9 100644 (file)
@@ -1091,8 +1091,11 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
        u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
 
                /* watermark for high clocks */
                if (adev->pm.dpm_enabled) {
index 40d2827a6d19846c96d6e06ff84c0fdfc63567d1..53e78d092d18e3b9085d0784772639f8fa01f21c 100644 (file)
@@ -1,6 +1,7 @@
 config DRM_DW_HDMI
        tristate
        select DRM_KMS_HELPER
+       select REGMAP_MMIO
 
 config DRM_DW_HDMI_AHB_AUDIO
        tristate "Synopsys Designware AHB Audio interface"
index 9f847615ac74ab012f6203a141627a5c6f5993e2..48ca2457df8c964977f3f7edae0980bc227b97cf 100644 (file)
@@ -1229,21 +1229,6 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
        if (!connector)
                return -ENOENT;
 
-       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
-       encoder = drm_connector_get_encoder(connector);
-       if (encoder)
-               out_resp->encoder_id = encoder->base.id;
-       else
-               out_resp->encoder_id = 0;
-
-       ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
-                       (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
-                       (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
-                       &out_resp->count_props);
-       drm_modeset_unlock(&dev->mode_config.connection_mutex);
-       if (ret)
-               goto out_unref;
-
        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
                if (connector->encoder_ids[i] != 0)
                        encoders_count++;
@@ -1256,7 +1241,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
                                if (put_user(connector->encoder_ids[i],
                                             encoder_ptr + copied)) {
                                        ret = -EFAULT;
-                                       goto out_unref;
+                                       goto out;
                                }
                                copied++;
                        }
@@ -1300,15 +1285,32 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
                        if (copy_to_user(mode_ptr + copied,
                                         &u_mode, sizeof(u_mode))) {
                                ret = -EFAULT;
+                               mutex_unlock(&dev->mode_config.mutex);
+
                                goto out;
                        }
                        copied++;
                }
        }
        out_resp->count_modes = mode_count;
-out:
        mutex_unlock(&dev->mode_config.mutex);
-out_unref:
+
+       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+       encoder = drm_connector_get_encoder(connector);
+       if (encoder)
+               out_resp->encoder_id = encoder->base.id;
+       else
+               out_resp->encoder_id = 0;
+
+       /* Only grab properties after probing, to make sure EDID and other
+        * properties reflect the latest status. */
+       ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
+                       (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
+                       (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
+                       &out_resp->count_props);
+       drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+out:
        drm_connector_put(connector);
 
        return ret;
index c4a091e874269fd9ac79a025f9d37f250ac95520..e437fba1209d925cca7bf7f33b5651c3eeeda21a 100644 (file)
@@ -106,9 +106,10 @@ struct etnaviv_gem_submit {
        struct etnaviv_gpu *gpu;
        struct ww_acquire_ctx ticket;
        struct dma_fence *fence;
+       u32 flags;
        unsigned int nr_bos;
        struct etnaviv_gem_submit_bo bos[0];
-       u32 flags;
+       /* No new members here, the previous one is variable-length! */
 };
 
 int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj,
index de80ee1b71dfa2e8380b6e74b2d8cc6ed4aa6f25..1013765274da4a4853c21b302dbc646dacba5760 100644 (file)
@@ -172,7 +172,7 @@ static int submit_fence_sync(const struct etnaviv_gem_submit *submit)
        for (i = 0; i < submit->nr_bos; i++) {
                struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;
                bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE;
-               bool explicit = !(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
+               bool explicit = !!(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
 
                ret = etnaviv_gpu_fence_sync_obj(etnaviv_obj, context, write,
                                                 explicit);
index d689e511744e8f2fc9508e2d7345827c6a70bbb2..4bd1467c17b17c6225e27e05ccbde63444012f39 100644 (file)
@@ -292,6 +292,8 @@ static int per_file_stats(int id, void *ptr, void *data)
        struct file_stats *stats = data;
        struct i915_vma *vma;
 
+       lockdep_assert_held(&obj->base.dev->struct_mutex);
+
        stats->count++;
        stats->total += obj->base.size;
        if (!obj->bind_count)
@@ -476,6 +478,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
                struct drm_i915_gem_request *request;
                struct task_struct *task;
 
+               mutex_lock(&dev->struct_mutex);
+
                memset(&stats, 0, sizeof(stats));
                stats.file_priv = file->driver_priv;
                spin_lock(&file->table_lock);
@@ -487,7 +491,6 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
                 * still alive (e.g. get_pid(current) => fork() => exit()).
                 * Therefore, we need to protect this ->comm access using RCU.
                 */
-               mutex_lock(&dev->struct_mutex);
                request = list_first_entry_or_null(&file_priv->mm.request_list,
                                                   struct drm_i915_gem_request,
                                                   client_link);
@@ -497,6 +500,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
                                PIDTYPE_PID);
                print_file_stats(m, task ? task->comm : "<unknown>", stats);
                rcu_read_unlock();
+
                mutex_unlock(&dev->struct_mutex);
        }
        mutex_unlock(&dev->filelist_mutex);
index 462031cbd77f714b23a3b7645039c0d8dba71f40..615f0a855222f630d07311c92dce17d3bd371298 100644 (file)
@@ -2285,8 +2285,8 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
        struct page *page;
        unsigned long last_pfn = 0;     /* suppress gcc warning */
        unsigned int max_segment;
+       gfp_t noreclaim;
        int ret;
-       gfp_t gfp;
 
        /* Assert that the object is not currently in any GPU domain. As it
         * wasn't in the GTT, there shouldn't be any way it could have been in
@@ -2315,22 +2315,31 @@ rebuild_st:
         * Fail silently without starting the shrinker
         */
        mapping = obj->base.filp->f_mapping;
-       gfp = mapping_gfp_constraint(mapping, ~(__GFP_IO | __GFP_RECLAIM));
-       gfp |= __GFP_NORETRY | __GFP_NOWARN;
+       noreclaim = mapping_gfp_constraint(mapping,
+                                          ~(__GFP_IO | __GFP_RECLAIM));
+       noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
+
        sg = st->sgl;
        st->nents = 0;
        for (i = 0; i < page_count; i++) {
-               page = shmem_read_mapping_page_gfp(mapping, i, gfp);
-               if (unlikely(IS_ERR(page))) {
-                       i915_gem_shrink(dev_priv,
-                                       page_count,
-                                       I915_SHRINK_BOUND |
-                                       I915_SHRINK_UNBOUND |
-                                       I915_SHRINK_PURGEABLE);
+               const unsigned int shrink[] = {
+                       I915_SHRINK_BOUND | I915_SHRINK_UNBOUND | I915_SHRINK_PURGEABLE,
+                       0,
+               }, *s = shrink;
+               gfp_t gfp = noreclaim;
+
+               do {
                        page = shmem_read_mapping_page_gfp(mapping, i, gfp);
-               }
-               if (unlikely(IS_ERR(page))) {
-                       gfp_t reclaim;
+                       if (likely(!IS_ERR(page)))
+                               break;
+
+                       if (!*s) {
+                               ret = PTR_ERR(page);
+                               goto err_sg;
+                       }
+
+                       i915_gem_shrink(dev_priv, 2 * page_count, *s++);
+                       cond_resched();
 
                        /* We've tried hard to allocate the memory by reaping
                         * our own buffer, now let the real VM do its job and
@@ -2340,15 +2349,26 @@ rebuild_st:
                         * defer the oom here by reporting the ENOMEM back
                         * to userspace.
                         */
-                       reclaim = mapping_gfp_mask(mapping);
-                       reclaim |= __GFP_NORETRY; /* reclaim, but no oom */
-
-                       page = shmem_read_mapping_page_gfp(mapping, i, reclaim);
-                       if (IS_ERR(page)) {
-                               ret = PTR_ERR(page);
-                               goto err_sg;
+                       if (!*s) {
+                               /* reclaim and warn, but no oom */
+                               gfp = mapping_gfp_mask(mapping);
+
+                               /* Our bo are always dirty and so we require
+                                * kswapd to reclaim our pages (direct reclaim
+                                * does not effectively begin pageout of our
+                                * buffers on its own). However, direct reclaim
+                                * only waits for kswapd when under allocation
+                                * congestion. So as a result __GFP_RECLAIM is
+                                * unreliable and fails to actually reclaim our
+                                * dirty pages -- unless you try over and over
+                                * again with !__GFP_NORETRY. However, we still
+                                * want to fail this allocation rather than
+                                * trigger the out-of-memory killer and for
+                                * this we want the future __GFP_MAYFAIL.
+                                */
                        }
-               }
+               } while (1);
+
                if (!i ||
                    sg->length >= max_segment ||
                    page_to_pfn(page) != last_pfn + 1) {
@@ -4222,6 +4242,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 
        mapping = obj->base.filp->f_mapping;
        mapping_set_gfp_mask(mapping, mask);
+       GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM));
 
        i915_gem_object_init(obj, &i915_gem_object_ops);
 
index a3e59c8ef27baf4f3584ff5016635d8005735af6..9ad13eeed904d4d012c3fe93f6124b5ed5884b04 100644 (file)
@@ -546,11 +546,12 @@ repeat:
 }
 
 static int
-i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+i915_gem_execbuffer_relocate_entry(struct i915_vma *vma,
                                   struct eb_vmas *eb,
                                   struct drm_i915_gem_relocation_entry *reloc,
                                   struct reloc_cache *cache)
 {
+       struct drm_i915_gem_object *obj = vma->obj;
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        struct drm_gem_object *target_obj;
        struct drm_i915_gem_object *target_i915_obj;
@@ -628,6 +629,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
                return -EINVAL;
        }
 
+       /*
+        * If we write into the object, we need to force the synchronisation
+        * barrier, either with an asynchronous clflush or if we executed the
+        * patching using the GPU (though that should be serialised by the
+        * timeline). To be completely sure, and since we are required to
+        * do relocations we are already stalling, disable the user's opt
+        * of our synchronisation.
+        */
+       vma->exec_entry->flags &= ~EXEC_OBJECT_ASYNC;
+
        ret = relocate_entry(obj, reloc, cache, target_offset);
        if (ret)
                return ret;
@@ -678,7 +689,7 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
                do {
                        u64 offset = r->presumed_offset;
 
-                       ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r, &cache);
+                       ret = i915_gem_execbuffer_relocate_entry(vma, eb, r, &cache);
                        if (ret)
                                goto out;
 
@@ -726,7 +737,7 @@ i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
 
        reloc_cache_init(&cache, eb->i915);
        for (i = 0; i < entry->relocation_count; i++) {
-               ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i], &cache);
+               ret = i915_gem_execbuffer_relocate_entry(vma, eb, &relocs[i], &cache);
                if (ret)
                        break;
        }
index 5ddbc94997751adf5c9f04f7dd4a37a74d70de24..a74d0ac737cbeb7f9b9c5e93ea712a396e3c09d5 100644 (file)
@@ -623,7 +623,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
         * GPU processing the request, we never over-estimate the
         * position of the head.
         */
-       req->head = req->ring->tail;
+       req->head = req->ring->emit;
 
        /* Check that we didn't interrupt ourselves with a new request */
        GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
index 1642fff9cf135d5edbe85864d1b327d59002c026..ab5140ba108ddcb2c9c5382cc6439223704f9fda 100644 (file)
@@ -480,9 +480,7 @@ static void guc_wq_item_append(struct i915_guc_client *client,
        GEM_BUG_ON(freespace < wqi_size);
 
        /* The GuC firmware wants the tail index in QWords, not bytes */
-       tail = rq->tail;
-       assert_ring_tail_valid(rq->ring, rq->tail);
-       tail >>= 3;
+       tail = intel_ring_set_tail(rq->ring, rq->tail) >> 3;
        GEM_BUG_ON(tail > WQ_RING_TAIL_MAX);
 
        /* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we
index c0cb2974caacdb0357b8fcde1a585da51ead7b43..2cfe96d3e5d13e0dd1f6cc689a9af78608007617 100644 (file)
 #define VGT_VERSION_MAJOR 1
 #define VGT_VERSION_MINOR 0
 
-#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
-#define INTEL_VGT_IF_VERSION \
-       INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
-
 /*
  * notifications from guest to vgpu device model
  */
@@ -55,8 +51,8 @@ enum vgt_g2v_type {
 
 struct vgt_if {
        u64 magic;              /* VGT_MAGIC */
-       uint16_t version_major;
-       uint16_t version_minor;
+       u16 version_major;
+       u16 version_minor;
        u32 vgt_id;             /* ID of vGT instance */
        u32 rsv1[12];           /* pad to offset 0x40 */
        /*
index 4ab8a973b61f155c47ba528d1a907385e22b3b94..2e739018fb4c69581832d49800c5364d02160fb5 100644 (file)
@@ -60,8 +60,8 @@
  */
 void i915_check_vgpu(struct drm_i915_private *dev_priv)
 {
-       uint64_t magic;
-       uint32_t version;
+       u64 magic;
+       u16 version_major;
 
        BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
 
@@ -69,10 +69,8 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
        if (magic != VGT_MAGIC)
                return;
 
-       version = INTEL_VGT_IF_VERSION_ENCODE(
-               __raw_i915_read16(dev_priv, vgtif_reg(version_major)),
-               __raw_i915_read16(dev_priv, vgtif_reg(version_minor)));
-       if (version != INTEL_VGT_IF_VERSION) {
+       version_major = __raw_i915_read16(dev_priv, vgtif_reg(version_major));
+       if (version_major < VGT_VERSION_MAJOR) {
                DRM_INFO("VGT interface version mismatch!\n");
                return;
        }
index 1aba47024656817190168984f1d076ceea710e9b..f066e2d785f5c9d30fbe544b3caec698a3b4f8d1 100644 (file)
@@ -650,6 +650,11 @@ int i915_vma_unbind(struct i915_vma *vma)
                                break;
                }
 
+               if (!ret) {
+                       ret = i915_gem_active_retire(&vma->last_fence,
+                                                    &vma->vm->i915->drm.struct_mutex);
+               }
+
                __i915_vma_unpin(vma);
                if (ret)
                        return ret;
index 569717a1272367a91cf682a9cae7640f9ae32777..9106ea32b048cac4783ae316d7cc198a4bf8ae88 100644 (file)
@@ -120,7 +120,8 @@ static void intel_crtc_init_scalers(struct intel_crtc *crtc,
 static void skylake_pfit_enable(struct intel_crtc *crtc);
 static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
 static void ironlake_pfit_enable(struct intel_crtc *crtc);
-static void intel_modeset_setup_hw_state(struct drm_device *dev);
+static void intel_modeset_setup_hw_state(struct drm_device *dev,
+                                        struct drm_modeset_acquire_ctx *ctx);
 static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc);
 
 struct intel_limit {
@@ -3449,7 +3450,7 @@ __intel_display_resume(struct drm_device *dev,
        struct drm_crtc *crtc;
        int i, ret;
 
-       intel_modeset_setup_hw_state(dev);
+       intel_modeset_setup_hw_state(dev, ctx);
        i915_redisable_vga(to_i915(dev));
 
        if (!state)
@@ -4598,7 +4599,7 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
 
 static int
 skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
-                 unsigned scaler_user, int *scaler_id, unsigned int rotation,
+                 unsigned int scaler_user, int *scaler_id,
                  int src_w, int src_h, int dst_w, int dst_h)
 {
        struct intel_crtc_scaler_state *scaler_state =
@@ -4607,9 +4608,12 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
                to_intel_crtc(crtc_state->base.crtc);
        int need_scaling;
 
-       need_scaling = drm_rotation_90_or_270(rotation) ?
-               (src_h != dst_w || src_w != dst_h):
-               (src_w != dst_w || src_h != dst_h);
+       /*
+        * Src coordinates are already rotated by 270 degrees for
+        * the 90/270 degree plane rotation cases (to match the
+        * GTT mapping), hence no need to account for rotation here.
+        */
+       need_scaling = src_w != dst_w || src_h != dst_h;
 
        /*
         * if plane is being disabled or scaler is no more required or force detach
@@ -4671,7 +4675,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
        const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
 
        return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
-               &state->scaler_state.scaler_id, DRM_ROTATE_0,
+               &state->scaler_state.scaler_id,
                state->pipe_src_w, state->pipe_src_h,
                adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
 }
@@ -4700,7 +4704,6 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
        ret = skl_update_scaler(crtc_state, force_detach,
                                drm_plane_index(&intel_plane->base),
                                &plane_state->scaler_id,
-                               plane_state->base.rotation,
                                drm_rect_width(&plane_state->base.src) >> 16,
                                drm_rect_height(&plane_state->base.src) >> 16,
                                drm_rect_width(&plane_state->base.dst),
@@ -5823,7 +5826,8 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
                intel_update_watermarks(intel_crtc);
 }
 
-static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
+static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
+                                       struct drm_modeset_acquire_ctx *ctx)
 {
        struct intel_encoder *encoder;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -5853,7 +5857,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
                return;
        }
 
-       state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
+       state->acquire_ctx = ctx;
 
        /* Everything's already locked, -EDEADLK can't happen. */
        crtc_state = intel_atomic_get_crtc_state(state, intel_crtc);
@@ -15028,7 +15032,7 @@ int intel_modeset_init(struct drm_device *dev)
        intel_setup_outputs(dev_priv);
 
        drm_modeset_lock_all(dev);
-       intel_modeset_setup_hw_state(dev);
+       intel_modeset_setup_hw_state(dev, dev->mode_config.acquire_ctx);
        drm_modeset_unlock_all(dev);
 
        for_each_intel_crtc(dev, crtc) {
@@ -15065,13 +15069,13 @@ int intel_modeset_init(struct drm_device *dev)
        return 0;
 }
 
-static void intel_enable_pipe_a(struct drm_device *dev)
+static void intel_enable_pipe_a(struct drm_device *dev,
+                               struct drm_modeset_acquire_ctx *ctx)
 {
        struct intel_connector *connector;
        struct drm_connector_list_iter conn_iter;
        struct drm_connector *crt = NULL;
        struct intel_load_detect_pipe load_detect_temp;
-       struct drm_modeset_acquire_ctx *ctx = dev->mode_config.acquire_ctx;
        int ret;
 
        /* We can't just switch on the pipe A, we need to set things up with a
@@ -15143,7 +15147,8 @@ static bool has_pch_trancoder(struct drm_i915_private *dev_priv,
                (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == TRANSCODER_A);
 }
 
-static void intel_sanitize_crtc(struct intel_crtc *crtc)
+static void intel_sanitize_crtc(struct intel_crtc *crtc,
+                               struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -15189,7 +15194,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                plane = crtc->plane;
                crtc->base.primary->state->visible = true;
                crtc->plane = !plane;
-               intel_crtc_disable_noatomic(&crtc->base);
+               intel_crtc_disable_noatomic(&crtc->base, ctx);
                crtc->plane = plane;
        }
 
@@ -15199,13 +15204,13 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                 * resume. Force-enable the pipe to fix this, the update_dpms
                 * call below we restore the pipe to the right state, but leave
                 * the required bits on. */
-               intel_enable_pipe_a(dev);
+               intel_enable_pipe_a(dev, ctx);
        }
 
        /* Adjust the state of the output pipe according to whether we
         * have active connectors/encoders. */
        if (crtc->active && !intel_crtc_has_encoders(crtc))
-               intel_crtc_disable_noatomic(&crtc->base);
+               intel_crtc_disable_noatomic(&crtc->base, ctx);
 
        if (crtc->active || HAS_GMCH_DISPLAY(dev_priv)) {
                /*
@@ -15503,7 +15508,8 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv)
  * and sanitizes it to the current state
  */
 static void
-intel_modeset_setup_hw_state(struct drm_device *dev)
+intel_modeset_setup_hw_state(struct drm_device *dev,
+                            struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        enum pipe pipe;
@@ -15523,7 +15529,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
        for_each_pipe(dev_priv, pipe) {
                crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
 
-               intel_sanitize_crtc(crtc);
+               intel_sanitize_crtc(crtc, ctx);
                intel_dump_pipe_config(crtc, crtc->config,
                                       "[setup_hw_state]");
        }
index 6532e226db29b63da766a8571de231de4f7261f6..40ba3134545ef7e339c5bfe347501eeb7715dac0 100644 (file)
@@ -119,8 +119,6 @@ static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
        struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
        struct intel_panel *panel = &connector->panel;
 
-       intel_dp_aux_enable_backlight(connector);
-
        if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
                panel->backlight.max = 0xFFFF;
        else
index dac4e003c1f317ec402110132bad0c3a734bf52a..62f44d3e7c43c0d90df093050d5af6d3d68fe3a3 100644 (file)
@@ -326,8 +326,7 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq)
                rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
        u32 *reg_state = ce->lrc_reg_state;
 
-       assert_ring_tail_valid(rq->ring, rq->tail);
-       reg_state[CTX_RING_TAIL+1] = rq->tail;
+       reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
 
        /* True 32b PPGTT with dynamic page allocation: update PDP
         * registers and point the unallocated PDPs to scratch page.
@@ -2036,8 +2035,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
                        ce->state->obj->mm.dirty = true;
                        i915_gem_object_unpin_map(ce->state->obj);
 
-                       ce->ring->head = ce->ring->tail = 0;
-                       intel_ring_update_space(ce->ring);
+                       intel_ring_reset(ce->ring, 0);
                }
        }
 }
index 2ca481b5aa691872d39263605ef67b9c7335cec6..078fd1bfa5ea8aaa47cd552a8b37766394e76d01 100644 (file)
@@ -3373,20 +3373,26 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
 
        /* n.b., src is 16.16 fixed point, dst is whole integer */
        if (plane->id == PLANE_CURSOR) {
+               /*
+                * Cursors only support 0/180 degree rotation,
+                * hence no need to account for rotation here.
+                */
                src_w = pstate->base.src_w;
                src_h = pstate->base.src_h;
                dst_w = pstate->base.crtc_w;
                dst_h = pstate->base.crtc_h;
        } else {
+               /*
+                * Src coordinates are already rotated by 270 degrees for
+                * the 90/270 degree plane rotation cases (to match the
+                * GTT mapping), hence no need to account for rotation here.
+                */
                src_w = drm_rect_width(&pstate->base.src);
                src_h = drm_rect_height(&pstate->base.src);
                dst_w = drm_rect_width(&pstate->base.dst);
                dst_h = drm_rect_height(&pstate->base.dst);
        }
 
-       if (drm_rotation_90_or_270(pstate->base.rotation))
-               swap(dst_w, dst_h);
-
        downscale_h = max(src_h / dst_h, (uint32_t)DRM_PLANE_HELPER_NO_SCALING);
        downscale_w = max(src_w / dst_w, (uint32_t)DRM_PLANE_HELPER_NO_SCALING);
 
@@ -3417,12 +3423,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
        if (y && format != DRM_FORMAT_NV12)
                return 0;
 
+       /*
+        * Src coordinates are already rotated by 270 degrees for
+        * the 90/270 degree plane rotation cases (to match the
+        * GTT mapping), hence no need to account for rotation here.
+        */
        width = drm_rect_width(&intel_pstate->base.src) >> 16;
        height = drm_rect_height(&intel_pstate->base.src) >> 16;
 
-       if (drm_rotation_90_or_270(pstate->rotation))
-               swap(width, height);
-
        /* for planar format */
        if (format == DRM_FORMAT_NV12) {
                if (y)  /* y-plane data rate */
@@ -3505,12 +3513,14 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
            fb->modifier != I915_FORMAT_MOD_Yf_TILED)
                return 8;
 
+       /*
+        * Src coordinates are already rotated by 270 degrees for
+        * the 90/270 degree plane rotation cases (to match the
+        * GTT mapping), hence no need to account for rotation here.
+        */
        src_w = drm_rect_width(&intel_pstate->base.src) >> 16;
        src_h = drm_rect_height(&intel_pstate->base.src) >> 16;
 
-       if (drm_rotation_90_or_270(pstate->rotation))
-               swap(src_w, src_h);
-
        /* Halve UV plane width and height for NV12 */
        if (fb->format->format == DRM_FORMAT_NV12 && !y) {
                src_w /= 2;
@@ -3794,13 +3804,15 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
                width = intel_pstate->base.crtc_w;
                height = intel_pstate->base.crtc_h;
        } else {
+               /*
+                * Src coordinates are already rotated by 270 degrees for
+                * the 90/270 degree plane rotation cases (to match the
+                * GTT mapping), hence no need to account for rotation here.
+                */
                width = drm_rect_width(&intel_pstate->base.src) >> 16;
                height = drm_rect_height(&intel_pstate->base.src) >> 16;
        }
 
-       if (drm_rotation_90_or_270(pstate->rotation))
-               swap(width, height);
-
        cpp = fb->format->cpp[0];
        plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
 
index 66a2b8b83972691d04f2737337e7ea6cf6a72851..513a0f4b469b32c9d0ac2e87c089bb6f2e4907ba 100644 (file)
@@ -49,7 +49,7 @@ static int __intel_ring_space(int head, int tail, int size)
 
 void intel_ring_update_space(struct intel_ring *ring)
 {
-       ring->space = __intel_ring_space(ring->head, ring->tail, ring->size);
+       ring->space = __intel_ring_space(ring->head, ring->emit, ring->size);
 }
 
 static int
@@ -774,8 +774,8 @@ static void i9xx_submit_request(struct drm_i915_gem_request *request)
 
        i915_gem_request_submit(request);
 
-       assert_ring_tail_valid(request->ring, request->tail);
-       I915_WRITE_TAIL(request->engine, request->tail);
+       I915_WRITE_TAIL(request->engine,
+                       intel_ring_set_tail(request->ring, request->tail));
 }
 
 static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
@@ -1316,11 +1316,23 @@ err:
        return PTR_ERR(addr);
 }
 
+void intel_ring_reset(struct intel_ring *ring, u32 tail)
+{
+       GEM_BUG_ON(!list_empty(&ring->request_list));
+       ring->tail = tail;
+       ring->head = tail;
+       ring->emit = tail;
+       intel_ring_update_space(ring);
+}
+
 void intel_ring_unpin(struct intel_ring *ring)
 {
        GEM_BUG_ON(!ring->vma);
        GEM_BUG_ON(!ring->vaddr);
 
+       /* Discard any unused bytes beyond that submitted to hw. */
+       intel_ring_reset(ring, ring->tail);
+
        if (i915_vma_is_map_and_fenceable(ring->vma))
                i915_vma_unpin_iomap(ring->vma);
        else
@@ -1562,8 +1574,9 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv)
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
 
+       /* Restart from the beginning of the rings for convenience */
        for_each_engine(engine, dev_priv, id)
-               engine->buffer->head = engine->buffer->tail;
+               intel_ring_reset(engine->buffer, 0);
 }
 
 static int ring_request_alloc(struct drm_i915_gem_request *request)
@@ -1616,7 +1629,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
                unsigned space;
 
                /* Would completion of this request free enough space? */
-               space = __intel_ring_space(target->postfix, ring->tail,
+               space = __intel_ring_space(target->postfix, ring->emit,
                                           ring->size);
                if (space >= bytes)
                        break;
@@ -1641,8 +1654,8 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 {
        struct intel_ring *ring = req->ring;
-       int remain_actual = ring->size - ring->tail;
-       int remain_usable = ring->effective_size - ring->tail;
+       int remain_actual = ring->size - ring->emit;
+       int remain_usable = ring->effective_size - ring->emit;
        int bytes = num_dwords * sizeof(u32);
        int total_bytes, wait_bytes;
        bool need_wrap = false;
@@ -1678,17 +1691,17 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 
        if (unlikely(need_wrap)) {
                GEM_BUG_ON(remain_actual > ring->space);
-               GEM_BUG_ON(ring->tail + remain_actual > ring->size);
+               GEM_BUG_ON(ring->emit + remain_actual > ring->size);
 
                /* Fill the tail with MI_NOOP */
-               memset(ring->vaddr + ring->tail, 0, remain_actual);
-               ring->tail = 0;
+               memset(ring->vaddr + ring->emit, 0, remain_actual);
+               ring->emit = 0;
                ring->space -= remain_actual;
        }
 
-       GEM_BUG_ON(ring->tail > ring->size - bytes);
-       cs = ring->vaddr + ring->tail;
-       ring->tail += bytes;
+       GEM_BUG_ON(ring->emit > ring->size - bytes);
+       cs = ring->vaddr + ring->emit;
+       ring->emit += bytes;
        ring->space -= bytes;
        GEM_BUG_ON(ring->space < 0);
 
@@ -1699,7 +1712,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 int intel_ring_cacheline_align(struct drm_i915_gem_request *req)
 {
        int num_dwords =
-               (req->ring->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
+               (req->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
        u32 *cs;
 
        if (num_dwords == 0)
index a82a0807f64dbd0624728fe3c65215abe3647565..f7144fe0961347826c62e620af879bb4db9f0d77 100644 (file)
@@ -145,6 +145,7 @@ struct intel_ring {
 
        u32 head;
        u32 tail;
+       u32 emit;
 
        int space;
        int size;
@@ -488,6 +489,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 struct intel_ring *
 intel_engine_create_ring(struct intel_engine_cs *engine, int size);
 int intel_ring_pin(struct intel_ring *ring, unsigned int offset_bias);
+void intel_ring_reset(struct intel_ring *ring, u32 tail);
+void intel_ring_update_space(struct intel_ring *ring);
 void intel_ring_unpin(struct intel_ring *ring);
 void intel_ring_free(struct intel_ring *ring);
 
@@ -511,7 +514,7 @@ intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs)
         * reserved for the command packet (i.e. the value passed to
         * intel_ring_begin()).
         */
-       GEM_BUG_ON((req->ring->vaddr + req->ring->tail) != cs);
+       GEM_BUG_ON((req->ring->vaddr + req->ring->emit) != cs);
 }
 
 static inline u32
@@ -540,7 +543,19 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
        GEM_BUG_ON(tail >= ring->size);
 }
 
-void intel_ring_update_space(struct intel_ring *ring);
+static inline unsigned int
+intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
+{
+       /* Whilst writes to the tail are strictly order, there is no
+        * serialisation between readers and the writers. The tail may be
+        * read by i915_gem_request_retire() just as it is being updated
+        * by execlists, as although the breadcrumb is complete, the context
+        * switch hasn't been seen.
+        */
+       assert_ring_tail_valid(ring, tail);
+       ring->tail = tail;
+       return tail;
+}
 
 void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);
 
index adb411a078e8237c0fcb5ecde76bdf1287f9df50..f4b53588e071e4cdc10ecbf152fcb0cee3d55e10 100644 (file)
@@ -1173,7 +1173,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
 
 
        if (IS_G200_SE(mdev)) {
-               if (mdev->unique_rev_id >= 0x02) {
+               if  (mdev->unique_rev_id >= 0x04) {
+                       WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
+                       WREG8(MGAREG_CRTCEXT_DATA, 0);
+               } else if (mdev->unique_rev_id >= 0x02) {
                        u8 hi_pri_lvl;
                        u32 bpp;
                        u32 mb;
@@ -1639,6 +1642,10 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
                        if (mga_vga_calculate_mode_bandwidth(mode, bpp)
                                > (30100 * 1024))
                                return MODE_BANDWIDTH;
+               } else {
+                       if (mga_vga_calculate_mode_bandwidth(mode, bpp)
+                               > (55000 * 1024))
+                               return MODE_BANDWIDTH;
                }
        } else if (mdev->type == G200_WB) {
                if (mode->hdisplay > 1280)
index 1144e0c9e8942ddb6226a7f409ed07f25a0eb96a..0abe77675b76d36ceaa38ece5a2a14afdf3eb060 100644 (file)
 #include "mxsfb_drv.h"
 #include "mxsfb_regs.h"
 
+#define MXS_SET_ADDR           0x4
+#define MXS_CLR_ADDR           0x8
+#define MODULE_CLKGATE         BIT(30)
+#define MODULE_SFTRST          BIT(31)
+/* 1 second delay should be plenty of time for block reset */
+#define RESET_TIMEOUT          1000000
+
 static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val)
 {
        return (val & mxsfb->devdata->hs_wdth_mask) <<
@@ -159,6 +166,36 @@ static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb)
                clk_disable_unprepare(mxsfb->clk_disp_axi);
 }
 
+/*
+ * Clear the bit and poll it cleared.  This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+       u32 reg;
+
+       writel(mask, addr + MXS_CLR_ADDR);
+       return readl_poll_timeout(addr, reg, !(reg & mask), 0, RESET_TIMEOUT);
+}
+
+static int mxsfb_reset_block(void __iomem *reset_addr)
+{
+       int ret;
+
+       ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
+       if (ret)
+               return ret;
+
+       writel(MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
+
+       ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
+       if (ret)
+               return ret;
+
+       return clear_poll_bit(reset_addr, MODULE_CLKGATE);
+}
+
 static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
 {
        struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
@@ -173,6 +210,11 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
         */
        mxsfb_enable_axi_clk(mxsfb);
 
+       /* Mandatory eLCDIF reset as per the Reference Manual */
+       err = mxsfb_reset_block(mxsfb->base);
+       if (err)
+               return;
+
        /* Clear the FIFOs */
        writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET);
 
index 008c145b7f29f60a298419931f1922555de5e35a..ca44233ceaccb87482068d992e4c415f756fa540 100644 (file)
@@ -9267,8 +9267,11 @@ static void dce8_program_watermarks(struct radeon_device *rdev,
        u32 tmp, wm_mask;
 
        if (radeon_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
 
                /* watermark for high clocks */
                if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
index 0bf103536404e5dde2d480bf692a496a6865e817..534637203e709909bc11c934c7e1e20b4551e31e 100644 (file)
@@ -2266,8 +2266,11 @@ static void evergreen_program_watermarks(struct radeon_device *rdev,
        fixed20_12 a, b, c;
 
        if (radeon_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
                priority_a_cnt = 0;
                priority_b_cnt = 0;
                dram_channels = evergreen_get_number_of_dram_channels(rdev);
index 432480ff9d228857d57170b3353c143bf0501c3f..3178ba0c537c1915af3b857aad83efd6371f17ad 100644 (file)
@@ -3393,6 +3393,13 @@ void radeon_combios_asic_init(struct drm_device *dev)
            rdev->pdev->subsystem_vendor == 0x103c &&
            rdev->pdev->subsystem_device == 0x280a)
                return;
+       /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
+        * - it hangs on resume inside the dynclk 1 table.
+        */
+       if (rdev->family == CHIP_RS400 &&
+           rdev->pdev->subsystem_vendor == 0x1179 &&
+           rdev->pdev->subsystem_device == 0xff31)
+               return;
 
        /* DYN CLK 1 */
        table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
index 6ecf42783d4b0c45539325edd2e5ffd2fc08e29f..0a6444d72000c434a6b494229a75c1a7d3e41631 100644 (file)
@@ -136,6 +136,10 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = {
         * https://bugzilla.kernel.org/show_bug.cgi?id=51381
         */
        { PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX },
+       /* Asus K53TK laptop with AMD A6-3420M APU and Radeon 7670m GPU
+        * https://bugs.freedesktop.org/show_bug.cgi?id=101491
+        */
+       { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX },
        /* macbook pro 8.2 */
        { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP },
        { 0, 0, 0, 0, 0 },
index 7431eb4a11b7f721fc8e44240c09742b02dc0446..d34d1cf33895766c55a122adad041be62e42c70c 100644 (file)
@@ -621,7 +621,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
        }
 
        /* TODO: is this still necessary on NI+ ? */
-       if ((cmd == 0 || cmd == 1 || cmd == 0x3) &&
+       if ((cmd == 0 || cmd == 0x3) &&
            (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) {
                DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n",
                          start, end);
index 76d1888528e675c700b543fa6e10c77a466054d7..5303f25d5280ed49548db40007444dee7cf79abe 100644 (file)
@@ -2284,8 +2284,11 @@ static void dce6_program_watermarks(struct radeon_device *rdev,
        fixed20_12 a, b, c;
 
        if (radeon_crtc->base.enabled && num_heads && mode) {
-               active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-               line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+                                           (u32)mode->clock);
+               line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+                                         (u32)mode->clock);
+               line_time = min(line_time, (u32)65535);
                priority_a_cnt = 0;
                priority_b_cnt = 0;
 
index 9a1e34e48f64fb0ab684a20811a0be0ff0a09ab6..81f86a67c10d28416a3fbe3d69694b8c7dfc34ee 100644 (file)
@@ -451,18 +451,6 @@ fail:
 
 
 #ifdef CONFIG_DRM_TEGRA_STAGING
-static struct tegra_drm_context *
-tegra_drm_file_get_context(struct tegra_drm_file *file, u32 id)
-{
-       struct tegra_drm_context *context;
-
-       mutex_lock(&file->lock);
-       context = idr_find(&file->contexts, id);
-       mutex_unlock(&file->lock);
-
-       return context;
-}
-
 static int tegra_gem_create(struct drm_device *drm, void *data,
                            struct drm_file *file)
 {
@@ -551,7 +539,7 @@ static int tegra_client_open(struct tegra_drm_file *fpriv,
        if (err < 0)
                return err;
 
-       err = idr_alloc(&fpriv->contexts, context, 0, 0, GFP_KERNEL);
+       err = idr_alloc(&fpriv->contexts, context, 1, 0, GFP_KERNEL);
        if (err < 0) {
                client->ops->close_channel(context);
                return err;
@@ -606,7 +594,7 @@ static int tegra_close_channel(struct drm_device *drm, void *data,
 
        mutex_lock(&fpriv->lock);
 
-       context = tegra_drm_file_get_context(fpriv, args->context);
+       context = idr_find(&fpriv->contexts, args->context);
        if (!context) {
                err = -EINVAL;
                goto unlock;
@@ -631,7 +619,7 @@ static int tegra_get_syncpt(struct drm_device *drm, void *data,
 
        mutex_lock(&fpriv->lock);
 
-       context = tegra_drm_file_get_context(fpriv, args->context);
+       context = idr_find(&fpriv->contexts, args->context);
        if (!context) {
                err = -ENODEV;
                goto unlock;
@@ -660,7 +648,7 @@ static int tegra_submit(struct drm_device *drm, void *data,
 
        mutex_lock(&fpriv->lock);
 
-       context = tegra_drm_file_get_context(fpriv, args->context);
+       context = idr_find(&fpriv->contexts, args->context);
        if (!context) {
                err = -ENODEV;
                goto unlock;
@@ -685,7 +673,7 @@ static int tegra_get_syncpt_base(struct drm_device *drm, void *data,
 
        mutex_lock(&fpriv->lock);
 
-       context = tegra_drm_file_get_context(fpriv, args->context);
+       context = idr_find(&fpriv->contexts, args->context);
        if (!context) {
                err = -ENODEV;
                goto unlock;
index 13db8a2851edd475cc1e44adedd44796c3ccbca1..1f013d45c9e9a3959dfa19300ba76fc37820592a 100644 (file)
@@ -321,6 +321,7 @@ void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man)
        list_for_each_entry_safe(entry, next, &man->list, head)
                vmw_cmdbuf_res_free(man, entry);
 
+       drm_ht_remove(&man->resources);
        kfree(man);
 }
 
index f05ebb14fa636bce578c2fd00db88dbc835fdbe9..ac65f52850a6351e3ecb3ee27816b4c3d8df5e67 100644 (file)
@@ -172,7 +172,7 @@ static int host1x_probe(struct platform_device *pdev)
 
        host->rst = devm_reset_control_get(&pdev->dev, "host1x");
        if (IS_ERR(host->rst)) {
-               err = PTR_ERR(host->clk);
+               err = PTR_ERR(host->rst);
                dev_err(&pdev->dev, "failed to get reset: %d\n", err);
                return err;
        }
index 04cee65531d761c18e53775ffc784c3c3d993daa..6e040692f1d8f2c7032c51ad96540a341f80c35b 100644 (file)
@@ -826,11 +826,35 @@ static int hid_scan_report(struct hid_device *hid)
                                 * hid-rmi should take care of them,
                                 * not hid-generic
                                 */
-                               if (IS_ENABLED(CONFIG_HID_RMI))
-                                       hid->group = HID_GROUP_RMI;
+                               hid->group = HID_GROUP_RMI;
                break;
        }
 
+       /* fall back to generic driver in case specific driver doesn't exist */
+       switch (hid->group) {
+       case HID_GROUP_MULTITOUCH_WIN_8:
+               /* fall-through */
+       case HID_GROUP_MULTITOUCH:
+               if (!IS_ENABLED(CONFIG_HID_MULTITOUCH))
+                       hid->group = HID_GROUP_GENERIC;
+               break;
+       case HID_GROUP_SENSOR_HUB:
+               if (!IS_ENABLED(CONFIG_HID_SENSOR_HUB))
+                       hid->group = HID_GROUP_GENERIC;
+               break;
+       case HID_GROUP_RMI:
+               if (!IS_ENABLED(CONFIG_HID_RMI))
+                       hid->group = HID_GROUP_GENERIC;
+               break;
+       case HID_GROUP_WACOM:
+               if (!IS_ENABLED(CONFIG_HID_WACOM))
+                       hid->group = HID_GROUP_GENERIC;
+               break;
+       case HID_GROUP_LOGITECH_DJ_DEVICE:
+               if (!IS_ENABLED(CONFIG_HID_LOGITECH_DJ))
+                       hid->group = HID_GROUP_GENERIC;
+               break;
+       }
        vfree(parser);
        return 0;
 }
@@ -1763,15 +1787,23 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
  * used as a driver. See hid_scan_report().
  */
 static const struct hid_device_id hid_have_special_driver[] = {
+#if IS_ENABLED(CONFIG_HID_A4TECH)
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ACCUTOUCH)
+       { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ACRUX)
        { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ALPS)
        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
+#endif
+#if IS_ENABLED(CONFIG_HID_APPLE)
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
@@ -1792,11 +1824,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
@@ -1851,62 +1878,100 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
+#endif
+#if IS_ENABLED(CONFIG_HID_APPLEIR)
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ASUS)
        { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },
        { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD) },
+#endif
+#if IS_ENABLED(CONFIG_HID_AUREAL)
        { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) },
+#endif
+#if IS_ENABLED(CONFIG_HID_BELKIN)
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
+#endif
+#if IS_ENABLED(CONFIG_HID_BETOP_FF)
        { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
+#endif
+#if IS_ENABLED(CONFIG_HID_CHERRY)
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
+#endif
+#if IS_ENABLED(CONFIG_HID_CHICONY)
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
        { 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) },
+#endif
+#if IS_ENABLED(CONFIG_HID_CMEDIA)
+       { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) },
+#endif
+#if IS_ENABLED(CONFIG_HID_CORSAIR)
        { 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) },
+#endif
+#if IS_ENABLED(CONFIG_HID_CP2112)
        { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
+#endif
+#if IS_ENABLED(CONFIG_HID_CYPRESS)
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, USB_DEVICE_ID_DELCOM_VISUAL_IND) },
+#endif
+#if IS_ENABLED(CONFIG_HID_DRAGONRISE)
        { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
-#if IS_ENABLED(CONFIG_HID_MAYFLASH)
-       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) },
 #endif
-       { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) },
+#if IS_ENABLED(CONFIG_HID_ELECOM)
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ELO)
        { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) },
+#endif
+#if IS_ENABLED(CONFIG_HID_EMS_FF)
        { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
+#endif
+#if IS_ENABLED(CONFIG_HID_EZKEY)
        { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
+#endif
+#if IS_ENABLED(CONFIG_HID_GEMBIRD)
        { HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
+#endif
+#if IS_ENABLED(CONFIG_HID_GFRM)
+        { HID_BLUETOOTH_DEVICE(0x58, 0x2000) },
+        { HID_BLUETOOTH_DEVICE(0x471, 0x2210) },
+#endif
+#if IS_ENABLED(CONFIG_HID_GREENASIA)
        { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
+#endif
+#if IS_ENABLED(CONFIG_HID_GT683R)
+       { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
+#endif
+#if IS_ENABLED(CONFIG_HID_GYRATION)
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
+#endif
+#if IS_ENABLED(CONFIG_HID_HOLTEK)
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
@@ -1915,12 +1980,17 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
        { 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) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ICADE)
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
+#endif
+#if IS_ENABLED(CONFIG_HID_KENSINGTON)
        { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+#endif
+#if IS_ENABLED(CONFIG_HID_KEYTOUCH)
        { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
+#endif
+#if IS_ENABLED(CONFIG_HID_KYE)
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
@@ -1930,21 +2000,29 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
+#endif
+#if IS_ENABLED(CONFIG_HID_LCPOWER)
        { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
+#endif
+#if IS_ENABLED(CONFIG_HID_LED)
+       { HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, USB_DEVICE_ID_DELCOM_VISUAL_IND) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_LUXAFOR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) },
+#endif
 #if IS_ENABLED(CONFIG_HID_LENOVO)
        { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },
 #endif
-       { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) },
+#if IS_ENABLED(CONFIG_HID_LOGITECH)
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
@@ -1957,7 +2035,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
@@ -1969,17 +2046,30 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
-#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
-       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) },
-#endif
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_LUXAFOR) },
+#endif
+#if IS_ENABLED(CONFIG_HID_LOGITECH_HIDPP)
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
+#endif
+#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
+       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) },
+#endif
+#if IS_ENABLED(CONFIG_HID_MAGICMOUSE)
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
+#endif
+#if IS_ENABLED(CONFIG_HID_MAYFLASH)
+       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) },
+#endif
+#if IS_ENABLED(CONFIG_HID_MICROSOFT)
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
@@ -1995,9 +2085,22 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
+#endif
+#if IS_ENABLED(CONFIG_HID_MONTEREY)
        { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
+#endif
+#if IS_ENABLED(CONFIG_HID_MULTITOUCH)
+       { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) },
+#endif
+#if IS_ENABLED(CONFIG_HID_WIIMOTE)
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
+#endif
+#if IS_ENABLED(CONFIG_HID_NTI)
        { HID_USB_DEVICE(USB_VENDOR_ID_NTI, USB_DEVICE_ID_USB_SUN) },
+#endif
+#if IS_ENABLED(CONFIG_HID_NTRIG)
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
@@ -2017,13 +2120,41 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ORTEK)
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PANTHERLORD)
+       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PENMOUNT)
        { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PETALYNX)
        { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PICOLCD)
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PLANTRONICS)
        { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PRIMAX)
        { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) },
+#endif
+#if IS_ENABLED(CONFIG_HID_PRODIKEYS)
+       { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
+#endif
+#if IS_ENABLED(CONFIG_HID_RMI)
+       { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
+#endif
 #if IS_ENABLED(CONFIG_HID_ROCCAT)
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
@@ -2051,9 +2182,21 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },
 #endif
+#if IS_ENABLED(CONFIG_HID_SAMSUNG)
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
+#endif
+#if IS_ENABLED(CONFIG_HID_SMARTJOYPLUS)
+       { HID_USB_DEVICE(USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
+#endif
+#if IS_ENABLED(CONFIG_HID_SONY)
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
@@ -2072,9 +2215,17 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) },
+#endif
+#if IS_ENABLED(CONFIG_HID_SPEEDLINK)
+       { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
+#endif
+#if IS_ENABLED(CONFIG_HID_STEELSERIES)
        { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
+#endif
+#if IS_ENABLED(CONFIG_HID_SUNPLUS)
        { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) },
+#endif
+#if IS_ENABLED(CONFIG_HID_THRUSTMASTER)
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
@@ -2083,12 +2234,25 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
+#endif
+#if IS_ENABLED(CONFIG_HID_TIVO)
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) },
+#endif
+#if IS_ENABLED(CONFIG_HID_TOPSEED)
+       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
+#endif
+#if IS_ENABLED(CONFIG_HID_TWINHAN)
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
+#endif
+#if IS_ENABLED(CONFIG_HID_UCLOGIC)
+       { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
@@ -2096,20 +2260,17 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_YIYNOVA_TABLET) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UGEE_TABLET_81) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UGEE_TABLET_45) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_TABLET_EX07S) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
+#endif
+#if IS_ENABLED(CONFIG_HID_UDRAW_PS3)
+       { HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },
+#endif
+#if IS_ENABLED(CONFIG_HID_WALTOP)
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) },
@@ -2117,19 +2278,18 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
        { 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) },
+#endif
+#if IS_ENABLED(CONFIG_HID_XINMO)
        { 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) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ZEROPLUS)
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+#endif
+#if IS_ENABLED(CONFIG_HID_ZYDACRON)
        { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
-
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
+#endif
        { }
 };
 
index 8ca1e8ce0af24e325957526c125ccf55d9081eb8..4f9a3938189a020ca6257b85182e6c1b53426158 100644 (file)
 #define USB_VENDOR_ID_DELCOM           0x0fc5
 #define USB_DEVICE_ID_DELCOM_VISUAL_IND        0xb080
 
+#define USB_VENDOR_ID_DELL                             0x413c
+#define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE    0x301a
+
 #define USB_VENDOR_ID_DELORME          0x1163
 #define USB_DEVICE_ID_DELORME_EARTHMATE        0x0100
 #define USB_DEVICE_ID_DELORME_EM_LT20  0x0200
index 1d6c997b300149269367d00fb5db66b7c2ea25b7..20b40ad2632503754685b84cc07d8787a4a44515 100644 (file)
@@ -349,7 +349,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 
        if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
                magicmouse_emit_buttons(msc, clicks & 3);
-               input_mt_report_pointer_emulation(input, true);
                input_report_rel(input, REL_X, x);
                input_report_rel(input, REL_Y, y);
        } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
@@ -389,16 +388,16 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
                __clear_bit(BTN_RIGHT, input->keybit);
                __clear_bit(BTN_MIDDLE, input->keybit);
                __set_bit(BTN_MOUSE, input->keybit);
+               __set_bit(BTN_TOOL_FINGER, input->keybit);
+               __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
+               __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
+               __set_bit(BTN_TOOL_QUADTAP, input->keybit);
+               __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
+               __set_bit(BTN_TOUCH, input->keybit);
+               __set_bit(INPUT_PROP_POINTER, input->propbit);
                __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
        }
 
-       __set_bit(BTN_TOOL_FINGER, input->keybit);
-       __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
-       __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
-       __set_bit(BTN_TOOL_QUADTAP, input->keybit);
-       __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
-       __set_bit(BTN_TOUCH, input->keybit);
-       __set_bit(INPUT_PROP_POINTER, input->propbit);
 
        __set_bit(EV_ABS, input->evbit);
 
index 6316498b78128574ff63b0047772f009e6d0cfeb..a88e7c7bea0a0cb7d069c262c026231f3bc75dea 100644 (file)
@@ -85,6 +85,7 @@ static const struct hid_blacklist {
        { 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_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
        { 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 },
        { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT },
index 26b05106f0d3152e74bc0377dc9006203fc2c7db..93d28c0ec8bf0ef867bc958592c58f60d3ce2913 100644 (file)
@@ -1066,7 +1066,7 @@ static void ssip_pn_setup(struct net_device *dev)
        dev->addr_len           = 1;
        dev->tx_queue_len       = SSIP_TXQUEUE_LEN;
 
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->header_ops         = &phonet_header_ops;
 }
 
index 95ed17183e73e904e06b13c383bee28410797172..54a47b40546f69c7ea0d3dbf033c22c95f106516 100644 (file)
@@ -734,9 +734,9 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
                 * the first read operation, otherwise the first read cost
                 * one extra clock cycle.
                 */
-               temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                temp |= I2CR_MTX;
-               writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+               imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        }
        msgs->buf[msgs->len-1] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
 
@@ -857,9 +857,9 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
                                 * the first read operation, otherwise the first read cost
                                 * one extra clock cycle.
                                 */
-                               temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+                               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                                temp |= I2CR_MTX;
-                               writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+                               imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                        }
                } else if (i == (msgs->len - 2)) {
                        dev_dbg(&i2c_imx->adapter.dev,
index f573448d2132161d4839a17d11afb1c1f4104188..e98e44e584a44a6e17dc3af00ae1f02ce50ae95b 100644 (file)
@@ -584,7 +584,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
 
        /* unmap the data buffer */
        if (dma_size != 0)
-               dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction);
+               dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
 
        if (unlikely(!time_left)) {
                dev_err(dev, "completion wait timed out\n");
index 214bf2835d1f95ff176cb0ded24654b20b821944..8be3e6cb8fe686a02b62eb1b699a1763e0186df5 100644 (file)
@@ -319,7 +319,7 @@ static void rcar_i2c_dma_unmap(struct rcar_i2c_priv *priv)
        rcar_i2c_write(priv, ICFBSCR, TCYC06);
 
        dma_unmap_single(chan->device->dev, sg_dma_address(&priv->sg),
-                        priv->msg->len, priv->dma_direction);
+                        sg_dma_len(&priv->sg), priv->dma_direction);
 
        priv->dma_direction = DMA_NONE;
 }
index dd4190b50df6a71a43d0fb22175ddb3f1e7d64c7..6066bbfc42fe4126a849495563e1eae58d4244d4 100644 (file)
@@ -468,13 +468,13 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
 static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
-       int count;
+       unsigned int count, tmp;
 
        for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) {
                if (!meson_sar_adc_get_fifo_count(indio_dev))
                        break;
 
-               regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, 0);
+               regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp);
        }
 }
 
index b0c7d8ee5cb8d859d683b2b0aca40ef5999d2546..6888167ca1e6cb65ab926b36fe8199684a00527d 100644 (file)
@@ -718,9 +718,12 @@ static int mxs_lradc_adc_probe(struct platform_device *pdev)
        adc->dev = dev;
 
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!iores)
+               return -EINVAL;
+
        adc->base = devm_ioremap(dev, iores->start, resource_size(iores));
-       if (IS_ERR(adc->base))
-               return PTR_ERR(adc->base);
+       if (!adc->base)
+               return -ENOMEM;
 
        init_completion(&adc->completion);
        spin_lock_init(&adc->lock);
index dd99d273bae9bf620f2543b39400d10e5ae66fd6..ff03324dee132f49455fd156bacbc9b450146a19 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/poll.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/buffer_impl.h>
 #include <linux/iio/buffer-dma.h>
 #include <linux/dma-mapping.h>
 #include <linux/sizes.h>
index 9fabed47053ddaf2517500845d337429f6c9af22..2b5a320f42c51e1872835b19454f8924f2e004ea 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/buffer_impl.h>
 #include <linux/iio/buffer-dma.h>
 #include <linux/iio/buffer-dmaengine.h>
 
index 96dabbd2f004b3d91c1cde6cca2f6dfdaf091d58..88a7c5d4e4d2850ae9755b5fb79ff595855cac7c 100644 (file)
@@ -41,6 +41,7 @@ static const int accel_scale[] = {598, 1196, 2392, 4785};
 static const struct inv_mpu6050_reg_map reg_set_6500 = {
        .sample_rate_div        = INV_MPU6050_REG_SAMPLE_RATE_DIV,
        .lpf                    = INV_MPU6050_REG_CONFIG,
+       .accel_lpf              = INV_MPU6500_REG_ACCEL_CONFIG_2,
        .user_ctrl              = INV_MPU6050_REG_USER_CTRL,
        .fifo_en                = INV_MPU6050_REG_FIFO_EN,
        .gyro_config            = INV_MPU6050_REG_GYRO_CONFIG,
@@ -210,6 +211,37 @@ int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
 }
 EXPORT_SYMBOL_GPL(inv_mpu6050_set_power_itg);
 
+/**
+ *  inv_mpu6050_set_lpf_regs() - set low pass filter registers, chip dependent
+ *
+ *  MPU60xx/MPU9150 use only 1 register for accelerometer + gyroscope
+ *  MPU6500 and above have a dedicated register for accelerometer
+ */
+static int inv_mpu6050_set_lpf_regs(struct inv_mpu6050_state *st,
+                                   enum inv_mpu6050_filter_e val)
+{
+       int result;
+
+       result = regmap_write(st->map, st->reg->lpf, val);
+       if (result)
+               return result;
+
+       switch (st->chip_type) {
+       case INV_MPU6050:
+       case INV_MPU6000:
+       case INV_MPU9150:
+               /* old chips, nothing to do */
+               result = 0;
+               break;
+       default:
+               /* set accel lpf */
+               result = regmap_write(st->map, st->reg->accel_lpf, val);
+               break;
+       }
+
+       return result;
+}
+
 /**
  *  inv_mpu6050_init_config() - Initialize hardware, disable FIFO.
  *
@@ -233,8 +265,7 @@ static int inv_mpu6050_init_config(struct iio_dev *indio_dev)
        if (result)
                return result;
 
-       d = INV_MPU6050_FILTER_20HZ;
-       result = regmap_write(st->map, st->reg->lpf, d);
+       result = inv_mpu6050_set_lpf_regs(st, INV_MPU6050_FILTER_20HZ);
        if (result)
                return result;
 
@@ -537,6 +568,8 @@ error_write_raw:
  *                  would be alising. This function basically search for the
  *                  correct low pass parameters based on the fifo rate, e.g,
  *                  sampling frequency.
+ *
+ *  lpf is set automatically when setting sampling rate to avoid any aliases.
  */
 static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
 {
@@ -552,7 +585,7 @@ static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
        while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
                i++;
        data = d[i];
-       result = regmap_write(st->map, st->reg->lpf, data);
+       result = inv_mpu6050_set_lpf_regs(st, data);
        if (result)
                return result;
        st->chip_config.lpf = data;
index ef13de7a2c20fd6ef3e450f8d3094483af71b9a9..953a0c09d5685a18d447e4ad07f3f334b32cd8cf 100644 (file)
@@ -28,6 +28,7 @@
  *  struct inv_mpu6050_reg_map - Notable registers.
  *  @sample_rate_div:  Divider applied to gyro output rate.
  *  @lpf:              Configures internal low pass filter.
+ *  @accel_lpf:                Configures accelerometer low pass filter.
  *  @user_ctrl:                Enables/resets the FIFO.
  *  @fifo_en:          Determines which data will appear in FIFO.
  *  @gyro_config:      gyro config register.
@@ -47,6 +48,7 @@
 struct inv_mpu6050_reg_map {
        u8 sample_rate_div;
        u8 lpf;
+       u8 accel_lpf;
        u8 user_ctrl;
        u8 fifo_en;
        u8 gyro_config;
@@ -188,6 +190,7 @@ struct inv_mpu6050_state {
 #define INV_MPU6050_FIFO_THRESHOLD           500
 
 /* mpu6500 registers */
+#define INV_MPU6500_REG_ACCEL_CONFIG_2      0x1D
 #define INV_MPU6500_REG_ACCEL_OFFSET        0x77
 
 /* delay time in milliseconds */
index 02971e239a182debc69aea1306169be981d97086..ece6926fa2e6aa242e38a189a7b3a8f7ed22e140 100644 (file)
@@ -449,12 +449,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                return ret;
 
        rt = (struct rt6_info *)dst;
-       if (ipv6_addr_any(&fl6.saddr)) {
-               ret = ipv6_dev_get_saddr(addr->net, ip6_dst_idev(dst)->dev,
-                                        &fl6.daddr, 0, &fl6.saddr);
-               if (ret)
-                       goto put;
-
+       if (ipv6_addr_any(&src_in->sin6_addr)) {
                src_in->sin6_family = AF_INET6;
                src_in->sin6_addr = fl6.saddr;
        }
@@ -471,9 +466,6 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 
        *pdst = dst;
        return 0;
-put:
-       dst_release(dst);
-       return ret;
 }
 #else
 static int addr6_resolve(struct sockaddr_in6 *src_in,
index ebf7be8d4139b87dd8232568603ab1aa8c19d045..08772836fded416e41be8eccfe53cf3e8427691b 100644 (file)
 #define BNXT_RE_MAX_SRQC_COUNT         (64 * 1024)
 #define BNXT_RE_MAX_CQ_COUNT           (64 * 1024)
 
+#define BNXT_RE_UD_QP_HW_STALL         0x400000
+
+#define BNXT_RE_RQ_WQE_THRESHOLD       32
+
 struct bnxt_re_work {
        struct work_struct      work;
        unsigned long           event;
index 7ba9e699d7abc65cb82fbd588e9ea12e7f71433b..c7bd68311d0c5317973ecf9c3fb8fce8fe8ffad4 100644 (file)
 #include "ib_verbs.h"
 #include <rdma/bnxt_re-abi.h>
 
+static int __from_ib_access_flags(int iflags)
+{
+       int qflags = 0;
+
+       if (iflags & IB_ACCESS_LOCAL_WRITE)
+               qflags |= BNXT_QPLIB_ACCESS_LOCAL_WRITE;
+       if (iflags & IB_ACCESS_REMOTE_READ)
+               qflags |= BNXT_QPLIB_ACCESS_REMOTE_READ;
+       if (iflags & IB_ACCESS_REMOTE_WRITE)
+               qflags |= BNXT_QPLIB_ACCESS_REMOTE_WRITE;
+       if (iflags & IB_ACCESS_REMOTE_ATOMIC)
+               qflags |= BNXT_QPLIB_ACCESS_REMOTE_ATOMIC;
+       if (iflags & IB_ACCESS_MW_BIND)
+               qflags |= BNXT_QPLIB_ACCESS_MW_BIND;
+       if (iflags & IB_ZERO_BASED)
+               qflags |= BNXT_QPLIB_ACCESS_ZERO_BASED;
+       if (iflags & IB_ACCESS_ON_DEMAND)
+               qflags |= BNXT_QPLIB_ACCESS_ON_DEMAND;
+       return qflags;
+};
+
+static enum ib_access_flags __to_ib_access_flags(int qflags)
+{
+       enum ib_access_flags iflags = 0;
+
+       if (qflags & BNXT_QPLIB_ACCESS_LOCAL_WRITE)
+               iflags |= IB_ACCESS_LOCAL_WRITE;
+       if (qflags & BNXT_QPLIB_ACCESS_REMOTE_WRITE)
+               iflags |= IB_ACCESS_REMOTE_WRITE;
+       if (qflags & BNXT_QPLIB_ACCESS_REMOTE_READ)
+               iflags |= IB_ACCESS_REMOTE_READ;
+       if (qflags & BNXT_QPLIB_ACCESS_REMOTE_ATOMIC)
+               iflags |= IB_ACCESS_REMOTE_ATOMIC;
+       if (qflags & BNXT_QPLIB_ACCESS_MW_BIND)
+               iflags |= IB_ACCESS_MW_BIND;
+       if (qflags & BNXT_QPLIB_ACCESS_ZERO_BASED)
+               iflags |= IB_ZERO_BASED;
+       if (qflags & BNXT_QPLIB_ACCESS_ON_DEMAND)
+               iflags |= IB_ACCESS_ON_DEMAND;
+       return iflags;
+};
+
 static int bnxt_re_build_sgl(struct ib_sge *ib_sg_list,
                             struct bnxt_qplib_sge *sg_list, int num)
 {
@@ -149,8 +191,8 @@ int bnxt_re_query_device(struct ib_device *ibdev,
        ib_attr->max_total_mcast_qp_attach = 0;
        ib_attr->max_ah = dev_attr->max_ah;
 
-       ib_attr->max_fmr = dev_attr->max_fmr;
-       ib_attr->max_map_per_fmr = 1;   /* ? */
+       ib_attr->max_fmr = 0;
+       ib_attr->max_map_per_fmr = 0;
 
        ib_attr->max_srq = dev_attr->max_srq;
        ib_attr->max_srq_wr = dev_attr->max_srq_wqes;
@@ -410,6 +452,158 @@ enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
        return IB_LINK_LAYER_ETHERNET;
 }
 
+#define        BNXT_RE_FENCE_PBL_SIZE  DIV_ROUND_UP(BNXT_RE_FENCE_BYTES, PAGE_SIZE)
+
+static void bnxt_re_create_fence_wqe(struct bnxt_re_pd *pd)
+{
+       struct bnxt_re_fence_data *fence = &pd->fence;
+       struct ib_mr *ib_mr = &fence->mr->ib_mr;
+       struct bnxt_qplib_swqe *wqe = &fence->bind_wqe;
+
+       memset(wqe, 0, sizeof(*wqe));
+       wqe->type = BNXT_QPLIB_SWQE_TYPE_BIND_MW;
+       wqe->wr_id = BNXT_QPLIB_FENCE_WRID;
+       wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
+       wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
+       wqe->bind.zero_based = false;
+       wqe->bind.parent_l_key = ib_mr->lkey;
+       wqe->bind.va = (u64)(unsigned long)fence->va;
+       wqe->bind.length = fence->size;
+       wqe->bind.access_cntl = __from_ib_access_flags(IB_ACCESS_REMOTE_READ);
+       wqe->bind.mw_type = SQ_BIND_MW_TYPE_TYPE1;
+
+       /* Save the initial rkey in fence structure for now;
+        * wqe->bind.r_key will be set at (re)bind time.
+        */
+       fence->bind_rkey = ib_inc_rkey(fence->mw->rkey);
+}
+
+static int bnxt_re_bind_fence_mw(struct bnxt_qplib_qp *qplib_qp)
+{
+       struct bnxt_re_qp *qp = container_of(qplib_qp, struct bnxt_re_qp,
+                                            qplib_qp);
+       struct ib_pd *ib_pd = qp->ib_qp.pd;
+       struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
+       struct bnxt_re_fence_data *fence = &pd->fence;
+       struct bnxt_qplib_swqe *fence_wqe = &fence->bind_wqe;
+       struct bnxt_qplib_swqe wqe;
+       int rc;
+
+       memcpy(&wqe, fence_wqe, sizeof(wqe));
+       wqe.bind.r_key = fence->bind_rkey;
+       fence->bind_rkey = ib_inc_rkey(fence->bind_rkey);
+
+       dev_dbg(rdev_to_dev(qp->rdev),
+               "Posting bind fence-WQE: rkey: %#x QP: %d PD: %p\n",
+               wqe.bind.r_key, qp->qplib_qp.id, pd);
+       rc = bnxt_qplib_post_send(&qp->qplib_qp, &wqe);
+       if (rc) {
+               dev_err(rdev_to_dev(qp->rdev), "Failed to bind fence-WQE\n");
+               return rc;
+       }
+       bnxt_qplib_post_send_db(&qp->qplib_qp);
+
+       return rc;
+}
+
+static void bnxt_re_destroy_fence_mr(struct bnxt_re_pd *pd)
+{
+       struct bnxt_re_fence_data *fence = &pd->fence;
+       struct bnxt_re_dev *rdev = pd->rdev;
+       struct device *dev = &rdev->en_dev->pdev->dev;
+       struct bnxt_re_mr *mr = fence->mr;
+
+       if (fence->mw) {
+               bnxt_re_dealloc_mw(fence->mw);
+               fence->mw = NULL;
+       }
+       if (mr) {
+               if (mr->ib_mr.rkey)
+                       bnxt_qplib_dereg_mrw(&rdev->qplib_res, &mr->qplib_mr,
+                                            true);
+               if (mr->ib_mr.lkey)
+                       bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr);
+               kfree(mr);
+               fence->mr = NULL;
+       }
+       if (fence->dma_addr) {
+               dma_unmap_single(dev, fence->dma_addr, BNXT_RE_FENCE_BYTES,
+                                DMA_BIDIRECTIONAL);
+               fence->dma_addr = 0;
+       }
+}
+
+static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd)
+{
+       int mr_access_flags = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_MW_BIND;
+       struct bnxt_re_fence_data *fence = &pd->fence;
+       struct bnxt_re_dev *rdev = pd->rdev;
+       struct device *dev = &rdev->en_dev->pdev->dev;
+       struct bnxt_re_mr *mr = NULL;
+       dma_addr_t dma_addr = 0;
+       struct ib_mw *mw;
+       u64 pbl_tbl;
+       int rc;
+
+       dma_addr = dma_map_single(dev, fence->va, BNXT_RE_FENCE_BYTES,
+                                 DMA_BIDIRECTIONAL);
+       rc = dma_mapping_error(dev, dma_addr);
+       if (rc) {
+               dev_err(rdev_to_dev(rdev), "Failed to dma-map fence-MR-mem\n");
+               rc = -EIO;
+               fence->dma_addr = 0;
+               goto fail;
+       }
+       fence->dma_addr = dma_addr;
+
+       /* Allocate a MR */
+       mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+       if (!mr) {
+               rc = -ENOMEM;
+               goto fail;
+       }
+       fence->mr = mr;
+       mr->rdev = rdev;
+       mr->qplib_mr.pd = &pd->qplib_pd;
+       mr->qplib_mr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR;
+       mr->qplib_mr.flags = __from_ib_access_flags(mr_access_flags);
+       rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr);
+       if (rc) {
+               dev_err(rdev_to_dev(rdev), "Failed to alloc fence-HW-MR\n");
+               goto fail;
+       }
+
+       /* Register MR */
+       mr->ib_mr.lkey = mr->qplib_mr.lkey;
+       mr->qplib_mr.va = (u64)(unsigned long)fence->va;
+       mr->qplib_mr.total_size = BNXT_RE_FENCE_BYTES;
+       pbl_tbl = dma_addr;
+       rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, &pbl_tbl,
+                              BNXT_RE_FENCE_PBL_SIZE, false);
+       if (rc) {
+               dev_err(rdev_to_dev(rdev), "Failed to register fence-MR\n");
+               goto fail;
+       }
+       mr->ib_mr.rkey = mr->qplib_mr.rkey;
+
+       /* Create a fence MW only for kernel consumers */
+       mw = bnxt_re_alloc_mw(&pd->ib_pd, IB_MW_TYPE_1, NULL);
+       if (!mw) {
+               dev_err(rdev_to_dev(rdev),
+                       "Failed to create fence-MW for PD: %p\n", pd);
+               rc = -EINVAL;
+               goto fail;
+       }
+       fence->mw = mw;
+
+       bnxt_re_create_fence_wqe(pd);
+       return 0;
+
+fail:
+       bnxt_re_destroy_fence_mr(pd);
+       return rc;
+}
+
 /* Protection Domains */
 int bnxt_re_dealloc_pd(struct ib_pd *ib_pd)
 {
@@ -417,6 +611,7 @@ int bnxt_re_dealloc_pd(struct ib_pd *ib_pd)
        struct bnxt_re_dev *rdev = pd->rdev;
        int rc;
 
+       bnxt_re_destroy_fence_mr(pd);
        if (ib_pd->uobject && pd->dpi.dbr) {
                struct ib_ucontext *ib_uctx = ib_pd->uobject->context;
                struct bnxt_re_ucontext *ucntx;
@@ -498,6 +693,10 @@ struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
                }
        }
 
+       if (!udata)
+               if (bnxt_re_create_fence_mr(pd))
+                       dev_warn(rdev_to_dev(rdev),
+                                "Failed to create Fence-MR\n");
        return &pd->ib_pd;
 dbfail:
        (void)bnxt_qplib_dealloc_pd(&rdev->qplib_res, &rdev->qplib_res.pd_tbl,
@@ -849,12 +1048,16 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
        /* Shadow QP SQ depth should be same as QP1 RQ depth */
        qp->qplib_qp.sq.max_wqe = qp1_qp->rq.max_wqe;
        qp->qplib_qp.sq.max_sge = 2;
+       /* Q full delta can be 1 since it is internal QP */
+       qp->qplib_qp.sq.q_full_delta = 1;
 
        qp->qplib_qp.scq = qp1_qp->scq;
        qp->qplib_qp.rcq = qp1_qp->rcq;
 
        qp->qplib_qp.rq.max_wqe = qp1_qp->rq.max_wqe;
        qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge;
+       /* Q full delta can be 1 since it is internal QP */
+       qp->qplib_qp.rq.q_full_delta = 1;
 
        qp->qplib_qp.mtu = qp1_qp->mtu;
 
@@ -917,10 +1120,6 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
        qp->qplib_qp.sig_type = ((qp_init_attr->sq_sig_type ==
                                  IB_SIGNAL_ALL_WR) ? true : false);
 
-       entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + 1);
-       qp->qplib_qp.sq.max_wqe = min_t(u32, entries,
-                                       dev_attr->max_qp_wqes + 1);
-
        qp->qplib_qp.sq.max_sge = qp_init_attr->cap.max_send_sge;
        if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges)
                qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges;
@@ -959,6 +1158,9 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
                qp->qplib_qp.rq.max_wqe = min_t(u32, entries,
                                                dev_attr->max_qp_wqes + 1);
 
+               qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe -
+                                               qp_init_attr->cap.max_recv_wr;
+
                qp->qplib_qp.rq.max_sge = qp_init_attr->cap.max_recv_sge;
                if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges)
                        qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges;
@@ -967,6 +1169,12 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
        qp->qplib_qp.mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu));
 
        if (qp_init_attr->qp_type == IB_QPT_GSI) {
+               /* Allocate 1 more than what's provided */
+               entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + 1);
+               qp->qplib_qp.sq.max_wqe = min_t(u32, entries,
+                                               dev_attr->max_qp_wqes + 1);
+               qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe -
+                                               qp_init_attr->cap.max_send_wr;
                qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges;
                if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges)
                        qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges;
@@ -1006,6 +1214,22 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
                }
 
        } else {
+               /* Allocate 128 + 1 more than what's provided */
+               entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr +
+                                            BNXT_QPLIB_RESERVED_QP_WRS + 1);
+               qp->qplib_qp.sq.max_wqe = min_t(u32, entries,
+                                               dev_attr->max_qp_wqes +
+                                               BNXT_QPLIB_RESERVED_QP_WRS + 1);
+               qp->qplib_qp.sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1;
+
+               /*
+                * Reserving one slot for Phantom WQE. Application can
+                * post one extra entry in this case. But allowing this to avoid
+                * unexpected Queue full condition
+                */
+
+               qp->qplib_qp.sq.q_full_delta -= 1;
+
                qp->qplib_qp.max_rd_atomic = dev_attr->max_qp_rd_atom;
                qp->qplib_qp.max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom;
                if (udata) {
@@ -1025,6 +1249,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
 
        qp->ib_qp.qp_num = qp->qplib_qp.id;
        spin_lock_init(&qp->sq_lock);
+       spin_lock_init(&qp->rq_lock);
 
        if (udata) {
                struct bnxt_re_qp_resp resp;
@@ -1129,48 +1354,6 @@ static enum ib_mtu __to_ib_mtu(u32 mtu)
        }
 }
 
-static int __from_ib_access_flags(int iflags)
-{
-       int qflags = 0;
-
-       if (iflags & IB_ACCESS_LOCAL_WRITE)
-               qflags |= BNXT_QPLIB_ACCESS_LOCAL_WRITE;
-       if (iflags & IB_ACCESS_REMOTE_READ)
-               qflags |= BNXT_QPLIB_ACCESS_REMOTE_READ;
-       if (iflags & IB_ACCESS_REMOTE_WRITE)
-               qflags |= BNXT_QPLIB_ACCESS_REMOTE_WRITE;
-       if (iflags & IB_ACCESS_REMOTE_ATOMIC)
-               qflags |= BNXT_QPLIB_ACCESS_REMOTE_ATOMIC;
-       if (iflags & IB_ACCESS_MW_BIND)
-               qflags |= BNXT_QPLIB_ACCESS_MW_BIND;
-       if (iflags & IB_ZERO_BASED)
-               qflags |= BNXT_QPLIB_ACCESS_ZERO_BASED;
-       if (iflags & IB_ACCESS_ON_DEMAND)
-               qflags |= BNXT_QPLIB_ACCESS_ON_DEMAND;
-       return qflags;
-};
-
-static enum ib_access_flags __to_ib_access_flags(int qflags)
-{
-       enum ib_access_flags iflags = 0;
-
-       if (qflags & BNXT_QPLIB_ACCESS_LOCAL_WRITE)
-               iflags |= IB_ACCESS_LOCAL_WRITE;
-       if (qflags & BNXT_QPLIB_ACCESS_REMOTE_WRITE)
-               iflags |= IB_ACCESS_REMOTE_WRITE;
-       if (qflags & BNXT_QPLIB_ACCESS_REMOTE_READ)
-               iflags |= IB_ACCESS_REMOTE_READ;
-       if (qflags & BNXT_QPLIB_ACCESS_REMOTE_ATOMIC)
-               iflags |= IB_ACCESS_REMOTE_ATOMIC;
-       if (qflags & BNXT_QPLIB_ACCESS_MW_BIND)
-               iflags |= IB_ACCESS_MW_BIND;
-       if (qflags & BNXT_QPLIB_ACCESS_ZERO_BASED)
-               iflags |= IB_ZERO_BASED;
-       if (qflags & BNXT_QPLIB_ACCESS_ON_DEMAND)
-               iflags |= IB_ACCESS_ON_DEMAND;
-       return iflags;
-};
-
 static int bnxt_re_modify_shadow_qp(struct bnxt_re_dev *rdev,
                                    struct bnxt_re_qp *qp1_qp,
                                    int qp_attr_mask)
@@ -1378,11 +1561,21 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
                entries = roundup_pow_of_two(qp_attr->cap.max_send_wr);
                qp->qplib_qp.sq.max_wqe = min_t(u32, entries,
                                                dev_attr->max_qp_wqes + 1);
+               qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe -
+                                               qp_attr->cap.max_send_wr;
+               /*
+                * Reserving one slot for Phantom WQE. Some application can
+                * post one extra entry in this case. Allowing this to avoid
+                * unexpected Queue full condition
+                */
+               qp->qplib_qp.sq.q_full_delta -= 1;
                qp->qplib_qp.sq.max_sge = qp_attr->cap.max_send_sge;
                if (qp->qplib_qp.rq.max_wqe) {
                        entries = roundup_pow_of_two(qp_attr->cap.max_recv_wr);
                        qp->qplib_qp.rq.max_wqe =
                                min_t(u32, entries, dev_attr->max_qp_wqes + 1);
+                       qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe -
+                                                      qp_attr->cap.max_recv_wr;
                        qp->qplib_qp.rq.max_sge = qp_attr->cap.max_recv_sge;
                } else {
                        /* SRQ was used prior, just ignore the RQ caps */
@@ -1883,6 +2076,22 @@ static int bnxt_re_copy_wr_payload(struct bnxt_re_dev *rdev,
        return payload_sz;
 }
 
+static void bnxt_ud_qp_hw_stall_workaround(struct bnxt_re_qp *qp)
+{
+       if ((qp->ib_qp.qp_type == IB_QPT_UD ||
+            qp->ib_qp.qp_type == IB_QPT_GSI ||
+            qp->ib_qp.qp_type == IB_QPT_RAW_ETHERTYPE) &&
+            qp->qplib_qp.wqe_cnt == BNXT_RE_UD_QP_HW_STALL) {
+               int qp_attr_mask;
+               struct ib_qp_attr qp_attr;
+
+               qp_attr_mask = IB_QP_STATE;
+               qp_attr.qp_state = IB_QPS_RTS;
+               bnxt_re_modify_qp(&qp->ib_qp, &qp_attr, qp_attr_mask, NULL);
+               qp->qplib_qp.wqe_cnt = 0;
+       }
+}
+
 static int bnxt_re_post_send_shadow_qp(struct bnxt_re_dev *rdev,
                                       struct bnxt_re_qp *qp,
                                struct ib_send_wr *wr)
@@ -1928,6 +2137,7 @@ bad:
                wr = wr->next;
        }
        bnxt_qplib_post_send_db(&qp->qplib_qp);
+       bnxt_ud_qp_hw_stall_workaround(qp);
        spin_unlock_irqrestore(&qp->sq_lock, flags);
        return rc;
 }
@@ -2024,6 +2234,7 @@ bad:
                wr = wr->next;
        }
        bnxt_qplib_post_send_db(&qp->qplib_qp);
+       bnxt_ud_qp_hw_stall_workaround(qp);
        spin_unlock_irqrestore(&qp->sq_lock, flags);
 
        return rc;
@@ -2071,7 +2282,10 @@ int bnxt_re_post_recv(struct ib_qp *ib_qp, struct ib_recv_wr *wr,
        struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
        struct bnxt_qplib_swqe wqe;
        int rc = 0, payload_sz = 0;
+       unsigned long flags;
+       u32 count = 0;
 
+       spin_lock_irqsave(&qp->rq_lock, flags);
        while (wr) {
                /* House keeping */
                memset(&wqe, 0, sizeof(wqe));
@@ -2100,9 +2314,21 @@ int bnxt_re_post_recv(struct ib_qp *ib_qp, struct ib_recv_wr *wr,
                        *bad_wr = wr;
                        break;
                }
+
+               /* Ring DB if the RQEs posted reaches a threshold value */
+               if (++count >= BNXT_RE_RQ_WQE_THRESHOLD) {
+                       bnxt_qplib_post_recv_db(&qp->qplib_qp);
+                       count = 0;
+               }
+
                wr = wr->next;
        }
-       bnxt_qplib_post_recv_db(&qp->qplib_qp);
+
+       if (count)
+               bnxt_qplib_post_recv_db(&qp->qplib_qp);
+
+       spin_unlock_irqrestore(&qp->rq_lock, flags);
+
        return rc;
 }
 
@@ -2643,12 +2869,36 @@ static void bnxt_re_process_res_ud_wc(struct ib_wc *wc,
                wc->opcode = IB_WC_RECV_RDMA_WITH_IMM;
 }
 
+static int send_phantom_wqe(struct bnxt_re_qp *qp)
+{
+       struct bnxt_qplib_qp *lib_qp = &qp->qplib_qp;
+       unsigned long flags;
+       int rc = 0;
+
+       spin_lock_irqsave(&qp->sq_lock, flags);
+
+       rc = bnxt_re_bind_fence_mw(lib_qp);
+       if (!rc) {
+               lib_qp->sq.phantom_wqe_cnt++;
+               dev_dbg(&lib_qp->sq.hwq.pdev->dev,
+                       "qp %#x sq->prod %#x sw_prod %#x phantom_wqe_cnt %d\n",
+                       lib_qp->id, lib_qp->sq.hwq.prod,
+                       HWQ_CMP(lib_qp->sq.hwq.prod, &lib_qp->sq.hwq),
+                       lib_qp->sq.phantom_wqe_cnt);
+       }
+
+       spin_unlock_irqrestore(&qp->sq_lock, flags);
+       return rc;
+}
+
 int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
 {
        struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq);
        struct bnxt_re_qp *qp;
        struct bnxt_qplib_cqe *cqe;
        int i, ncqe, budget;
+       struct bnxt_qplib_q *sq;
+       struct bnxt_qplib_qp *lib_qp;
        u32 tbl_idx;
        struct bnxt_re_sqp_entries *sqp_entry = NULL;
        unsigned long flags;
@@ -2661,7 +2911,21 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
        }
        cqe = &cq->cql[0];
        while (budget) {
-               ncqe = bnxt_qplib_poll_cq(&cq->qplib_cq, cqe, budget);
+               lib_qp = NULL;
+               ncqe = bnxt_qplib_poll_cq(&cq->qplib_cq, cqe, budget, &lib_qp);
+               if (lib_qp) {
+                       sq = &lib_qp->sq;
+                       if (sq->send_phantom) {
+                               qp = container_of(lib_qp,
+                                                 struct bnxt_re_qp, qplib_qp);
+                               if (send_phantom_wqe(qp) == -ENOMEM)
+                                       dev_err(rdev_to_dev(cq->rdev),
+                                               "Phantom failed! Scheduled to send again\n");
+                               else
+                                       sq->send_phantom = false;
+                       }
+               }
+
                if (!ncqe)
                        break;
 
@@ -2822,6 +3086,12 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr)
        struct bnxt_re_dev *rdev = mr->rdev;
        int rc;
 
+       rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr);
+       if (rc) {
+               dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc);
+               return rc;
+       }
+
        if (mr->npages && mr->pages) {
                rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res,
                                                        &mr->qplib_frpl);
@@ -2829,8 +3099,6 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr)
                mr->npages = 0;
                mr->pages = NULL;
        }
-       rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr);
-
        if (!IS_ERR_OR_NULL(mr->ib_umem))
                ib_umem_release(mr->ib_umem);
 
@@ -2914,97 +3182,52 @@ fail:
        return ERR_PTR(rc);
 }
 
-/* Fast Memory Regions */
-struct ib_fmr *bnxt_re_alloc_fmr(struct ib_pd *ib_pd, int mr_access_flags,
-                                struct ib_fmr_attr *fmr_attr)
+struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,
+                              struct ib_udata *udata)
 {
        struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
        struct bnxt_re_dev *rdev = pd->rdev;
-       struct bnxt_re_fmr *fmr;
+       struct bnxt_re_mw *mw;
        int rc;
 
-       if (fmr_attr->max_pages > MAX_PBL_LVL_2_PGS ||
-           fmr_attr->max_maps > rdev->dev_attr.max_map_per_fmr) {
-               dev_err(rdev_to_dev(rdev), "Allocate FMR exceeded Max limit");
+       mw = kzalloc(sizeof(*mw), GFP_KERNEL);
+       if (!mw)
                return ERR_PTR(-ENOMEM);
-       }
-       fmr = kzalloc(sizeof(*fmr), GFP_KERNEL);
-       if (!fmr)
-               return ERR_PTR(-ENOMEM);
-
-       fmr->rdev = rdev;
-       fmr->qplib_fmr.pd = &pd->qplib_pd;
-       fmr->qplib_fmr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR;
+       mw->rdev = rdev;
+       mw->qplib_mw.pd = &pd->qplib_pd;
 
-       rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &fmr->qplib_fmr);
-       if (rc)
+       mw->qplib_mw.type = (type == IB_MW_TYPE_1 ?
+                              CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1 :
+                              CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B);
+       rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mw->qplib_mw);
+       if (rc) {
+               dev_err(rdev_to_dev(rdev), "Allocate MW failed!");
                goto fail;
+       }
+       mw->ib_mw.rkey = mw->qplib_mw.rkey;
 
-       fmr->qplib_fmr.flags = __from_ib_access_flags(mr_access_flags);
-       fmr->ib_fmr.lkey = fmr->qplib_fmr.lkey;
-       fmr->ib_fmr.rkey = fmr->ib_fmr.lkey;
+       atomic_inc(&rdev->mw_count);
+       return &mw->ib_mw;
 
-       atomic_inc(&rdev->mr_count);
-       return &fmr->ib_fmr;
 fail:
-       kfree(fmr);
+       kfree(mw);
        return ERR_PTR(rc);
 }
 
-int bnxt_re_map_phys_fmr(struct ib_fmr *ib_fmr, u64 *page_list, int list_len,
-                        u64 iova)
+int bnxt_re_dealloc_mw(struct ib_mw *ib_mw)
 {
-       struct bnxt_re_fmr *fmr = container_of(ib_fmr, struct bnxt_re_fmr,
-                                            ib_fmr);
-       struct bnxt_re_dev *rdev = fmr->rdev;
+       struct bnxt_re_mw *mw = container_of(ib_mw, struct bnxt_re_mw, ib_mw);
+       struct bnxt_re_dev *rdev = mw->rdev;
        int rc;
 
-       fmr->qplib_fmr.va = iova;
-       fmr->qplib_fmr.total_size = list_len * PAGE_SIZE;
-
-       rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &fmr->qplib_fmr, page_list,
-                              list_len, true);
-       if (rc)
-               dev_err(rdev_to_dev(rdev), "Failed to map FMR for lkey = 0x%x!",
-                       fmr->ib_fmr.lkey);
-       return rc;
-}
-
-int bnxt_re_unmap_fmr(struct list_head *fmr_list)
-{
-       struct bnxt_re_dev *rdev;
-       struct bnxt_re_fmr *fmr;
-       struct ib_fmr *ib_fmr;
-       int rc = 0;
-
-       /* Validate each FMRs inside the fmr_list */
-       list_for_each_entry(ib_fmr, fmr_list, list) {
-               fmr = container_of(ib_fmr, struct bnxt_re_fmr, ib_fmr);
-               rdev = fmr->rdev;
-
-               if (rdev) {
-                       rc = bnxt_qplib_dereg_mrw(&rdev->qplib_res,
-                                                 &fmr->qplib_fmr, true);
-                       if (rc)
-                               break;
-               }
+       rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mw->qplib_mw);
+       if (rc) {
+               dev_err(rdev_to_dev(rdev), "Free MW failed: %#x\n", rc);
+               return rc;
        }
-       return rc;
-}
-
-int bnxt_re_dealloc_fmr(struct ib_fmr *ib_fmr)
-{
-       struct bnxt_re_fmr *fmr = container_of(ib_fmr, struct bnxt_re_fmr,
-                                              ib_fmr);
-       struct bnxt_re_dev *rdev = fmr->rdev;
-       int rc;
 
-       rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &fmr->qplib_fmr);
-       if (rc)
-               dev_err(rdev_to_dev(rdev), "Failed to free FMR");
-
-       kfree(fmr);
-       atomic_dec(&rdev->mr_count);
+       kfree(mw);
+       atomic_dec(&rdev->mw_count);
        return rc;
 }
 
index 5c3d71765454f6e8476b86fd329d63b45d7735f6..6c160f6a5398702d4b73a3c319db3660f472c190 100644 (file)
@@ -44,11 +44,23 @@ struct bnxt_re_gid_ctx {
        u32                     refcnt;
 };
 
+#define BNXT_RE_FENCE_BYTES    64
+struct bnxt_re_fence_data {
+       u32 size;
+       u8 va[BNXT_RE_FENCE_BYTES];
+       dma_addr_t dma_addr;
+       struct bnxt_re_mr *mr;
+       struct ib_mw *mw;
+       struct bnxt_qplib_swqe bind_wqe;
+       u32 bind_rkey;
+};
+
 struct bnxt_re_pd {
        struct bnxt_re_dev      *rdev;
        struct ib_pd            ib_pd;
        struct bnxt_qplib_pd    qplib_pd;
        struct bnxt_qplib_dpi   dpi;
+       struct bnxt_re_fence_data fence;
 };
 
 struct bnxt_re_ah {
@@ -62,6 +74,7 @@ struct bnxt_re_qp {
        struct bnxt_re_dev      *rdev;
        struct ib_qp            ib_qp;
        spinlock_t              sq_lock;        /* protect sq */
+       spinlock_t              rq_lock;        /* protect rq */
        struct bnxt_qplib_qp    qplib_qp;
        struct ib_umem          *sumem;
        struct ib_umem          *rumem;
@@ -181,12 +194,9 @@ int bnxt_re_map_mr_sg(struct ib_mr *ib_mr, struct scatterlist *sg, int sg_nents,
 struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type mr_type,
                               u32 max_num_sg);
 int bnxt_re_dereg_mr(struct ib_mr *mr);
-struct ib_fmr *bnxt_re_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
-                                struct ib_fmr_attr *fmr_attr);
-int bnxt_re_map_phys_fmr(struct ib_fmr *fmr, u64 *page_list, int list_len,
-                        u64 iova);
-int bnxt_re_unmap_fmr(struct list_head *fmr_list);
-int bnxt_re_dealloc_fmr(struct ib_fmr *fmr);
+struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,
+                              struct ib_udata *udata);
+int bnxt_re_dealloc_mw(struct ib_mw *mw);
 struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                  u64 virt_addr, int mr_access_flags,
                                  struct ib_udata *udata);
index 5d355401179b8ae5107e411421c673db86164696..1fce5e73216be1bc74c23d2773690dc824d0e251 100644 (file)
@@ -507,10 +507,6 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
        ibdev->dereg_mr                 = bnxt_re_dereg_mr;
        ibdev->alloc_mr                 = bnxt_re_alloc_mr;
        ibdev->map_mr_sg                = bnxt_re_map_mr_sg;
-       ibdev->alloc_fmr                = bnxt_re_alloc_fmr;
-       ibdev->map_phys_fmr             = bnxt_re_map_phys_fmr;
-       ibdev->unmap_fmr                = bnxt_re_unmap_fmr;
-       ibdev->dealloc_fmr              = bnxt_re_dealloc_fmr;
 
        ibdev->reg_user_mr              = bnxt_re_reg_user_mr;
        ibdev->alloc_ucontext           = bnxt_re_alloc_ucontext;
index 43d08b5e908525eae96b567178fdc8ad15dec9c5..f05500bcdcf1e35d21a88aba70b013d0d0d8a2cf 100644 (file)
@@ -284,7 +284,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_create_qp1 req;
-       struct creq_create_qp1_resp *resp;
+       struct creq_create_qp1_resp resp;
        struct bnxt_qplib_pbl *pbl;
        struct bnxt_qplib_q *sq = &qp->sq;
        struct bnxt_qplib_q *rq = &qp->rq;
@@ -394,31 +394,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
        req.pd_id = cpu_to_le32(qp->pd->id);
 
-       resp = (struct creq_create_qp1_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&res->pdev->dev, "QPLIB: FP: CREATE_QP1 send failed");
-               rc = -EINVAL;
-               goto fail;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP1 timed out");
-               rc = -ETIMEDOUT;
-               goto fail;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP1 failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               rc = -EINVAL;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
                goto fail;
-       }
-       qp->id = le32_to_cpu(resp->xid);
+
+       qp->id = le32_to_cpu(resp.xid);
        qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
        sq->flush_in_progress = false;
        rq->flush_in_progress = false;
@@ -442,7 +423,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct sq_send *hw_sq_send_hdr, **hw_sq_send_ptr;
        struct cmdq_create_qp req;
-       struct creq_create_qp_resp *resp;
+       struct creq_create_qp_resp resp;
        struct bnxt_qplib_pbl *pbl;
        struct sq_psn_search **psn_search_ptr;
        unsigned long int psn_search, poff = 0;
@@ -627,31 +608,12 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        }
        req.pd_id = cpu_to_le32(qp->pd->id);
 
-       resp = (struct creq_create_qp_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP send failed");
-               rc = -EINVAL;
-               goto fail;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP timed out");
-               rc = -ETIMEDOUT;
-               goto fail;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               rc = -EINVAL;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
                goto fail;
-       }
-       qp->id = le32_to_cpu(resp->xid);
+
+       qp->id = le32_to_cpu(resp.xid);
        qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
        sq->flush_in_progress = false;
        rq->flush_in_progress = false;
@@ -769,10 +731,11 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_modify_qp req;
-       struct creq_modify_qp_resp *resp;
+       struct creq_modify_qp_resp resp;
        u16 cmd_flags = 0, pkey;
        u32 temp32[4];
        u32 bmask;
+       int rc;
 
        RCFW_CMD_PREP(req, MODIFY_QP, cmd_flags);
 
@@ -862,27 +825,10 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
        req.vlan_pcp_vlan_dei_vlan_id = cpu_to_le16(qp->vlan_id);
 
-       resp = (struct creq_modify_qp_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: MODIFY_QP send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: MODIFY_QP timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: MODIFY_QP failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
+               return rc;
        qp->cur_qp_state = qp->state;
        return 0;
 }
@@ -891,37 +837,26 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_query_qp req;
-       struct creq_query_qp_resp *resp;
+       struct creq_query_qp_resp resp;
+       struct bnxt_qplib_rcfw_sbuf *sbuf;
        struct creq_query_qp_resp_sb *sb;
        u16 cmd_flags = 0;
        u32 temp32[4];
-       int i;
+       int i, rc = 0;
 
        RCFW_CMD_PREP(req, QUERY_QP, cmd_flags);
 
+       sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
+       if (!sbuf)
+               return -ENOMEM;
+       sb = sbuf->sb;
+
        req.qp_cid = cpu_to_le32(qp->id);
        req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
-       resp = (struct creq_query_qp_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    (void **)&sb, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: QUERY_QP send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: QUERY_QP timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: QUERY_QP failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         (void *)sbuf, 0);
+       if (rc)
+               goto bail;
        /* Extract the context from the side buffer */
        qp->state = sb->en_sqd_async_notify_state &
                        CREQ_QUERY_QP_RESP_SB_STATE_MASK;
@@ -976,7 +911,9 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        qp->dest_qpn = le32_to_cpu(sb->dest_qp_id);
        memcpy(qp->smac, sb->src_mac, 6);
        qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id);
-       return 0;
+bail:
+       bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
+       return rc;
 }
 
 static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp)
@@ -1021,34 +958,18 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_destroy_qp req;
-       struct creq_destroy_qp_resp *resp;
+       struct creq_destroy_qp_resp resp;
        unsigned long flags;
        u16 cmd_flags = 0;
+       int rc;
 
        RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);
 
        req.qp_cid = cpu_to_le32(qp->id);
-       resp = (struct creq_destroy_qp_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_QP send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_QP timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_QP failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
+               return rc;
 
        /* Must walk the associated CQs to nullified the QP ptr */
        spin_lock_irqsave(&qp->scq->hwq.lock, flags);
@@ -1162,8 +1083,12 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
                rc = -EINVAL;
                goto done;
        }
-       if (HWQ_CMP((sq->hwq.prod + 1), &sq->hwq) ==
-           HWQ_CMP(sq->hwq.cons, &sq->hwq)) {
+
+       if (bnxt_qplib_queue_full(sq)) {
+               dev_err(&sq->hwq.pdev->dev,
+                       "QPLIB: prod = %#x cons = %#x qdepth = %#x delta = %#x",
+                       sq->hwq.prod, sq->hwq.cons, sq->hwq.max_elements,
+                       sq->q_full_delta);
                rc = -ENOMEM;
                goto done;
        }
@@ -1373,6 +1298,9 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
        }
 
        sq->hwq.prod++;
+
+       qp->wqe_cnt++;
+
 done:
        return rc;
 }
@@ -1411,8 +1339,7 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
                rc = -EINVAL;
                goto done;
        }
-       if (HWQ_CMP((rq->hwq.prod + 1), &rq->hwq) ==
-           HWQ_CMP(rq->hwq.cons, &rq->hwq)) {
+       if (bnxt_qplib_queue_full(rq)) {
                dev_err(&rq->hwq.pdev->dev,
                        "QPLIB: FP: QP (0x%x) RQ is full!", qp->id);
                rc = -EINVAL;
@@ -1483,7 +1410,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_create_cq req;
-       struct creq_create_cq_resp *resp;
+       struct creq_create_cq_resp resp;
        struct bnxt_qplib_pbl *pbl;
        u16 cmd_flags = 0;
        int rc;
@@ -1525,30 +1452,12 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
                        (cq->cnq_hw_ring_id & CMDQ_CREATE_CQ_CNQ_ID_MASK) <<
                         CMDQ_CREATE_CQ_CNQ_ID_SFT);
 
-       resp = (struct creq_create_cq_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_CQ send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_CQ timed out");
-               rc = -ETIMEDOUT;
-               goto fail;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_CQ failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               rc = -EINVAL;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
                goto fail;
-       }
-       cq->id = le32_to_cpu(resp->xid);
+
+       cq->id = le32_to_cpu(resp.xid);
        cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem;
        cq->period = BNXT_QPLIB_QUEUE_START_PERIOD;
        init_waitqueue_head(&cq->waitq);
@@ -1566,33 +1475,17 @@ int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_destroy_cq req;
-       struct creq_destroy_cq_resp *resp;
+       struct creq_destroy_cq_resp resp;
        u16 cmd_flags = 0;
+       int rc;
 
        RCFW_CMD_PREP(req, DESTROY_CQ, cmd_flags);
 
        req.cq_cid = cpu_to_le32(cq->id);
-       resp = (struct creq_destroy_cq_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_CQ send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_CQ timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_CQ failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
+               return rc;
        bnxt_qplib_free_hwq(res->pdev, &cq->hwq);
        return 0;
 }
@@ -1664,14 +1557,113 @@ static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp,
        return rc;
 }
 
+/* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)
+ *       CQE is track from sw_cq_cons to max_element but valid only if VALID=1
+ */
+static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
+                    u32 cq_cons, u32 sw_sq_cons, u32 cqe_sq_cons)
+{
+       struct bnxt_qplib_q *sq = &qp->sq;
+       struct bnxt_qplib_swq *swq;
+       u32 peek_sw_cq_cons, peek_raw_cq_cons, peek_sq_cons_idx;
+       struct cq_base *peek_hwcqe, **peek_hw_cqe_ptr;
+       struct cq_req *peek_req_hwcqe;
+       struct bnxt_qplib_qp *peek_qp;
+       struct bnxt_qplib_q *peek_sq;
+       int i, rc = 0;
+
+       /* Normal mode */
+       /* Check for the psn_search marking before completing */
+       swq = &sq->swq[sw_sq_cons];
+       if (swq->psn_search &&
+           le32_to_cpu(swq->psn_search->flags_next_psn) & 0x80000000) {
+               /* Unmark */
+               swq->psn_search->flags_next_psn = cpu_to_le32
+                       (le32_to_cpu(swq->psn_search->flags_next_psn)
+                                    & ~0x80000000);
+               dev_dbg(&cq->hwq.pdev->dev,
+                       "FP: Process Req cq_cons=0x%x qp=0x%x sq cons sw=0x%x cqe=0x%x marked!\n",
+                       cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);
+               sq->condition = true;
+               sq->send_phantom = true;
+
+               /* TODO: Only ARM if the previous SQE is ARMALL */
+               bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ_ARMALL);
+
+               rc = -EAGAIN;
+               goto out;
+       }
+       if (sq->condition) {
+               /* Peek at the completions */
+               peek_raw_cq_cons = cq->hwq.cons;
+               peek_sw_cq_cons = cq_cons;
+               i = cq->hwq.max_elements;
+               while (i--) {
+                       peek_sw_cq_cons = HWQ_CMP((peek_sw_cq_cons), &cq->hwq);
+                       peek_hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
+                       peek_hwcqe = &peek_hw_cqe_ptr[CQE_PG(peek_sw_cq_cons)]
+                                                    [CQE_IDX(peek_sw_cq_cons)];
+                       /* If the next hwcqe is VALID */
+                       if (CQE_CMP_VALID(peek_hwcqe, peek_raw_cq_cons,
+                                         cq->hwq.max_elements)) {
+                               /* If the next hwcqe is a REQ */
+                               if ((peek_hwcqe->cqe_type_toggle &
+                                   CQ_BASE_CQE_TYPE_MASK) ==
+                                   CQ_BASE_CQE_TYPE_REQ) {
+                                       peek_req_hwcqe = (struct cq_req *)
+                                                        peek_hwcqe;
+                                       peek_qp = (struct bnxt_qplib_qp *)
+                                               ((unsigned long)
+                                                le64_to_cpu
+                                                (peek_req_hwcqe->qp_handle));
+                                       peek_sq = &peek_qp->sq;
+                                       peek_sq_cons_idx = HWQ_CMP(le16_to_cpu(
+                                               peek_req_hwcqe->sq_cons_idx) - 1
+                                               , &sq->hwq);
+                                       /* If the hwcqe's sq's wr_id matches */
+                                       if (peek_sq == sq &&
+                                           sq->swq[peek_sq_cons_idx].wr_id ==
+                                           BNXT_QPLIB_FENCE_WRID) {
+                                               /*
+                                                *  Unbreak only if the phantom
+                                                *  comes back
+                                                */
+                                               dev_dbg(&cq->hwq.pdev->dev,
+                                                       "FP:Got Phantom CQE");
+                                               sq->condition = false;
+                                               sq->single = true;
+                                               rc = 0;
+                                               goto out;
+                                       }
+                               }
+                               /* Valid but not the phantom, so keep looping */
+                       } else {
+                               /* Not valid yet, just exit and wait */
+                               rc = -EINVAL;
+                               goto out;
+                       }
+                       peek_sw_cq_cons++;
+                       peek_raw_cq_cons++;
+               }
+               dev_err(&cq->hwq.pdev->dev,
+                       "Should not have come here! cq_cons=0x%x qp=0x%x sq cons sw=0x%x hw=0x%x",
+                       cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);
+               rc = -EINVAL;
+       }
+out:
+       return rc;
+}
+
 static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
                                     struct cq_req *hwcqe,
-                                    struct bnxt_qplib_cqe **pcqe, int *budget)
+                                    struct bnxt_qplib_cqe **pcqe, int *budget,
+                                    u32 cq_cons, struct bnxt_qplib_qp **lib_qp)
 {
        struct bnxt_qplib_qp *qp;
        struct bnxt_qplib_q *sq;
        struct bnxt_qplib_cqe *cqe;
-       u32 sw_cons, cqe_cons;
+       u32 sw_sq_cons, cqe_sq_cons;
+       struct bnxt_qplib_swq *swq;
        int rc = 0;
 
        qp = (struct bnxt_qplib_qp *)((unsigned long)
@@ -1683,13 +1675,13 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
        }
        sq = &qp->sq;
 
-       cqe_cons = HWQ_CMP(le16_to_cpu(hwcqe->sq_cons_idx), &sq->hwq);
-       if (cqe_cons > sq->hwq.max_elements) {
+       cqe_sq_cons = HWQ_CMP(le16_to_cpu(hwcqe->sq_cons_idx), &sq->hwq);
+       if (cqe_sq_cons > sq->hwq.max_elements) {
                dev_err(&cq->hwq.pdev->dev,
                        "QPLIB: FP: CQ Process req reported ");
                dev_err(&cq->hwq.pdev->dev,
                        "QPLIB: sq_cons_idx 0x%x which exceeded max 0x%x",
-                       cqe_cons, sq->hwq.max_elements);
+                       cqe_sq_cons, sq->hwq.max_elements);
                return -EINVAL;
        }
        /* If we were in the middle of flushing the SQ, continue */
@@ -1698,53 +1690,74 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
 
        /* Require to walk the sq's swq to fabricate CQEs for all previously
         * signaled SWQEs due to CQE aggregation from the current sq cons
-        * to the cqe_cons
+        * to the cqe_sq_cons
         */
        cqe = *pcqe;
        while (*budget) {
-               sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
-               if (sw_cons == cqe_cons)
+               sw_sq_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
+               if (sw_sq_cons == cqe_sq_cons)
+                       /* Done */
                        break;
+
+               swq = &sq->swq[sw_sq_cons];
                memset(cqe, 0, sizeof(*cqe));
                cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
                cqe->qp_handle = (u64)(unsigned long)qp;
                cqe->src_qp = qp->id;
-               cqe->wr_id = sq->swq[sw_cons].wr_id;
-               cqe->type = sq->swq[sw_cons].type;
+               cqe->wr_id = swq->wr_id;
+               if (cqe->wr_id == BNXT_QPLIB_FENCE_WRID)
+                       goto skip;
+               cqe->type = swq->type;
 
                /* For the last CQE, check for status.  For errors, regardless
                 * of the request being signaled or not, it must complete with
                 * the hwcqe error status
                 */
-               if (HWQ_CMP((sw_cons + 1), &sq->hwq) == cqe_cons &&
+               if (HWQ_CMP((sw_sq_cons + 1), &sq->hwq) == cqe_sq_cons &&
                    hwcqe->status != CQ_REQ_STATUS_OK) {
                        cqe->status = hwcqe->status;
                        dev_err(&cq->hwq.pdev->dev,
                                "QPLIB: FP: CQ Processed Req ");
                        dev_err(&cq->hwq.pdev->dev,
                                "QPLIB: wr_id[%d] = 0x%llx with status 0x%x",
-                               sw_cons, cqe->wr_id, cqe->status);
+                               sw_sq_cons, cqe->wr_id, cqe->status);
                        cqe++;
                        (*budget)--;
                        sq->flush_in_progress = true;
                        /* Must block new posting of SQ and RQ */
                        qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
+                       sq->condition = false;
+                       sq->single = false;
                } else {
-                       if (sq->swq[sw_cons].flags &
-                           SQ_SEND_FLAGS_SIGNAL_COMP) {
+                       if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
+                               /* Before we complete, do WA 9060 */
+                               if (do_wa9060(qp, cq, cq_cons, sw_sq_cons,
+                                             cqe_sq_cons)) {
+                                       *lib_qp = qp;
+                                       goto out;
+                               }
                                cqe->status = CQ_REQ_STATUS_OK;
                                cqe++;
                                (*budget)--;
                        }
                }
+skip:
                sq->hwq.cons++;
+               if (sq->single)
+                       break;
        }
+out:
        *pcqe = cqe;
-       if (!*budget && HWQ_CMP(sq->hwq.cons, &sq->hwq) != cqe_cons) {
+       if (HWQ_CMP(sq->hwq.cons, &sq->hwq) != cqe_sq_cons) {
                /* Out of budget */
                rc = -EAGAIN;
                goto done;
        }
+       /*
+        * Back to normal completion mode only after it has completed all of
+        * the WC for this CQE
+        */
+       sq->single = false;
        if (!sq->flush_in_progress)
                goto done;
 flush:
@@ -2074,7 +2087,7 @@ static int bnxt_qplib_cq_process_cutoff(struct bnxt_qplib_cq *cq,
 }
 
 int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
-                      int num_cqes)
+                      int num_cqes, struct bnxt_qplib_qp **lib_qp)
 {
        struct cq_base *hw_cqe, **hw_cqe_ptr;
        unsigned long flags;
@@ -2099,7 +2112,8 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
                case CQ_BASE_CQE_TYPE_REQ:
                        rc = bnxt_qplib_cq_process_req(cq,
                                                       (struct cq_req *)hw_cqe,
-                                                      &cqe, &budget);
+                                                      &cqe, &budget,
+                                                      sw_cons, lib_qp);
                        break;
                case CQ_BASE_CQE_TYPE_RES_RC:
                        rc = bnxt_qplib_cq_process_res_rc(cq,
index f0150f8da1e3929b309d14006b68469a965d8945..36b7b7db0e3f9782104ee8b049e674edb830226b 100644 (file)
@@ -88,6 +88,7 @@ struct bnxt_qplib_swq {
 
 struct bnxt_qplib_swqe {
        /* General */
+#define        BNXT_QPLIB_FENCE_WRID   0x46454E43      /* "FENC" */
        u64                             wr_id;
        u8                              reqs_type;
        u8                              type;
@@ -216,9 +217,16 @@ struct bnxt_qplib_q {
        struct scatterlist              *sglist;
        u32                             nmap;
        u32                             max_wqe;
+       u16                             q_full_delta;
        u16                             max_sge;
        u32                             psn;
        bool                            flush_in_progress;
+       bool                            condition;
+       bool                            single;
+       bool                            send_phantom;
+       u32                             phantom_wqe_cnt;
+       u32                             phantom_cqe_cnt;
+       u32                             next_cq_cons;
 };
 
 struct bnxt_qplib_qp {
@@ -242,6 +250,7 @@ struct bnxt_qplib_qp {
        u8                              timeout;
        u8                              retry_cnt;
        u8                              rnr_retry;
+       u64                             wqe_cnt;
        u32                             min_rnr_timer;
        u32                             max_rd_atomic;
        u32                             max_dest_rd_atomic;
@@ -301,6 +310,13 @@ struct bnxt_qplib_qp {
        (!!((hdr)->cqe_type_toggle & CQ_BASE_TOGGLE) ==         \
           !((raw_cons) & (cp_bit)))
 
+static inline bool bnxt_qplib_queue_full(struct bnxt_qplib_q *qplib_q)
+{
+       return HWQ_CMP((qplib_q->hwq.prod + qplib_q->q_full_delta),
+                      &qplib_q->hwq) == HWQ_CMP(qplib_q->hwq.cons,
+                                                &qplib_q->hwq);
+}
+
 struct bnxt_qplib_cqe {
        u8                              status;
        u8                              type;
@@ -432,7 +448,7 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
 int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq);
 int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq);
 int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
-                      int num);
+                      int num, struct bnxt_qplib_qp **qp);
 void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type);
 void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq);
 int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq);
index 23fb7260662b134b8d030f6c0ef7c6648976c434..16e42754dbeccfef863509b0bd8226683582df2a 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/prefetch.h>
+#include <linux/delay.h>
+
 #include "roce_hsi.h"
 #include "qplib_res.h"
 #include "qplib_rcfw.h"
 static void bnxt_qplib_service_creq(unsigned long data);
 
 /* Hardware communication channel */
-int bnxt_qplib_rcfw_wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
 {
        u16 cbit;
        int rc;
 
-       cookie &= RCFW_MAX_COOKIE_VALUE;
        cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
-       if (!test_bit(cbit, rcfw->cmdq_bitmap))
-               dev_warn(&rcfw->pdev->dev,
-                        "QPLIB: CMD bit %d for cookie 0x%x is not set?",
-                        cbit, cookie);
-
        rc = wait_event_timeout(rcfw->waitq,
                                !test_bit(cbit, rcfw->cmdq_bitmap),
                                msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS));
-       if (!rc) {
-               dev_warn(&rcfw->pdev->dev,
-                        "QPLIB: Bono Error: timeout %d msec, msg {0x%x}\n",
-                        RCFW_CMD_WAIT_TIME_MS, cookie);
-       }
-
-       return rc;
+       return rc ? 0 : -ETIMEDOUT;
 };
 
-int bnxt_qplib_rcfw_block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
 {
-       u32 count = -1;
+       u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT;
        u16 cbit;
 
-       cookie &= RCFW_MAX_COOKIE_VALUE;
        cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
        if (!test_bit(cbit, rcfw->cmdq_bitmap))
                goto done;
        do {
+               mdelay(1); /* 1m sec */
                bnxt_qplib_service_creq((unsigned long)rcfw);
        } while (test_bit(cbit, rcfw->cmdq_bitmap) && --count);
 done:
-       return count;
+       return count ? 0 : -ETIMEDOUT;
 };
 
-void *bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
-                                  struct cmdq_base *req, void **crsbe,
-                                  u8 is_block)
+static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
+                         struct creq_base *resp, void *sb, u8 is_block)
 {
-       struct bnxt_qplib_crsq *crsq = &rcfw->crsq;
        struct bnxt_qplib_cmdqe *cmdqe, **cmdq_ptr;
        struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
-       struct bnxt_qplib_hwq *crsb = &rcfw->crsb;
-       struct bnxt_qplib_crsqe *crsqe = NULL;
-       struct bnxt_qplib_crsbe **crsb_ptr;
+       struct bnxt_qplib_crsq *crsqe;
        u32 sw_prod, cmdq_prod;
-       u8 retry_cnt = 0xFF;
-       dma_addr_t dma_addr;
        unsigned long flags;
        u32 size, opcode;
        u16 cookie, cbit;
        int pg, idx;
        u8 *preq;
 
-retry:
        opcode = req->opcode;
        if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) &&
            (opcode != CMDQ_BASE_OPCODE_QUERY_FUNC &&
@@ -112,63 +95,50 @@ retry:
                dev_err(&rcfw->pdev->dev,
                        "QPLIB: RCFW not initialized, reject opcode 0x%x",
                        opcode);
-               return NULL;
+               return -EINVAL;
        }
 
        if (test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) &&
            opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) {
                dev_err(&rcfw->pdev->dev, "QPLIB: RCFW already initialized!");
-               return NULL;
+               return -EINVAL;
        }
 
        /* Cmdq are in 16-byte units, each request can consume 1 or more
         * cmdqe
         */
        spin_lock_irqsave(&cmdq->lock, flags);
-       if (req->cmd_size > cmdq->max_elements -
-           ((HWQ_CMP(cmdq->prod, cmdq) - HWQ_CMP(cmdq->cons, cmdq)) &
-            (cmdq->max_elements - 1))) {
+       if (req->cmd_size >= HWQ_FREE_SLOTS(cmdq)) {
                dev_err(&rcfw->pdev->dev, "QPLIB: RCFW: CMDQ is full!");
                spin_unlock_irqrestore(&cmdq->lock, flags);
-
-               if (!retry_cnt--)
-                       return NULL;
-               goto retry;
+               return -EAGAIN;
        }
 
-       retry_cnt = 0xFF;
 
-       cookie = atomic_inc_return(&rcfw->seq_num) & RCFW_MAX_COOKIE_VALUE;
+       cookie = rcfw->seq_num & RCFW_MAX_COOKIE_VALUE;
        cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
        if (is_block)
                cookie |= RCFW_CMD_IS_BLOCKING;
+
+       set_bit(cbit, rcfw->cmdq_bitmap);
        req->cookie = cpu_to_le16(cookie);
-       if (test_and_set_bit(cbit, rcfw->cmdq_bitmap)) {
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: RCFW MAX outstanding cmd reached!");
-               atomic_dec(&rcfw->seq_num);
+       crsqe = &rcfw->crsqe_tbl[cbit];
+       if (crsqe->resp) {
                spin_unlock_irqrestore(&cmdq->lock, flags);
-
-               if (!retry_cnt--)
-                       return NULL;
-               goto retry;
+               return -EBUSY;
        }
-       /* Reserve a resp buffer slot if requested */
-       if (req->resp_size && crsbe) {
-               spin_lock(&crsb->lock);
-               sw_prod = HWQ_CMP(crsb->prod, crsb);
-               crsb_ptr = (struct bnxt_qplib_crsbe **)crsb->pbl_ptr;
-               *crsbe = (void *)&crsb_ptr[get_crsb_pg(sw_prod)]
-                                         [get_crsb_idx(sw_prod)];
-               bnxt_qplib_crsb_dma_next(crsb->pbl_dma_ptr, sw_prod, &dma_addr);
-               req->resp_addr = cpu_to_le64(dma_addr);
-               crsb->prod++;
-               spin_unlock(&crsb->lock);
-
-               req->resp_size = (sizeof(struct bnxt_qplib_crsbe) +
-                                 BNXT_QPLIB_CMDQE_UNITS - 1) /
-                                BNXT_QPLIB_CMDQE_UNITS;
+       memset(resp, 0, sizeof(*resp));
+       crsqe->resp = (struct creq_qp_event *)resp;
+       crsqe->resp->cookie = req->cookie;
+       crsqe->req_size = req->cmd_size;
+       if (req->resp_size && sb) {
+               struct bnxt_qplib_rcfw_sbuf *sbuf = sb;
+
+               req->resp_addr = cpu_to_le64(sbuf->dma_addr);
+               req->resp_size = (sbuf->size + BNXT_QPLIB_CMDQE_UNITS - 1) /
+                                 BNXT_QPLIB_CMDQE_UNITS;
        }
+
        cmdq_ptr = (struct bnxt_qplib_cmdqe **)cmdq->pbl_ptr;
        preq = (u8 *)req;
        size = req->cmd_size * BNXT_QPLIB_CMDQE_UNITS;
@@ -190,23 +160,24 @@ retry:
                preq += min_t(u32, size, sizeof(*cmdqe));
                size -= min_t(u32, size, sizeof(*cmdqe));
                cmdq->prod++;
+               rcfw->seq_num++;
        } while (size > 0);
 
+       rcfw->seq_num++;
+
        cmdq_prod = cmdq->prod;
        if (rcfw->flags & FIRMWARE_FIRST_FLAG) {
-               /* The very first doorbell write is required to set this flag
-                * which prompts the FW to reset its internal pointers
+               /* The very first doorbell write
+                * is required to set this flag
+                * which prompts the FW to reset
+                * its internal pointers
                 */
                cmdq_prod |= FIRMWARE_FIRST_FLAG;
                rcfw->flags &= ~FIRMWARE_FIRST_FLAG;
        }
-       sw_prod = HWQ_CMP(crsq->prod, crsq);
-       crsqe = &crsq->crsq[sw_prod];
-       memset(crsqe, 0, sizeof(*crsqe));
-       crsq->prod++;
-       crsqe->req_size = req->cmd_size;
 
        /* ring CMDQ DB */
+       wmb();
        writel(cmdq_prod, rcfw->cmdq_bar_reg_iomem +
               rcfw->cmdq_bar_reg_prod_off);
        writel(RCFW_CMDQ_TRIG_VAL, rcfw->cmdq_bar_reg_iomem +
@@ -214,9 +185,56 @@ retry:
 done:
        spin_unlock_irqrestore(&cmdq->lock, flags);
        /* Return the CREQ response pointer */
-       return crsqe ? &crsqe->qp_event : NULL;
+       return 0;
 }
 
+int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+                                struct cmdq_base *req,
+                                struct creq_base *resp,
+                                void *sb, u8 is_block)
+{
+       struct creq_qp_event *evnt = (struct creq_qp_event *)resp;
+       u16 cookie;
+       u8 opcode, retry_cnt = 0xFF;
+       int rc = 0;
+
+       do {
+               opcode = req->opcode;
+               rc = __send_message(rcfw, req, resp, sb, is_block);
+               cookie = le16_to_cpu(req->cookie) & RCFW_MAX_COOKIE_VALUE;
+               if (!rc)
+                       break;
+
+               if (!retry_cnt || (rc != -EAGAIN && rc != -EBUSY)) {
+                       /* send failed */
+                       dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x send failed",
+                               cookie, opcode);
+                       return rc;
+               }
+               is_block ? mdelay(1) : usleep_range(500, 1000);
+
+       } while (retry_cnt--);
+
+       if (is_block)
+               rc = __block_for_resp(rcfw, cookie);
+       else
+               rc = __wait_for_resp(rcfw, cookie);
+       if (rc) {
+               /* timed out */
+               dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x timedout (%d)msec",
+                       cookie, opcode, RCFW_CMD_WAIT_TIME_MS);
+               return rc;
+       }
+
+       if (evnt->status) {
+               /* failed with status */
+               dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x status %#x",
+                       cookie, opcode, evnt->status);
+               rc = -EFAULT;
+       }
+
+       return rc;
+}
 /* Completions */
 static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw,
                                         struct creq_func_event *func_event)
@@ -260,12 +278,12 @@ static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw,
 static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
                                       struct creq_qp_event *qp_event)
 {
-       struct bnxt_qplib_crsq *crsq = &rcfw->crsq;
        struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
-       struct bnxt_qplib_crsqe *crsqe;
-       u16 cbit, cookie, blocked = 0;
+       struct bnxt_qplib_crsq *crsqe;
        unsigned long flags;
-       u32 sw_cons;
+       u16 cbit, blocked = 0;
+       u16 cookie;
+       __le16  mcookie;
 
        switch (qp_event->event) {
        case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
@@ -275,24 +293,31 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
        default:
                /* Command Response */
                spin_lock_irqsave(&cmdq->lock, flags);
-               sw_cons = HWQ_CMP(crsq->cons, crsq);
-               crsqe = &crsq->crsq[sw_cons];
-               crsq->cons++;
-               memcpy(&crsqe->qp_event, qp_event, sizeof(crsqe->qp_event));
-
-               cookie = le16_to_cpu(crsqe->qp_event.cookie);
+               cookie = le16_to_cpu(qp_event->cookie);
+               mcookie = qp_event->cookie;
                blocked = cookie & RCFW_CMD_IS_BLOCKING;
                cookie &= RCFW_MAX_COOKIE_VALUE;
                cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
+               crsqe = &rcfw->crsqe_tbl[cbit];
+               if (crsqe->resp &&
+                   crsqe->resp->cookie  == mcookie) {
+                       memcpy(crsqe->resp, qp_event, sizeof(*qp_event));
+                       crsqe->resp = NULL;
+               } else {
+                       dev_err(&rcfw->pdev->dev,
+                               "QPLIB: CMD %s resp->cookie = %#x, evnt->cookie = %#x",
+                               crsqe->resp ? "mismatch" : "collision",
+                               crsqe->resp ? crsqe->resp->cookie : 0, mcookie);
+               }
                if (!test_and_clear_bit(cbit, rcfw->cmdq_bitmap))
                        dev_warn(&rcfw->pdev->dev,
                                 "QPLIB: CMD bit %d was not requested", cbit);
-
                cmdq->cons += crsqe->req_size;
-               spin_unlock_irqrestore(&cmdq->lock, flags);
+               crsqe->req_size = 0;
+
                if (!blocked)
                        wake_up(&rcfw->waitq);
-               break;
+               spin_unlock_irqrestore(&cmdq->lock, flags);
        }
        return 0;
 }
@@ -305,12 +330,12 @@ static void bnxt_qplib_service_creq(unsigned long data)
        struct creq_base *creqe, **creq_ptr;
        u32 sw_cons, raw_cons;
        unsigned long flags;
-       u32 type;
+       u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
 
-       /* Service the CREQ until empty */
+       /* Service the CREQ until budget is over */
        spin_lock_irqsave(&creq->lock, flags);
        raw_cons = creq->cons;
-       while (1) {
+       while (budget > 0) {
                sw_cons = HWQ_CMP(raw_cons, creq);
                creq_ptr = (struct creq_base **)creq->pbl_ptr;
                creqe = &creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)];
@@ -320,15 +345,9 @@ static void bnxt_qplib_service_creq(unsigned long data)
                type = creqe->type & CREQ_BASE_TYPE_MASK;
                switch (type) {
                case CREQ_BASE_TYPE_QP_EVENT:
-                       if (!bnxt_qplib_process_qp_event
-                           (rcfw, (struct creq_qp_event *)creqe))
-                               rcfw->creq_qp_event_processed++;
-                       else {
-                               dev_warn(&rcfw->pdev->dev, "QPLIB: crsqe with");
-                               dev_warn(&rcfw->pdev->dev,
-                                        "QPLIB: type = 0x%x not handled",
-                                        type);
-                       }
+                       bnxt_qplib_process_qp_event
+                               (rcfw, (struct creq_qp_event *)creqe);
+                       rcfw->creq_qp_event_processed++;
                        break;
                case CREQ_BASE_TYPE_FUNC_EVENT:
                        if (!bnxt_qplib_process_func_event
@@ -346,7 +365,9 @@ static void bnxt_qplib_service_creq(unsigned long data)
                        break;
                }
                raw_cons++;
+               budget--;
        }
+
        if (creq->cons != raw_cons) {
                creq->cons = raw_cons;
                CREQ_DB_REARM(rcfw->creq_bar_reg_iomem, raw_cons,
@@ -375,23 +396,16 @@ static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance)
 /* RCFW */
 int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw)
 {
-       struct creq_deinitialize_fw_resp *resp;
        struct cmdq_deinitialize_fw req;
+       struct creq_deinitialize_fw_resp resp;
        u16 cmd_flags = 0;
+       int rc;
 
        RCFW_CMD_PREP(req, DEINITIALIZE_FW, cmd_flags);
-       resp = (struct creq_deinitialize_fw_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp)
-               return -EINVAL;
-
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie)))
-               return -ETIMEDOUT;
-
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie))
-               return -EFAULT;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         NULL, 0);
+       if (rc)
+               return rc;
 
        clear_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags);
        return 0;
@@ -417,9 +431,10 @@ static int __get_pbl_pg_idx(struct bnxt_qplib_pbl *pbl)
 int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
                         struct bnxt_qplib_ctx *ctx, int is_virtfn)
 {
-       struct creq_initialize_fw_resp *resp;
        struct cmdq_initialize_fw req;
+       struct creq_initialize_fw_resp resp;
        u16 cmd_flags = 0, level;
+       int rc;
 
        RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags);
 
@@ -482,37 +497,19 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
 
 skip_ctx_setup:
        req.stat_ctx_id = cpu_to_le32(ctx->stats.fw_id);
-       resp = (struct creq_initialize_fw_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: RCFW: INITIALIZE_FW send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: RCFW: INITIALIZE_FW timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: RCFW: INITIALIZE_FW failed");
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         NULL, 0);
+       if (rc)
+               return rc;
        set_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags);
        return 0;
 }
 
 void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
 {
-       bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->crsb);
-       kfree(rcfw->crsq.crsq);
+       kfree(rcfw->crsqe_tbl);
        bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->cmdq);
        bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->creq);
-
        rcfw->pdev = NULL;
 }
 
@@ -539,21 +536,11 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
                goto fail;
        }
 
-       rcfw->crsq.max_elements = rcfw->cmdq.max_elements;
-       rcfw->crsq.crsq = kcalloc(rcfw->crsq.max_elements,
-                                 sizeof(*rcfw->crsq.crsq), GFP_KERNEL);
-       if (!rcfw->crsq.crsq)
+       rcfw->crsqe_tbl = kcalloc(rcfw->cmdq.max_elements,
+                                 sizeof(*rcfw->crsqe_tbl), GFP_KERNEL);
+       if (!rcfw->crsqe_tbl)
                goto fail;
 
-       rcfw->crsb.max_elements = BNXT_QPLIB_CRSBE_MAX_CNT;
-       if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->crsb, NULL, 0,
-                                     &rcfw->crsb.max_elements,
-                                     BNXT_QPLIB_CRSBE_UNITS, 0, PAGE_SIZE,
-                                     HWQ_TYPE_CTX)) {
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: HW channel CRSB allocation failed");
-               goto fail;
-       }
        return 0;
 
 fail:
@@ -606,7 +593,7 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
        int rc;
 
        /* General */
-       atomic_set(&rcfw->seq_num, 0);
+       rcfw->seq_num = 0;
        rcfw->flags = FIRMWARE_FIRST_FLAG;
        bmap_size = BITS_TO_LONGS(RCFW_MAX_OUTSTANDING_CMD *
                                  sizeof(unsigned long));
@@ -636,10 +623,6 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
 
        rcfw->cmdq_bar_reg_trig_off = RCFW_COMM_TRIG_OFFSET;
 
-       /* CRSQ */
-       rcfw->crsq.prod = 0;
-       rcfw->crsq.cons = 0;
-
        /* CREQ */
        rcfw->creq_bar_reg = RCFW_COMM_CONS_PCI_BAR_REGION;
        res_base = pci_resource_start(pdev, rcfw->creq_bar_reg);
@@ -692,3 +675,34 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
        __iowrite32_copy(rcfw->cmdq_bar_reg_iomem, &init, sizeof(init) / 4);
        return 0;
 }
+
+struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf(
+               struct bnxt_qplib_rcfw *rcfw,
+               u32 size)
+{
+       struct bnxt_qplib_rcfw_sbuf *sbuf;
+
+       sbuf = kzalloc(sizeof(*sbuf), GFP_ATOMIC);
+       if (!sbuf)
+               return NULL;
+
+       sbuf->size = size;
+       sbuf->sb = dma_zalloc_coherent(&rcfw->pdev->dev, sbuf->size,
+                                      &sbuf->dma_addr, GFP_ATOMIC);
+       if (!sbuf->sb)
+               goto bail;
+
+       return sbuf;
+bail:
+       kfree(sbuf);
+       return NULL;
+}
+
+void bnxt_qplib_rcfw_free_sbuf(struct bnxt_qplib_rcfw *rcfw,
+                              struct bnxt_qplib_rcfw_sbuf *sbuf)
+{
+       if (sbuf->sb)
+               dma_free_coherent(&rcfw->pdev->dev, sbuf->size,
+                                 sbuf->sb, sbuf->dma_addr);
+       kfree(sbuf);
+}
index d3567d75bf58fe4e5e496c78ec27643af7d80cdc..09ce121770cdafd1af01bd815788f6b25eac3bf0 100644 (file)
@@ -73,6 +73,7 @@
 #define RCFW_MAX_OUTSTANDING_CMD       BNXT_QPLIB_CMDQE_MAX_CNT
 #define RCFW_MAX_COOKIE_VALUE          0x7FFF
 #define RCFW_CMD_IS_BLOCKING           0x8000
+#define RCFW_BLOCKED_CMD_WAIT_COUNT    0x4E20
 
 /* Cmdq contains a fix number of a 16-Byte slots */
 struct bnxt_qplib_cmdqe {
@@ -94,32 +95,6 @@ struct bnxt_qplib_crsbe {
        u8                      data[1024];
 };
 
-/* CRSQ SB */
-#define BNXT_QPLIB_CRSBE_MAX_CNT       4
-#define BNXT_QPLIB_CRSBE_UNITS         sizeof(struct bnxt_qplib_crsbe)
-#define BNXT_QPLIB_CRSBE_CNT_PER_PG    (PAGE_SIZE / BNXT_QPLIB_CRSBE_UNITS)
-
-#define MAX_CRSB_IDX                   (BNXT_QPLIB_CRSBE_MAX_CNT - 1)
-#define MAX_CRSB_IDX_PER_PG            (BNXT_QPLIB_CRSBE_CNT_PER_PG - 1)
-
-static inline u32 get_crsb_pg(u32 val)
-{
-       return (val & ~MAX_CRSB_IDX_PER_PG) / BNXT_QPLIB_CRSBE_CNT_PER_PG;
-}
-
-static inline u32 get_crsb_idx(u32 val)
-{
-       return val & MAX_CRSB_IDX_PER_PG;
-}
-
-static inline void bnxt_qplib_crsb_dma_next(dma_addr_t *pg_map_arr,
-                                           u32 prod, dma_addr_t *dma_addr)
-{
-               *dma_addr = pg_map_arr[(prod) / BNXT_QPLIB_CRSBE_CNT_PER_PG];
-               *dma_addr += ((prod) % BNXT_QPLIB_CRSBE_CNT_PER_PG) *
-                             BNXT_QPLIB_CRSBE_UNITS;
-}
-
 /* CREQ */
 /* Allocate 1 per QP for async error notification for now */
 #define BNXT_QPLIB_CREQE_MAX_CNT       (64 * 1024)
@@ -158,17 +133,19 @@ static inline u32 get_creq_idx(u32 val)
 #define CREQ_DB(db, raw_cons, cp_bit)                          \
        writel(CREQ_DB_CP_FLAGS | ((raw_cons) & ((cp_bit) - 1)), db)
 
+#define CREQ_ENTRY_POLL_BUDGET         0x100
+
 /* HWQ */
-struct bnxt_qplib_crsqe {
-       struct creq_qp_event    qp_event;
+
+struct bnxt_qplib_crsq {
+       struct creq_qp_event    *resp;
        u32                     req_size;
 };
 
-struct bnxt_qplib_crsq {
-       struct bnxt_qplib_crsqe *crsq;
-       u32                     prod;
-       u32                     cons;
-       u32                     max_elements;
+struct bnxt_qplib_rcfw_sbuf {
+       void *sb;
+       dma_addr_t dma_addr;
+       u32 size;
 };
 
 /* RCFW Communication Channels */
@@ -185,7 +162,7 @@ struct bnxt_qplib_rcfw {
        wait_queue_head_t       waitq;
        int                     (*aeq_handler)(struct bnxt_qplib_rcfw *,
                                               struct creq_func_event *);
-       atomic_t                seq_num;
+       u32                     seq_num;
 
        /* Bar region info */
        void __iomem            *cmdq_bar_reg_iomem;
@@ -203,8 +180,7 @@ struct bnxt_qplib_rcfw {
 
        /* Actual Cmd and Resp Queues */
        struct bnxt_qplib_hwq   cmdq;
-       struct bnxt_qplib_crsq  crsq;
-       struct bnxt_qplib_hwq   crsb;
+       struct bnxt_qplib_crsq  *crsqe_tbl;
 };
 
 void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
@@ -219,11 +195,14 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
                                        (struct bnxt_qplib_rcfw *,
                                         struct creq_func_event *));
 
-int bnxt_qplib_rcfw_block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie);
-int bnxt_qplib_rcfw_wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie);
-void *bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
-                                  struct cmdq_base *req, void **crsbe,
-                                  u8 is_block);
+struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf(
+                               struct bnxt_qplib_rcfw *rcfw,
+                               u32 size);
+void bnxt_qplib_rcfw_free_sbuf(struct bnxt_qplib_rcfw *rcfw,
+                              struct bnxt_qplib_rcfw_sbuf *sbuf);
+int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+                                struct cmdq_base *req, struct creq_base *resp,
+                                void *sbuf, u8 is_block);
 
 int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw);
 int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
index 6277d802ca4bc7e231e010331b5045c92cb57aad..2e4855509719cbf5ffa1725c8bee4d7e8e2c2f34 100644 (file)
@@ -48,6 +48,10 @@ extern const struct bnxt_qplib_gid bnxt_qplib_gid_zero;
 
 #define HWQ_CMP(idx, hwq)      ((idx) & ((hwq)->max_elements - 1))
 
+#define HWQ_FREE_SLOTS(hwq)    (hwq->max_elements - \
+                               ((HWQ_CMP(hwq->prod, hwq)\
+                               - HWQ_CMP(hwq->cons, hwq))\
+                               & (hwq->max_elements - 1)))
 enum bnxt_qplib_hwq_type {
        HWQ_TYPE_CTX,
        HWQ_TYPE_QUEUE,
index 7b31eccedf11fa8f36a29e6251127144e75a59a5..fde18cf0e406b9f78e2af96d70077622f3d02732 100644 (file)
@@ -55,37 +55,30 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
                            struct bnxt_qplib_dev_attr *attr)
 {
        struct cmdq_query_func req;
-       struct creq_query_func_resp *resp;
+       struct creq_query_func_resp resp;
+       struct bnxt_qplib_rcfw_sbuf *sbuf;
        struct creq_query_func_resp_sb *sb;
        u16 cmd_flags = 0;
        u32 temp;
        u8 *tqm_alloc;
-       int i;
+       int i, rc = 0;
 
        RCFW_CMD_PREP(req, QUERY_FUNC, cmd_flags);
 
-       req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
-       resp = (struct creq_query_func_resp *)
-               bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void **)&sb,
-                                            0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: QUERY_FUNC send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: QUERY_FUNC timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: QUERY_FUNC failed ");
+       sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
+       if (!sbuf) {
                dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
+                       "QPLIB: SP: QUERY_FUNC alloc side buffer failed");
+               return -ENOMEM;
        }
+
+       sb = sbuf->sb;
+       req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         (void *)sbuf, 0);
+       if (rc)
+               goto bail;
+
        /* Extract the context from the side buffer */
        attr->max_qp = le32_to_cpu(sb->max_qp);
        attr->max_qp_rd_atom =
@@ -95,6 +88,11 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
                sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
                BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
        attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr);
+       /*
+        * 128 WQEs needs to be reserved for the HW (8916). Prevent
+        * reporting the max number
+        */
+       attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS;
        attr->max_qp_sges = sb->max_sge;
        attr->max_cq = le32_to_cpu(sb->max_cq);
        attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
@@ -130,7 +128,10 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
                attr->tqm_alloc_reqs[i * 4 + 2] = *(++tqm_alloc);
                attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc);
        }
-       return 0;
+
+bail:
+       bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
+       return rc;
 }
 
 /* SGID */
@@ -178,8 +179,9 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
        /* Remove GID from the SGID table */
        if (update) {
                struct cmdq_delete_gid req;
-               struct creq_delete_gid_resp *resp;
+               struct creq_delete_gid_resp resp;
                u16 cmd_flags = 0;
+               int rc;
 
                RCFW_CMD_PREP(req, DELETE_GID, cmd_flags);
                if (sgid_tbl->hw_id[index] == 0xFFFF) {
@@ -188,31 +190,10 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
                        return -EINVAL;
                }
                req.gid_index = cpu_to_le16(sgid_tbl->hw_id[index]);
-               resp = (struct creq_delete_gid_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, NULL,
-                                                    0);
-               if (!resp) {
-                       dev_err(&res->pdev->dev,
-                               "QPLIB: SP: DELETE_GID send failed");
-                       return -EINVAL;
-               }
-               if (!bnxt_qplib_rcfw_wait_for_resp(rcfw,
-                                                  le16_to_cpu(req.cookie))) {
-                       /* Cmd timed out */
-                       dev_err(&res->pdev->dev,
-                               "QPLIB: SP: DELETE_GID timed out");
-                       return -ETIMEDOUT;
-               }
-               if (resp->status ||
-                   le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-                       dev_err(&res->pdev->dev,
-                               "QPLIB: SP: DELETE_GID failed ");
-                       dev_err(&res->pdev->dev,
-                               "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                               resp->status, le16_to_cpu(req.cookie),
-                               le16_to_cpu(resp->cookie));
-                       return -EINVAL;
-               }
+               rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                                 (void *)&resp, NULL, 0);
+               if (rc)
+                       return rc;
        }
        memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
               sizeof(bnxt_qplib_gid_zero));
@@ -234,7 +215,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
                                                   struct bnxt_qplib_res,
                                                   sgid_tbl);
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
-       int i, free_idx, rc = 0;
+       int i, free_idx;
 
        if (!sgid_tbl) {
                dev_err(&res->pdev->dev, "QPLIB: SGID table not allocated");
@@ -266,10 +247,11 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
        }
        if (update) {
                struct cmdq_add_gid req;
-               struct creq_add_gid_resp *resp;
+               struct creq_add_gid_resp resp;
                u16 cmd_flags = 0;
                u32 temp32[4];
                u16 temp16[3];
+               int rc;
 
                RCFW_CMD_PREP(req, ADD_GID, cmd_flags);
 
@@ -290,31 +272,11 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
                req.src_mac[1] = cpu_to_be16(temp16[1]);
                req.src_mac[2] = cpu_to_be16(temp16[2]);
 
-               resp = (struct creq_add_gid_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-               if (!resp) {
-                       dev_err(&res->pdev->dev,
-                               "QPLIB: SP: ADD_GID send failed");
-                       return -EINVAL;
-               }
-               if (!bnxt_qplib_rcfw_wait_for_resp(rcfw,
-                                                  le16_to_cpu(req.cookie))) {
-                       /* Cmd timed out */
-                       dev_err(&res->pdev->dev,
-                               "QPIB: SP: ADD_GID timed out");
-                       return -ETIMEDOUT;
-               }
-               if (resp->status ||
-                   le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-                       dev_err(&res->pdev->dev, "QPLIB: SP: ADD_GID failed ");
-                       dev_err(&res->pdev->dev,
-                               "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                               resp->status, le16_to_cpu(req.cookie),
-                               le16_to_cpu(resp->cookie));
-                       return -EINVAL;
-               }
-               sgid_tbl->hw_id[free_idx] = le32_to_cpu(resp->xid);
+               rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                                 (void *)&resp, NULL, 0);
+               if (rc)
+                       return rc;
+               sgid_tbl->hw_id[free_idx] = le32_to_cpu(resp.xid);
        }
        /* Add GID to the sgid_tbl */
        memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
@@ -325,7 +287,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
 
        *index = free_idx;
        /* unlock */
-       return rc;
+       return 0;
 }
 
 /* pkeys */
@@ -422,10 +384,11 @@ int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_create_ah req;
-       struct creq_create_ah_resp *resp;
+       struct creq_create_ah_resp resp;
        u16 cmd_flags = 0;
        u32 temp32[4];
        u16 temp16[3];
+       int rc;
 
        RCFW_CMD_PREP(req, CREATE_AH, cmd_flags);
 
@@ -450,28 +413,12 @@ int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
        req.dest_mac[1] = cpu_to_le16(temp16[1]);
        req.dest_mac[2] = cpu_to_le16(temp16[2]);
 
-       resp = (struct creq_create_ah_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 1);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: CREATE_AH send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_block_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: CREATE_AH timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: CREATE_AH failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
-       ah->id = le32_to_cpu(resp->xid);
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         NULL, 1);
+       if (rc)
+               return rc;
+
+       ah->id = le32_to_cpu(resp.xid);
        return 0;
 }
 
@@ -479,35 +426,19 @@ int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_destroy_ah req;
-       struct creq_destroy_ah_resp *resp;
+       struct creq_destroy_ah_resp resp;
        u16 cmd_flags = 0;
+       int rc;
 
        /* Clean up the AH table in the device */
        RCFW_CMD_PREP(req, DESTROY_AH, cmd_flags);
 
        req.ah_cid = cpu_to_le32(ah->id);
 
-       resp = (struct creq_destroy_ah_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 1);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: DESTROY_AH send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_block_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: DESTROY_AH timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: DESTROY_AH failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         NULL, 1);
+       if (rc)
+               return rc;
        return 0;
 }
 
@@ -516,8 +447,9 @@ int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_deallocate_key req;
-       struct creq_deallocate_key_resp *resp;
+       struct creq_deallocate_key_resp resp;
        u16 cmd_flags = 0;
+       int rc;
 
        if (mrw->lkey == 0xFFFFFFFF) {
                dev_info(&res->pdev->dev,
@@ -536,27 +468,11 @@ int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
        else
                req.key = cpu_to_le32(mrw->lkey);
 
-       resp = (struct creq_deallocate_key_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&res->pdev->dev, "QPLIB: SP: FREE_MR send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&res->pdev->dev, "QPLIB: SP: FREE_MR timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&res->pdev->dev, "QPLIB: SP: FREE_MR failed ");
-               dev_err(&res->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         NULL, 0);
+       if (rc)
+               return rc;
+
        /* Free the qplib's MRW memory */
        if (mrw->hwq.max_elements)
                bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
@@ -568,9 +484,10 @@ int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_allocate_mrw req;
-       struct creq_allocate_mrw_resp *resp;
+       struct creq_allocate_mrw_resp resp;
        u16 cmd_flags = 0;
        unsigned long tmp;
+       int rc;
 
        RCFW_CMD_PREP(req, ALLOCATE_MRW, cmd_flags);
 
@@ -584,33 +501,17 @@ int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
        tmp = (unsigned long)mrw;
        req.mrw_handle = cpu_to_le64(tmp);
 
-       resp = (struct creq_allocate_mrw_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, 0);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: ALLOC_MRW send failed");
-               return -EINVAL;
-       }
-       if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
-               /* Cmd timed out */
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: ALLOC_MRW timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: ALLOC_MRW failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
+       if (rc)
+               return rc;
+
        if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1)  ||
            (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A) ||
            (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B))
-               mrw->rkey = le32_to_cpu(resp->xid);
+               mrw->rkey = le32_to_cpu(resp.xid);
        else
-               mrw->lkey = le32_to_cpu(resp->xid);
+               mrw->lkey = le32_to_cpu(resp.xid);
        return 0;
 }
 
@@ -619,40 +520,17 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_deregister_mr req;
-       struct creq_deregister_mr_resp *resp;
+       struct creq_deregister_mr_resp resp;
        u16 cmd_flags = 0;
        int rc;
 
        RCFW_CMD_PREP(req, DEREGISTER_MR, cmd_flags);
 
        req.lkey = cpu_to_le32(mrw->lkey);
-       resp = (struct creq_deregister_mr_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, block);
-       if (!resp) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: DEREG_MR send failed");
-               return -EINVAL;
-       }
-       if (block)
-               rc = bnxt_qplib_rcfw_block_for_resp(rcfw,
-                                                   le16_to_cpu(req.cookie));
-       else
-               rc = bnxt_qplib_rcfw_wait_for_resp(rcfw,
-                                                  le16_to_cpu(req.cookie));
-       if (!rc) {
-               /* Cmd timed out */
-               dev_err(&res->pdev->dev, "QPLIB: SP: DEREG_MR timed out");
-               return -ETIMEDOUT;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&rcfw->pdev->dev, "QPLIB: SP: DEREG_MR failed ");
-               dev_err(&rcfw->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, block);
+       if (rc)
+               return rc;
 
        /* Free the qplib's MR memory */
        if (mrw->hwq.max_elements) {
@@ -669,7 +547,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_register_mr req;
-       struct creq_register_mr_resp *resp;
+       struct creq_register_mr_resp resp;
        u16 cmd_flags = 0, level;
        int pg_ptrs, pages, i, rc;
        dma_addr_t **pbl_ptr;
@@ -730,36 +608,11 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
        req.key = cpu_to_le32(mr->lkey);
        req.mr_size = cpu_to_le64(mr->total_size);
 
-       resp = (struct creq_register_mr_resp *)
-                       bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-                                                    NULL, block);
-       if (!resp) {
-               dev_err(&res->pdev->dev, "SP: REG_MR send failed");
-               rc = -EINVAL;
-               goto fail;
-       }
-       if (block)
-               rc = bnxt_qplib_rcfw_block_for_resp(rcfw,
-                                                   le16_to_cpu(req.cookie));
-       else
-               rc = bnxt_qplib_rcfw_wait_for_resp(rcfw,
-                                                  le16_to_cpu(req.cookie));
-       if (!rc) {
-               /* Cmd timed out */
-               dev_err(&res->pdev->dev, "SP: REG_MR timed out");
-               rc = -ETIMEDOUT;
-               goto fail;
-       }
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&res->pdev->dev, "QPLIB: SP: REG_MR failed ");
-               dev_err(&res->pdev->dev,
-                       "QPLIB: SP: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               rc = -EINVAL;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, block);
+       if (rc)
                goto fail;
-       }
+
        return 0;
 
 fail:
@@ -804,35 +657,15 @@ int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res *res, u16 *cids)
 {
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_map_tc_to_cos req;
-       struct creq_map_tc_to_cos_resp *resp;
+       struct creq_map_tc_to_cos_resp resp;
        u16 cmd_flags = 0;
-       int tleft;
+       int rc = 0;
 
        RCFW_CMD_PREP(req, MAP_TC_TO_COS, cmd_flags);
        req.cos0 = cpu_to_le16(cids[0]);
        req.cos1 = cpu_to_le16(cids[1]);
 
-       resp = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, NULL, 0);
-       if (!resp) {
-               dev_err(&res->pdev->dev, "QPLIB: SP: MAP_TC2COS send failed");
-               return -EINVAL;
-       }
-
-       tleft = bnxt_qplib_rcfw_block_for_resp(rcfw, le16_to_cpu(req.cookie));
-       if (!tleft) {
-               dev_err(&res->pdev->dev, "QPLIB: SP: MAP_TC2COS timed out");
-               return -ETIMEDOUT;
-       }
-
-       if (resp->status ||
-           le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
-               dev_err(&res->pdev->dev, "QPLIB: SP: MAP_TC2COS failed ");
-               dev_err(&res->pdev->dev,
-                       "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
-                       resp->status, le16_to_cpu(req.cookie),
-                       le16_to_cpu(resp->cookie));
-               return -EINVAL;
-       }
-
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+                                         (void *)&resp, NULL, 0);
        return 0;
 }
index 1442a617e968e1d367a9fd9e69a0540da645ce6f..a543f959098bd11972383a9d907725c08497a8f4 100644 (file)
@@ -40,6 +40,8 @@
 #ifndef __BNXT_QPLIB_SP_H__
 #define __BNXT_QPLIB_SP_H__
 
+#define BNXT_QPLIB_RESERVED_QP_WRS     128
+
 struct bnxt_qplib_dev_attr {
        char                            fw_ver[32];
        u16                             max_sgid;
index f96a96dbcf1ff4e40b75de36122a3efd0405faae..ae0b79aeea2ec141ebc83b9960f59718035eb1bf 100644 (file)
@@ -767,7 +767,7 @@ void c4iw_release_dev_ucontext(struct c4iw_rdev *rdev,
                kfree(entry);
        }
 
-       list_for_each_safe(pos, nxt, &uctx->qpids) {
+       list_for_each_safe(pos, nxt, &uctx->cqids) {
                entry = list_entry(pos, struct c4iw_qid_list, entry);
                list_del_init(&entry->entry);
                kfree(entry);
@@ -880,13 +880,15 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
        rdev->free_workq = create_singlethread_workqueue("iw_cxgb4_free");
        if (!rdev->free_workq) {
                err = -ENOMEM;
-               goto err_free_status_page;
+               goto err_free_status_page_and_wr_log;
        }
 
        rdev->status_page->db_off = 0;
 
        return 0;
-err_free_status_page:
+err_free_status_page_and_wr_log:
+       if (c4iw_wr_log && rdev->wr_log)
+               kfree(rdev->wr_log);
        free_page((unsigned long)rdev->status_page);
 destroy_ocqp_pool:
        c4iw_ocqp_pool_destroy(rdev);
@@ -903,9 +905,11 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev)
 {
        destroy_workqueue(rdev->free_workq);
        kfree(rdev->wr_log);
+       c4iw_release_dev_ucontext(rdev, &rdev->uctx);
        free_page((unsigned long)rdev->status_page);
        c4iw_pblpool_destroy(rdev);
        c4iw_rqtpool_destroy(rdev);
+       c4iw_ocqp_pool_destroy(rdev);
        c4iw_destroy_resource(&rdev->resource);
 }
 
index 0c79983c8b1a0a4e6189fb5e02439ff3522a9098..9ecc089d4529440fa87929fb74461558db920549 100644 (file)
@@ -3692,8 +3692,10 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
        dev->ib_dev.check_mr_status     = mlx5_ib_check_mr_status;
        dev->ib_dev.get_port_immutable  = mlx5_port_immutable;
        dev->ib_dev.get_dev_fw_str      = get_dev_fw_str;
-       dev->ib_dev.alloc_rdma_netdev   = mlx5_ib_alloc_rdma_netdev;
-       dev->ib_dev.free_rdma_netdev    = mlx5_ib_free_rdma_netdev;
+       if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads)) {
+               dev->ib_dev.alloc_rdma_netdev   = mlx5_ib_alloc_rdma_netdev;
+               dev->ib_dev.free_rdma_netdev    = mlx5_ib_free_rdma_netdev;
+       }
        if (mlx5_core_is_pf(mdev)) {
                dev->ib_dev.get_vf_config       = mlx5_ib_get_vf_config;
                dev->ib_dev.set_vf_link_state   = mlx5_ib_set_vf_link_state;
index aa08c76a42450a2ef86d1854b45a80d7bcd4387c..d961f79b317cba526fe52ca4af6adc40c0781868 100644 (file)
 #define QEDR_MSG_QP   "  QP"
 #define QEDR_MSG_GSI  " GSI"
 
-#define QEDR_CQ_MAGIC_NUMBER   (0x11223344)
+#define QEDR_CQ_MAGIC_NUMBER   (0x11223344)
+
+#define FW_PAGE_SIZE           (RDMA_RING_PAGE_SIZE)
+#define FW_PAGE_SHIFT          (12)
 
 struct qedr_dev;
 
index 17685cfea6a2dcb435e659675805dcbc29139e7b..d6723c365c7fba36168bc11c227de8bc34eef862 100644 (file)
@@ -653,14 +653,15 @@ static int qedr_prepare_pbl_tbl(struct qedr_dev *dev,
 
 static void qedr_populate_pbls(struct qedr_dev *dev, struct ib_umem *umem,
                               struct qedr_pbl *pbl,
-                              struct qedr_pbl_info *pbl_info)
+                              struct qedr_pbl_info *pbl_info, u32 pg_shift)
 {
        int shift, pg_cnt, pages, pbe_cnt, total_num_pbes = 0;
+       u32 fw_pg_cnt, fw_pg_per_umem_pg;
        struct qedr_pbl *pbl_tbl;
        struct scatterlist *sg;
        struct regpair *pbe;
+       u64 pg_addr;
        int entry;
-       u32 addr;
 
        if (!pbl_info->num_pbes)
                return;
@@ -683,29 +684,35 @@ static void qedr_populate_pbls(struct qedr_dev *dev, struct ib_umem *umem,
 
        shift = umem->page_shift;
 
+       fw_pg_per_umem_pg = BIT(umem->page_shift - pg_shift);
+
        for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) {
                pages = sg_dma_len(sg) >> shift;
+               pg_addr = sg_dma_address(sg);
                for (pg_cnt = 0; pg_cnt < pages; pg_cnt++) {
-                       /* store the page address in pbe */
-                       pbe->lo = cpu_to_le32(sg_dma_address(sg) +
-                                             (pg_cnt << shift));
-                       addr = upper_32_bits(sg_dma_address(sg) +
-                                            (pg_cnt << shift));
-                       pbe->hi = cpu_to_le32(addr);
-                       pbe_cnt++;
-                       total_num_pbes++;
-                       pbe++;
-
-                       if (total_num_pbes == pbl_info->num_pbes)
-                               return;
-
-                       /* If the given pbl is full storing the pbes,
-                        * move to next pbl.
-                        */
-                       if (pbe_cnt == (pbl_info->pbl_size / sizeof(u64))) {
-                               pbl_tbl++;
-                               pbe = (struct regpair *)pbl_tbl->va;
-                               pbe_cnt = 0;
+                       for (fw_pg_cnt = 0; fw_pg_cnt < fw_pg_per_umem_pg;) {
+                               pbe->lo = cpu_to_le32(pg_addr);
+                               pbe->hi = cpu_to_le32(upper_32_bits(pg_addr));
+
+                               pg_addr += BIT(pg_shift);
+                               pbe_cnt++;
+                               total_num_pbes++;
+                               pbe++;
+
+                               if (total_num_pbes == pbl_info->num_pbes)
+                                       return;
+
+                               /* If the given pbl is full storing the pbes,
+                                * move to next pbl.
+                                */
+                               if (pbe_cnt ==
+                                   (pbl_info->pbl_size / sizeof(u64))) {
+                                       pbl_tbl++;
+                                       pbe = (struct regpair *)pbl_tbl->va;
+                                       pbe_cnt = 0;
+                               }
+
+                               fw_pg_cnt++;
                        }
                }
        }
@@ -754,7 +761,7 @@ static inline int qedr_init_user_queue(struct ib_ucontext *ib_ctx,
                                       u64 buf_addr, size_t buf_len,
                                       int access, int dmasync)
 {
-       int page_cnt;
+       u32 fw_pages;
        int rc;
 
        q->buf_addr = buf_addr;
@@ -766,8 +773,10 @@ static inline int qedr_init_user_queue(struct ib_ucontext *ib_ctx,
                return PTR_ERR(q->umem);
        }
 
-       page_cnt = ib_umem_page_count(q->umem);
-       rc = qedr_prepare_pbl_tbl(dev, &q->pbl_info, page_cnt, 0);
+       fw_pages = ib_umem_page_count(q->umem) <<
+           (q->umem->page_shift - FW_PAGE_SHIFT);
+
+       rc = qedr_prepare_pbl_tbl(dev, &q->pbl_info, fw_pages, 0);
        if (rc)
                goto err0;
 
@@ -777,7 +786,8 @@ static inline int qedr_init_user_queue(struct ib_ucontext *ib_ctx,
                goto err0;
        }
 
-       qedr_populate_pbls(dev, q->umem, q->pbl_tbl, &q->pbl_info);
+               qedr_populate_pbls(dev, q->umem, q->pbl_tbl, &q->pbl_info,
+                                  FW_PAGE_SHIFT);
 
        return 0;
 
@@ -2226,7 +2236,7 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
                goto err1;
 
        qedr_populate_pbls(dev, mr->umem, mr->info.pbl_table,
-                          &mr->info.pbl_info);
+                          &mr->info.pbl_info, mr->umem->page_shift);
 
        rc = dev->ops->rdma_alloc_tid(dev->rdma_ctx, &mr->hw_mr.itid);
        if (rc) {
@@ -3209,6 +3219,10 @@ static int process_req(struct qedr_dev *dev, struct qedr_qp *qp,
                case IB_WC_REG_MR:
                        qp->wqe_wr_id[qp->sq.cons].mr->info.completed++;
                        break;
+               case IB_WC_RDMA_READ:
+               case IB_WC_SEND:
+                       wc->byte_len = qp->wqe_wr_id[qp->sq.cons].bytes_len;
+                       break;
                default:
                        break;
                }
index ecdba2fce0837675f4a9ae6cddb80c7b1c1c0a3d..1ac5b8551a4d37325e782e5dc438ed4915d7243f 100644 (file)
@@ -68,6 +68,7 @@
 static inline u32 rxe_crc32(struct rxe_dev *rxe,
                            u32 crc, void *next, size_t len)
 {
+       u32 retval;
        int err;
 
        SHASH_DESC_ON_STACK(shash, rxe->tfm);
@@ -81,7 +82,9 @@ static inline u32 rxe_crc32(struct rxe_dev *rxe,
                return crc32_le(crc, next, len);
        }
 
-       return *(u32 *)shash_desc_ctx(shash);
+       retval = *(u32 *)shash_desc_ctx(shash);
+       barrier_data(shash_desc_ctx(shash));
+       return retval;
 }
 
 int rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu);
index 83d709e74dfb87ab0dcec30c87f0e49cd57022d2..073e66783f1dd8a4b62f9fc59a84319b507b51b8 100644 (file)
@@ -740,13 +740,8 @@ static int init_send_wqe(struct rxe_qp *qp, struct ib_send_wr *ibwr,
 
                sge = ibwr->sg_list;
                for (i = 0; i < num_sge; i++, sge++) {
-                       if (qp->is_user && copy_from_user(p, (__user void *)
-                                           (uintptr_t)sge->addr, sge->length))
-                               return -EFAULT;
-
-                       else if (!qp->is_user)
-                               memcpy(p, (void *)(uintptr_t)sge->addr,
-                                      sge->length);
+                       memcpy(p, (void *)(uintptr_t)sge->addr,
+                                       sge->length);
 
                        p += sge->length;
                }
index 0060b2f9f659d7ad1ee9a1767d0029dc8529ff4c..efe7402f48852195efae4fc70cf843d0398dda30 100644 (file)
@@ -863,7 +863,6 @@ dev_stop:
        set_bit(IPOIB_STOP_REAPER, &priv->flags);
        cancel_delayed_work(&priv->ah_reap_task);
        set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
-       napi_enable(&priv->napi);
        ipoib_ib_dev_stop(dev);
        return -1;
 }
index a115c0b7a310ed630c1c32ffd9e2c17574358f7c..1015a63de6aed6f3a8b88f3816dc5720a2d24092 100644 (file)
@@ -1596,6 +1596,8 @@ static void ipoib_dev_uninit_default(struct net_device *dev)
 
        ipoib_transport_dev_cleanup(dev);
 
+       netif_napi_del(&priv->napi);
+
        ipoib_cm_dev_cleanup(dev);
 
        kfree(priv->rx_ring);
@@ -1649,6 +1651,7 @@ out_rx_ring_cleanup:
        kfree(priv->rx_ring);
 
 out:
+       netif_napi_del(&priv->napi);
        return -ENOMEM;
 }
 
@@ -2237,6 +2240,7 @@ event_failed:
 
 device_init_failed:
        free_netdev(priv->dev);
+       kfree(priv);
 
 alloc_mem_failed:
        return ERR_PTR(result);
@@ -2277,7 +2281,7 @@ static void ipoib_add_one(struct ib_device *device)
 
 static void ipoib_remove_one(struct ib_device *device, void *client_data)
 {
-       struct ipoib_dev_priv *priv, *tmp;
+       struct ipoib_dev_priv *priv, *tmp, *cpriv, *tcpriv;
        struct list_head *dev_list = client_data;
 
        if (!dev_list)
@@ -2300,7 +2304,14 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
                flush_workqueue(priv->wq);
 
                unregister_netdev(priv->dev);
-               free_netdev(priv->dev);
+               if (device->free_rdma_netdev)
+                       device->free_rdma_netdev(priv->dev);
+               else
+                       free_netdev(priv->dev);
+
+               list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list)
+                       kfree(cpriv);
+
                kfree(priv);
        }
 
index 36dc4fcaa3cdbcd2516d44fb9360c5dcccce1404..081b33deff1bcbf6f381c9993af174a3dc5e90b4 100644 (file)
@@ -133,13 +133,13 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
        snprintf(intf_name, sizeof intf_name, "%s.%04x",
                 ppriv->dev->name, pkey);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
+
        priv = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name);
        if (!priv)
                return -ENOMEM;
 
-       if (!rtnl_trylock())
-               return restart_syscall();
-
        down_write(&ppriv->vlan_rwsem);
 
        /*
@@ -167,8 +167,10 @@ out:
 
        rtnl_unlock();
 
-       if (result)
+       if (result) {
                free_netdev(priv->dev);
+               kfree(priv);
+       }
 
        return result;
 }
@@ -209,6 +211,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 
        if (dev) {
                free_netdev(dev);
+               kfree(priv);
                return 0;
        }
 
index e37d37273182097d412f30a3878ea0303f9f7a5b..f600f3a7a3c685488e1ede36058439c59f0703dc 100644 (file)
@@ -248,7 +248,8 @@ static struct soc_button_info *soc_button_get_button_info(struct device *dev)
 
        if (!btns_desc) {
                dev_err(dev, "ACPI Button Descriptors not found\n");
-               return ERR_PTR(-ENODEV);
+               button_info = ERR_PTR(-ENODEV);
+               goto out;
        }
 
        /* The first package describes the collection */
@@ -264,24 +265,31 @@ static struct soc_button_info *soc_button_get_button_info(struct device *dev)
        }
        if (collection_uid == -1) {
                dev_err(dev, "Invalid Button Collection Descriptor\n");
-               return ERR_PTR(-ENODEV);
+               button_info = ERR_PTR(-ENODEV);
+               goto out;
        }
 
        /* There are package.count - 1 buttons + 1 terminating empty entry */
        button_info = devm_kcalloc(dev, btns_desc->package.count,
                                   sizeof(*button_info), GFP_KERNEL);
-       if (!button_info)
-               return ERR_PTR(-ENOMEM);
+       if (!button_info) {
+               button_info = ERR_PTR(-ENOMEM);
+               goto out;
+       }
 
        /* Parse the button descriptors */
        for (i = 1, btn = 0; i < btns_desc->package.count; i++, btn++) {
                if (soc_button_parse_btn_desc(dev,
                                              &btns_desc->package.elements[i],
                                              collection_uid,
-                                             &button_info[btn]))
-                       return ERR_PTR(-ENODEV);
+                                             &button_info[btn])) {
+                       button_info = ERR_PTR(-ENODEV);
+                       goto out;
+               }
        }
 
+out:
+       kfree(buf.pointer);
        return button_info;
 }
 
index dea63e2db3e6213f5e83d6067870a16cc5707e6d..f5206e2c767ebf3579c2468b2a2956cc4bff3dcc 100644 (file)
@@ -31,9 +31,6 @@
 #define F54_GET_REPORT          1
 #define F54_FORCE_CAL           2
 
-/* Fixed sizes of reports */
-#define F54_QUERY_LEN                  27
-
 /* F54 capabilities */
 #define F54_CAP_BASELINE       (1 << 2)
 #define F54_CAP_IMAGE8         (1 << 3)
@@ -95,7 +92,6 @@ struct rmi_f54_reports {
 struct f54_data {
        struct rmi_function *fn;
 
-       u8 qry[F54_QUERY_LEN];
        u8 num_rx_electrodes;
        u8 num_tx_electrodes;
        u8 capabilities;
@@ -632,22 +628,23 @@ static int rmi_f54_detect(struct rmi_function *fn)
 {
        int error;
        struct f54_data *f54;
+       u8 buf[6];
 
        f54 = dev_get_drvdata(&fn->dev);
 
        error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
-                              &f54->qry, sizeof(f54->qry));
+                              buf, sizeof(buf));
        if (error) {
                dev_err(&fn->dev, "%s: Failed to query F54 properties\n",
                        __func__);
                return error;
        }
 
-       f54->num_rx_electrodes = f54->qry[0];
-       f54->num_tx_electrodes = f54->qry[1];
-       f54->capabilities = f54->qry[2];
-       f54->clock_rate = f54->qry[3] | (f54->qry[4] << 8);
-       f54->family = f54->qry[5];
+       f54->num_rx_electrodes = buf[0];
+       f54->num_tx_electrodes = buf[1];
+       f54->capabilities = buf[2];
+       f54->clock_rate = buf[3] | (buf[4] << 8);
+       f54->family = buf[5];
 
        rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F54 num_rx_electrodes: %d\n",
                f54->num_rx_electrodes);
index 09720d950686c844b49f1d7f32710e160d21624a..f932a83b4990210d8daeb25c1d2482b958c3719e 100644 (file)
@@ -723,6 +723,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
                },
        },
+       {
+               /* Fujitsu UH554 laptop */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
+               },
+       },
        { }
 };
 
index eb7fbe15996304fc9eecca11a2b71b70bffd284d..929f8558bf1c0fe247d5c0ab99e40dfaaea094bd 100644 (file)
@@ -140,7 +140,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 }
 
 #ifdef CONFIG_CLKSRC_MIPS_GIC
-u64 gic_read_count(void)
+u64 notrace gic_read_count(void)
 {
        unsigned int hi, hi2, lo;
 
@@ -167,7 +167,7 @@ unsigned int gic_get_count_width(void)
        return bits;
 }
 
-void gic_write_compare(u64 cnt)
+void notrace gic_write_compare(u64 cnt)
 {
        if (mips_cm_is64) {
                gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
@@ -179,7 +179,7 @@ void gic_write_compare(u64 cnt)
        }
 }
 
-void gic_write_cpu_compare(u64 cnt, int cpu)
+void notrace gic_write_cpu_compare(u64 cnt, int cpu)
 {
        unsigned long flags;
 
index bb3ac5fe5846b9e2d27b71bea9bf0bff9bcb8e2d..72a391e01011c8356474765cde4ab18d2f997f10 100644 (file)
@@ -142,7 +142,7 @@ static struct irq_chip xtensa_mx_irq_chip = {
 int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent)
 {
        struct irq_domain *root_domain =
-               irq_domain_add_legacy(NULL, NR_IRQS, 0, 0,
+               irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,
                                &xtensa_mx_irq_domain_ops,
                                &xtensa_mx_irq_chip);
        irq_set_default_host(root_domain);
index 472ae17709647201606a10344fd741d77e81e988..f728755fa2922019e6b117105f3a9b9dfe0fc3e9 100644 (file)
@@ -89,7 +89,7 @@ static struct irq_chip xtensa_irq_chip = {
 int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent)
 {
        struct irq_domain *root_domain =
-               irq_domain_add_legacy(NULL, NR_IRQS, 0, 0,
+               irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,
                                &xtensa_irq_domain_ops, &xtensa_irq_chip);
        irq_set_default_host(root_domain);
        return 0;
index 1548259297c185e8cfefb4f6df7127b97755da2b..2cfd9389ee96f8cc69a40681374a19a31aa174ed 100644 (file)
@@ -242,7 +242,7 @@ static int bcm6328_hwled(struct device *dev, struct device_node *nc, u32 reg,
 
                spin_lock_irqsave(lock, flags);
                val = bcm6328_led_read(addr);
-               val |= (BIT(reg) << (((sel % 4) * 4) + 16));
+               val |= (BIT(reg % 4) << (((sel % 4) * 4) + 16));
                bcm6328_led_write(addr, val);
                spin_unlock_irqrestore(lock, flags);
        }
@@ -269,7 +269,7 @@ static int bcm6328_hwled(struct device *dev, struct device_node *nc, u32 reg,
 
                spin_lock_irqsave(lock, flags);
                val = bcm6328_led_read(addr);
-               val |= (BIT(reg) << ((sel % 4) * 4));
+               val |= (BIT(reg % 4) << ((sel % 4) * 4));
                bcm6328_led_write(addr, val);
                spin_unlock_irqrestore(lock, flags);
        }
index afa3b40992140b2cf194ef971502a517b1cc9bd2..e95ea65380c864b5aef90c9eec0bb000b4b51086 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/sched/loadavg.h>
 #include <linux/leds.h>
 #include <linux/reboot.h>
-#include <linux/suspend.h>
 #include "../leds.h"
 
 static int panic_heartbeats;
@@ -163,30 +162,6 @@ static struct led_trigger heartbeat_led_trigger = {
        .deactivate = heartbeat_trig_deactivate,
 };
 
-static int heartbeat_pm_notifier(struct notifier_block *nb,
-                                unsigned long pm_event, void *unused)
-{
-       int rc;
-
-       switch (pm_event) {
-       case PM_SUSPEND_PREPARE:
-       case PM_HIBERNATION_PREPARE:
-       case PM_RESTORE_PREPARE:
-               led_trigger_unregister(&heartbeat_led_trigger);
-               break;
-       case PM_POST_SUSPEND:
-       case PM_POST_HIBERNATION:
-       case PM_POST_RESTORE:
-               rc = led_trigger_register(&heartbeat_led_trigger);
-               if (rc)
-                       pr_err("could not re-register heartbeat trigger\n");
-               break;
-       default:
-               break;
-       }
-       return NOTIFY_DONE;
-}
-
 static int heartbeat_reboot_notifier(struct notifier_block *nb,
                                     unsigned long code, void *unused)
 {
@@ -201,10 +176,6 @@ static int heartbeat_panic_notifier(struct notifier_block *nb,
        return NOTIFY_DONE;
 }
 
-static struct notifier_block heartbeat_pm_nb = {
-       .notifier_call = heartbeat_pm_notifier,
-};
-
 static struct notifier_block heartbeat_reboot_nb = {
        .notifier_call = heartbeat_reboot_notifier,
 };
@@ -221,14 +192,12 @@ static int __init heartbeat_trig_init(void)
                atomic_notifier_chain_register(&panic_notifier_list,
                                               &heartbeat_panic_nb);
                register_reboot_notifier(&heartbeat_reboot_nb);
-               register_pm_notifier(&heartbeat_pm_nb);
        }
        return rc;
 }
 
 static void __exit heartbeat_trig_exit(void)
 {
-       unregister_pm_notifier(&heartbeat_pm_nb);
        unregister_reboot_notifier(&heartbeat_reboot_nb);
        atomic_notifier_chain_unregister(&panic_notifier_list,
                                         &heartbeat_panic_nb);
index 4e25a950ae6f5af73c7bc7bd305a51368ef7d52b..43428cec3a01cde9ca4deb920ceb1fde47289076 100644 (file)
@@ -1,5 +1,6 @@
 config MEDIA_CEC_RC
        bool "HDMI CEC RC integration"
        depends on CEC_CORE && RC_CORE
+       depends on CEC_CORE=m || RC_CORE=y
        ---help---
          Pass on CEC remote control messages to the RC framework.
index 0860fb458757df3871ccab290867fcf7c4d5c11e..999926f731c88827802029ba2a928ee457e49ffb 100644 (file)
@@ -271,16 +271,10 @@ static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh,
                        bool block, struct cec_msg __user *parg)
 {
        struct cec_msg msg = {};
-       long err = 0;
+       long err;
 
        if (copy_from_user(&msg, parg, sizeof(msg)))
                return -EFAULT;
-       mutex_lock(&adap->lock);
-       if (!adap->is_configured && fh->mode_follower < CEC_MODE_MONITOR)
-               err = -ENONET;
-       mutex_unlock(&adap->lock);
-       if (err)
-               return err;
 
        err = cec_receive_msg(fh, &msg, block);
        if (err)
index acef4eca269f1c1f3f1e36d6ca8c76e1523cd9b6..3251cba89e8f63052091aa5b1bdaf7f2bb74afc3 100644 (file)
@@ -223,7 +223,7 @@ static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val)
 static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg,
                u8 mask, u8 val)
 {
-       i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2);
+       i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 1) & mask) | val, 1);
 }
 
 static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)
index e12ec50bf0bf7531cb76ef129149d77f531fa525..90a5f8fd5eea68d6e1f007843c6bb67f7c8790b2 100644 (file)
@@ -183,9 +183,15 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id)
        static unsigned long delt;
        unsigned long deltintr;
        unsigned long flags;
+       int counter = 0;
        int iir, lsr;
 
        while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) {
+               if (++counter > 256) {
+                       dev_err(&sir_ir_dev->dev, "Trapped in interrupt");
+                       break;
+               }
+
                switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */
                case UART_IIR_MSI:
                        (void)inb(io + UART_MSR);
index 71bd68548c9c87d3359a458efe9069c59a81e81a..4126552c90556ede32ec1bf2aee53c4d3afc3811 100644 (file)
@@ -336,6 +336,7 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv)
        serio_set_drvdata(serio, rain);
        INIT_WORK(&rain->work, rain_irq_work_handler);
        mutex_init(&rain->write_lock);
+       spin_lock_init(&rain->buf_lock);
 
        err = serio_open(serio, drv);
        if (err)
index 94afbbf928072ba6c24c850bdc41c3ab0820a96d..c0175ea7e7ad186d7d62c352c917cb3d14e28649 100644 (file)
@@ -868,7 +868,7 @@ EXPORT_SYMBOL_GPL(vb2_core_create_bufs);
 
 void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
 {
-       if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv)
+       if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv)
                return NULL;
 
        return call_ptr_memop(vb, vaddr, vb->planes[plane_no].mem_priv);
index 75488e65cd96cf6484e300d47280df77f1eec77a..8d46e3ad9529d46a2b2e27229668e517ef38552f 100644 (file)
@@ -245,8 +245,7 @@ static int arizona_poll_reg(struct arizona *arizona,
        int ret;
 
        ret = regmap_read_poll_timeout(arizona->regmap,
-                                      ARIZONA_INTERRUPT_RAW_STATUS_5, val,
-                                      ((val & mask) == target),
+                                      reg, val, ((val & mask) == target),
                                       ARIZONA_REG_POLL_DELAY_US,
                                       timeout_ms * 1000);
        if (ret)
index 1842ed341af10e38902f1178f409d645b7301679..de962c2d5e000a834bc40064be3bbe426e55bf5a 100644 (file)
@@ -210,6 +210,15 @@ static void meson_mmc_get_transfer_mode(struct mmc_host *mmc,
        int i;
        bool use_desc_chain_mode = true;
 
+       /*
+        * Broken SDIO with AP6255-based WiFi on Khadas VIM Pro has been
+        * reported. For some strange reason this occurs in descriptor
+        * chain mode only. So let's fall back to bounce buffer mode
+        * for command SD_IO_RW_EXTENDED.
+        */
+       if (mrq->cmd->opcode == SD_IO_RW_EXTENDED)
+               return;
+
        for_each_sg(data->sg, sg, data->sg_len, i)
                /* check for 8 byte alignment */
                if (sg->offset & 7) {
index b44a6aeb346d0404144dde0304a502268de1da91..e5386ab706ec7fa394162b338c6ff4ad1de8944c 100644 (file)
@@ -90,10 +90,13 @@ enum ad_link_speed_type {
        AD_LINK_SPEED_100MBPS,
        AD_LINK_SPEED_1000MBPS,
        AD_LINK_SPEED_2500MBPS,
+       AD_LINK_SPEED_5000MBPS,
        AD_LINK_SPEED_10000MBPS,
+       AD_LINK_SPEED_14000MBPS,
        AD_LINK_SPEED_20000MBPS,
        AD_LINK_SPEED_25000MBPS,
        AD_LINK_SPEED_40000MBPS,
+       AD_LINK_SPEED_50000MBPS,
        AD_LINK_SPEED_56000MBPS,
        AD_LINK_SPEED_100000MBPS,
 };
@@ -259,10 +262,13 @@ static inline int __check_agg_selection_timer(struct port *port)
  *     %AD_LINK_SPEED_100MBPS,
  *     %AD_LINK_SPEED_1000MBPS,
  *     %AD_LINK_SPEED_2500MBPS,
+ *     %AD_LINK_SPEED_5000MBPS,
  *     %AD_LINK_SPEED_10000MBPS
+ *     %AD_LINK_SPEED_14000MBPS,
  *     %AD_LINK_SPEED_20000MBPS
  *     %AD_LINK_SPEED_25000MBPS
  *     %AD_LINK_SPEED_40000MBPS
+ *     %AD_LINK_SPEED_50000MBPS
  *     %AD_LINK_SPEED_56000MBPS
  *     %AD_LINK_SPEED_100000MBPS
  */
@@ -296,10 +302,18 @@ static u16 __get_link_speed(struct port *port)
                        speed = AD_LINK_SPEED_2500MBPS;
                        break;
 
+               case SPEED_5000:
+                       speed = AD_LINK_SPEED_5000MBPS;
+                       break;
+
                case SPEED_10000:
                        speed = AD_LINK_SPEED_10000MBPS;
                        break;
 
+               case SPEED_14000:
+                       speed = AD_LINK_SPEED_14000MBPS;
+                       break;
+
                case SPEED_20000:
                        speed = AD_LINK_SPEED_20000MBPS;
                        break;
@@ -312,6 +326,10 @@ static u16 __get_link_speed(struct port *port)
                        speed = AD_LINK_SPEED_40000MBPS;
                        break;
 
+               case SPEED_50000:
+                       speed = AD_LINK_SPEED_50000MBPS;
+                       break;
+
                case SPEED_56000:
                        speed = AD_LINK_SPEED_56000MBPS;
                        break;
@@ -707,9 +725,15 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
                case AD_LINK_SPEED_2500MBPS:
                        bandwidth = nports * 2500;
                        break;
+               case AD_LINK_SPEED_5000MBPS:
+                       bandwidth = nports * 5000;
+                       break;
                case AD_LINK_SPEED_10000MBPS:
                        bandwidth = nports * 10000;
                        break;
+               case AD_LINK_SPEED_14000MBPS:
+                       bandwidth = nports * 14000;
+                       break;
                case AD_LINK_SPEED_20000MBPS:
                        bandwidth = nports * 20000;
                        break;
@@ -719,6 +743,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
                case AD_LINK_SPEED_40000MBPS:
                        bandwidth = nports * 40000;
                        break;
+               case AD_LINK_SPEED_50000MBPS:
+                       bandwidth = nports * 50000;
+                       break;
                case AD_LINK_SPEED_56000MBPS:
                        bandwidth = nports * 56000;
                        break;
index 2359478b977f0e008335e51dc8f63adc2dc35087..8ab6bdbe16820dd3e56ec517838903bedda515de 100644 (file)
@@ -4192,7 +4192,6 @@ static void bond_destructor(struct net_device *bond_dev)
        struct bonding *bond = netdev_priv(bond_dev);
        if (bond->wq)
                destroy_workqueue(bond->wq);
-       free_netdev(bond_dev);
 }
 
 void bond_setup(struct net_device *bond_dev)
@@ -4212,7 +4211,8 @@ void bond_setup(struct net_device *bond_dev)
        bond_dev->netdev_ops = &bond_netdev_ops;
        bond_dev->ethtool_ops = &bond_ethtool_ops;
 
-       bond_dev->destructor = bond_destructor;
+       bond_dev->needs_free_netdev = true;
+       bond_dev->priv_destructor = bond_destructor;
 
        SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
 
@@ -4736,7 +4736,7 @@ int bond_create(struct net *net, const char *name)
 
        rtnl_unlock();
        if (res < 0)
-               bond_destructor(bond_dev);
+               free_netdev(bond_dev);
        return res;
 }
 
index ddabce7594565232a5e903c23248ea884995c149..71a7c3b44fdde3c3a7ede652a7dab681d577e6ce 100644 (file)
@@ -1121,7 +1121,7 @@ static void cfhsi_setup(struct net_device *dev)
        dev->flags = IFF_POINTOPOINT | IFF_NOARP;
        dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
        dev->priv_flags |= IFF_NO_QUEUE;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        dev->netdev_ops = &cfhsi_netdevops;
        for (i = 0; i < CFHSI_PRIO_LAST; ++i)
                skb_queue_head_init(&cfhsi->qhead[i]);
index c2dea4916e5d720bb29814153f302ec364fe4f61..76e1d3545105e8abb9e2ef644e03fab0d2f5b243 100644 (file)
@@ -428,7 +428,7 @@ static void caifdev_setup(struct net_device *dev)
        dev->flags = IFF_POINTOPOINT | IFF_NOARP;
        dev->mtu = CAIF_MAX_MTU;
        dev->priv_flags |= IFF_NO_QUEUE;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        skb_queue_head_init(&serdev->head);
        serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
        serdev->common.use_frag = true;
index 3a529fbe539fb6ee098f0b85515a49bdc1b64d90..fc21afe852b9817a2bdd242fc371834c515213dd 100644 (file)
@@ -712,7 +712,7 @@ static void cfspi_setup(struct net_device *dev)
        dev->flags = IFF_NOARP | IFF_POINTOPOINT;
        dev->priv_flags |= IFF_NO_QUEUE;
        dev->mtu = SPI_MAX_PAYLOAD_SIZE;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        skb_queue_head_init(&cfspi->qhead);
        skb_queue_head_init(&cfspi->chead);
        cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
index 6122768c86444ec5b9c5fa67d7a63aa2690ba2f5..1794ea0420b794e76c75fafdede7e1a73ca86868 100644 (file)
@@ -617,7 +617,7 @@ static void cfv_netdev_setup(struct net_device *netdev)
        netdev->tx_queue_len = 100;
        netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
        netdev->mtu = CFV_DEF_MTU_SIZE;
-       netdev->destructor = free_netdev;
+       netdev->needs_free_netdev = true;
 }
 
 /* Create debugfs counters for the device */
index 611d16a7061de5cb45f5e7bf7903b45472657965..ae4ed03dc6420d2e8eb0c6c0267982ab6ca58780 100644 (file)
@@ -391,6 +391,9 @@ void can_change_state(struct net_device *dev, struct can_frame *cf,
        can_update_state_error_stats(dev, new_state);
        priv->state = new_state;
 
+       if (!cf)
+               return;
+
        if (unlikely(new_state == CAN_STATE_BUS_OFF)) {
                cf->can_id |= CAN_ERR_BUSOFF;
                return;
index 0d57be5ea97bafb2e9a119d28429549a91b80012..85268be0c913df5f5dc595405ade48efbd8add0a 100644 (file)
@@ -489,7 +489,7 @@ int peak_canfd_handle_msgs_list(struct peak_canfd_priv *priv,
                                struct pucan_rx_msg *msg_list, int msg_count)
 {
        void *msg_ptr = msg_list;
-       int i, msg_size;
+       int i, msg_size = 0;
 
        for (i = 0; i < msg_count; i++) {
                msg_size = peak_canfd_handle_msg(priv, msg_ptr);
index eb7173713bbcb0c339ae6ccbf99fc8014fb17133..6a6e896e52fa09415ae72715602fd4713e28f899 100644 (file)
@@ -417,7 +417,7 @@ static int slc_open(struct net_device *dev)
 static void slc_free_netdev(struct net_device *dev)
 {
        int i = dev->base_addr;
-       free_netdev(dev);
+
        slcan_devs[i] = NULL;
 }
 
@@ -436,7 +436,8 @@ static const struct net_device_ops slc_netdev_ops = {
 static void slc_setup(struct net_device *dev)
 {
        dev->netdev_ops         = &slc_netdev_ops;
-       dev->destructor         = slc_free_netdev;
+       dev->needs_free_netdev  = true;
+       dev->priv_destructor    = slc_free_netdev;
 
        dev->hard_header_len    = 0;
        dev->addr_len           = 0;
@@ -761,8 +762,6 @@ static void __exit slcan_exit(void)
                if (sl->tty) {
                        printk(KERN_ERR "%s: tty discipline still running\n",
                               dev->name);
-                       /* Intentionally leak the control block. */
-                       dev->destructor = NULL;
                }
 
                unregister_netdev(dev);
index eecee7f8dfb70763aa0e7c3f90f85ae66ff85385..afcc1312dbaf8f67bce640e17dbc20c06592dc45 100644 (file)
@@ -265,6 +265,8 @@ static int gs_cmd_reset(struct gs_usb *gsusb, struct gs_can *gsdev)
                             sizeof(*dm),
                             1000);
 
+       kfree(dm);
+
        return rc;
 }
 
index 57913dbbae0a970f5f28051d10f064792d69333c..1ca76e03e965ce0b1185c3220a86cb306d89e3e5 100644 (file)
@@ -908,8 +908,6 @@ static int peak_usb_probe(struct usb_interface *intf,
        const struct peak_usb_adapter *peak_usb_adapter = NULL;
        int i, err = -ENOMEM;
 
-       usb_dev = interface_to_usbdev(intf);
-
        /* get corresponding PCAN-USB adapter */
        for (i = 0; i < ARRAY_SIZE(peak_usb_adapters_list); i++)
                if (peak_usb_adapters_list[i]->device_id == usb_id_product) {
@@ -920,7 +918,7 @@ static int peak_usb_probe(struct usb_interface *intf,
        if (!peak_usb_adapter) {
                /* should never come except device_id bad usage in this file */
                pr_err("%s: didn't find device id. 0x%x in devices list\n",
-                       PCAN_USB_DRIVER_NAME, usb_dev->descriptor.idProduct);
+                       PCAN_USB_DRIVER_NAME, usb_id_product);
                return -ENODEV;
        }
 
index facca33d53e9fd24b996dc6dfd38c925b8128fdb..a8cb33264ff1ef32e9f9d44955e07f768f1cc543 100644 (file)
@@ -152,7 +152,7 @@ static const struct net_device_ops vcan_netdev_ops = {
 static void vcan_setup(struct net_device *dev)
 {
        dev->type               = ARPHRD_CAN;
-       dev->mtu                = CAN_MTU;
+       dev->mtu                = CANFD_MTU;
        dev->hard_header_len    = 0;
        dev->addr_len           = 0;
        dev->tx_queue_len       = 0;
@@ -163,7 +163,7 @@ static void vcan_setup(struct net_device *dev)
                dev->flags |= IFF_ECHO;
 
        dev->netdev_ops         = &vcan_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 }
 
 static struct rtnl_link_ops vcan_link_ops __read_mostly = {
index 7fbb2479568160b3b57fedb187429618937d2248..cfe889e8f1723823d5a3b9db71e9ba438624a9a2 100644 (file)
@@ -150,13 +150,13 @@ static const struct net_device_ops vxcan_netdev_ops = {
 static void vxcan_setup(struct net_device *dev)
 {
        dev->type               = ARPHRD_CAN;
-       dev->mtu                = CAN_MTU;
+       dev->mtu                = CANFD_MTU;
        dev->hard_header_len    = 0;
        dev->addr_len           = 0;
        dev->tx_queue_len       = 0;
        dev->flags              = (IFF_NOARP|IFF_ECHO);
        dev->netdev_ops         = &vxcan_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 }
 
 /* forward declaration for rtnl_create_link() */
index 149244aac20aa765551b93ca25d78018b28f17f9..9905b52fe293c221b1ae9852d72016191ebbadda 100644 (file)
@@ -328,7 +328,6 @@ static void dummy_free_netdev(struct net_device *dev)
        struct dummy_priv *priv = netdev_priv(dev);
 
        kfree(priv->vfinfo);
-       free_netdev(dev);
 }
 
 static void dummy_setup(struct net_device *dev)
@@ -338,7 +337,8 @@ static void dummy_setup(struct net_device *dev)
        /* Initialize the device structure. */
        dev->netdev_ops = &dummy_netdev_ops;
        dev->ethtool_ops = &dummy_ethtool_ops;
-       dev->destructor = dummy_free_netdev;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = dummy_free_netdev;
 
        /* Fill in device structure with ethernet-generic values. */
        dev->flags |= IFF_NOARP;
index 08d11cede9c972596ee683c5d255fe143b76b9b8..f5b237e0bd60e2f0e2e6fd5a95d78515285629b1 100644 (file)
@@ -61,6 +61,8 @@
 
 #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF
 
+#define ENA_REGS_ADMIN_INTR_MASK 1
+
 /*****************************************************************************/
 /*****************************************************************************/
 /*****************************************************************************/
@@ -232,11 +234,9 @@ static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queu
        tail_masked = admin_queue->sq.tail & queue_size_mask;
 
        /* In case of queue FULL */
-       cnt = admin_queue->sq.tail - admin_queue->sq.head;
+       cnt = atomic_read(&admin_queue->outstanding_cmds);
        if (cnt >= admin_queue->q_depth) {
-               pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n",
-                        admin_queue->sq.tail, admin_queue->sq.head,
-                        admin_queue->q_depth);
+               pr_debug("admin queue is full.\n");
                admin_queue->stats.out_of_space++;
                return ERR_PTR(-ENOSPC);
        }
@@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
 static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx,
                                                     struct ena_com_admin_queue *admin_queue)
 {
-       unsigned long flags;
-       u32 start_time;
+       unsigned long flags, timeout;
        int ret;
 
-       start_time = ((u32)jiffies_to_usecs(jiffies));
+       timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+
+       while (1) {
+               spin_lock_irqsave(&admin_queue->q_lock, flags);
+               ena_com_handle_admin_completion(admin_queue);
+               spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+
+               if (comp_ctx->status != ENA_CMD_SUBMITTED)
+                       break;
 
-       while (comp_ctx->status == ENA_CMD_SUBMITTED) {
-               if ((((u32)jiffies_to_usecs(jiffies)) - start_time) >
-                   ADMIN_CMD_TIMEOUT_US) {
+               if (time_is_before_jiffies(timeout)) {
                        pr_err("Wait for completion (polling) timeout\n");
                        /* ENA didn't have any completion */
                        spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -528,10 +533,6 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
                        goto err;
                }
 
-               spin_lock_irqsave(&admin_queue->q_lock, flags);
-               ena_com_handle_admin_completion(admin_queue);
-               spin_unlock_irqrestore(&admin_queue->q_lock, flags);
-
                msleep(100);
        }
 
@@ -1455,6 +1456,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev)
 
 void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)
 {
+       u32 mask_value = 0;
+
+       if (polling)
+               mask_value = ENA_REGS_ADMIN_INTR_MASK;
+
+       writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF);
        ena_dev->admin_queue.polling = polling;
 }
 
index 67b2338f8fb34100df983fc11727d4e661548b24..3ee55e2fd69465e12603890bce1b530be551a2d9 100644 (file)
@@ -80,7 +80,6 @@ static const struct ena_stats ena_stats_tx_strings[] = {
        ENA_STAT_TX_ENTRY(tx_poll),
        ENA_STAT_TX_ENTRY(doorbells),
        ENA_STAT_TX_ENTRY(prepare_ctx_err),
-       ENA_STAT_TX_ENTRY(missing_tx_comp),
        ENA_STAT_TX_ENTRY(bad_req_id),
 };
 
@@ -94,6 +93,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
        ENA_STAT_RX_ENTRY(dma_mapping_err),
        ENA_STAT_RX_ENTRY(bad_desc_num),
        ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+       ENA_STAT_RX_ENTRY(empty_rx_ring),
 };
 
 static const struct ena_stats ena_stats_ena_com_strings[] = {
index 7c1214d7885566ded4dfc05e85c2ee86b8d3c949..4f16ed38bcf3a267f84894177da1f89713a0eb3e 100644 (file)
@@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter)
                rxr->sgl_size = adapter->max_rx_sgl_size;
                rxr->smoothed_interval =
                        ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+               rxr->empty_rx_queue = 0;
        }
 }
 
@@ -1078,6 +1079,26 @@ inline void ena_adjust_intr_moderation(struct ena_ring *rx_ring,
        rx_ring->per_napi_bytes = 0;
 }
 
+static inline void ena_unmask_interrupt(struct ena_ring *tx_ring,
+                                       struct ena_ring *rx_ring)
+{
+       struct ena_eth_io_intr_reg intr_reg;
+
+       /* Update intr register: rx intr delay,
+        * tx intr delay and interrupt unmask
+        */
+       ena_com_update_intr_reg(&intr_reg,
+                               rx_ring->smoothed_interval,
+                               tx_ring->smoothed_interval,
+                               true);
+
+       /* It is a shared MSI-X.
+        * Tx and Rx CQ have pointer to it.
+        * So we use one of them to reach the intr reg
+        */
+       ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+}
+
 static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,
                                             struct ena_ring *rx_ring)
 {
@@ -1108,7 +1129,6 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
 {
        struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
        struct ena_ring *tx_ring, *rx_ring;
-       struct ena_eth_io_intr_reg intr_reg;
 
        u32 tx_work_done;
        u32 rx_work_done;
@@ -1149,22 +1169,9 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
                        if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
                                ena_adjust_intr_moderation(rx_ring, tx_ring);
 
-                       /* Update intr register: rx intr delay,
-                        * tx intr delay and interrupt unmask
-                        */
-                       ena_com_update_intr_reg(&intr_reg,
-                                               rx_ring->smoothed_interval,
-                                               tx_ring->smoothed_interval,
-                                               true);
-
-                       /* It is a shared MSI-X.
-                        * Tx and Rx CQ have pointer to it.
-                        * So we use one of them to reach the intr reg
-                        */
-                       ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+                       ena_unmask_interrupt(tx_ring, rx_ring);
                }
 
-
                ena_update_ring_numa_node(tx_ring, rx_ring);
 
                ret = rx_work_done;
@@ -1485,6 +1492,11 @@ static int ena_up_complete(struct ena_adapter *adapter)
 
        ena_napi_enable_all(adapter);
 
+       /* Enable completion queues interrupt */
+       for (i = 0; i < adapter->num_queues; i++)
+               ena_unmask_interrupt(&adapter->tx_ring[i],
+                                    &adapter->rx_ring[i]);
+
        /* schedule napi in case we had pending packets
         * from the last time we disable napi
         */
@@ -1532,6 +1544,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
                          "Failed to get TX queue handlers. TX queue num %d rc: %d\n",
                          qid, rc);
                ena_com_destroy_io_queue(ena_dev, ena_qid);
+               return rc;
        }
 
        ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node);
@@ -1596,6 +1609,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
                          "Failed to get RX queue handlers. RX queue num %d rc: %d\n",
                          qid, rc);
                ena_com_destroy_io_queue(ena_dev, ena_qid);
+               return rc;
        }
 
        ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node);
@@ -1981,6 +1995,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        tx_info->tx_descs = nb_hw_desc;
        tx_info->last_jiffies = jiffies;
+       tx_info->print_once = 0;
 
        tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
                tx_ring->ring_size);
@@ -2550,13 +2565,44 @@ err:
                "Reset attempt failed. Can not reset the device\n");
 }
 
-static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+static int check_missing_comp_in_queue(struct ena_adapter *adapter,
+                                      struct ena_ring *tx_ring)
 {
        struct ena_tx_buffer *tx_buf;
        unsigned long last_jiffies;
+       u32 missed_tx = 0;
+       int i;
+
+       for (i = 0; i < tx_ring->ring_size; i++) {
+               tx_buf = &tx_ring->tx_buffer_info[i];
+               last_jiffies = tx_buf->last_jiffies;
+               if (unlikely(last_jiffies &&
+                            time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
+                       if (!tx_buf->print_once)
+                               netif_notice(adapter, tx_err, adapter->netdev,
+                                            "Found a Tx that wasn't completed on time, qid %d, index %d.\n",
+                                            tx_ring->qid, i);
+
+                       tx_buf->print_once = 1;
+                       missed_tx++;
+
+                       if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) {
+                               netif_err(adapter, tx_err, adapter->netdev,
+                                         "The number of lost tx completions is above the threshold (%d > %d). Reset the device\n",
+                                         missed_tx, MAX_NUM_OF_TIMEOUTED_PACKETS);
+                               set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+                               return -EIO;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+{
        struct ena_ring *tx_ring;
-       int i, j, budget;
-       u32 missed_tx;
+       int i, budget, rc;
 
        /* Make sure the driver doesn't turn the device in other process */
        smp_rmb();
@@ -2572,31 +2618,9 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter)
        for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
                tx_ring = &adapter->tx_ring[i];
 
-               for (j = 0; j < tx_ring->ring_size; j++) {
-                       tx_buf = &tx_ring->tx_buffer_info[j];
-                       last_jiffies = tx_buf->last_jiffies;
-                       if (unlikely(last_jiffies && time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
-                               netif_notice(adapter, tx_err, adapter->netdev,
-                                            "Found a Tx that wasn't completed on time, qid %d, index %d.\n",
-                                            tx_ring->qid, j);
-
-                               u64_stats_update_begin(&tx_ring->syncp);
-                               missed_tx = tx_ring->tx_stats.missing_tx_comp++;
-                               u64_stats_update_end(&tx_ring->syncp);
-
-                               /* Clear last jiffies so the lost buffer won't
-                                * be counted twice.
-                                */
-                               tx_buf->last_jiffies = 0;
-
-                               if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) {
-                                       netif_err(adapter, tx_err, adapter->netdev,
-                                                 "The number of lost tx completion is above the threshold (%d > %d). Reset the device\n",
-                                                 missed_tx, MAX_NUM_OF_TIMEOUTED_PACKETS);
-                                       set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
-                               }
-                       }
-               }
+               rc = check_missing_comp_in_queue(adapter, tx_ring);
+               if (unlikely(rc))
+                       return;
 
                budget--;
                if (!budget)
@@ -2606,6 +2630,58 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter)
        adapter->last_monitored_tx_qid = i % adapter->num_queues;
 }
 
+/* trigger napi schedule after 2 consecutive detections */
+#define EMPTY_RX_REFILL 2
+/* For the rare case where the device runs out of Rx descriptors and the
+ * napi handler failed to refill new Rx descriptors (due to a lack of memory
+ * for example).
+ * This case will lead to a deadlock:
+ * The device won't send interrupts since all the new Rx packets will be dropped
+ * The napi handler won't allocate new Rx descriptors so the device will be
+ * able to send new packets.
+ *
+ * This scenario can happen when the kernel's vm.min_free_kbytes is too small.
+ * It is recommended to have at least 512MB, with a minimum of 128MB for
+ * constrained environment).
+ *
+ * When such a situation is detected - Reschedule napi
+ */
+static void check_for_empty_rx_ring(struct ena_adapter *adapter)
+{
+       struct ena_ring *rx_ring;
+       int i, refill_required;
+
+       if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+               return;
+
+       if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))
+               return;
+
+       for (i = 0; i < adapter->num_queues; i++) {
+               rx_ring = &adapter->rx_ring[i];
+
+               refill_required =
+                       ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
+               if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
+                       rx_ring->empty_rx_queue++;
+
+                       if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL) {
+                               u64_stats_update_begin(&rx_ring->syncp);
+                               rx_ring->rx_stats.empty_rx_ring++;
+                               u64_stats_update_end(&rx_ring->syncp);
+
+                               netif_err(adapter, drv, adapter->netdev,
+                                         "trigger refill for ring %d\n", i);
+
+                               napi_schedule(rx_ring->napi);
+                               rx_ring->empty_rx_queue = 0;
+                       }
+               } else {
+                       rx_ring->empty_rx_queue = 0;
+               }
+       }
+}
+
 /* Check for keep alive expiration */
 static void check_for_missing_keep_alive(struct ena_adapter *adapter)
 {
@@ -2660,6 +2736,8 @@ static void ena_timer_service(unsigned long data)
 
        check_for_missing_tx_completions(adapter);
 
+       check_for_empty_rx_ring(adapter);
+
        if (debug_area)
                ena_dump_stats_to_buf(adapter, debug_area);
 
@@ -2840,6 +2918,11 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
 {
        int release_bars;
 
+       if (ena_dev->mem_bar)
+               devm_iounmap(&pdev->dev, ena_dev->mem_bar);
+
+       devm_iounmap(&pdev->dev, ena_dev->reg_bar);
+
        release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
        pci_release_selected_regions(pdev, release_bars);
 }
@@ -2927,8 +3010,9 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_free_ena_dev;
        }
 
-       ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR),
-                                  pci_resource_len(pdev, ENA_REG_BAR));
+       ena_dev->reg_bar = devm_ioremap(&pdev->dev,
+                                       pci_resource_start(pdev, ENA_REG_BAR),
+                                       pci_resource_len(pdev, ENA_REG_BAR));
        if (!ena_dev->reg_bar) {
                dev_err(&pdev->dev, "failed to remap regs bar\n");
                rc = -EFAULT;
@@ -2948,8 +3032,9 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);
 
        if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
-               ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, ENA_MEM_BAR),
-                                             pci_resource_len(pdev, ENA_MEM_BAR));
+               ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
+                                                  pci_resource_start(pdev, ENA_MEM_BAR),
+                                                  pci_resource_len(pdev, ENA_MEM_BAR));
                if (!ena_dev->mem_bar) {
                        rc = -EFAULT;
                        goto err_device_destroy;
index 0e22bce6239d0e06c73a366e0d98a2348a9b7fa9..a4d3d5e2106885b093424dc2ae3856c002653d06 100644 (file)
@@ -45,7 +45,7 @@
 
 #define DRV_MODULE_VER_MAJOR   1
 #define DRV_MODULE_VER_MINOR   1
-#define DRV_MODULE_VER_SUBMINOR 2
+#define DRV_MODULE_VER_SUBMINOR 7
 
 #define DRV_MODULE_NAME                "ena"
 #ifndef DRV_MODULE_VERSION
@@ -146,7 +146,18 @@ struct ena_tx_buffer {
        u32 tx_descs;
        /* num of buffers used by this skb */
        u32 num_of_bufs;
-       /* Save the last jiffies to detect missing tx packets */
+
+       /* Used for detect missing tx packets to limit the number of prints */
+       u32 print_once;
+       /* Save the last jiffies to detect missing tx packets
+        *
+        * sets to non zero value on ena_start_xmit and set to zero on
+        * napi and timer_Service_routine.
+        *
+        * while this value is not protected by lock,
+        * a given packet is not expected to be handled by ena_start_xmit
+        * and by napi/timer_service at the same time.
+        */
        unsigned long last_jiffies;
        struct ena_com_buf bufs[ENA_PKT_MAX_BUFS];
 } ____cacheline_aligned;
@@ -170,7 +181,6 @@ struct ena_stats_tx {
        u64 napi_comp;
        u64 tx_poll;
        u64 doorbells;
-       u64 missing_tx_comp;
        u64 bad_req_id;
 };
 
@@ -184,6 +194,7 @@ struct ena_stats_rx {
        u64 dma_mapping_err;
        u64 bad_desc_num;
        u64 rx_copybreak_pkt;
+       u64 empty_rx_ring;
 };
 
 struct ena_ring {
@@ -231,6 +242,7 @@ struct ena_ring {
                struct ena_stats_tx tx_stats;
                struct ena_stats_rx rx_stats;
        };
+       int empty_rx_queue;
 } ____cacheline_aligned;
 
 struct ena_stats_dev {
index b8e3d88f08790a2e16ae3fc6b5edb8bedaaadf2f..a66aee51ab5b049c4e9f6367aebdd57cbbf5fc5a 100644 (file)
@@ -193,9 +193,6 @@ int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
                             struct aq_hw_caps_s *aq_hw_caps,
                             u32 *regs_buff);
 
-int hw_atl_utils_hw_get_settings(struct aq_hw_s *self,
-                                struct ethtool_cmd *cmd);
-
 int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
                              unsigned int power_state);
 
index 5f49334dcad5a8c8602cc3aa2e8795b2d489bb43..f619c4cac51f0f3a8a6631091c8e022de087a719 100644 (file)
@@ -3883,15 +3883,26 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                /* when transmitting in a vf, start bd must hold the ethertype
                 * for fw to enforce it
                 */
+               u16 vlan_tci = 0;
 #ifndef BNX2X_STOP_ON_ERROR
-               if (IS_VF(bp))
+               if (IS_VF(bp)) {
 #endif
-                       tx_start_bd->vlan_or_ethertype =
-                               cpu_to_le16(ntohs(eth->h_proto));
+                       /* Still need to consider inband vlan for enforced */
+                       if (__vlan_get_tag(skb, &vlan_tci)) {
+                               tx_start_bd->vlan_or_ethertype =
+                                       cpu_to_le16(ntohs(eth->h_proto));
+                       } else {
+                               tx_start_bd->bd_flags.as_bitfield |=
+                                       (X_ETH_INBAND_VLAN <<
+                                        ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
+                               tx_start_bd->vlan_or_ethertype =
+                                       cpu_to_le16(vlan_tci);
+                       }
 #ifndef BNX2X_STOP_ON_ERROR
-               else
+               } else {
                        /* used by FW for packet accounting */
                        tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
+               }
 #endif
        }
 
index bdfd53b46bc568286ac9debc70bb14563329040b..9ca994d0bab66eeec49c53275d5257350a5f4f8e 100644 (file)
@@ -901,6 +901,8 @@ static void bnx2x_vf_flr(struct bnx2x *bp, struct bnx2x_virtf *vf)
        /* release VF resources */
        bnx2x_vf_free_resc(bp, vf);
 
+       vf->malicious = false;
+
        /* re-open the mailbox */
        bnx2x_vf_enable_mbx(bp, vf->abs_vfid);
        return;
@@ -1822,9 +1824,11 @@ get_vf:
                   vf->abs_vfid, qidx);
                bnx2x_vf_handle_rss_update_eqe(bp, vf);
        case EVENT_RING_OPCODE_VF_FLR:
-       case EVENT_RING_OPCODE_MALICIOUS_VF:
                /* Do nothing for now */
                return 0;
+       case EVENT_RING_OPCODE_MALICIOUS_VF:
+               vf->malicious = true;
+               return 0;
        }
 
        return 0;
@@ -1905,6 +1909,13 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp)
                        continue;
                }
 
+               if (vf->malicious) {
+                       DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS),
+                              "vf %d malicious so no stats for it\n",
+                              vf->abs_vfid);
+                       continue;
+               }
+
                DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS),
                       "add addresses for vf %d\n", vf->abs_vfid);
                for_each_vfq(vf, j) {
@@ -3042,7 +3053,7 @@ void bnx2x_vf_pci_dealloc(struct bnx2x *bp)
 {
        BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,
                       sizeof(struct bnx2x_vf_mbx_msg));
-       BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping,
+       BNX2X_PCI_FREE(bp->pf2vf_bulletin, bp->pf2vf_bulletin_mapping,
                       sizeof(union pf_vf_bulletin));
 }
 
index 888d0b6632e86f2f7ab7e2f9e605be87fa4c7061..53466f6cebabc4cd3089a0b45fdaa74e8bd9d905 100644 (file)
@@ -141,6 +141,7 @@ struct bnx2x_virtf {
 #define VF_RESET       3       /* VF FLR'd, pending cleanup */
 
        bool flr_clnup_stage;   /* true during flr cleanup */
+       bool malicious;         /* true if FW indicated so, until FLR */
 
        /* dma */
        dma_addr_t fw_stat_map;
index 77ed2f628f9ca23854ae8b062ff919ce6d2e3425..53309f659951042ca6301c95e110910414031e70 100644 (file)
@@ -2171,9 +2171,10 @@ static int cxgb_up(struct adapter *adap)
 {
        int err;
 
+       mutex_lock(&uld_mutex);
        err = setup_sge_queues(adap);
        if (err)
-               goto out;
+               goto rel_lock;
        err = setup_rss(adap);
        if (err)
                goto freeq;
@@ -2197,7 +2198,6 @@ static int cxgb_up(struct adapter *adap)
                        goto irq_err;
        }
 
-       mutex_lock(&uld_mutex);
        enable_rx(adap);
        t4_sge_start(adap);
        t4_intr_enable(adap);
@@ -2210,13 +2210,15 @@ static int cxgb_up(struct adapter *adap)
 #endif
        /* Initialize hash mac addr list*/
        INIT_LIST_HEAD(&adap->mac_hlist);
- out:
        return err;
+
  irq_err:
        dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err);
  freeq:
        t4_free_sge_resources(adap);
-       goto out;
+ rel_lock:
+       mutex_unlock(&uld_mutex);
+       return err;
 }
 
 static void cxgb_down(struct adapter *adapter)
@@ -4525,7 +4527,7 @@ static void dummy_setup(struct net_device *dev)
        /* Initialize the device structure. */
        dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
        dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
 }
 
 static int config_mgmt_dev(struct pci_dev *pdev)
index 9a520e4f0df9a0d47b75f71f01557414ba3d4eab..290ad0563320d6bd9f59212d0cd70b765336441d 100644 (file)
@@ -2647,7 +2647,7 @@ static int dpaa_eth_probe(struct platform_device *pdev)
        priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */
 
        /* device used for DMA mapping */
-       arch_setup_dma_ops(dev, 0, 0, NULL, false);
+       set_dma_ops(dev, get_dma_ops(&pdev->dev));
        err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
        if (err) {
                dev_err(dev, "dma_coerce_mask_and_coherent() failed\n");
index 0b31f8502adae2e86c292fb99437ee943c0794bf..6e67d22fd0d54f69e5ee3358717e7ed539fad952 100644 (file)
@@ -623,6 +623,8 @@ static struct platform_device *dpaa_eth_add_device(int fman_id,
                goto no_mem;
        }
 
+       set_dma_ops(&pdev->dev, get_dma_ops(priv->dev));
+
        ret = platform_device_add_data(pdev, &data, sizeof(data));
        if (ret)
                goto err;
index b8fab149690f880394f0d973560aecca69d1171e..e95795b3c84160c6dd567c3a725d66f7886fe6fe 100644 (file)
@@ -288,9 +288,15 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
 
                /* Force 1000M Link, Default is 0x0200 */
                phy_write(phy_dev, 7, 0x20C);
-               phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
 
-               /* Enable PHY loop-back */
+               /* Powerup Fiber */
+               phy_write(phy_dev, HNS_PHY_PAGE_REG, 1);
+               val = phy_read(phy_dev, COPPER_CONTROL_REG);
+               val &= ~PHY_POWER_DOWN;
+               phy_write(phy_dev, COPPER_CONTROL_REG, val);
+
+               /* Enable Phy Loopback */
+               phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
                val = phy_read(phy_dev, COPPER_CONTROL_REG);
                val |= PHY_LOOP_BACK;
                val &= ~PHY_POWER_DOWN;
@@ -299,6 +305,12 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
                phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA);
                phy_write(phy_dev, 1, 0x400);
                phy_write(phy_dev, 7, 0x200);
+
+               phy_write(phy_dev, HNS_PHY_PAGE_REG, 1);
+               val = phy_read(phy_dev, COPPER_CONTROL_REG);
+               val |= PHY_POWER_DOWN;
+               phy_write(phy_dev, COPPER_CONTROL_REG, val);
+
                phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
                phy_write(phy_dev, 9, 0xF00);
 
index 508923f39ccfe0cbc39ed23305af46860eef32c9..259e69a52ec52acde37849b9858c9953029679af 100644 (file)
@@ -343,6 +343,7 @@ static int emac_reset(struct emac_instance *dev)
 {
        struct emac_regs __iomem *p = dev->emacp;
        int n = 20;
+       bool __maybe_unused try_internal_clock = false;
 
        DBG(dev, "reset" NL);
 
@@ -355,6 +356,7 @@ static int emac_reset(struct emac_instance *dev)
        }
 
 #ifdef CONFIG_PPC_DCR_NATIVE
+do_retry:
        /*
         * PPC460EX/GT Embedded Processor Advanced User's Manual
         * section 28.10.1 Mode Register 0 (EMACx_MR0) states:
@@ -362,10 +364,19 @@ static int emac_reset(struct emac_instance *dev)
         * of the EMAC. If none is present, select the internal clock
         * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
         * After a soft reset, select the external clock.
+        *
+        * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the
+        * ethernet cable is not attached. This causes the reset to timeout
+        * and the PHY detection code in emac_init_phy() is unable to
+        * communicate and detect the AR8035-A PHY. As a result, the emac
+        * driver bails out early and the user has no ethernet.
+        * In order to stay compatible with existing configurations, the
+        * driver will temporarily switch to the internal clock, after
+        * the first reset fails.
         */
        if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-               if (dev->phy_address == 0xffffffff &&
-                   dev->phy_map == 0xffffffff) {
+               if (try_internal_clock || (dev->phy_address == 0xffffffff &&
+                                          dev->phy_map == 0xffffffff)) {
                        /* No PHY: select internal loop clock before reset */
                        dcri_clrset(SDR0, SDR0_ETH_CFG,
                                    0, SDR0_ETH_CFG_ECS << dev->cell_index);
@@ -383,8 +394,15 @@ static int emac_reset(struct emac_instance *dev)
 
 #ifdef CONFIG_PPC_DCR_NATIVE
        if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-               if (dev->phy_address == 0xffffffff &&
-                   dev->phy_map == 0xffffffff) {
+               if (!n && !try_internal_clock) {
+                       /* first attempt has timed out. */
+                       n = 20;
+                       try_internal_clock = true;
+                       goto do_retry;
+               }
+
+               if (try_internal_clock || (dev->phy_address == 0xffffffff &&
+                                          dev->phy_map == 0xffffffff)) {
                        /* No PHY: restore external clock source after reset */
                        dcri_clrset(SDR0, SDR0_ETH_CFG,
                                    SDR0_ETH_CFG_ECS << dev->cell_index, 0);
@@ -2460,20 +2478,24 @@ static int emac_mii_bus_reset(struct mii_bus *bus)
        return emac_reset(dev);
 }
 
+static int emac_mdio_phy_start_aneg(struct mii_phy *phy,
+                                   struct phy_device *phy_dev)
+{
+       phy_dev->autoneg = phy->autoneg;
+       phy_dev->speed = phy->speed;
+       phy_dev->duplex = phy->duplex;
+       phy_dev->advertising = phy->advertising;
+       return phy_start_aneg(phy_dev);
+}
+
 static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
 {
        struct net_device *ndev = phy->dev;
        struct emac_instance *dev = netdev_priv(ndev);
 
-       dev->phy.autoneg = AUTONEG_ENABLE;
-       dev->phy.speed = SPEED_1000;
-       dev->phy.duplex = DUPLEX_FULL;
-       dev->phy.advertising = advertise;
        phy->autoneg = AUTONEG_ENABLE;
-       phy->speed = dev->phy.speed;
-       phy->duplex = dev->phy.duplex;
        phy->advertising = advertise;
-       return phy_start_aneg(dev->phy_dev);
+       return emac_mdio_phy_start_aneg(phy, dev->phy_dev);
 }
 
 static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
@@ -2481,13 +2503,10 @@ static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
        struct net_device *ndev = phy->dev;
        struct emac_instance *dev = netdev_priv(ndev);
 
-       dev->phy.autoneg =  AUTONEG_DISABLE;
-       dev->phy.speed = speed;
-       dev->phy.duplex = fd;
        phy->autoneg = AUTONEG_DISABLE;
        phy->speed = speed;
        phy->duplex = fd;
-       return phy_start_aneg(dev->phy_dev);
+       return emac_mdio_phy_start_aneg(phy, dev->phy_dev);
 }
 
 static int emac_mdio_poll_link(struct mii_phy *phy)
@@ -2509,16 +2528,17 @@ static int emac_mdio_read_link(struct mii_phy *phy)
 {
        struct net_device *ndev = phy->dev;
        struct emac_instance *dev = netdev_priv(ndev);
+       struct phy_device *phy_dev = dev->phy_dev;
        int res;
 
-       res = phy_read_status(dev->phy_dev);
+       res = phy_read_status(phy_dev);
        if (res)
                return res;
 
-       dev->phy.speed = phy->speed;
-       dev->phy.duplex = phy->duplex;
-       dev->phy.pause = phy->pause;
-       dev->phy.asym_pause = phy->asym_pause;
+       phy->speed = phy_dev->speed;
+       phy->duplex = phy_dev->duplex;
+       phy->pause = phy_dev->pause;
+       phy->asym_pause = phy_dev->asym_pause;
        return 0;
 }
 
@@ -2528,13 +2548,6 @@ static int emac_mdio_init_phy(struct mii_phy *phy)
        struct emac_instance *dev = netdev_priv(ndev);
 
        phy_start(dev->phy_dev);
-       dev->phy.autoneg = phy->autoneg;
-       dev->phy.speed = phy->speed;
-       dev->phy.duplex = phy->duplex;
-       dev->phy.advertising = phy->advertising;
-       dev->phy.pause = phy->pause;
-       dev->phy.asym_pause = phy->asym_pause;
-
        return phy_init_hw(dev->phy_dev);
 }
 
index a93757c255f77445e2245ee8b065d2c6ee31cf3f..c0fbeb387db46627bed908e8f4cb145ed0bcfe4b 100644 (file)
@@ -1468,6 +1468,11 @@ static void ibmvnic_netpoll_controller(struct net_device *dev)
 }
 #endif
 
+static int ibmvnic_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       return -EOPNOTSUPP;
+}
+
 static const struct net_device_ops ibmvnic_netdev_ops = {
        .ndo_open               = ibmvnic_open,
        .ndo_stop               = ibmvnic_close,
@@ -1479,6 +1484,7 @@ static const struct net_device_ops ibmvnic_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = ibmvnic_netpoll_controller,
 #endif
+       .ndo_change_mtu         = ibmvnic_change_mtu,
 };
 
 /* ethtool functions */
index cdde3cc28fb59f16234fe5aaf501f569abb62dc4..44d9610f7a15d739c3b8b9312cd81bd9a8dc0ed0 100644 (file)
@@ -399,6 +399,7 @@ struct i40e_pf {
 #define I40E_FLAG_RX_CSUM_ENABLED              BIT_ULL(1)
 #define I40E_FLAG_MSI_ENABLED                  BIT_ULL(2)
 #define I40E_FLAG_MSIX_ENABLED                 BIT_ULL(3)
+#define I40E_FLAG_HW_ATR_EVICT_ENABLED         BIT_ULL(4)
 #define I40E_FLAG_RSS_ENABLED                  BIT_ULL(6)
 #define I40E_FLAG_VMDQ_ENABLED                 BIT_ULL(7)
 #define I40E_FLAG_IWARP_ENABLED                        BIT_ULL(10)
index 7a8eb486b9ea554421fc7f62929a973b9c6efad4..894c8e57ba004398c5a86981930504ace9027a29 100644 (file)
@@ -224,7 +224,7 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
        I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENABLED, 0),
        I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),
        I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0),
-       I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_CAPABLE, 0),
+       I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_ENABLED, 0),
        I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0),
 };
 
@@ -4092,7 +4092,7 @@ flags_complete:
 
        /* Only allow ATR evict on hardware that is capable of handling it */
        if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
-               pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE;
+               pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_ENABLED;
 
        if (changed_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT) {
                u16 sw_flags = 0, valid_flags = 0;
index 150caf6ca2b4bb1da5e0ea63f37fd086c058efad..a7a4b28b4144c62c35982dba952f7e77a5809f2e 100644 (file)
@@ -8821,11 +8821,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
                    (pf->hw.aq.api_min_ver > 4))) {
                /* Supported in FW API version higher than 1.4 */
                pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
-               pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
-       } else {
-               pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
        }
 
+       /* Enable HW ATR eviction if possible */
+       if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
+               pf->flags |= I40E_FLAG_HW_ATR_EVICT_ENABLED;
+
        pf->eeprom_version = 0xDEAD;
        pf->lan_veb = I40E_NO_VEB;
        pf->lan_vsi = I40E_NO_VSI;
index cd894f4023b1b68cc4e202ff7064e63e2f8be031..77115c25d96fa88e8348bd0e891d03ca964b4d12 100644 (file)
@@ -2341,7 +2341,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
        /* Due to lack of space, no more new filters can be programmed */
        if (th->syn && (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED))
                return;
-       if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) {
+       if (pf->flags & I40E_FLAG_HW_ATR_EVICT_ENABLED) {
                /* HW ATR eviction will take care of removing filters on FIN
                 * and RST packets.
                 */
@@ -2403,7 +2403,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
                        I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) &
                        I40E_TXD_FLTR_QW1_CNTINDEX_MASK;
 
-       if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
+       if (pf->flags & I40E_FLAG_HW_ATR_EVICT_ENABLED)
                dtype_cmd |= I40E_TXD_FLTR_QW1_ATR_MASK;
 
        fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype);
index 95c23fbaa2113214d9cd34ddfa176a7d1cd8d89e..0fb38ca78900312c59a6cd0f0373dc6cd87ecf84 100644 (file)
@@ -3017,10 +3017,12 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
                                           VLAN_VID_MASK));
        }
 
+       spin_unlock_bh(&vsi->mac_filter_hash_lock);
        if (vlan_id || qos)
                ret = i40e_vsi_add_pvid(vsi, vlanprio);
        else
                i40e_vsi_remove_pvid(vsi);
+       spin_lock_bh(&vsi->mac_filter_hash_lock);
 
        if (vlan_id) {
                dev_info(&pf->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n",
index 9b875d776b296d165c4ae3a994bd527a8dafb698..33c901622ed5b94aef2a0335aa4576962072d34c 100644 (file)
@@ -3719,7 +3719,7 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,
                                    dma_addr_t *dma_addr,
                                    phys_addr_t *phys_addr)
 {
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
 
        *dma_addr = mvpp2_percpu_read(priv, cpu,
                                      MVPP2_BM_PHY_ALLOC_REG(bm_pool->id));
@@ -3740,6 +3740,8 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,
                if (sizeof(phys_addr_t) == 8)
                        *phys_addr |= (u64)phys_addr_highbits << 32;
        }
+
+       put_cpu();
 }
 
 /* Free all buffers from the pool */
@@ -3920,18 +3922,12 @@ static inline u32 mvpp2_bm_cookie_pool_set(u32 cookie, int pool)
        return bm;
 }
 
-/* Get pool number from a BM cookie */
-static inline int mvpp2_bm_cookie_pool_get(unsigned long cookie)
-{
-       return (cookie >> MVPP2_BM_COOKIE_POOL_OFFS) & 0xFF;
-}
-
 /* Release buffer to BM */
 static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
                                     dma_addr_t buf_dma_addr,
                                     phys_addr_t buf_phys_addr)
 {
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
 
        if (port->priv->hw_version == MVPP22) {
                u32 val = 0;
@@ -3958,15 +3954,15 @@ static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
                           MVPP2_BM_VIRT_RLS_REG, buf_phys_addr);
        mvpp2_percpu_write(port->priv, cpu,
                           MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr);
+
+       put_cpu();
 }
 
 /* Refill BM pool */
-static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm,
+static void mvpp2_pool_refill(struct mvpp2_port *port, int pool,
                              dma_addr_t dma_addr,
                              phys_addr_t phys_addr)
 {
-       int pool = mvpp2_bm_cookie_pool_get(bm);
-
        mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
 }
 
@@ -4186,8 +4182,6 @@ static void mvpp22_port_mii_set(struct mvpp2_port *port)
 {
        u32 val;
 
-       return;
-
        /* Only GOP port 0 has an XLG MAC */
        if (port->gop_id == 0) {
                val = readl(port->base + MVPP22_XLG_CTRL3_REG);
@@ -4515,21 +4509,6 @@ static void mvpp2_rxq_offset_set(struct mvpp2_port *port,
        mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
 }
 
-/* Obtain BM cookie information from descriptor */
-static u32 mvpp2_bm_cookie_build(struct mvpp2_port *port,
-                                struct mvpp2_rx_desc *rx_desc)
-{
-       int cpu = smp_processor_id();
-       int pool;
-
-       pool = (mvpp2_rxdesc_status_get(port, rx_desc) &
-               MVPP2_RXD_BM_POOL_ID_MASK) >>
-               MVPP2_RXD_BM_POOL_ID_OFFS;
-
-       return ((pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS) |
-              ((cpu & 0xFF) << MVPP2_BM_COOKIE_CPU_OFFS);
-}
-
 /* Tx descriptors helper methods */
 
 /* Get pointer to next Tx descriptor to be processed (send) by HW */
@@ -4757,7 +4736,7 @@ static void mvpp2_txp_max_tx_size_set(struct mvpp2_port *port)
 static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,
                                   struct mvpp2_rx_queue *rxq)
 {
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
 
        if (rxq->pkts_coal > MVPP2_OCCUPIED_THRESH_MASK)
                rxq->pkts_coal = MVPP2_OCCUPIED_THRESH_MASK;
@@ -4765,6 +4744,8 @@ static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_THRESH_REG,
                           rxq->pkts_coal);
+
+       put_cpu();
 }
 
 static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz)
@@ -4945,7 +4926,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
        mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
 
        /* Set Rx descriptors queue starting address - indirect access */
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id);
        if (port->priv->hw_version == MVPP21)
                rxq_dma = rxq->descs_dma;
@@ -4954,6 +4935,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_ADDR_REG, rxq_dma);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_SIZE_REG, rxq->size);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_INDEX_REG, 0);
+       put_cpu();
 
        /* Set Offset */
        mvpp2_rxq_offset_set(port, rxq->id, NET_SKB_PAD);
@@ -4980,9 +4962,13 @@ static void mvpp2_rxq_drop_pkts(struct mvpp2_port *port,
 
        for (i = 0; i < rx_received; i++) {
                struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
-               u32 bm = mvpp2_bm_cookie_build(port, rx_desc);
+               u32 status = mvpp2_rxdesc_status_get(port, rx_desc);
+               int pool;
+
+               pool = (status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+                       MVPP2_RXD_BM_POOL_ID_OFFS;
 
-               mvpp2_pool_refill(port, bm,
+               mvpp2_pool_refill(port, pool,
                                  mvpp2_rxdesc_dma_addr_get(port, rx_desc),
                                  mvpp2_rxdesc_cookie_get(port, rx_desc));
        }
@@ -5012,10 +4998,11 @@ static void mvpp2_rxq_deinit(struct mvpp2_port *port,
         * free descriptor number
         */
        mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_ADDR_REG, 0);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_SIZE_REG, 0);
+       put_cpu();
 }
 
 /* Create and initialize a Tx queue */
@@ -5038,7 +5025,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
        txq->last_desc = txq->size - 1;
 
        /* Set Tx descriptors queue starting address - indirect access */
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_ADDR_REG,
                           txq->descs_dma);
@@ -5063,6 +5050,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG,
                           MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 |
                           MVPP2_PREF_BUF_THRESH(desc_per_txq / 2));
+       put_cpu();
 
        /* WRR / EJP configuration - indirect access */
        tx_port_num = mvpp2_egress_port(port);
@@ -5133,10 +5121,11 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port,
        mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0);
 
        /* Set Tx descriptors queue starting address and size */
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_ADDR_REG, 0);
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_SIZE_REG, 0);
+       put_cpu();
 }
 
 /* Cleanup Tx ports */
@@ -5146,7 +5135,7 @@ static void mvpp2_txq_clean(struct mvpp2_port *port, struct mvpp2_tx_queue *txq)
        int delay, pending, cpu;
        u32 val;
 
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id);
        val = mvpp2_percpu_read(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG);
        val |= MVPP2_TXQ_DRAIN_EN_MASK;
@@ -5173,6 +5162,7 @@ static void mvpp2_txq_clean(struct mvpp2_port *port, struct mvpp2_tx_queue *txq)
 
        val &= ~MVPP2_TXQ_DRAIN_EN_MASK;
        mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG, val);
+       put_cpu();
 
        for_each_present_cpu(cpu) {
                txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
@@ -5420,7 +5410,7 @@ static void mvpp2_rx_csum(struct mvpp2_port *port, u32 status,
 
 /* Reuse skb if possible, or allocate a new skb and add it to BM pool */
 static int mvpp2_rx_refill(struct mvpp2_port *port,
-                          struct mvpp2_bm_pool *bm_pool, u32 bm)
+                          struct mvpp2_bm_pool *bm_pool, int pool)
 {
        dma_addr_t dma_addr;
        phys_addr_t phys_addr;
@@ -5432,7 +5422,7 @@ static int mvpp2_rx_refill(struct mvpp2_port *port,
        if (!buf)
                return -ENOMEM;
 
-       mvpp2_pool_refill(port, bm, dma_addr, phys_addr);
+       mvpp2_pool_refill(port, pool, dma_addr, phys_addr);
 
        return 0;
 }
@@ -5490,7 +5480,7 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
                unsigned int frag_size;
                dma_addr_t dma_addr;
                phys_addr_t phys_addr;
-               u32 bm, rx_status;
+               u32 rx_status;
                int pool, rx_bytes, err;
                void *data;
 
@@ -5502,8 +5492,8 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
                phys_addr = mvpp2_rxdesc_cookie_get(port, rx_desc);
                data = (void *)phys_to_virt(phys_addr);
 
-               bm = mvpp2_bm_cookie_build(port, rx_desc);
-               pool = mvpp2_bm_cookie_pool_get(bm);
+               pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+                       MVPP2_RXD_BM_POOL_ID_OFFS;
                bm_pool = &port->priv->bm_pools[pool];
 
                /* In case of an error, release the requested buffer pointer
@@ -5516,7 +5506,7 @@ err_drop_frame:
                        dev->stats.rx_errors++;
                        mvpp2_rx_error(port, rx_desc);
                        /* Return the buffer to the pool */
-                       mvpp2_pool_refill(port, bm, dma_addr, phys_addr);
+                       mvpp2_pool_refill(port, pool, dma_addr, phys_addr);
                        continue;
                }
 
@@ -5531,7 +5521,7 @@ err_drop_frame:
                        goto err_drop_frame;
                }
 
-               err = mvpp2_rx_refill(port, bm_pool, bm);
+               err = mvpp2_rx_refill(port, bm_pool, pool);
                if (err) {
                        netdev_err(port->dev, "failed to refill BM pools\n");
                        goto err_drop_frame;
index 2fd044b238750fedc61384fda55bf25206d25b51..944fc17424642189d82b5540aaa3751e7ea2c9e2 100644 (file)
@@ -458,13 +458,15 @@ struct mlx5e_mpw_info {
 
 struct mlx5e_rx_am_stats {
        int ppms; /* packets per msec */
+       int bpms; /* bytes per msec */
        int epms; /* events per msec */
 };
 
 struct mlx5e_rx_am_sample {
-       ktime_t         time;
-       unsigned int    pkt_ctr;
-       u16             event_ctr;
+       ktime_t time;
+       u32     pkt_ctr;
+       u32     byte_ctr;
+       u16     event_ctr;
 };
 
 struct mlx5e_rx_am { /* Adaptive Moderation */
index 8209affa75c3e5e0419634740d6985970f61fa67..16486dff14933807d47b2a99f970ffbe3996b3a2 100644 (file)
@@ -1242,11 +1242,11 @@ static int mlx5e_get_ts_info(struct net_device *dev,
                                 SOF_TIMESTAMPING_RX_HARDWARE |
                                 SOF_TIMESTAMPING_RAW_HARDWARE;
 
-       info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) |
-                        (BIT(1) << HWTSTAMP_TX_ON);
+       info->tx_types = BIT(HWTSTAMP_TX_OFF) |
+                        BIT(HWTSTAMP_TX_ON);
 
-       info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) |
-                          (BIT(1) << HWTSTAMP_FILTER_ALL);
+       info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+                          BIT(HWTSTAMP_FILTER_ALL);
 
        return 0;
 }
index 41cd22a223dccbd9dae460331525a1fc2414be9e..277f4de303751d6328a6bcf3282f28e6d5565e5d 100644 (file)
@@ -4241,7 +4241,8 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
        return netdev;
 
 err_cleanup_nic:
-       profile->cleanup(priv);
+       if (profile->cleanup)
+               profile->cleanup(priv);
        free_netdev(netdev);
 
        return NULL;
index 79462c0368a0781ca7a38354726ed628097c0c89..46984a52a94bb7fad172704b177bdf1c81ef27b8 100644 (file)
@@ -791,6 +791,8 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
        params->tx_max_inline         = mlx5e_get_max_inline_cap(mdev);
        params->num_tc                = 1;
        params->lro_wqe_sz            = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
+
+       mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
 }
 
 static void mlx5e_build_rep_netdev(struct net_device *netdev)
index 02dd3a95ed8f013d0d4795d5054bd79ae4ca1201..acf32fe952cdef6f994e2937433ac4b1b7962e84 100644 (file)
@@ -183,28 +183,27 @@ static void mlx5e_am_exit_parking(struct mlx5e_rx_am *am)
        mlx5e_am_step(am);
 }
 
+#define IS_SIGNIFICANT_DIFF(val, ref) \
+       (((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
+
 static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,
                                  struct mlx5e_rx_am_stats *prev)
 {
-       int diff;
-
-       if (!prev->ppms)
-               return curr->ppms ? MLX5E_AM_STATS_BETTER :
+       if (!prev->bpms)
+               return curr->bpms ? MLX5E_AM_STATS_BETTER :
                                    MLX5E_AM_STATS_SAME;
 
-       diff = curr->ppms - prev->ppms;
-       if (((100 * abs(diff)) / prev->ppms) > 10) /* more than 10% diff */
-               return (diff > 0) ? MLX5E_AM_STATS_BETTER :
-                                   MLX5E_AM_STATS_WORSE;
+       if (IS_SIGNIFICANT_DIFF(curr->bpms, prev->bpms))
+               return (curr->bpms > prev->bpms) ? MLX5E_AM_STATS_BETTER :
+                                                  MLX5E_AM_STATS_WORSE;
 
-       if (!prev->epms)
-               return curr->epms ? MLX5E_AM_STATS_WORSE :
-                                   MLX5E_AM_STATS_SAME;
+       if (IS_SIGNIFICANT_DIFF(curr->ppms, prev->ppms))
+               return (curr->ppms > prev->ppms) ? MLX5E_AM_STATS_BETTER :
+                                                  MLX5E_AM_STATS_WORSE;
 
-       diff = curr->epms - prev->epms;
-       if (((100 * abs(diff)) / prev->epms) > 10) /* more than 10% diff */
-               return (diff < 0) ? MLX5E_AM_STATS_BETTER :
-                                   MLX5E_AM_STATS_WORSE;
+       if (IS_SIGNIFICANT_DIFF(curr->epms, prev->epms))
+               return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER :
+                                                  MLX5E_AM_STATS_WORSE;
 
        return MLX5E_AM_STATS_SAME;
 }
@@ -266,10 +265,13 @@ static void mlx5e_am_sample(struct mlx5e_rq *rq,
 {
        s->time      = ktime_get();
        s->pkt_ctr   = rq->stats.packets;
+       s->byte_ctr  = rq->stats.bytes;
        s->event_ctr = rq->cq.event_ctr;
 }
 
 #define MLX5E_AM_NEVENTS 64
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
 
 static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
                                struct mlx5e_rx_am_sample *end,
@@ -277,13 +279,17 @@ static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
 {
        /* u32 holds up to 71 minutes, should be enough */
        u32 delta_us = ktime_us_delta(end->time, start->time);
-       unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
+       u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
+       u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
+                            start->byte_ctr);
 
        if (!delta_us)
                return;
 
-       curr_stats->ppms =            (npkts * USEC_PER_MSEC) / delta_us;
-       curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us;
+       curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
+       curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
+       curr_stats->epms = DIV_ROUND_UP(MLX5E_AM_NEVENTS * USEC_PER_MSEC,
+                                       delta_us);
 }
 
 void mlx5e_rx_am_work(struct work_struct *work)
@@ -308,7 +314,8 @@ void mlx5e_rx_am(struct mlx5e_rq *rq)
 
        switch (am->state) {
        case MLX5E_AM_MEASURE_IN_PROGRESS:
-               nevents = rq->cq.event_ctr - am->start_sample.event_ctr;
+               nevents = BIT_GAP(BITS_PER_TYPE(u16), rq->cq.event_ctr,
+                                 am->start_sample.event_ctr);
                if (nevents < MLX5E_AM_NEVENTS)
                        break;
                mlx5e_am_sample(rq, &end_sample);
index 53e4992d6511f578c5bb31e993afb0986789a979..f81c3aa60b469bef9223fd4313b9d136803ff2b1 100644 (file)
@@ -417,20 +417,13 @@ struct mlx5e_stats {
 };
 
 static const struct counter_desc mlx5e_pme_status_desc[] = {
-       { "module_plug", 0 },
        { "module_unplug", 8 },
 };
 
 static const struct counter_desc mlx5e_pme_error_desc[] = {
-       { "module_pwr_budget_exd", 0 },  /* power budget exceed */
-       { "module_long_range", 8 },      /* long range for non MLNX cable */
-       { "module_bus_stuck", 16 },      /* bus stuck (I2C or data shorted) */
-       { "module_no_eeprom", 24 },      /* no eeprom/retry time out */
-       { "module_enforce_part", 32 },   /* enforce part number list */
-       { "module_unknown_id", 40 },     /* unknown identifier */
-       { "module_high_temp", 48 },      /* high temperature */
+       { "module_bus_stuck", 16 },       /* bus stuck (I2C or data shorted) */
+       { "module_high_temp", 48 },       /* high temperature */
        { "module_bad_shorted", 56 },    /* bad or shorted cable/module */
-       { "module_unknown_status", 64 },
 };
 
 #endif /* __MLX5_EN_STATS_H__ */
index ec63158ab64330c939ffa4ca8c001f8134f8e4e2..9df9fc0d26f5b89457b1406198fa5c51d50536b3 100644 (file)
@@ -895,7 +895,6 @@ static struct mlx5_fields fields[] = {
        {MLX5_ACTION_IN_FIELD_OUT_SMAC_15_0,  2, offsetof(struct pedit_headers, eth.h_source[4])},
        {MLX5_ACTION_IN_FIELD_OUT_ETHERTYPE,  2, offsetof(struct pedit_headers, eth.h_proto)},
 
-       {MLX5_ACTION_IN_FIELD_OUT_IP_DSCP, 1, offsetof(struct pedit_headers, ip4.tos)},
        {MLX5_ACTION_IN_FIELD_OUT_IP_TTL,  1, offsetof(struct pedit_headers, ip4.ttl)},
        {MLX5_ACTION_IN_FIELD_OUT_SIPV4,   4, offsetof(struct pedit_headers, ip4.saddr)},
        {MLX5_ACTION_IN_FIELD_OUT_DIPV4,   4, offsetof(struct pedit_headers, ip4.daddr)},
index f991f669047e5df2531f043c3934d248bf3099b8..a53e982a68634b5129324fb5af58776804fc5853 100644 (file)
@@ -906,21 +906,34 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode)
        return 0;
 }
 
-int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode)
+static int mlx5_devlink_eswitch_check(struct devlink *devlink)
 {
-       struct mlx5_core_dev *dev;
-       u16 cur_mlx5_mode, mlx5_mode = 0;
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
 
-       dev = devlink_priv(devlink);
+       if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+               return -EOPNOTSUPP;
 
        if (!MLX5_CAP_GEN(dev, vport_group_manager))
                return -EOPNOTSUPP;
 
-       cur_mlx5_mode = dev->priv.eswitch->mode;
-
-       if (cur_mlx5_mode == SRIOV_NONE)
+       if (dev->priv.eswitch->mode == SRIOV_NONE)
                return -EOPNOTSUPP;
 
+       return 0;
+}
+
+int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode)
+{
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
+       u16 cur_mlx5_mode, mlx5_mode = 0;
+       int err;
+
+       err = mlx5_devlink_eswitch_check(devlink);
+       if (err)
+               return err;
+
+       cur_mlx5_mode = dev->priv.eswitch->mode;
+
        if (esw_mode_from_devlink(mode, &mlx5_mode))
                return -EINVAL;
 
@@ -937,15 +950,12 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode)
 
 int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
 {
-       struct mlx5_core_dev *dev;
-
-       dev = devlink_priv(devlink);
-
-       if (!MLX5_CAP_GEN(dev, vport_group_manager))
-               return -EOPNOTSUPP;
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
+       int err;
 
-       if (dev->priv.eswitch->mode == SRIOV_NONE)
-               return -EOPNOTSUPP;
+       err = mlx5_devlink_eswitch_check(devlink);
+       if (err)
+               return err;
 
        return esw_mode_to_devlink(dev->priv.eswitch->mode, mode);
 }
@@ -954,15 +964,12 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode)
 {
        struct mlx5_core_dev *dev = devlink_priv(devlink);
        struct mlx5_eswitch *esw = dev->priv.eswitch;
-       int num_vports = esw->enabled_vports;
        int err, vport;
        u8 mlx5_mode;
 
-       if (!MLX5_CAP_GEN(dev, vport_group_manager))
-               return -EOPNOTSUPP;
-
-       if (esw->mode == SRIOV_NONE)
-               return -EOPNOTSUPP;
+       err = mlx5_devlink_eswitch_check(devlink);
+       if (err)
+               return err;
 
        switch (MLX5_CAP_ETH(dev, wqe_inline_mode)) {
        case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
@@ -985,7 +992,7 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode)
        if (err)
                goto out;
 
-       for (vport = 1; vport < num_vports; vport++) {
+       for (vport = 1; vport < esw->enabled_vports; vport++) {
                err = mlx5_modify_nic_vport_min_inline(dev, vport, mlx5_mode);
                if (err) {
                        esw_warn(dev, "Failed to set min inline on vport %d\n",
@@ -1010,12 +1017,11 @@ int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode)
 {
        struct mlx5_core_dev *dev = devlink_priv(devlink);
        struct mlx5_eswitch *esw = dev->priv.eswitch;
+       int err;
 
-       if (!MLX5_CAP_GEN(dev, vport_group_manager))
-               return -EOPNOTSUPP;
-
-       if (esw->mode == SRIOV_NONE)
-               return -EOPNOTSUPP;
+       err = mlx5_devlink_eswitch_check(devlink);
+       if (err)
+               return err;
 
        return esw_inline_mode_to_devlink(esw->offloads.inline_mode, mode);
 }
@@ -1062,11 +1068,9 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap)
        struct mlx5_eswitch *esw = dev->priv.eswitch;
        int err;
 
-       if (!MLX5_CAP_GEN(dev, vport_group_manager))
-               return -EOPNOTSUPP;
-
-       if (esw->mode == SRIOV_NONE)
-               return -EOPNOTSUPP;
+       err = mlx5_devlink_eswitch_check(devlink);
+       if (err)
+               return err;
 
        if (encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE &&
            (!MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) ||
@@ -1105,12 +1109,11 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap)
 {
        struct mlx5_core_dev *dev = devlink_priv(devlink);
        struct mlx5_eswitch *esw = dev->priv.eswitch;
+       int err;
 
-       if (!MLX5_CAP_GEN(dev, vport_group_manager))
-               return -EOPNOTSUPP;
-
-       if (esw->mode == SRIOV_NONE)
-               return -EOPNOTSUPP;
+       err = mlx5_devlink_eswitch_check(devlink);
+       if (err)
+               return err;
 
        *encap = esw->offloads.encap;
        return 0;
index 0e487e8ca634bce0108979823e755918fe27c3fb..8f5125ccd8d4f430a2c0e5d60273e7002ca527bd 100644 (file)
@@ -862,7 +862,7 @@ struct mlx5_flow_table *mlx5_create_vport_flow_table(struct mlx5_flow_namespace
        ft_attr.level   = level;
        ft_attr.prio    = prio;
 
-       return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_NORMAL, 0);
+       return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_NORMAL, vport);
 }
 
 struct mlx5_flow_table*
index 44f59b1d6f0f27f7bb4f818b11f341af28ba09dc..f27f84ffbc850487557ad0184960d7c872abb160 100644 (file)
@@ -275,10 +275,8 @@ static void poll_health(unsigned long data)
        struct mlx5_core_health *health = &dev->priv.health;
        u32 count;
 
-       if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
-               mod_timer(&health->timer, get_next_poll_jiffies());
-               return;
-       }
+       if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
+               goto out;
 
        count = ioread32be(health->health_counter);
        if (count == health->prev)
@@ -290,8 +288,6 @@ static void poll_health(unsigned long data)
        if (health->miss_counter == MAX_MISSES) {
                dev_err(&dev->pdev->dev, "device's health compromised - reached miss count\n");
                print_health_info(dev);
-       } else {
-               mod_timer(&health->timer, get_next_poll_jiffies());
        }
 
        if (in_fatal(dev) && !health->sick) {
@@ -305,6 +301,9 @@ static void poll_health(unsigned long data)
                                "new health works are not permitted at this stage\n");
                spin_unlock(&health->wq_lock);
        }
+
+out:
+       mod_timer(&health->timer, get_next_poll_jiffies());
 }
 
 void mlx5_start_health_poll(struct mlx5_core_dev *dev)
index af945edfee1905dbe676218cb53123535a37171f..13be264587f135737887688005ed7ba872b54157 100644 (file)
@@ -175,8 +175,9 @@ static struct mlx5_profile profile[] = {
        },
 };
 
-#define FW_INIT_TIMEOUT_MILI   2000
-#define FW_INIT_WAIT_MS                2
+#define FW_INIT_TIMEOUT_MILI           2000
+#define FW_INIT_WAIT_MS                        2
+#define FW_PRE_INIT_TIMEOUT_MILI       10000
 
 static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili)
 {
@@ -537,8 +538,10 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
        /* disable cmdif checksum */
        MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
 
-       /* If the HCA supports 4K UARs use it */
-       if (MLX5_CAP_GEN_MAX(dev, uar_4k))
+       /* Enable 4K UAR only when HCA supports it and page size is bigger
+        * than 4K.
+        */
+       if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096)
                MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);
 
        MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
@@ -1011,6 +1014,15 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
         */
        dev->state = MLX5_DEVICE_STATE_UP;
 
+       /* wait for firmware to accept initialization segments configurations
+        */
+       err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI);
+       if (err) {
+               dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n",
+                       FW_PRE_INIT_TIMEOUT_MILI);
+               goto out;
+       }
+
        err = mlx5_cmd_init(dev);
        if (err) {
                dev_err(&pdev->dev, "Failed initializing command interface, aborting\n");
index 483241b4b05db2add64ff928ccc9419fe733355a..a672f6a860dc4e7a49b2175283d2720c610d4453 100644 (file)
@@ -2956,7 +2956,7 @@ static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
                                qed_wr(p_hwfn,
                                       p_ptt,
                                       s_storm_defs[storm_id].cm_ctx_wr_addr,
-                                      BIT(9) | lid);
+                                      (i << 9) | lid);
                                *(dump_buf + offset) = qed_rd(p_hwfn,
                                                              p_ptt,
                                                              rd_reg_addr);
index b7e4345c990d55454f52cbcb9c7c4d5df66ef176..019cef1d3cf72ce2d34b3a36283cabf9227c9879 100644 (file)
@@ -661,8 +661,6 @@ restore_filters:
                up_write(&vf->efx->filter_sem);
                mutex_unlock(&vf->efx->mac_lock);
 
-               up_write(&vf->efx->filter_sem);
-
                rc2 = efx_net_open(vf->efx->net_dev);
                if (rc2)
                        goto reset_nic;
index aa6476439aee7f4c65784af4a451a8ffe5173561..e0ef02f9503bae027268b1b058f9875b6c1365a7 100644 (file)
@@ -214,13 +214,13 @@ static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p)
 {
        /* Context type from W/B descriptor must be zero */
        if (le32_to_cpu(p->des3) & TDES3_CONTEXT_TYPE)
-               return -EINVAL;
+               return 0;
 
        /* Tx Timestamp Status is 1 so des0 and des1'll have valid values */
        if (le32_to_cpu(p->des3) & TDES3_TIMESTAMP_STATUS)
-               return 0;
+               return 1;
 
-       return 1;
+       return 0;
 }
 
 static inline u64 dwmac4_get_timestamp(void *desc, u32 ats)
@@ -282,7 +282,10 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
                }
        }
 exit:
-       return ret;
+       if (likely(ret == 0))
+               return 1;
+
+       return 0;
 }
 
 static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
index 12236daf7bb6d5358fdafe50e37227e19b95bc33..6e4cbc6ce0efd9843a55341ec47eb76fd9932327 100644 (file)
@@ -434,14 +434,14 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
                return;
 
        /* check tx tstamp status */
-       if (!priv->hw->desc->get_tx_timestamp_status(p)) {
+       if (priv->hw->desc->get_tx_timestamp_status(p)) {
                /* get the valid tstamp */
                ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
 
                memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
                shhwtstamp.hwtstamp = ns_to_ktime(ns);
 
-               netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns);
+               netdev_dbg(priv->dev, "get valid TX hw timestamp %llu\n", ns);
                /* pass tstamp to stack */
                skb_tstamp_tx(skb, &shhwtstamp);
        }
@@ -468,19 +468,19 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
                return;
 
        /* Check if timestamp is available */
-       if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) {
+       if (priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) {
                /* For GMAC4, the valid timestamp is from CTX next desc. */
                if (priv->plat->has_gmac4)
                        ns = priv->hw->desc->get_timestamp(np, priv->adv_ts);
                else
                        ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
 
-               netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns);
+               netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns);
                shhwtstamp = skb_hwtstamps(skb);
                memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
                shhwtstamp->hwtstamp = ns_to_ktime(ns);
        } else  {
-               netdev_err(priv->dev, "cannot get RX hw timestamp\n");
+               netdev_dbg(priv->dev, "cannot get RX hw timestamp\n");
        }
 }
 
@@ -546,7 +546,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
                        /* PTP v1, UDP, any kind of event packet */
                        config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
                        /* take time stamp for all event messages */
-                       snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
+                       if (priv->plat->has_gmac4)
+                               snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
+                       else
+                               snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
 
                        ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
                        ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
@@ -578,7 +581,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
                        config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
                        ptp_v2 = PTP_TCR_TSVER2ENA;
                        /* take time stamp for all event messages */
-                       snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
+                       if (priv->plat->has_gmac4)
+                               snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
+                       else
+                               snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
 
                        ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
                        ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
@@ -612,7 +618,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
                        config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
                        ptp_v2 = PTP_TCR_TSVER2ENA;
                        /* take time stamp for all event messages */
-                       snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
+                       if (priv->plat->has_gmac4)
+                               snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
+                       else
+                               snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
 
                        ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
                        ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
@@ -2822,7 +2831,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
        tx_q->tx_skbuff_dma[first_entry].buf = des;
        tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb);
-       tx_q->tx_skbuff[first_entry] = skb;
 
        first->des0 = cpu_to_le32(des);
 
@@ -2856,6 +2864,14 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
        tx_q->tx_skbuff_dma[tx_q->cur_tx].last_segment = true;
 
+       /* Only the last descriptor gets to point to the skb. */
+       tx_q->tx_skbuff[tx_q->cur_tx] = skb;
+
+       /* We've used all descriptors we need for this skb, however,
+        * advance cur_tx so that it references a fresh descriptor.
+        * ndo_start_xmit will fill this descriptor the next time it's
+        * called and stmmac_tx_clean may clean up to this descriptor.
+        */
        tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE);
 
        if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) {
@@ -2989,8 +3005,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
        first = desc;
 
-       tx_q->tx_skbuff[first_entry] = skb;
-
        enh_desc = priv->plat->enh_desc;
        /* To program the descriptors according to the size of the frame */
        if (enh_desc)
@@ -3038,8 +3052,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
                                                skb->len);
        }
 
-       entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
+       /* Only the last descriptor gets to point to the skb. */
+       tx_q->tx_skbuff[entry] = skb;
 
+       /* We've used all descriptors we need for this skb, however,
+        * advance cur_tx so that it references a fresh descriptor.
+        * ndo_start_xmit will fill this descriptor the next time it's
+        * called and stmmac_tx_clean may clean up to this descriptor.
+        */
+       entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
        tx_q->cur_tx = entry;
 
        if (netif_msg_pktdata(priv)) {
index 48fb72fc423c9f7c29aa713376867c90c32932af..f4b31d69f60eb7291191a9ae714ef4377db508bb 100644 (file)
@@ -59,7 +59,8 @@
 /* Enable Snapshot for Messages Relevant to Master */
 #define        PTP_TCR_TSMSTRENA       BIT(15)
 /* Select PTP packets for Taking Snapshots */
-#define        PTP_TCR_SNAPTYPSEL_1    GENMASK(17, 16)
+#define        PTP_TCR_SNAPTYPSEL_1    BIT(16)
+#define        PTP_GMAC4_TCR_SNAPTYPSEL_1      GENMASK(17, 16)
 /* Enable MAC address for PTP Frame Filtering */
 #define        PTP_TCR_TSENMACADDR     BIT(18)
 
index 6ebb0f559a427fdb4d27d9b668b46d7151650043..199459bd69612478e596dc97248d2a40defd6db8 100644 (file)
@@ -1007,7 +1007,7 @@ static void geneve_setup(struct net_device *dev)
 
        dev->netdev_ops = &geneve_netdev_ops;
        dev->ethtool_ops = &geneve_ethtool_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
 
        SET_NETDEV_DEVTYPE(dev, &geneve_type);
 
index 7b652bb7ebe407b35c054009b521b173fd9fa361..ca110cd2a4e42cdebed760bdad103627b556e2f7 100644 (file)
@@ -611,7 +611,7 @@ static const struct net_device_ops gtp_netdev_ops = {
 static void gtp_link_setup(struct net_device *dev)
 {
        dev->netdev_ops         = &gtp_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 
        dev->hard_header_len = 0;
        dev->addr_len = 0;
index 922bf440e9f1cb2d20ba2d2419f73972b09714c3..021a8ec411ab8316d6080592e2469e37c912bc31 100644 (file)
@@ -311,7 +311,7 @@ static void sp_setup(struct net_device *dev)
 {
        /* Finish setting up the DEVICE info. */
        dev->netdev_ops         = &sp_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->mtu                = SIXP_MTU;
        dev->hard_header_len    = AX25_MAX_HEADER_LEN;
        dev->header_ops         = &ax25_header_ops;
index f62e7f325cf92edeca25c40a1d11e53166017049..78a6414c5fd994445c7e530065bd6cfa7e5ad213 100644 (file)
@@ -476,7 +476,7 @@ static const struct net_device_ops bpq_netdev_ops = {
 static void bpq_setup(struct net_device *dev)
 {
        dev->netdev_ops      = &bpq_netdev_ops;
-       dev->destructor      = free_netdev;
+       dev->needs_free_netdev = true;
 
        memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
        memcpy(dev->dev_addr,  &ax25_defaddr, AX25_ADDR_LEN);
index 262b2ea576a38e4bb7d1c442f2dfcbc2c40fa302..6066f1bcaf2d55e7be1708f1a96e592849611169 100644 (file)
@@ -171,6 +171,8 @@ struct rndis_device {
        spinlock_t request_lock;
        struct list_head req_list;
 
+       struct work_struct mcast_work;
+
        u8 hw_mac_adr[ETH_ALEN];
        u8 rss_key[NETVSC_HASH_KEYLEN];
        u16 ind_table[ITAB_NUM];
@@ -201,6 +203,7 @@ int rndis_filter_open(struct netvsc_device *nvdev);
 int rndis_filter_close(struct netvsc_device *nvdev);
 int rndis_filter_device_add(struct hv_device *dev,
                            struct netvsc_device_info *info);
+void rndis_filter_update(struct netvsc_device *nvdev);
 void rndis_filter_device_remove(struct hv_device *dev,
                                struct netvsc_device *nvdev);
 int rndis_filter_set_rss_param(struct rndis_device *rdev,
@@ -211,7 +214,6 @@ int rndis_filter_receive(struct net_device *ndev,
                         struct vmbus_channel *channel,
                         void *data, u32 buflen);
 
-int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
 int rndis_filter_set_device_mac(struct net_device *ndev, char *mac);
 
 void netvsc_switch_datapath(struct net_device *nv_dev, bool vf);
@@ -696,7 +698,6 @@ struct net_device_context {
        /* list protection */
        spinlock_t lock;
 
-       struct work_struct work;
        u32 msg_enable; /* debug level */
 
        u32 tx_checksum_mask;
index 4421a6d0037579bbff80ee909d42510947f77690..82d6c022ca859735c412eadad487556eb34b6f33 100644 (file)
@@ -56,37 +56,12 @@ static int debug = -1;
 module_param(debug, int, S_IRUGO);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
-static void do_set_multicast(struct work_struct *w)
-{
-       struct net_device_context *ndevctx =
-               container_of(w, struct net_device_context, work);
-       struct hv_device *device_obj = ndevctx->device_ctx;
-       struct net_device *ndev = hv_get_drvdata(device_obj);
-       struct netvsc_device *nvdev = rcu_dereference(ndevctx->nvdev);
-       struct rndis_device *rdev;
-
-       if (!nvdev)
-               return;
-
-       rdev = nvdev->extension;
-       if (rdev == NULL)
-               return;
-
-       if (ndev->flags & IFF_PROMISC)
-               rndis_filter_set_packet_filter(rdev,
-                       NDIS_PACKET_TYPE_PROMISCUOUS);
-       else
-               rndis_filter_set_packet_filter(rdev,
-                       NDIS_PACKET_TYPE_BROADCAST |
-                       NDIS_PACKET_TYPE_ALL_MULTICAST |
-                       NDIS_PACKET_TYPE_DIRECTED);
-}
-
 static void netvsc_set_multicast_list(struct net_device *net)
 {
        struct net_device_context *net_device_ctx = netdev_priv(net);
+       struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
 
-       schedule_work(&net_device_ctx->work);
+       rndis_filter_update(nvdev);
 }
 
 static int netvsc_open(struct net_device *net)
@@ -123,8 +98,6 @@ static int netvsc_close(struct net_device *net)
 
        netif_tx_disable(net);
 
-       /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
-       cancel_work_sync(&net_device_ctx->work);
        ret = rndis_filter_close(nvdev);
        if (ret != 0) {
                netdev_err(net, "unable to close device (ret %d).\n", ret);
@@ -1028,7 +1001,7 @@ static const struct {
 static int netvsc_get_sset_count(struct net_device *dev, int string_set)
 {
        struct net_device_context *ndc = netdev_priv(dev);
-       struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev);
+       struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
 
        if (!nvdev)
                return -ENODEV;
@@ -1158,11 +1131,22 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static void netvsc_poll_controller(struct net_device *net)
+static void netvsc_poll_controller(struct net_device *dev)
 {
-       /* As netvsc_start_xmit() works synchronous we don't have to
-        * trigger anything here.
-        */
+       struct net_device_context *ndc = netdev_priv(dev);
+       struct netvsc_device *ndev;
+       int i;
+
+       rcu_read_lock();
+       ndev = rcu_dereference(ndc->nvdev);
+       if (ndev) {
+               for (i = 0; i < ndev->num_chn; i++) {
+                       struct netvsc_channel *nvchan = &ndev->chan_table[i];
+
+                       napi_schedule(&nvchan->napi);
+               }
+       }
+       rcu_read_unlock();
 }
 #endif
 
@@ -1552,7 +1536,6 @@ static int netvsc_probe(struct hv_device *dev,
        hv_set_drvdata(dev, net);
 
        INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
-       INIT_WORK(&net_device_ctx->work, do_set_multicast);
 
        spin_lock_init(&net_device_ctx->lock);
        INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
@@ -1622,7 +1605,6 @@ static int netvsc_remove(struct hv_device *dev)
        netif_device_detach(net);
 
        cancel_delayed_work_sync(&ndev_ctx->dwork);
-       cancel_work_sync(&ndev_ctx->work);
 
        /*
         * Call to the vsc driver to let it know that the device is being
index f9d5b0b8209a7ffffa07984ba6d942ddb011610b..cb79cd081f427d6a22c2d48427779593965e793c 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "hyperv_net.h"
 
+static void rndis_set_multicast(struct work_struct *w);
 
 #define RNDIS_EXT_LEN PAGE_SIZE
 struct rndis_request {
@@ -76,6 +77,7 @@ static struct rndis_device *get_rndis_device(void)
        spin_lock_init(&device->request_lock);
 
        INIT_LIST_HEAD(&device->req_list);
+       INIT_WORK(&device->mcast_work, rndis_set_multicast);
 
        device->state = RNDIS_DEV_UNINITIALIZED;
 
@@ -815,7 +817,8 @@ static int rndis_filter_query_link_speed(struct rndis_device *dev)
        return ret;
 }
 
-int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
+static int rndis_filter_set_packet_filter(struct rndis_device *dev,
+                                         u32 new_filter)
 {
        struct rndis_request *request;
        struct rndis_set_request *set;
@@ -846,6 +849,28 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
        return ret;
 }
 
+static void rndis_set_multicast(struct work_struct *w)
+{
+       struct rndis_device *rdev
+               = container_of(w, struct rndis_device, mcast_work);
+
+       if (rdev->ndev->flags & IFF_PROMISC)
+               rndis_filter_set_packet_filter(rdev,
+                                              NDIS_PACKET_TYPE_PROMISCUOUS);
+       else
+               rndis_filter_set_packet_filter(rdev,
+                                              NDIS_PACKET_TYPE_BROADCAST |
+                                              NDIS_PACKET_TYPE_ALL_MULTICAST |
+                                              NDIS_PACKET_TYPE_DIRECTED);
+}
+
+void rndis_filter_update(struct netvsc_device *nvdev)
+{
+       struct rndis_device *rdev = nvdev->extension;
+
+       schedule_work(&rdev->mcast_work);
+}
+
 static int rndis_filter_init_device(struct rndis_device *dev)
 {
        struct rndis_request *request;
@@ -973,6 +998,9 @@ static int rndis_filter_close_device(struct rndis_device *dev)
        if (dev->state != RNDIS_DEV_DATAINITIALIZED)
                return 0;
 
+       /* Make sure rndis_set_multicast doesn't re-enable filter! */
+       cancel_work_sync(&dev->mcast_work);
+
        ret = rndis_filter_set_packet_filter(dev, 0);
        if (ret == -ENODEV)
                ret = 0;
index 312fce7302d3252903282599223063e7d97bb863..144ea5ae8ab4abda588cb6b23292c9f3ccf06c9c 100644 (file)
@@ -207,7 +207,6 @@ static void ifb_dev_free(struct net_device *dev)
                __skb_queue_purge(&txp->tq);
        }
        kfree(dp->tx_private);
-       free_netdev(dev);
 }
 
 static void ifb_setup(struct net_device *dev)
@@ -230,7 +229,8 @@ static void ifb_setup(struct net_device *dev)
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        netif_keep_dst(dev);
        eth_hw_addr_random(dev);
-       dev->destructor = ifb_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = ifb_dev_free;
 }
 
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
index 618ed88fad0fc1d4e227f0e84fde74462b2bc496..7c7680c8f0e32e149167f7943dc02bdc9646da23 100644 (file)
@@ -632,7 +632,7 @@ void ipvlan_link_setup(struct net_device *dev)
        dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;
        dev->netdev_ops = &ipvlan_netdev_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        dev->header_ops = &ipvlan_header_ops;
        dev->ethtool_ops = &ipvlan_ethtool_ops;
 }
index 224f65cb576bbf106a4779ef5f60b75f34903b1c..30612497643c08caa8a3bf352b13f784f729f725 100644 (file)
@@ -159,7 +159,6 @@ static void loopback_dev_free(struct net_device *dev)
 {
        dev_net(dev)->loopback_dev = NULL;
        free_percpu(dev->lstats);
-       free_netdev(dev);
 }
 
 static const struct net_device_ops loopback_ops = {
@@ -196,7 +195,8 @@ static void loopback_setup(struct net_device *dev)
        dev->ethtool_ops        = &loopback_ethtool_ops;
        dev->header_ops         = &eth_header_ops;
        dev->netdev_ops         = &loopback_ops;
-       dev->destructor         = loopback_dev_free;
+       dev->needs_free_netdev  = true;
+       dev->priv_destructor    = loopback_dev_free;
 }
 
 /* Setup and register the loopback device. */
index cdc347be68f23196d6ba820d21475260bc5bae3b..79411675f0e66376ecf2fa640b51c7172d8085d9 100644 (file)
@@ -2996,7 +2996,6 @@ static void macsec_free_netdev(struct net_device *dev)
        free_percpu(macsec->secy.tx_sc.stats);
 
        dev_put(real_dev);
-       free_netdev(dev);
 }
 
 static void macsec_setup(struct net_device *dev)
@@ -3006,7 +3005,8 @@ static void macsec_setup(struct net_device *dev)
        dev->max_mtu = ETH_MAX_MTU;
        dev->priv_flags |= IFF_NO_QUEUE;
        dev->netdev_ops = &macsec_netdev_ops;
-       dev->destructor = macsec_free_netdev;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = macsec_free_netdev;
        SET_NETDEV_DEVTYPE(dev, &macsec_type);
 
        eth_zero_addr(dev->broadcast);
index 346ad2ff39989d3da4cacc6ec1965ca882c475cd..67bf7ebae5c6dba9b9ea28c0c9c0801093f55eb7 100644 (file)
@@ -1092,7 +1092,7 @@ void macvlan_common_setup(struct net_device *dev)
        netif_keep_dst(dev);
        dev->priv_flags        |= IFF_UNICAST_FLT;
        dev->netdev_ops         = &macvlan_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->header_ops         = &macvlan_hard_header_ops;
        dev->ethtool_ops        = &macvlan_ethtool_ops;
 }
index 06ee6395117f9df71a07d22326bc6c15c1e87f2e..0e27920c2b6b6219e70871ad13031bf56711907e 100644 (file)
@@ -358,7 +358,7 @@ static ssize_t enabled_store(struct config_item *item,
                if (err)
                        goto out_unlock;
 
-               pr_info("netconsole: network logging started\n");
+               pr_info("network logging started\n");
        } else {        /* false */
                /* We need to disable the netconsole before cleaning it up
                 * otherwise we might end up in write_msg() with
index b91603835d2680aa08911da7870ea176c5dd0792..c4b3362da4a2e33184b02dff0df3082b4d7e45e4 100644 (file)
@@ -113,7 +113,7 @@ static void nlmon_setup(struct net_device *dev)
 
        dev->netdev_ops = &nlmon_ops;
        dev->ethtool_ops = &nlmon_ethtool_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
 
        dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
                        NETIF_F_HIGHDMA | NETIF_F_LLTX;
index c360dd6ead2213b112282ff508b963354cf15d72..3ab6c58d4be6fd42812bfd783715c13ef42e13c4 100644 (file)
@@ -127,6 +127,7 @@ config MDIO_THUNDER
        tristate "ThunderX SOCs MDIO buses"
        depends on 64BIT
        depends on PCI
+       depends on !(MDIO_DEVICE=y && PHYLIB=m)
        select MDIO_CAVIUM
        help
          This driver supports the MDIO interfaces found on Cavium
index 7524caa0f29d9806e11826c7ecfd57842bff1822..eebb0e1c70ff51a40189fd9690217c34ce9bb4cb 100644 (file)
@@ -54,6 +54,8 @@ static const char *phy_speed_to_str(int speed)
                return "5Gbps";
        case SPEED_10000:
                return "10Gbps";
+       case SPEED_14000:
+               return "14Gbps";
        case SPEED_20000:
                return "20Gbps";
        case SPEED_25000:
index 1da31dc47f863845d50823b69e51f2abab5bf3f0..74b907206aa749d894531005716a0c6dd3d0ec1f 100644 (file)
@@ -629,7 +629,7 @@ static void sl_uninit(struct net_device *dev)
 static void sl_free_netdev(struct net_device *dev)
 {
        int i = dev->base_addr;
-       free_netdev(dev);
+
        slip_devs[i] = NULL;
 }
 
@@ -651,7 +651,8 @@ static const struct net_device_ops sl_netdev_ops = {
 static void sl_setup(struct net_device *dev)
 {
        dev->netdev_ops         = &sl_netdev_ops;
-       dev->destructor         = sl_free_netdev;
+       dev->needs_free_netdev  = true;
+       dev->priv_destructor    = sl_free_netdev;
 
        dev->hard_header_len    = 0;
        dev->addr_len           = 0;
@@ -1369,8 +1370,6 @@ static void __exit slip_exit(void)
                if (sl->tty) {
                        printk(KERN_ERR "%s: tty discipline still running\n",
                               dev->name);
-                       /* Intentionally leak the control block. */
-                       dev->destructor = NULL;
                }
 
                unregister_netdev(dev);
index 6c5d5ef46f75aa9a9089ac80bbee30a7f579b016..fba8c136aa7c1513b288e641cfe8cd6dca304ccd 100644 (file)
@@ -1643,7 +1643,6 @@ static void team_destructor(struct net_device *dev)
        struct team *team = netdev_priv(dev);
 
        free_percpu(team->pcpu_stats);
-       free_netdev(dev);
 }
 
 static int team_open(struct net_device *dev)
@@ -2079,7 +2078,8 @@ static void team_setup(struct net_device *dev)
 
        dev->netdev_ops = &team_netdev_ops;
        dev->ethtool_ops = &team_ethtool_ops;
-       dev->destructor = team_destructor;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = team_destructor;
        dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        dev->priv_flags |= IFF_NO_QUEUE;
        dev->priv_flags |= IFF_TEAM;
index bbd707b9ef7a6a305804ed0d56c3fc0e1db7d565..9ee7d4275640919f2293182cb47dca41412975ba 100644 (file)
@@ -1560,7 +1560,6 @@ static void tun_free_netdev(struct net_device *dev)
        free_percpu(tun->pcpu_stats);
        tun_flow_uninit(tun);
        security_tun_dev_free_security(tun->security);
-       free_netdev(dev);
 }
 
 static void tun_setup(struct net_device *dev)
@@ -1571,7 +1570,8 @@ static void tun_setup(struct net_device *dev)
        tun->group = INVALID_GID;
 
        dev->ethtool_ops = &tun_ethtool_ops;
-       dev->destructor = tun_free_netdev;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = tun_free_netdev;
        /* We prefer our own queue length */
        dev->tx_queue_len = TUN_READQ_SIZE;
 }
index eb52de8205f0d48044bcb6c1302ce7bda779128e..c7a350bbaaa7c881a831ec8ed7b4b59dd83c6de9 100644 (file)
@@ -298,7 +298,7 @@ static void usbpn_setup(struct net_device *dev)
        dev->addr_len           = 1;
        dev->tx_queue_len       = 3;
 
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 }
 
 /*
index 8f923a147fa93117296312c59fdc6761fef50f3c..32a22f4e8356422ba144a3e3485810537afaad2c 100644 (file)
@@ -123,7 +123,7 @@ static void qmimux_setup(struct net_device *dev)
        dev->addr_len        = 0;
        dev->flags           = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
        dev->netdev_ops      = &qmimux_netdev_ops;
-       dev->destructor      = free_netdev;
+       dev->needs_free_netdev = true;
 }
 
 static struct net_device *qmimux_find_dev(struct usbnet *dev, u8 mux_id)
@@ -1192,6 +1192,8 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x9056, 8)},    /* Sierra Wireless Modem */
        {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
        {QMI_FIXED_INTF(0x1199, 0x9061, 8)},    /* Sierra Wireless Modem */
+       {QMI_FIXED_INTF(0x1199, 0x9063, 8)},    /* Sierra Wireless EM7305 */
+       {QMI_FIXED_INTF(0x1199, 0x9063, 10)},   /* Sierra Wireless EM7305 */
        {QMI_FIXED_INTF(0x1199, 0x9071, 8)},    /* Sierra Wireless MC74xx */
        {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx */
        {QMI_FIXED_INTF(0x1199, 0x9079, 8)},    /* Sierra Wireless EM74xx */
@@ -1206,6 +1208,8 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},    /* Telit ME910 */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
+       {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)},    /* Telewell TW-3G HSPA+ */
+       {QMI_FIXED_INTF(0x1c9e, 0x9803, 4)},    /* Telewell TW-3G HSPA+ */
        {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},    /* XS Stick W100-2 from 4G Systems */
        {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)},    /* Olivetti Olicard 100 */
        {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)},    /* Olivetti Olicard 120 */
index ddc62cb69be828a730e6ed32ecc9ee951fef8d3b..1a419a45e2a2e77e07e1746c9035230da465424d 100644 (file)
@@ -4368,6 +4368,8 @@ static u8 rtl_get_version(struct usb_interface *intf)
                break;
        }
 
+       dev_dbg(&intf->dev, "Detected version 0x%04x\n", version);
+
        return version;
 }
 
index 38f0f03a29c8898131110a620e73da4776cb7020..0156fe8cac172a909cfe4ed5b9567572132b888d 100644 (file)
@@ -222,7 +222,6 @@ static int veth_dev_init(struct net_device *dev)
 static void veth_dev_free(struct net_device *dev)
 {
        free_percpu(dev->vstats);
-       free_netdev(dev);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -317,7 +316,8 @@ static void veth_setup(struct net_device *dev)
                               NETIF_F_HW_VLAN_STAG_TX |
                               NETIF_F_HW_VLAN_CTAG_RX |
                               NETIF_F_HW_VLAN_STAG_RX);
-       dev->destructor = veth_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = veth_dev_free;
        dev->max_mtu = ETH_MAX_MTU;
 
        dev->hw_features = VETH_FEATURES;
index db882493875cd97d30ac5a2b26a764a5b65d9e2e..022c0b5f9844242bc08b766eabf208fb41d9e03d 100644 (file)
 #include <net/addrconf.h>
 #include <net/l3mdev.h>
 #include <net/fib_rules.h>
+#include <net/netns/generic.h>
 
 #define DRV_NAME       "vrf"
 #define DRV_VERSION    "1.0"
 
 #define FIB_RULE_PREF  1000       /* default preference for FIB rules */
-static bool add_fib_rules = true;
+
+static unsigned int vrf_net_id;
 
 struct net_vrf {
        struct rtable __rcu     *rth;
@@ -1348,7 +1350,7 @@ static void vrf_setup(struct net_device *dev)
        dev->netdev_ops = &vrf_netdev_ops;
        dev->l3mdev_ops = &vrf_l3mdev_ops;
        dev->ethtool_ops = &vrf_ethtool_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
 
        /* Fill in device structure with ethernet-generic values. */
        eth_hw_addr_random(dev);
@@ -1394,6 +1396,8 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
                       struct nlattr *tb[], struct nlattr *data[])
 {
        struct net_vrf *vrf = netdev_priv(dev);
+       bool *add_fib_rules;
+       struct net *net;
        int err;
 
        if (!data || !data[IFLA_VRF_TABLE])
@@ -1409,13 +1413,15 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
        if (err)
                goto out;
 
-       if (add_fib_rules) {
+       net = dev_net(dev);
+       add_fib_rules = net_generic(net, vrf_net_id);
+       if (*add_fib_rules) {
                err = vrf_add_fib_rules(dev);
                if (err) {
                        unregister_netdevice(dev);
                        goto out;
                }
-               add_fib_rules = false;
+               *add_fib_rules = false;
        }
 
 out:
@@ -1498,16 +1504,38 @@ static struct notifier_block vrf_notifier_block __read_mostly = {
        .notifier_call = vrf_device_event,
 };
 
+/* Initialize per network namespace state */
+static int __net_init vrf_netns_init(struct net *net)
+{
+       bool *add_fib_rules = net_generic(net, vrf_net_id);
+
+       *add_fib_rules = true;
+
+       return 0;
+}
+
+static struct pernet_operations vrf_net_ops __net_initdata = {
+       .init = vrf_netns_init,
+       .id   = &vrf_net_id,
+       .size = sizeof(bool),
+};
+
 static int __init vrf_init_module(void)
 {
        int rc;
 
        register_netdevice_notifier(&vrf_notifier_block);
 
-       rc = rtnl_link_register(&vrf_link_ops);
+       rc = register_pernet_subsys(&vrf_net_ops);
        if (rc < 0)
                goto error;
 
+       rc = rtnl_link_register(&vrf_link_ops);
+       if (rc < 0) {
+               unregister_pernet_subsys(&vrf_net_ops);
+               goto error;
+       }
+
        return 0;
 
 error:
index 7f0136f2dd9d6167acc9b125fb03d8c2c5f9524d..c28bdce14fd5e32b287419227d7d33bf7835c409 100644 (file)
@@ -135,7 +135,7 @@ static void vsockmon_setup(struct net_device *dev)
 
        dev->netdev_ops = &vsockmon_ops;
        dev->ethtool_ops = &vsockmon_ethtool_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
 
        dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
                        NETIF_F_HIGHDMA | NETIF_F_LLTX;
index a6b5052c1d36bb99260dd4232842fa9e8df2621c..5fa798a5c9a695ac3796d2ee4a3c1eae59a1cf9f 100644 (file)
@@ -2611,7 +2611,7 @@ static void vxlan_setup(struct net_device *dev)
        eth_hw_addr_random(dev);
        ether_setup(dev);
 
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        SET_NETDEV_DEVTYPE(dev, &vxlan_type);
 
        dev->features   |= NETIF_F_LLTX;
index 65ee2a6f248cfcbd2761272431c37627eafaced5..a0d76f70c4289d03e7b8c25700c58b218a934bd0 100644 (file)
@@ -475,7 +475,7 @@ static void dlci_setup(struct net_device *dev)
        dev->flags              = 0;
        dev->header_ops         = &dlci_header_ops;
        dev->netdev_ops         = &dlci_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 
        dlp->receive            = dlci_receive;
 
index eb915281197efc98a0fae96cc9dcdd2691a21ee3..78596e42a3f3f27623284c86a0d791a2bf4a65b6 100644 (file)
@@ -1106,7 +1106,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
                return -EIO;
        }
 
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        *get_dev_p(pvc, type) = dev;
        if (!used) {
                state(hdlc)->dce_changed = 1;
index 9df9ed62beff0cb3b2c0be7dbe1f15e646da74de..63f749078a1f1051f3f46bec13f1f60c7c64ea5f 100644 (file)
@@ -306,7 +306,7 @@ static const struct net_device_ops lapbeth_netdev_ops = {
 static void lapbeth_setup(struct net_device *dev)
 {
        dev->netdev_ops      = &lapbeth_netdev_ops;
-       dev->destructor      = free_netdev;
+       dev->needs_free_netdev = true;
        dev->type            = ARPHRD_X25;
        dev->hard_header_len = 3;
        dev->mtu             = 1000;
index 91ee542de3d79ec0903d56f2d45463af83b01a95..b90c77ef792ef8908173aa2f762d15089dce55fd 100644 (file)
@@ -1287,7 +1287,7 @@ void init_netdev(struct net_device *dev)
        struct ath6kl *ar = ath6kl_priv(dev);
 
        dev->netdev_ops = &ath6kl_netdev_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
 
        dev->needed_headroom = ETH_HLEN;
index cd1d6730eab73d514db5a1b88d442607c7834e3d..617199c0e5a0e644576b3c73be0808878d4c102b 100644 (file)
@@ -5225,7 +5225,6 @@ void brcmf_cfg80211_free_netdev(struct net_device *ndev)
 
        if (vif)
                brcmf_free_vif(vif);
-       free_netdev(ndev);
 }
 
 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
index a3d82368f1a9f9722e62920e44ef52f7ee8602ef..511d190c6cca1e864e50c7b1b6ae9caa45307e00 100644 (file)
@@ -624,7 +624,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
                if (!ndev)
                        return ERR_PTR(-ENOMEM);
 
-               ndev->destructor = brcmf_cfg80211_free_netdev;
+               ndev->needs_free_netdev = true;
+               ndev->priv_destructor = brcmf_cfg80211_free_netdev;
                ifp = netdev_priv(ndev);
                ifp->ndev = ndev;
                /* store mapping ifidx to bsscfgidx */
index c7c1e9906500fd5be3d386ea4c43848caaff6ac1..d231042f19d6462018bc10fee0c789196c51abf9 100644 (file)
@@ -442,7 +442,7 @@ struct brcmf_fw {
        const char *nvram_name;
        u16 domain_nr;
        u16 bus_nr;
-       void (*done)(struct device *dev, const struct firmware *fw,
+       void (*done)(struct device *dev, int err, const struct firmware *fw,
                     void *nvram_image, u32 nvram_len);
 };
 
@@ -477,52 +477,51 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
        if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
                goto fail;
 
-       fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
+       fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
        kfree(fwctx);
        return;
 
 fail:
        brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
        release_firmware(fwctx->code);
-       device_release_driver(fwctx->dev);
+       fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
        kfree(fwctx);
 }
 
 static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
 {
        struct brcmf_fw *fwctx = ctx;
-       int ret;
+       int ret = 0;
 
        brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
-       if (!fw)
+       if (!fw) {
+               ret = -ENOENT;
                goto fail;
-
-       /* only requested code so done here */
-       if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
-               fwctx->done(fwctx->dev, fw, NULL, 0);
-               kfree(fwctx);
-               return;
        }
+       /* only requested code so done here */
+       if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM))
+               goto done;
+
        fwctx->code = fw;
        ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
                                      fwctx->dev, GFP_KERNEL, fwctx,
                                      brcmf_fw_request_nvram_done);
 
-       if (!ret)
-               return;
-
-       brcmf_fw_request_nvram_done(NULL, fwctx);
+       /* pass NULL to nvram callback for bcm47xx fallback */
+       if (ret)
+               brcmf_fw_request_nvram_done(NULL, fwctx);
        return;
 
 fail:
        brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
-       device_release_driver(fwctx->dev);
+done:
+       fwctx->done(fwctx->dev, ret, fw, NULL, 0);
        kfree(fwctx);
 }
 
 int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
                                const char *code, const char *nvram,
-                               void (*fw_cb)(struct device *dev,
+                               void (*fw_cb)(struct device *dev, int err,
                                              const struct firmware *fw,
                                              void *nvram_image, u32 nvram_len),
                                u16 domain_nr, u16 bus_nr)
@@ -555,7 +554,7 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
 
 int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
                           const char *code, const char *nvram,
-                          void (*fw_cb)(struct device *dev,
+                          void (*fw_cb)(struct device *dev, int err,
                                         const struct firmware *fw,
                                         void *nvram_image, u32 nvram_len))
 {
index d3c9f0d52ae3326eb18a76aaf735bb602a211a35..8fa4b7e1ab3db71c2522aa9a275ac9e6393eb0a7 100644 (file)
@@ -73,13 +73,13 @@ void brcmf_fw_nvram_free(void *nvram);
  */
 int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
                                const char *code, const char *nvram,
-                               void (*fw_cb)(struct device *dev,
+                               void (*fw_cb)(struct device *dev, int err,
                                              const struct firmware *fw,
                                              void *nvram_image, u32 nvram_len),
                                u16 domain_nr, u16 bus_nr);
 int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
                           const char *code, const char *nvram,
-                          void (*fw_cb)(struct device *dev,
+                          void (*fw_cb)(struct device *dev, int err,
                                         const struct firmware *fw,
                                         void *nvram_image, u32 nvram_len));
 
index 72373e59308e8fe54cf14090efd135a045273f4a..f59642b2c935a503f36600f4573861a7597ad267 100644 (file)
@@ -2145,7 +2145,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp)
        struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr);
        struct brcmf_fws_mac_descriptor *entry;
 
-       if (!ifp->ndev || fws->fcmode == BRCMF_FWS_FCMODE_NONE)
+       if (!ifp->ndev || !brcmf_fws_queue_skbs(fws))
                return;
 
        entry = &fws->desc.iface[ifp->ifidx];
index f36b96dc6acdfc2160ba35e187a46356a3b41c28..f878706613e679515410e573eb770f1b1a28ef26 100644 (file)
@@ -1650,16 +1650,23 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
        .write32 = brcmf_pcie_buscore_write32,
 };
 
-static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
+static void brcmf_pcie_setup(struct device *dev, int ret,
+                            const struct firmware *fw,
                             void *nvram, u32 nvram_len)
 {
-       struct brcmf_bus *bus = dev_get_drvdata(dev);
-       struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie;
-       struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
+       struct brcmf_bus *bus;
+       struct brcmf_pciedev *pcie_bus_dev;
+       struct brcmf_pciedev_info *devinfo;
        struct brcmf_commonring **flowrings;
-       int ret;
        u32 i;
 
+       /* check firmware loading result */
+       if (ret)
+               goto fail;
+
+       bus = dev_get_drvdata(dev);
+       pcie_bus_dev = bus->bus_priv.pcie;
+       devinfo = pcie_bus_dev->devinfo;
        brcmf_pcie_attach(devinfo);
 
        /* Some of the firmwares have the size of the memory of the device
index e03450059b06c0bfe510148f985c19668bcd3dff..5653d6dd38f6fe5c5132f2d7940facd31bef6549 100644 (file)
@@ -3982,21 +3982,26 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
        .get_memdump = brcmf_sdio_bus_get_memdump,
 };
 
-static void brcmf_sdio_firmware_callback(struct device *dev,
+static void brcmf_sdio_firmware_callback(struct device *dev, int err,
                                         const struct firmware *code,
                                         void *nvram, u32 nvram_len)
 {
-       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
-       struct brcmf_sdio *bus = sdiodev->bus;
-       int err = 0;
+       struct brcmf_bus *bus_if;
+       struct brcmf_sdio_dev *sdiodev;
+       struct brcmf_sdio *bus;
        u8 saveclk;
 
-       brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
+       brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
+       bus_if = dev_get_drvdata(dev);
+       sdiodev = bus_if->bus_priv.sdio;
+       if (err)
+               goto fail;
 
        if (!bus_if->drvr)
                return;
 
+       bus = sdiodev->bus;
+
        /* try to download image and nvram to the dongle */
        bus->alp_only = true;
        err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
@@ -4083,6 +4088,7 @@ release:
 fail:
        brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
        device_release_driver(dev);
+       device_release_driver(&sdiodev->func[2]->dev);
 }
 
 struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
index e4d545f9edeef6f119a0b67f50db679bedfcd91f..0eea48e73331d57297099266b1725df2be35a565 100644 (file)
@@ -1159,17 +1159,18 @@ fail:
        return ret;
 }
 
-static void brcmf_usb_probe_phase2(struct device *dev,
+static void brcmf_usb_probe_phase2(struct device *dev, int ret,
                                   const struct firmware *fw,
                                   void *nvram, u32 nvlen)
 {
        struct brcmf_bus *bus = dev_get_drvdata(dev);
-       struct brcmf_usbdev_info *devinfo;
-       int ret;
+       struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo;
+
+       if (ret)
+               goto error;
 
        brcmf_dbg(USB, "Start fw downloading\n");
 
-       devinfo = bus->bus_priv.usb->devinfo;
        ret = check_file(fw->data);
        if (ret < 0) {
                brcmf_err("invalid firmware\n");
index 544fc09dcb62435dc7316b2d8463c76d386ed91e..1372b20f931e0cca990a158e0ef8fdfc71fd7f88 100644 (file)
@@ -73,7 +73,7 @@ struct net_device * hostap_add_interface(struct local_info *local,
        dev->mem_end = mdev->mem_end;
 
        hostap_setup_dev(dev, local, type);
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
 
        sprintf(dev->name, "%s%s", prefix, name);
        if (!rtnl_locked)
index 002b25cff5b65e18460a2da08637886274bfdfa5..c854a557998b4266c5d63c55c0463497e8dde715 100644 (file)
@@ -2861,7 +2861,7 @@ static const struct net_device_ops hwsim_netdev_ops = {
 static void hwsim_mon_setup(struct net_device *dev)
 {
        dev->netdev_ops = &hwsim_netdev_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        ether_setup(dev);
        dev->priv_flags |= IFF_NO_QUEUE;
        dev->type = ARPHRD_IEEE80211_RADIOTAP;
index dd87b9ff64c371911a74308be55e93e3a46cdd43..39b6b5e3f6e0e4e9ec6eb81e458250485e94c487 100644 (file)
@@ -1280,7 +1280,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
                              struct net_device *dev)
 {
        dev->netdev_ops = &mwifiex_netdev_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        /* Initialize private structure */
        priv->current_key_index = 0;
        priv->media_connected = false;
index c00238491673766e05bc5bd2d2d3bec4aac30484..7b3b6fd63d7d7caa21bbc9c517c4e28910b0548b 100644 (file)
@@ -2878,7 +2878,7 @@ static const struct intel_ntb_reg skx_reg = {
        .link_is_up             = xeon_link_is_up,
        .db_ioread              = skx_db_ioread,
        .db_iowrite             = skx_db_iowrite,
-       .db_size                = sizeof(u64),
+       .db_size                = sizeof(u32),
        .ntb_ctl                = SKX_NTBCNTL_OFFSET,
        .mw_bar                 = {2, 4},
 };
index 02ca45fdd89203f31246f552811b1264059232d6..10e5bf4601398c8723d82b5f3340f9b246d341e5 100644 (file)
@@ -177,14 +177,12 @@ struct ntb_transport_qp {
        u64 rx_err_ver;
        u64 rx_memcpy;
        u64 rx_async;
-       u64 dma_rx_prep_err;
        u64 tx_bytes;
        u64 tx_pkts;
        u64 tx_ring_full;
        u64 tx_err_no_buf;
        u64 tx_memcpy;
        u64 tx_async;
-       u64 dma_tx_prep_err;
 };
 
 struct ntb_transport_mw {
@@ -254,8 +252,6 @@ enum {
 #define QP_TO_MW(nt, qp)       ((qp) % nt->mw_count)
 #define NTB_QP_DEF_NUM_ENTRIES 100
 #define NTB_LINK_DOWN_TIMEOUT  10
-#define DMA_RETRIES            20
-#define DMA_OUT_RESOURCE_TO    msecs_to_jiffies(50)
 
 static void ntb_transport_rxc_db(unsigned long data);
 static const struct ntb_ctx_ops ntb_transport_ops;
@@ -516,12 +512,6 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
                               "free tx - \t%u\n",
                               ntb_transport_tx_free_entry(qp));
-       out_offset += snprintf(buf + out_offset, out_count - out_offset,
-                              "DMA tx prep err - \t%llu\n",
-                              qp->dma_tx_prep_err);
-       out_offset += snprintf(buf + out_offset, out_count - out_offset,
-                              "DMA rx prep err - \t%llu\n",
-                              qp->dma_rx_prep_err);
 
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
                               "\n");
@@ -623,7 +613,7 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt,
        if (!mw->virt_addr)
                return -ENOMEM;
 
-       if (qp_count % mw_count && mw_num + 1 < qp_count / mw_count)
+       if (mw_num < qp_count % mw_count)
                num_qps_mw = qp_count / mw_count + 1;
        else
                num_qps_mw = qp_count / mw_count;
@@ -768,8 +758,6 @@ static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
        qp->tx_err_no_buf = 0;
        qp->tx_memcpy = 0;
        qp->tx_async = 0;
-       qp->dma_tx_prep_err = 0;
-       qp->dma_rx_prep_err = 0;
 }
 
 static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
@@ -1000,7 +988,7 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
        qp->event_handler = NULL;
        ntb_qp_link_down_reset(qp);
 
-       if (qp_count % mw_count && mw_num + 1 < qp_count / mw_count)
+       if (mw_num < qp_count % mw_count)
                num_qps_mw = qp_count / mw_count + 1;
        else
                num_qps_mw = qp_count / mw_count;
@@ -1128,8 +1116,8 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
        qp_count = ilog2(qp_bitmap);
        if (max_num_clients && max_num_clients < qp_count)
                qp_count = max_num_clients;
-       else if (mw_count < qp_count)
-               qp_count = mw_count;
+       else if (nt->mw_count < qp_count)
+               qp_count = nt->mw_count;
 
        qp_bitmap &= BIT_ULL(qp_count) - 1;
 
@@ -1317,7 +1305,6 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset)
        struct dmaengine_unmap_data *unmap;
        dma_cookie_t cookie;
        void *buf = entry->buf;
-       int retries = 0;
 
        len = entry->len;
        device = chan->device;
@@ -1346,22 +1333,11 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset)
 
        unmap->from_cnt = 1;
 
-       for (retries = 0; retries < DMA_RETRIES; retries++) {
-               txd = device->device_prep_dma_memcpy(chan,
-                                                    unmap->addr[1],
-                                                    unmap->addr[0], len,
-                                                    DMA_PREP_INTERRUPT);
-               if (txd)
-                       break;
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(DMA_OUT_RESOURCE_TO);
-       }
-
-       if (!txd) {
-               qp->dma_rx_prep_err++;
+       txd = device->device_prep_dma_memcpy(chan, unmap->addr[1],
+                                            unmap->addr[0], len,
+                                            DMA_PREP_INTERRUPT);
+       if (!txd)
                goto err_get_unmap;
-       }
 
        txd->callback_result = ntb_rx_copy_callback;
        txd->callback_param = entry;
@@ -1606,7 +1582,6 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
        struct dmaengine_unmap_data *unmap;
        dma_addr_t dest;
        dma_cookie_t cookie;
-       int retries = 0;
 
        device = chan->device;
        dest = qp->tx_mw_phys + qp->tx_max_frame * entry->tx_index;
@@ -1628,21 +1603,10 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
 
        unmap->to_cnt = 1;
 
-       for (retries = 0; retries < DMA_RETRIES; retries++) {
-               txd = device->device_prep_dma_memcpy(chan, dest,
-                                                    unmap->addr[0], len,
-                                                    DMA_PREP_INTERRUPT);
-               if (txd)
-                       break;
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(DMA_OUT_RESOURCE_TO);
-       }
-
-       if (!txd) {
-               qp->dma_tx_prep_err++;
+       txd = device->device_prep_dma_memcpy(chan, dest, unmap->addr[0], len,
+                                            DMA_PREP_INTERRUPT);
+       if (!txd)
                goto err_get_unmap;
-       }
 
        txd->callback_result = ntb_tx_copy_callback;
        txd->callback_param = entry;
index 434e1d474f3340e1d35b48c924a6bebfbfb0fa67..5cab2831ce99ae39dac8fe8a1c8b2bd216a9e901 100644 (file)
@@ -90,11 +90,11 @@ MODULE_PARM_DESC(max_mw_size, "Limit size of large memory windows");
 
 static unsigned int seg_order = 19; /* 512K */
 module_param(seg_order, uint, 0644);
-MODULE_PARM_DESC(seg_order, "size order [n^2] of buffer segment for testing");
+MODULE_PARM_DESC(seg_order, "size order [2^n] of buffer segment for testing");
 
 static unsigned int run_order = 32; /* 4G */
 module_param(run_order, uint, 0644);
-MODULE_PARM_DESC(run_order, "size order [n^2] of total data to transfer");
+MODULE_PARM_DESC(run_order, "size order [2^n] of total data to transfer");
 
 static bool use_dma; /* default to 0 */
 module_param(use_dma, bool, 0644);
index 951042a375d6b22dbd34988e38fef7114593c366..40c7581caeb00d30a60c7b9152ac67dd99a888d6 100644 (file)
@@ -1805,7 +1805,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
        if (pci_is_enabled(pdev)) {
                u32 csts = readl(dev->bar + NVME_REG_CSTS);
 
-               if (dev->ctrl.state == NVME_CTRL_LIVE)
+               if (dev->ctrl.state == NVME_CTRL_LIVE ||
+                   dev->ctrl.state == NVME_CTRL_RESETTING)
                        nvme_start_freeze(&dev->ctrl);
                dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) ||
                        pdev->error_state  != pci_channel_io_normal);
index 74cf5fffb1e1b93fdb1a6d44002d7727544195e7..c80e37a69305c18f2879957c92fa3308bb45b175 100644 (file)
@@ -896,7 +896,7 @@ int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
 {
        if (pci_dev_is_disconnected(dev)) {
                *val = ~0;
-               return -ENODEV;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        }
        return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
 }
@@ -906,7 +906,7 @@ int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
 {
        if (pci_dev_is_disconnected(dev)) {
                *val = ~0;
-               return -ENODEV;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        }
        return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
 }
@@ -917,7 +917,7 @@ int pci_read_config_dword(const struct pci_dev *dev, int where,
 {
        if (pci_dev_is_disconnected(dev)) {
                *val = ~0;
-               return -ENODEV;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        }
        return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
 }
@@ -926,7 +926,7 @@ EXPORT_SYMBOL(pci_read_config_dword);
 int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
 {
        if (pci_dev_is_disconnected(dev))
-               return -ENODEV;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
 }
 EXPORT_SYMBOL(pci_write_config_byte);
@@ -934,7 +934,7 @@ EXPORT_SYMBOL(pci_write_config_byte);
 int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
 {
        if (pci_dev_is_disconnected(dev))
-               return -ENODEV;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
 }
 EXPORT_SYMBOL(pci_write_config_word);
@@ -943,7 +943,7 @@ int pci_write_config_dword(const struct pci_dev *dev, int where,
                                         u32 val)
 {
        if (pci_dev_is_disconnected(dev))
-               return -ENODEV;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
 }
 EXPORT_SYMBOL(pci_write_config_dword);
index 175edad42d2f8fe100b762bbbe39bc042dceabe4..2942066607e0e9a6393139bfab65b5c13f6b09c5 100644 (file)
@@ -5,6 +5,7 @@
 config PCI_EPF_TEST
        tristate "PCI Endpoint Test driver"
        depends on PCI_ENDPOINT
+       select CRC32
        help
           Enable this configuration option to enable the test driver
           for PCI Endpoint.
index 1482d132fbb879ab39ec62dadcd48e9445feced9..e432ec887479d32b2be5afcc1a26e295909b04cb 100644 (file)
@@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip = {
        .flags        = IRQCHIP_SKIP_SET_WAKE,
 };
 
-static void amd_gpio_irq_handler(struct irq_desc *desc)
+#define PIN_IRQ_PENDING        (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
+
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 {
-       u32 i;
-       u32 off;
-       u32 reg;
-       u32 pin_reg;
-       u64 reg64;
-       int handled = 0;
-       unsigned int irq;
+       struct amd_gpio *gpio_dev = dev_id;
+       struct gpio_chip *gc = &gpio_dev->gc;
+       irqreturn_t ret = IRQ_NONE;
+       unsigned int i, irqnr;
        unsigned long flags;
-       struct irq_chip *chip = irq_desc_get_chip(desc);
-       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-       struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+       u32 *regs, regval;
+       u64 status, mask;
 
-       chained_irq_enter(chip, desc);
-       /*enable GPIO interrupt again*/
+       /* Read the wake status */
        raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-       reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
-       reg64 = reg;
-       reg64 = reg64 << 32;
-
-       reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
-       reg64 |= reg;
+       status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
+       status <<= 32;
+       status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
        raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-       /*
-        * first 46 bits indicates interrupt status.
-        * one bit represents four interrupt sources.
-       */
-       for (off = 0; off < 46 ; off++) {
-               if (reg64 & BIT(off)) {
-                       for (i = 0; i < 4; i++) {
-                               pin_reg = readl(gpio_dev->base +
-                                               (off * 4 + i) * 4);
-                               if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
-                                       (pin_reg & BIT(WAKE_STS_OFF))) {
-                                       irq = irq_find_mapping(gc->irqdomain,
-                                                               off * 4 + i);
-                                       generic_handle_irq(irq);
-                                       writel(pin_reg,
-                                               gpio_dev->base
-                                               + (off * 4 + i) * 4);
-                                       handled++;
-                               }
-                       }
+       /* Bit 0-45 contain the relevant status bits */
+       status &= (1ULL << 46) - 1;
+       regs = gpio_dev->base;
+       for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
+               if (!(status & mask))
+                       continue;
+               status &= ~mask;
+
+               /* Each status bit covers four pins */
+               for (i = 0; i < 4; i++) {
+                       regval = readl(regs + i);
+                       if (!(regval & PIN_IRQ_PENDING))
+                               continue;
+                       irq = irq_find_mapping(gc->irqdomain, irqnr + i);
+                       generic_handle_irq(irq);
+                       /* Clear interrupt */
+                       writel(regval, regs + i);
+                       ret = IRQ_HANDLED;
                }
        }
 
-       if (handled == 0)
-               handle_bad_irq(desc);
-
+       /* Signal EOI to the GPIO unit */
        raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-       reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
-       reg |= EOI_MASK;
-       writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
+       regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+       regval |= EOI_MASK;
+       writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
        raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-       chained_irq_exit(chip, desc);
+       return ret;
 }
 
 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
@@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platform_device *pdev)
                goto out2;
        }
 
-       gpiochip_set_chained_irqchip(&gpio_dev->gc,
-                                &amd_gpio_irqchip,
-                                irq_base,
-                                amd_gpio_irq_handler);
+       ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
+                              KBUILD_MODNAME, gpio_dev);
+       if (ret)
+               goto out2;
+
        platform_set_drvdata(pdev, gpio_dev);
 
        dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
index d3c5f5dfbbd7974258e4105e3da7114ba7b2324a..222b6685b09f2d72f144daadbf3a3b67a06c1109 100644 (file)
@@ -798,7 +798,7 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev,
                break;
        case PIN_CONFIG_OUTPUT:
                __stm32_gpio_set(bank, offset, arg);
-               ret = stm32_pmx_gpio_set_direction(pctldev, NULL, pin, false);
+               ret = stm32_pmx_gpio_set_direction(pctldev, range, pin, false);
                break;
        default:
                ret = -EINVAL;
index ef29f18b195164745bb0a67d9a0852e5b3a676bc..4cc2f4ea0a25043abbfd205465cd3cedeefffa2b 100644 (file)
        } \
 }
 
-#ifdef CONFIG_PM_SLEEP
 static u8 suspend_prep_ok;
 static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
 static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
-#endif
 
 struct telemetry_susp_stats {
        u32 shlw_swake_ctr;
@@ -807,7 +805,6 @@ static const struct file_operations telem_ioss_trc_verb_ops = {
        .release        = single_release,
 };
 
-#ifdef CONFIG_PM_SLEEP
 static int pm_suspend_prep_cb(void)
 {
        struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
@@ -937,7 +934,6 @@ static int pm_notification(struct notifier_block *this,
 static struct notifier_block pm_notifier = {
        .notifier_call = pm_notification,
 };
-#endif /* CONFIG_PM_SLEEP */
 
 static int __init telemetry_debugfs_init(void)
 {
@@ -960,14 +956,13 @@ static int __init telemetry_debugfs_init(void)
        if (err < 0)
                return -EINVAL;
 
-
-#ifdef CONFIG_PM_SLEEP
        register_pm_notifier(&pm_notifier);
-#endif /* CONFIG_PM_SLEEP */
 
        debugfs_conf->telemetry_dbg_dir = debugfs_create_dir("telemetry", NULL);
-       if (!debugfs_conf->telemetry_dbg_dir)
-               return -ENOMEM;
+       if (!debugfs_conf->telemetry_dbg_dir) {
+               err = -ENOMEM;
+               goto out_pm;
+       }
 
        f = debugfs_create_file("pss_info", S_IFREG | S_IRUGO,
                                debugfs_conf->telemetry_dbg_dir, NULL,
@@ -1014,6 +1009,8 @@ static int __init telemetry_debugfs_init(void)
 out:
        debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
        debugfs_conf->telemetry_dbg_dir = NULL;
+out_pm:
+       unregister_pm_notifier(&pm_notifier);
 
        return err;
 }
@@ -1022,6 +1019,7 @@ static void __exit telemetry_debugfs_exit(void)
 {
        debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
        debugfs_conf->telemetry_dbg_dir = NULL;
+       unregister_pm_notifier(&pm_notifier);
 }
 
 late_initcall(telemetry_debugfs_init);
index e72abbc18ee31afb2e20808364e7830089f94d15..a66a317f3e4fedb6d7caaf2276c3fe3721391a58 100644 (file)
@@ -70,14 +70,14 @@ static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf)
 {
        return sprintf(buf, "I/O subchannel (Non-QDIO)\n");
 }
-MDEV_TYPE_ATTR_RO(name);
+static MDEV_TYPE_ATTR_RO(name);
 
 static ssize_t device_api_show(struct kobject *kobj, struct device *dev,
                               char *buf)
 {
        return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
 }
-MDEV_TYPE_ATTR_RO(device_api);
+static MDEV_TYPE_ATTR_RO(device_api);
 
 static ssize_t available_instances_show(struct kobject *kobj,
                                        struct device *dev, char *buf)
@@ -86,7 +86,7 @@ static ssize_t available_instances_show(struct kobject *kobj,
 
        return sprintf(buf, "%d\n", atomic_read(&private->avail));
 }
-MDEV_TYPE_ATTR_RO(available_instances);
+static MDEV_TYPE_ATTR_RO(available_instances);
 
 static struct attribute *mdev_types_attrs[] = {
        &mdev_type_attr_name.attr,
@@ -100,7 +100,7 @@ static struct attribute_group mdev_type_group = {
        .attrs = mdev_types_attrs,
 };
 
-struct attribute_group *mdev_type_groups[] = {
+static struct attribute_group *mdev_type_groups[] = {
        &mdev_type_group,
        NULL,
 };
@@ -152,7 +152,7 @@ static int vfio_ccw_mdev_open(struct mdev_device *mdev)
                                      &events, &private->nb);
 }
 
-void vfio_ccw_mdev_release(struct mdev_device *mdev)
+static void vfio_ccw_mdev_release(struct mdev_device *mdev)
 {
        struct vfio_ccw_private *private =
                dev_get_drvdata(mdev_parent_dev(mdev));
@@ -233,7 +233,7 @@ static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
        }
 }
 
-int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
+static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
 {
        if (info->index != VFIO_CCW_IO_IRQ_INDEX)
                return -EINVAL;
index 9be4596d8a089c7ab8fa35703ebd8c8252608e63..ea099910b4e99466db57f1c2868cc889234e99d3 100644 (file)
@@ -668,10 +668,28 @@ static int ap_device_probe(struct device *dev)
        struct ap_driver *ap_drv = to_ap_drv(dev->driver);
        int rc;
 
+       /* Add queue/card to list of active queues/cards */
+       spin_lock_bh(&ap_list_lock);
+       if (is_card_dev(dev))
+               list_add(&to_ap_card(dev)->list, &ap_card_list);
+       else
+               list_add(&to_ap_queue(dev)->list,
+                        &to_ap_queue(dev)->card->queues);
+       spin_unlock_bh(&ap_list_lock);
+
        ap_dev->drv = ap_drv;
        rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
-       if (rc)
+
+       if (rc) {
+               spin_lock_bh(&ap_list_lock);
+               if (is_card_dev(dev))
+                       list_del_init(&to_ap_card(dev)->list);
+               else
+                       list_del_init(&to_ap_queue(dev)->list);
+               spin_unlock_bh(&ap_list_lock);
                ap_dev->drv = NULL;
+       }
+
        return rc;
 }
 
@@ -680,14 +698,17 @@ static int ap_device_remove(struct device *dev)
        struct ap_device *ap_dev = to_ap_dev(dev);
        struct ap_driver *ap_drv = ap_dev->drv;
 
+       if (ap_drv->remove)
+               ap_drv->remove(ap_dev);
+
+       /* Remove queue/card from list of active queues/cards */
        spin_lock_bh(&ap_list_lock);
        if (is_card_dev(dev))
                list_del_init(&to_ap_card(dev)->list);
        else
                list_del_init(&to_ap_queue(dev)->list);
        spin_unlock_bh(&ap_list_lock);
-       if (ap_drv->remove)
-               ap_drv->remove(ap_dev);
+
        return 0;
 }
 
@@ -1056,10 +1077,6 @@ static void ap_scan_bus(struct work_struct *unused)
                                }
                                /* get it and thus adjust reference counter */
                                get_device(&ac->ap_dev.device);
-                               /* Add card device to card list */
-                               spin_lock_bh(&ap_list_lock);
-                               list_add(&ac->list, &ap_card_list);
-                               spin_unlock_bh(&ap_list_lock);
                        }
                        /* now create the new queue device */
                        aq = ap_queue_create(qid, type);
@@ -1070,10 +1087,6 @@ static void ap_scan_bus(struct work_struct *unused)
                        aq->ap_dev.device.parent = &ac->ap_dev.device;
                        dev_set_name(&aq->ap_dev.device,
                                     "%02x.%04x", id, dom);
-                       /* Add queue device to card queue list */
-                       spin_lock_bh(&ap_list_lock);
-                       list_add(&aq->list, &ac->queues);
-                       spin_unlock_bh(&ap_list_lock);
                        /* Start with a device reset */
                        spin_lock_bh(&aq->lock);
                        ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
@@ -1081,9 +1094,6 @@ static void ap_scan_bus(struct work_struct *unused)
                        /* Register device */
                        rc = device_register(&aq->ap_dev.device);
                        if (rc) {
-                               spin_lock_bh(&ap_list_lock);
-                               list_del_init(&aq->list);
-                               spin_unlock_bh(&ap_list_lock);
                                put_device(&aq->ap_dev.device);
                                continue;
                        }
index cfa161ccc74e92112e48a041cf7f24b99c9204e8..836efac968137aaa297b82476a96a7ee306c1f6a 100644 (file)
@@ -160,7 +160,14 @@ static struct device_type ap_card_type = {
 
 static void ap_card_device_release(struct device *dev)
 {
-       kfree(to_ap_card(dev));
+       struct ap_card *ac = to_ap_card(dev);
+
+       if (!list_empty(&ac->list)) {
+               spin_lock_bh(&ap_list_lock);
+               list_del_init(&ac->list);
+               spin_unlock_bh(&ap_list_lock);
+       }
+       kfree(ac);
 }
 
 struct ap_card *ap_card_create(int id, int queue_depth, int device_type,
index 480c58a637694e3c8c1f885b7eefdeb309e88102..0f1a5d02acb0e151092504754900a3d889514e17 100644 (file)
@@ -584,7 +584,14 @@ static struct device_type ap_queue_type = {
 
 static void ap_queue_device_release(struct device *dev)
 {
-       kfree(to_ap_queue(dev));
+       struct ap_queue *aq = to_ap_queue(dev);
+
+       if (!list_empty(&aq->list)) {
+               spin_lock_bh(&ap_list_lock);
+               list_del_init(&aq->list);
+               spin_unlock_bh(&ap_list_lock);
+       }
+       kfree(aq);
 }
 
 struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type)
index dba94b486f057822ba45d29bea1589adb4026ea5..fa732bd8672961ce89c911f5e60212db1e2da386 100644 (file)
@@ -1954,7 +1954,6 @@ static void netiucv_free_netdevice(struct net_device *dev)
                privptr->conn = NULL; privptr->fsm = NULL;
                /* privptr gets freed by free_netdev() */
        }
-       free_netdev(dev);
 }
 
 /**
@@ -1972,7 +1971,8 @@ static void netiucv_setup_netdevice(struct net_device *dev)
        dev->mtu                 = NETIUCV_MTU_DEFAULT;
        dev->min_mtu             = 576;
        dev->max_mtu             = NETIUCV_MTU_MAX;
-       dev->destructor          = netiucv_free_netdevice;
+       dev->needs_free_netdev   = true;
+       dev->priv_destructor     = netiucv_free_netdevice;
        dev->hard_header_len     = NETIUCV_HDRLEN;
        dev->addr_len            = 0;
        dev->type                = ARPHRD_SLIP;
index 8bc7ee1a8ca81626829329e80831ffa2d57b8c63..507512cc478b1dd2632e033ac7d9a2dc99b8ab5d 100644 (file)
@@ -870,7 +870,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi,
                QEDI_ERR(&qedi->dbg_ctx,
                         "Delayed or untracked cleanup response, itt=0x%x, tid=0x%x, cid=0x%x, task=%p\n",
                         protoitt, cqe->itid, qedi_conn->iscsi_conn_id, task);
-               WARN_ON(1);
        }
 }
 
index 09a294634bc7e8898a2d209a9a5cef3d50eb8f32..879d3b7462f94f38bba4618aecf51dde947aa458 100644 (file)
@@ -1499,11 +1499,9 @@ err_idx:
 
 void qedi_clear_task_idx(struct qedi_ctx *qedi, int idx)
 {
-       if (!test_and_clear_bit(idx, qedi->task_idx_map)) {
+       if (!test_and_clear_bit(idx, qedi->task_idx_map))
                QEDI_ERR(&qedi->dbg_ctx,
                         "FW task context, already cleared, tid=0x%x\n", idx);
-               WARN_ON(1);
-       }
 }
 
 void qedi_update_itt_map(struct qedi_ctx *qedi, u32 tid, u32 proto_itt,
index dc6ecd8243659012629e5a2c1206861eec647eb3..ff10d1f0a7e452fb1f526395794caf0bd1ef26c4 100644 (file)
@@ -231,16 +231,12 @@ static int ad7152_write_raw_samp_freq(struct device *dev, int val)
        if (i >= ARRAY_SIZE(ad7152_filter_rate_table))
                i = ARRAY_SIZE(ad7152_filter_rate_table) - 1;
 
-       mutex_lock(&chip->state_lock);
        ret = i2c_smbus_write_byte_data(chip->client,
                                        AD7152_REG_CFG2, AD7152_CFG2_OSR(i));
-       if (ret < 0) {
-               mutex_unlock(&chip->state_lock);
+       if (ret < 0)
                return ret;
-       }
 
        chip->filter_rate_setup = i;
-       mutex_unlock(&chip->state_lock);
 
        return ret;
 }
index cfe37eb026d6d4418664b767c7b61473d79b1020..859d0d6051cdf6748d298a8f547aff141e5c55c6 100644 (file)
@@ -152,7 +152,7 @@ static const struct net_device_ops mon_netdev_ops = {
 static void mon_setup(struct net_device *dev)
 {
        dev->netdev_ops = &mon_netdev_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        ether_setup(dev);
        dev->priv_flags |= IFF_NO_QUEUE;
        dev->type = ARPHRD_IEEE80211;
index 36c3189fc4b7f6f981ca683dd53267a5f9e541c3..bd4352fe2de315a8b1f636a73d09974f0bcd6628 100644 (file)
@@ -2667,7 +2667,8 @@ static int rtw_cfg80211_add_monitor_if (struct adapter *padapter, char *name, st
        mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
        strncpy(mon_ndev->name, name, IFNAMSIZ);
        mon_ndev->name[IFNAMSIZ - 1] = 0;
-       mon_ndev->destructor = rtw_ndev_destructor;
+       mon_ndev->needs_free_netdev = true;
+       mon_ndev->priv_destructor = rtw_ndev_destructor;
 
        mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
 
index f83cfc76505c441392f8384bca9cfda850d1b273..021589913681075bbcaeb50cf97add2bf4228629 100644 (file)
@@ -1207,8 +1207,6 @@ void rtw_ndev_destructor(struct net_device *ndev)
 
        if (ndev->ieee80211_ptr)
                kfree((u8 *)ndev->ieee80211_ptr);
-
-       free_netdev(ndev);
 }
 
 void rtw_dev_unload(struct adapter *padapter)
index 02db59e8b593309e6e4b161d977178947cd24c57..aa16d1ab955b43ae57c1a317beb365b2cfd2d476 100644 (file)
@@ -160,7 +160,7 @@ static int isFileReadable(char *path)
                oldfs = get_fs(); set_fs(get_ds());
 
                if (1!=readFile(fp, &buf, 1))
-                       ret = PTR_ERR(fp);
+                       ret = -EINVAL;
 
                set_fs(oldfs);
                filp_close(fp, NULL);
index 0d8f81591bed076fa1f89f7cd27360776488f349..3fdca2cdd8da954b5a9c9d906c8b2d2b5e14f040 100644 (file)
@@ -1279,6 +1279,18 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
         */
        if (dump_payload)
                goto after_immediate_data;
+       /*
+        * Check for underflow case where both EDTL and immediate data payload
+        * exceeds what is presented by CDB's TRANSFER LENGTH, and what has
+        * already been set in target_cmd_size_check() as se_cmd->data_length.
+        *
+        * For this special case, fail the command and dump the immediate data
+        * payload.
+        */
+       if (cmd->first_burst_len > cmd->se_cmd.data_length) {
+               cmd->sense_reason = TCM_INVALID_CDB_FIELD;
+               goto after_immediate_data;
+       }
 
        immed_ret = iscsit_handle_immediate_data(cmd, hdr,
                                        cmd->first_burst_len);
@@ -4423,8 +4435,11 @@ static void iscsit_logout_post_handler_closesession(
         * always sleep waiting for RX/TX thread shutdown to complete
         * within iscsit_close_connection().
         */
-       if (!conn->conn_transport->rdma_shutdown)
+       if (!conn->conn_transport->rdma_shutdown) {
                sleep = cmpxchg(&conn->tx_thread_active, true, false);
+               if (!sleep)
+                       return;
+       }
 
        atomic_set(&conn->conn_logout_remove, 0);
        complete(&conn->conn_logout_comp);
@@ -4440,8 +4455,11 @@ static void iscsit_logout_post_handler_samecid(
 {
        int sleep = 1;
 
-       if (!conn->conn_transport->rdma_shutdown)
+       if (!conn->conn_transport->rdma_shutdown) {
                sleep = cmpxchg(&conn->tx_thread_active, true, false);
+               if (!sleep)
+                       return;
+       }
 
        atomic_set(&conn->conn_logout_remove, 0);
        complete(&conn->conn_logout_comp);
index 9ab7090f7c839c6900cb30ddf7db1b8be4bc78cf..0912de7c0cf8f3ade048de694b4e75f77fe27acd 100644 (file)
@@ -136,7 +136,7 @@ int init_se_kmem_caches(void);
 void   release_se_kmem_caches(void);
 u32    scsi_get_new_index(scsi_index_t);
 void   transport_subsystem_check_init(void);
-void   transport_cmd_finish_abort(struct se_cmd *, int);
+int    transport_cmd_finish_abort(struct se_cmd *, int);
 unsigned char *transport_dump_cmd_direction(struct se_cmd *);
 void   transport_dump_dev_state(struct se_device *, char *, int *);
 void   transport_dump_dev_info(struct se_device *, struct se_lun *,
index dce1e1b47316173329292f90276843d26d32407b..13f47bf4d16b1d790ab470b92127254835e76078 100644 (file)
@@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
        kfree(tmr);
 }
 
-static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
+static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
 {
        unsigned long flags;
        bool remove = true, send_tas;
@@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
                transport_send_task_abort(cmd);
        }
 
-       transport_cmd_finish_abort(cmd, remove);
+       return transport_cmd_finish_abort(cmd, remove);
 }
 
 static int target_check_cdb_and_preempt(struct list_head *list,
@@ -184,8 +184,8 @@ void core_tmr_abort_task(
                cancel_work_sync(&se_cmd->work);
                transport_wait_for_tasks(se_cmd);
 
-               transport_cmd_finish_abort(se_cmd, true);
-               target_put_sess_cmd(se_cmd);
+               if (!transport_cmd_finish_abort(se_cmd, true))
+                       target_put_sess_cmd(se_cmd);
 
                printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
                                " ref_tag: %llu\n", ref_tag);
@@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list(
                cancel_work_sync(&cmd->work);
                transport_wait_for_tasks(cmd);
 
-               transport_cmd_finish_abort(cmd, 1);
-               target_put_sess_cmd(cmd);
+               if (!transport_cmd_finish_abort(cmd, 1))
+                       target_put_sess_cmd(cmd);
        }
 }
 
@@ -380,8 +380,8 @@ static void core_tmr_drain_state_list(
                cancel_work_sync(&cmd->work);
                transport_wait_for_tasks(cmd);
 
-               core_tmr_handle_tas_abort(cmd, tas);
-               target_put_sess_cmd(cmd);
+               if (!core_tmr_handle_tas_abort(cmd, tas))
+                       target_put_sess_cmd(cmd);
        }
 }
 
index 6025935036c976edeeee0d7a91df79a66aa84a2b..f1b3a46bdcaffaf8a301569ef7e328ad2c47087f 100644 (file)
@@ -651,9 +651,10 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
                percpu_ref_put(&lun->lun_ref);
 }
 
-void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
+int transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 {
        bool ack_kref = (cmd->se_cmd_flags & SCF_ACK_KREF);
+       int ret = 0;
 
        if (cmd->se_cmd_flags & SCF_SE_LUN_CMD)
                transport_lun_remove_cmd(cmd);
@@ -665,9 +666,11 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
                cmd->se_tfo->aborted_task(cmd);
 
        if (transport_cmd_check_stop_to_fabric(cmd))
-               return;
+               return 1;
        if (remove && ack_kref)
-               transport_put_cmd(cmd);
+               ret = transport_put_cmd(cmd);
+
+       return ret;
 }
 
 static void target_complete_failure_work(struct work_struct *work)
index 49d685ad0da90d1a1282dd9d25f31ad64db22087..45b554032332e882e9bc99cb5489044053bd663c 100644 (file)
@@ -315,6 +315,9 @@ void usb_remove_function(struct usb_configuration *c, struct usb_function *f)
        list_del(&f->list);
        if (f->unbind)
                f->unbind(c, f);
+
+       if (f->bind_deactivated)
+               usb_function_activate(f);
 }
 EXPORT_SYMBOL_GPL(usb_remove_function);
 
@@ -956,12 +959,8 @@ static void remove_config(struct usb_composite_dev *cdev,
 
                f = list_first_entry(&config->functions,
                                struct usb_function, list);
-               list_del(&f->list);
-               if (f->unbind) {
-                       DBG(cdev, "unbind function '%s'/%p\n", f->name, f);
-                       f->unbind(config, f);
-                       /* may free memory for "f" */
-               }
+
+               usb_remove_function(config, f);
        }
        list_del(&config->list);
        if (config->unbind) {
index b4058f0000e4878efae4a475f834d06f16679fdd..6a1ce6a551587f232207612404df80807af215cd 100644 (file)
@@ -281,7 +281,7 @@ static void pn_net_setup(struct net_device *dev)
        dev->tx_queue_len       = 1;
 
        dev->netdev_ops         = &pn_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->header_ops         = &phonet_header_ops;
 }
 
index b9ca0a26cbd93e540a2df8f78544adb81e298805..684900fcfe24c3c5ab206568f24da857434a654f 100644 (file)
@@ -1183,8 +1183,10 @@ dev_release (struct inode *inode, struct file *fd)
 
        /* closing ep0 === shutdown all */
 
-       if (dev->gadget_registered)
+       if (dev->gadget_registered) {
                usb_gadget_unregister_driver (&gadgetfs_driver);
+               dev->gadget_registered = false;
+       }
 
        /* at this point "good" hardware has disconnected the
         * device from USB; the host won't see it any more.
@@ -1677,9 +1679,10 @@ static void
 gadgetfs_suspend (struct usb_gadget *gadget)
 {
        struct dev_data         *dev = get_gadget_data (gadget);
+       unsigned long           flags;
 
        INFO (dev, "suspended from state %d\n", dev->state);
-       spin_lock (&dev->lock);
+       spin_lock_irqsave(&dev->lock, flags);
        switch (dev->state) {
        case STATE_DEV_SETUP:           // VERY odd... host died??
        case STATE_DEV_CONNECTED:
@@ -1690,7 +1693,7 @@ gadgetfs_suspend (struct usb_gadget *gadget)
        default:
                break;
        }
-       spin_unlock (&dev->lock);
+       spin_unlock_irqrestore(&dev->lock, flags);
 }
 
 static struct usb_gadget_driver gadgetfs_driver = {
index ccabb51cb98da69b4b72d46a59846f3b97e1b8f6..7635fd7cc328caa371751d7a6ac15a5bb9ebdbae 100644 (file)
@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
                /* Report reset and disconnect events to the driver */
                if (dum->driver && (disconnect || reset)) {
                        stop_activity(dum);
-                       spin_unlock(&dum->lock);
                        if (reset)
                                usb_gadget_udc_reset(&dum->gadget, dum->driver);
                        else
                                dum->driver->disconnect(&dum->gadget);
-                       spin_lock(&dum->lock);
                }
        } else if (dum_hcd->active != dum_hcd->old_active) {
-               if (dum_hcd->old_active && dum->driver->suspend) {
-                       spin_unlock(&dum->lock);
+               if (dum_hcd->old_active && dum->driver->suspend)
                        dum->driver->suspend(&dum->gadget);
-                       spin_lock(&dum->lock);
-               } else if (!dum_hcd->old_active &&  dum->driver->resume) {
-                       spin_unlock(&dum->lock);
+               else if (!dum_hcd->old_active &&  dum->driver->resume)
                        dum->driver->resume(&dum->gadget);
-                       spin_lock(&dum->lock);
-               }
        }
 
        dum_hcd->old_status = dum_hcd->port_status;
@@ -983,7 +976,9 @@ static int dummy_udc_stop(struct usb_gadget *g)
        struct dummy_hcd        *dum_hcd = gadget_to_dummy_hcd(g);
        struct dummy            *dum = dum_hcd->dum;
 
+       spin_lock_irq(&dum->lock);
        dum->driver = NULL;
+       spin_unlock_irq(&dum->lock);
 
        return 0;
 }
index 6cf07857eacaa19b873b18c299079fd07507a5cf..f2cbd7f8005e149e028a11409aaa6aedc0716c36 100644 (file)
@@ -2470,11 +2470,8 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
                nuke(&dev->ep[i]);
 
        /* report disconnect; the driver is already quiesced */
-       if (driver) {
-               spin_unlock(&dev->lock);
+       if (driver)
                driver->disconnect(&dev->gadget);
-               spin_lock(&dev->lock);
-       }
 
        usb_reinit(dev);
 }
@@ -3348,8 +3345,6 @@ next_endpoints:
                BIT(PCI_RETRY_ABORT_INTERRUPT))
 
 static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
-__releases(dev->lock)
-__acquires(dev->lock)
 {
        struct net2280_ep       *ep;
        u32                     tmp, num, mask, scratch;
@@ -3390,14 +3385,12 @@ __acquires(dev->lock)
                        if (disconnect || reset) {
                                stop_activity(dev, dev->driver);
                                ep0_start(dev);
-                               spin_unlock(&dev->lock);
                                if (reset)
                                        usb_gadget_udc_reset
                                                (&dev->gadget, dev->driver);
                                else
                                        (dev->driver->disconnect)
                                                (&dev->gadget);
-                               spin_lock(&dev->lock);
                                return;
                        }
                }
index 1f1687e888d623c33ffe2413fb5584f02c6b733e..fddf2731f798ea3a05a5b18bae7749c064eb4af7 100644 (file)
@@ -2119,11 +2119,12 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
 {
        u32 temp, port_offset, port_count;
        int i;
-       u8 major_revision;
+       u8 major_revision, minor_revision;
        struct xhci_hub *rhub;
 
        temp = readl(addr);
        major_revision = XHCI_EXT_PORT_MAJOR(temp);
+       minor_revision = XHCI_EXT_PORT_MINOR(temp);
 
        if (major_revision == 0x03) {
                rhub = &xhci->usb3_rhub;
@@ -2137,7 +2138,9 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
                return;
        }
        rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp);
-       rhub->min_rev = XHCI_EXT_PORT_MINOR(temp);
+
+       if (rhub->min_rev < minor_revision)
+               rhub->min_rev = minor_revision;
 
        /* Port offset and count in the third dword, see section 7.2 */
        temp = readl(addr + 2);
index fcf1f3f63e7af3d60a62675beddca912ac853428..1bcf971141c09a69f3cd1674cca282bcc6ec8d46 100644 (file)
@@ -201,6 +201,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
                        pdev->device == 0x1042)
                xhci->quirks |= XHCI_BROKEN_STREAMS;
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+                       pdev->device == 0x1142)
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 
        if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
                xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
index 687ebb053438b343d63c77881aeebcdc0ad7f857..41d7979d81c53df3d459d39939798659386444a8 100644 (file)
@@ -1048,7 +1048,7 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 
        for (i = 0; i < (128 - edid[2]) / DETAILED_TIMING_DESCRIPTION_SIZE;
             i++, block += DETAILED_TIMING_DESCRIPTION_SIZE)
-               if (PIXEL_CLOCK)
+               if (PIXEL_CLOCK != 0)
                        edt[num++] = block - edid;
 
        /* Yikes, EDID data is totally useless */
index ec2e7e3536859cae3294d484c5bb56b5330c6db5..449fceaf79d5505a0e2c409adeb968dbaad4413c 100644 (file)
@@ -1646,8 +1646,9 @@ static int ufx_usb_probe(struct usb_interface *interface,
        dev_dbg(dev->gdev, "%s %s - serial #%s\n",
                usbdev->manufacturer, usbdev->product, usbdev->serial);
        dev_dbg(dev->gdev, "vid_%04x&pid_%04x&rev_%04x driver's ufx_data struct at %p\n",
-               usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
-               usbdev->descriptor.bcdDevice, dev);
+               le16_to_cpu(usbdev->descriptor.idVendor),
+               le16_to_cpu(usbdev->descriptor.idProduct),
+               le16_to_cpu(usbdev->descriptor.bcdDevice), dev);
        dev_dbg(dev->gdev, "console enable=%d\n", console);
        dev_dbg(dev->gdev, "fb_defio enable=%d\n", fb_defio);
 
index 6a3c353de7c35468e68f271126dca1c0b447ae82..05ef657235df2eb72c68e8a892d70e3edadd17d8 100644 (file)
@@ -1105,8 +1105,8 @@ static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
        char *bufptr;
        struct urb *urb;
 
-       pr_info("/dev/fb%d FB_BLANK mode %d --> %d\n",
-               info->node, dev->blank_mode, blank_mode);
+       pr_debug("/dev/fb%d FB_BLANK mode %d --> %d\n",
+                info->node, dev->blank_mode, blank_mode);
 
        if ((dev->blank_mode == FB_BLANK_POWERDOWN) &&
            (blank_mode != FB_BLANK_POWERDOWN)) {
@@ -1613,8 +1613,9 @@ static int dlfb_usb_probe(struct usb_interface *interface,
        pr_info("%s %s - serial #%s\n",
                usbdev->manufacturer, usbdev->product, usbdev->serial);
        pr_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n",
-               usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
-               usbdev->descriptor.bcdDevice, dev);
+               le16_to_cpu(usbdev->descriptor.idVendor),
+               le16_to_cpu(usbdev->descriptor.idProduct),
+               le16_to_cpu(usbdev->descriptor.bcdDevice), dev);
        pr_info("console enable=%d\n", console);
        pr_info("fb_defio enable=%d\n", fb_defio);
        pr_info("shadow enable=%d\n", shadow);
index f9718f012aae9be85a9568a2ce7be0740f08f5f6..badee04ef496cefd02b8f3f2faebb21fafb839b5 100644 (file)
@@ -1630,16 +1630,14 @@ static void viafb_init_proc(struct viafb_shared *shared)
 }
 static void viafb_remove_proc(struct viafb_shared *shared)
 {
-       struct proc_dir_entry *viafb_entry = shared->proc_entry,
-               *iga1_entry = shared->iga1_proc_entry,
-               *iga2_entry = shared->iga2_proc_entry;
+       struct proc_dir_entry *viafb_entry = shared->proc_entry;
 
        if (!viafb_entry)
                return;
 
-       remove_proc_entry("output_devices", iga2_entry);
+       remove_proc_entry("output_devices", shared->iga2_proc_entry);
        remove_proc_entry("iga2", viafb_entry);
-       remove_proc_entry("output_devices", iga1_entry);
+       remove_proc_entry("output_devices", shared->iga1_proc_entry);
        remove_proc_entry("iga1", viafb_entry);
        remove_proc_entry("supported_output_devices", viafb_entry);
 
index 408c174ef0d5c076dc2f51da612b8e0f3dfa8269..22caf808bfaba97e45662de0f4150632bcb85d2f 100644 (file)
@@ -663,6 +663,12 @@ static int virtballoon_restore(struct virtio_device *vdev)
 }
 #endif
 
+static int virtballoon_validate(struct virtio_device *vdev)
+{
+       __virtio_clear_bit(vdev, VIRTIO_F_IOMMU_PLATFORM);
+       return 0;
+}
+
 static unsigned int features[] = {
        VIRTIO_BALLOON_F_MUST_TELL_HOST,
        VIRTIO_BALLOON_F_STATS_VQ,
@@ -675,6 +681,7 @@ static struct virtio_driver virtio_balloon_driver = {
        .driver.name =  KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table =     id_table,
+       .validate =     virtballoon_validate,
        .probe =        virtballoon_probe,
        .remove =       virtballoon_remove,
        .config_changed = virtballoon_changed,
index 734cbf8d9676bd6f6f26561249504ccffd9f8360..dd9f1bebb5a3a980b55e5d0fb758c93e4f694722 100644 (file)
@@ -344,7 +344,7 @@ static int autofs_dev_ioctl_fail(struct file *fp,
        int status;
 
        token = (autofs_wqt_t) param->fail.token;
-       status = param->fail.status ? param->fail.status : -ENOENT;
+       status = param->fail.status < 0 ? param->fail.status : -ENOENT;
        return autofs4_wait_release(sbi, token, status);
 }
 
index 519599dddd3692ee373a9eb00d95d5757556ad42..0a7404ef9335bf7ea19926e2896c9b737951afe5 100644 (file)
@@ -263,7 +263,10 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
                kfree(vecs);
 
        if (unlikely(bio.bi_error))
-               return bio.bi_error;
+               ret = bio.bi_error;
+
+       bio_uninit(&bio);
+
        return ret;
 }
 
index a97fdc156a03512bf36df40dd1b4278df845115f..baacc18668611b778b9270256a8962b439e4b78e 100644 (file)
@@ -38,6 +38,7 @@ u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length)
 {
        SHASH_DESC_ON_STACK(shash, tfm);
        u32 *ctx = (u32 *)shash_desc_ctx(shash);
+       u32 retval;
        int err;
 
        shash->tfm = tfm;
@@ -47,5 +48,7 @@ u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length)
        err = crypto_shash_update(shash, address, length);
        BUG_ON(err);
 
-       return *ctx;
+       retval = *ctx;
+       barrier_data(ctx);
+       return retval;
 }
index 987044bca1c27176ab4d6fca34e5787ae3f9404c..59cb307b15fbea58eca82535b7a7b30ec6db5409 100644 (file)
@@ -131,6 +131,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        }
 
        if (new_mode != old_mode) {
+               newattrs.ia_ctime = current_time(inode);
                newattrs.ia_mode = new_mode;
                newattrs.ia_valid = ATTR_MODE;
                ret = __ceph_setattr(inode, &newattrs);
index e8f11fa565c53ac58fddf402f6ade6320d47d490..7df550c13d7f3e25c2f0f4d6259bd92255a44f58 100644 (file)
@@ -91,6 +91,10 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
                ceph_mdsc_put_request(req);
                if (!inode)
                        return ERR_PTR(-ESTALE);
+               if (inode->i_nlink == 0) {
+                       iput(inode);
+                       return ERR_PTR(-ESTALE);
+               }
        }
 
        return d_obtain_alias(inode);
index dcce79b844064447af8e542fe34188a4f58e22d9..4de6cdddf05928a29051e9996e75245732fee618 100644 (file)
@@ -2022,7 +2022,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                    attr->ia_size > inode->i_size) {
                        i_size_write(inode, attr->ia_size);
                        inode->i_blocks = calc_inode_blocks(attr->ia_size);
-                       inode->i_ctime = attr->ia_ctime;
                        ci->i_reported_size = attr->ia_size;
                        dirtied |= CEPH_CAP_FILE_EXCL;
                } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
@@ -2044,7 +2043,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                     inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
                     attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
                     only ? "ctime only" : "ignored");
-               inode->i_ctime = attr->ia_ctime;
                if (only) {
                        /*
                         * if kernel wants to dirty ctime but nothing else,
@@ -2067,7 +2065,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
        if (dirtied) {
                inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied,
                                                           &prealloc_cf);
-               inode->i_ctime = current_time(inode);
+               inode->i_ctime = attr->ia_ctime;
        }
 
        release &= issued;
@@ -2085,6 +2083,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                req->r_inode_drop = release;
                req->r_args.setattr.mask = cpu_to_le32(mask);
                req->r_num_caps = 1;
+               req->r_stamp = attr->ia_ctime;
                err = ceph_mdsc_do_request(mdsc, NULL, req);
        }
        dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
index f38e56fa97129d646285fa2b433e8130c7b85312..0c05df44cc6c8888d56d32f53d54fba109f8508c 100644 (file)
@@ -1687,7 +1687,6 @@ struct ceph_mds_request *
 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
 {
        struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
-       struct timespec ts;
 
        if (!req)
                return ERR_PTR(-ENOMEM);
@@ -1706,8 +1705,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
        init_completion(&req->r_safe_completion);
        INIT_LIST_HEAD(&req->r_unsafe_item);
 
-       ktime_get_real_ts(&ts);
-       req->r_stamp = timespec_trunc(ts, mdsc->fsc->sb->s_time_gran);
+       req->r_stamp = timespec_trunc(current_kernel_time(), mdsc->fsc->sb->s_time_gran);
 
        req->r_op = op;
        req->r_direct_mode = mode;
index 0fd081bd2a2f5d3fb4ed18fdcb7a1371cf9f5627..fcef70602b278b48ffd74e97f10d2a57b6968cc3 100644 (file)
@@ -3271,7 +3271,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
        if (!is_sync_kiocb(iocb))
                ctx->iocb = iocb;
 
-       if (to->type & ITER_IOVEC)
+       if (to->type == ITER_IOVEC)
                ctx->should_dirty = true;
 
        rc = setup_aio_ctx_iter(ctx, to, READ);
index b08531977daa4084f774c75de33204b2b6fa0902..3b147dc6af6344ee5c5e616466403f2cc211dbcb 100644 (file)
@@ -810,7 +810,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
 
        if (!pages) {
                pages = vmalloc(max_pages * sizeof(struct page *));
-               if (!bv) {
+               if (!pages) {
                        kvfree(bv);
                        return -ENOMEM;
                }
index 27bc360c7ffd7e1081f907c5f080dc4ba439fbfc..a723df3e01978cdca30afbf107772898ce66f33a 100644 (file)
@@ -849,8 +849,13 @@ cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
                     struct cifs_fid *fid, __u16 search_flags,
                     struct cifs_search_info *srch_inf)
 {
-       return CIFSFindFirst(xid, tcon, path, cifs_sb,
-                            &fid->netfid, search_flags, srch_inf, true);
+       int rc;
+
+       rc = CIFSFindFirst(xid, tcon, path, cifs_sb,
+                          &fid->netfid, search_flags, srch_inf, true);
+       if (rc)
+               cifs_dbg(FYI, "find first failed=%d\n", rc);
+       return rc;
 }
 
 static int
index c58691834eb2b74fa34f3fe2661ed3e211c4d22e..7e48561abd299012616428d28f256906a7c5381f 100644 (file)
@@ -982,7 +982,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
        rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
        kfree(utf16_path);
        if (rc) {
-               cifs_dbg(VFS, "open dir failed\n");
+               cifs_dbg(FYI, "open dir failed rc=%d\n", rc);
                return rc;
        }
 
@@ -992,7 +992,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
        rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
                                  fid->volatile_fid, 0, srch_inf);
        if (rc) {
-               cifs_dbg(VFS, "query directory failed\n");
+               cifs_dbg(FYI, "query directory failed rc=%d\n", rc);
                SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
        }
        return rc;
@@ -1809,7 +1809,8 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
 
        sg = init_sg(rqst, sign);
        if (!sg) {
-               cifs_dbg(VFS, "%s: Failed to init sg %d", __func__, rc);
+               cifs_dbg(VFS, "%s: Failed to init sg", __func__);
+               rc = -ENOMEM;
                goto free_req;
        }
 
@@ -1817,6 +1818,7 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
        iv = kzalloc(iv_len, GFP_KERNEL);
        if (!iv) {
                cifs_dbg(VFS, "%s: Failed to alloc IV", __func__);
+               rc = -ENOMEM;
                goto free_sg;
        }
        iv[0] = 3;
index 3cb5c9e2d4e78f641549818fbbad7681b193854d..de50e749ff058d79c67f7462962614c8c835ecdb 100644 (file)
@@ -188,8 +188,6 @@ static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode,
        pcreatetime = (__u64 *)value;
        *pcreatetime = CIFS_I(inode)->createtime;
        return sizeof(__u64);
-
-       return rc;
 }
 
 
index 8b2a994042ddeb2d1b8c00bbee3436e79fff52ad..a66f6624d89943997d1d35ead214aee85857e5d7 100644 (file)
@@ -138,6 +138,14 @@ struct config_item *config_item_get(struct config_item *item)
 }
 EXPORT_SYMBOL(config_item_get);
 
+struct config_item *config_item_get_unless_zero(struct config_item *item)
+{
+       if (item && kref_get_unless_zero(&item->ci_kref))
+               return item;
+       return NULL;
+}
+EXPORT_SYMBOL(config_item_get_unless_zero);
+
 static void config_item_cleanup(struct config_item *item)
 {
        struct config_item_type *t = item->ci_type;
index a6ab012a2c6acf9815bb8d4d1e29fb4568084b08..c8aabba502f6d7f019890bcdeba2fcdd7a56717f 100644 (file)
@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item,
        ret = -ENOMEM;
        sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
        if (sl) {
-               sl->sl_target = config_item_get(item);
                spin_lock(&configfs_dirent_lock);
                if (target_sd->s_type & CONFIGFS_USET_DROPPING) {
                        spin_unlock(&configfs_dirent_lock);
-                       config_item_put(item);
                        kfree(sl);
                        return -ENOENT;
                }
+               sl->sl_target = config_item_get(item);
                list_add(&sl->sl_list, &target_sd->s_links);
                spin_unlock(&configfs_dirent_lock);
                ret = configfs_create_link(sl, parent_item->ci_dentry,
index 2a6889b3585f068c73091d8895639b7e941d702a..9187f3b07f3e7f7b8546724d83dd06f4d16e7d8b 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -859,6 +859,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,
                        if (ret < 0)
                                goto out;
                }
+               start_index = indices[pvec.nr - 1] + 1;
        }
 out:
        put_dax(dax_dev);
index cddf39777835d0d27a71862b244cec37528b195b..a9f995f6859eb19ea3c5cddac19d86512ccf1d1e 100644 (file)
@@ -1494,7 +1494,7 @@ static void check_and_drop(void *_data)
 {
        struct detach_data *data = _data;
 
-       if (!data->mountpoint && !data->select.found)
+       if (!data->mountpoint && list_empty(&data->select.dispose))
                __d_drop(data->select.start);
 }
 
@@ -1536,17 +1536,15 @@ void d_invalidate(struct dentry *dentry)
 
                d_walk(dentry, &data, detach_and_collect, check_and_drop);
 
-               if (data.select.found)
+               if (!list_empty(&data.select.dispose))
                        shrink_dentry_list(&data.select.dispose);
+               else if (!data.mountpoint)
+                       return;
 
                if (data.mountpoint) {
                        detach_mounts(data.mountpoint);
                        dput(data.mountpoint);
                }
-
-               if (!data.mountpoint && !data.select.found)
-                       break;
-
                cond_resched();
        }
 }
index 72934df6847150ba50dfbadad78fe10e01d2eadd..904199086490d5fdf05d0eda850d04a3ce572fa5 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -220,8 +220,26 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 
        if (write) {
                unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+               unsigned long ptr_size;
                struct rlimit *rlim;
 
+               /*
+                * Since the stack will hold pointers to the strings, we
+                * must account for them as well.
+                *
+                * The size calculation is the entire vma while each arg page is
+                * built, so each time we get here it's calculating how far it
+                * is currently (rather than each call being just the newly
+                * added size from the arg page).  As a result, we need to
+                * always add the entire size of the pointers, so that on the
+                * last call to get_arg_page() we'll actually have the entire
+                * correct size.
+                */
+               ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
+               if (ptr_size > ULONG_MAX - size)
+                       goto fail;
+               size += ptr_size;
+
                acct_arg_size(bprm, size / PAGE_SIZE);
 
                /*
@@ -239,13 +257,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                 *    to work from.
                 */
                rlim = current->signal->rlim;
-               if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
-                       put_page(page);
-                       return NULL;
-               }
+               if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4)
+                       goto fail;
        }
 
        return page;
+
+fail:
+       put_page(page);
+       return NULL;
 }
 
 static void put_arg_page(struct page *page)
index 2185c7a040a12cf8b6e190df97b58bc7eecc6299..fd2e651bad6d3c620b83f9dc32e25dfad22a4e7f 100644 (file)
@@ -1078,6 +1078,7 @@ static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
 {
        SHASH_DESC_ON_STACK(shash, sbi->s_chksum_driver);
        u32 *ctx = (u32 *)shash_desc_ctx(shash);
+       u32 retval;
        int err;
 
        shash->tfm = sbi->s_chksum_driver;
@@ -1087,7 +1088,9 @@ static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
        err = crypto_shash_update(shash, address, length);
        BUG_ON(err);
 
-       return *ctx;
+       retval = *ctx;
+       barrier_data(ctx);
+       return retval;
 }
 
 static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc,
index dde861387a407810b35f73ff37c3ce6389048326..d44f5456eb9baf943186a2d145736c6435f891fb 100644 (file)
@@ -200,7 +200,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                addr = ALIGN(addr, huge_page_size(h));
                vma = find_vma(mm, addr);
                if (TASK_SIZE - len >= addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)))
                        return addr;
        }
 
index 8bd3e4d448b9f07a8aa148c8d08c092f45471a7c..5a4438445bf788e65ade26b741911861d7ea2084 100644 (file)
@@ -3488,6 +3488,8 @@ static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns)
                return err;
        }
 
+       put_mnt_ns(old_mnt_ns);
+
        /* Update the pwd and root */
        set_fs_pwd(fs, &root);
        set_fs_root(fs, &root);
index c14758e08d738eec44bf08c79acee71366ce0e70..390ac9c39c5932ef93f3ae8d3a5615f2737848af 100644 (file)
@@ -753,7 +753,6 @@ static void nfs4_callback_free_slot(struct nfs4_session *session,
         * A single slot, so highest used slotid is either 0 or -1
         */
        nfs4_free_slot(tbl, slot);
-       nfs4_slot_tbl_drain_complete(tbl);
        spin_unlock(&tbl->slot_tbl_lock);
 }
 
index 32ccd7754f8a2875933d1f9c532b54c656971bfd..2ac00bf4ecf146815bff44755f4406161e569007 100644 (file)
@@ -1946,29 +1946,6 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 }
 EXPORT_SYMBOL_GPL(nfs_link);
 
-static void
-nfs_complete_rename(struct rpc_task *task, struct nfs_renamedata *data)
-{
-       struct dentry *old_dentry = data->old_dentry;
-       struct dentry *new_dentry = data->new_dentry;
-       struct inode *old_inode = d_inode(old_dentry);
-       struct inode *new_inode = d_inode(new_dentry);
-
-       nfs_mark_for_revalidate(old_inode);
-
-       switch (task->tk_status) {
-       case 0:
-               if (new_inode != NULL)
-                       nfs_drop_nlink(new_inode);
-               d_move(old_dentry, new_dentry);
-               nfs_set_verifier(new_dentry,
-                                       nfs_save_change_attribute(data->new_dir));
-               break;
-       case -ENOENT:
-               nfs_dentry_handle_enoent(old_dentry);
-       }
-}
-
 /*
  * RENAME
  * FIXME: Some nfsds, like the Linux user space nfsd, may generate a
@@ -1999,7 +1976,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;
+       struct dentry *dentry = NULL, *rehash = NULL;
        struct rpc_task *task;
        int error = -EBUSY;
 
@@ -2022,8 +1999,10 @@ 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;
@@ -2040,6 +2019,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                                goto out;
 
                        new_dentry = dentry;
+                       rehash = NULL;
                        new_inode = NULL;
                }
        }
@@ -2048,8 +2028,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (new_inode != NULL)
                NFS_PROTO(new_inode)->return_delegation(new_inode);
 
-       task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
-                                       nfs_complete_rename);
+       task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
        if (IS_ERR(task)) {
                error = PTR_ERR(task);
                goto out;
@@ -2059,9 +2038,27 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (error == 0)
                error = task->tk_status;
        rpc_put_task(task);
+       nfs_mark_for_revalidate(old_inode);
 out:
+       if (rehash)
+               d_rehash(rehash);
        trace_nfs_rename_exit(old_dir, old_dentry,
                        new_dir, new_dentry, error);
+       if (!error) {
+               if (new_inode != NULL)
+                       nfs_drop_nlink(new_inode);
+               /*
+                * The d_move() should be here instead of in an async RPC completion
+                * handler because we need the proper locks to move the dentry.  If
+                * we're interrupted by a signal, the async RPC completion handler
+                * should mark the directories for revalidation.
+                */
+               d_move(old_dentry, new_dentry);
+               nfs_set_verifier(new_dentry,
+                                       nfs_save_change_attribute(new_dir));
+       } else if (error == -ENOENT)
+               nfs_dentry_handle_enoent(old_dentry);
+
        /* new dentry created? */
        if (dentry)
                dput(dentry);
index c08c46a3b8cde00ef5aa40fae87ed2fce06faea1..dbfa18900e25a38a0998a2d429644a860c559ac2 100644 (file)
@@ -2589,7 +2589,8 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
 
        /* Except MODE, it seems harmless of setting twice. */
        if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
-               attrset[1] & FATTR4_WORD1_MODE)
+               (attrset[1] & FATTR4_WORD1_MODE ||
+                attrset[2] & FATTR4_WORD2_MODE_UMASK))
                sattr->ia_valid &= ~ATTR_MODE;
 
        if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
@@ -8416,6 +8417,7 @@ static void nfs4_layoutget_release(void *calldata)
        size_t max_pages = max_response_pages(server);
 
        dprintk("--> %s\n", __func__);
+       nfs4_sequence_free_slot(&lgp->res.seq_res);
        nfs4_free_pages(lgp->args.layout.pages, max_pages);
        pnfs_put_layout_hdr(NFS_I(inode)->layout);
        put_nfs_open_context(lgp->args.ctx);
@@ -8490,7 +8492,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout, gfp_t gfp_flags)
        /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
        if (status == 0 && lgp->res.layoutp->len)
                lseg = pnfs_layout_process(lgp);
-       nfs4_sequence_free_slot(&lgp->res.seq_res);
        rpc_put_task(task);
        dprintk("<-- %s status=%d\n", __func__, status);
        if (status)
index b34de036501bc90e48be043aec38485f7f755e55..cbf82b0d446759a4934fbf7329e6a767ad5530ce 100644 (file)
@@ -2134,6 +2134,8 @@ again:
        put_rpccred(cred);
        switch (status) {
        case 0:
+       case -EINTR:
+       case -ERESTARTSYS:
                break;
        case -ETIMEDOUT:
                if (clnt->cl_softrtry)
index 3b7c937a36b528e67511a23b136215ffaab6d8e4..4689940a953c2f7fc3b3a0e07a7d01c8c09e7d9a 100644 (file)
@@ -2591,6 +2591,10 @@ void ocfs2_inode_unlock_tracker(struct inode *inode,
        struct ocfs2_lock_res *lockres;
 
        lockres = &OCFS2_I(inode)->ip_inode_lockres;
+       /* had_lock means that the currect process already takes the cluster
+        * lock previously. If had_lock is 1, we have nothing to do here, and
+        * it will get unlocked where we got the lock.
+        */
        if (!had_lock) {
                ocfs2_remove_holder(lockres, oh);
                ocfs2_inode_unlock(inode, ex);
index 3c5384d9b3a549f319b114a782c7daab966a2c28..f70c3778d600c6be63996572bee6fd46ac03440c 100644 (file)
@@ -1328,20 +1328,21 @@ static int ocfs2_xattr_get(struct inode *inode,
                           void *buffer,
                           size_t buffer_size)
 {
-       int ret;
+       int ret, had_lock;
        struct buffer_head *di_bh = NULL;
+       struct ocfs2_lock_holder oh;
 
-       ret = ocfs2_inode_lock(inode, &di_bh, 0);
-       if (ret < 0) {
-               mlog_errno(ret);
-               return ret;
+       had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 0, &oh);
+       if (had_lock < 0) {
+               mlog_errno(had_lock);
+               return had_lock;
        }
        down_read(&OCFS2_I(inode)->ip_xattr_sem);
        ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index,
                                     name, buffer, buffer_size);
        up_read(&OCFS2_I(inode)->ip_xattr_sem);
 
-       ocfs2_inode_unlock(inode, 0);
+       ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock);
 
        brelse(di_bh);
 
@@ -3537,11 +3538,12 @@ int ocfs2_xattr_set(struct inode *inode,
 {
        struct buffer_head *di_bh = NULL;
        struct ocfs2_dinode *di;
-       int ret, credits, ref_meta = 0, ref_credits = 0;
+       int ret, credits, had_lock, ref_meta = 0, ref_credits = 0;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        struct inode *tl_inode = osb->osb_tl_inode;
        struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, };
        struct ocfs2_refcount_tree *ref_tree = NULL;
+       struct ocfs2_lock_holder oh;
 
        struct ocfs2_xattr_info xi = {
                .xi_name_index = name_index,
@@ -3572,8 +3574,9 @@ int ocfs2_xattr_set(struct inode *inode,
                return -ENOMEM;
        }
 
-       ret = ocfs2_inode_lock(inode, &di_bh, 1);
-       if (ret < 0) {
+       had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 1, &oh);
+       if (had_lock < 0) {
+               ret = had_lock;
                mlog_errno(ret);
                goto cleanup_nolock;
        }
@@ -3670,7 +3673,7 @@ cleanup:
                if (ret)
                        mlog_errno(ret);
        }
-       ocfs2_inode_unlock(inode, 1);
+       ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock);
 cleanup_nolock:
        brelse(di_bh);
        brelse(xbs.xattr_bh);
index f0c8b33d99b137e0c607448237216c2826df3fe8..520802da059c25655eda0c1a421e963007b65ed7 100644 (file)
@@ -300,11 +300,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
 
        /* We don't show the stack guard page in /proc/maps */
        start = vma->vm_start;
-       if (stack_guard_page_start(vma, start))
-               start += PAGE_SIZE;
        end = vma->vm_end;
-       if (stack_guard_page_end(vma, end))
-               end -= PAGE_SIZE;
 
        seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
        seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
index 47c1d4484df9e6b69333215efc10d7a5db64210f..19d4d88fa285b39493d4b7793a69a23876a0988e 100644 (file)
@@ -1285,7 +1285,7 @@ static size_t compat_writev(struct file *file,
        if (!(file->f_mode & FMODE_CAN_WRITE))
                goto out;
 
-       ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos, 0);
+       ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos, flags);
 
 out:
        if (ret > 0)
index d642cc0a8271b06b6fea356d7b2d8893111f465d..f80be4c5df9d13b7009602dd5be2f4c58a5de1ac 100644 (file)
@@ -400,10 +400,12 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
        /*
         * There is not enough space for user on the device
         */
-       if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) {
-               mutex_unlock(&UFS_SB(sb)->s_lock);
-               UFSD("EXIT (FAILED)\n");
-               return 0;
+       if (unlikely(ufs_freefrags(uspi) <= uspi->s_root_blocks)) {
+               if (!capable(CAP_SYS_RESOURCE)) {
+                       mutex_unlock(&UFS_SB(sb)->s_lock);
+                       UFSD("EXIT (FAILED)\n");
+                       return 0;
+               }
        }
 
        if (goal >= uspi->s_size) 
@@ -421,12 +423,12 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
                if (result) {
                        ufs_clear_frags(inode, result + oldcount,
                                        newcount - oldcount, locked_page != NULL);
+                       *err = 0;
                        write_seqlock(&UFS_I(inode)->meta_lock);
                        ufs_cpu_to_data_ptr(sb, p, result);
-                       write_sequnlock(&UFS_I(inode)->meta_lock);
-                       *err = 0;
                        UFS_I(inode)->i_lastfrag =
                                max(UFS_I(inode)->i_lastfrag, fragment + count);
+                       write_sequnlock(&UFS_I(inode)->meta_lock);
                }
                mutex_unlock(&UFS_SB(sb)->s_lock);
                UFSD("EXIT, result %llu\n", (unsigned long long)result);
@@ -439,8 +441,10 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
        result = ufs_add_fragments(inode, tmp, oldcount, newcount);
        if (result) {
                *err = 0;
+               read_seqlock_excl(&UFS_I(inode)->meta_lock);
                UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag,
                                                fragment + count);
+               read_sequnlock_excl(&UFS_I(inode)->meta_lock);
                ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
                                locked_page != NULL);
                mutex_unlock(&UFS_SB(sb)->s_lock);
@@ -451,39 +455,29 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
        /*
         * allocate new block and move data
         */
-       switch (fs32_to_cpu(sb, usb1->fs_optim)) {
-           case UFS_OPTSPACE:
+       if (fs32_to_cpu(sb, usb1->fs_optim) == UFS_OPTSPACE) {
                request = newcount;
-               if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree
-                   > uspi->s_dsize * uspi->s_minfree / (2 * 100))
-                       break;
-               usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
-               break;
-           default:
-               usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
-       
-           case UFS_OPTTIME:
+               if (uspi->cs_total.cs_nffree < uspi->s_space_to_time)
+                       usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
+       } else {
                request = uspi->s_fpb;
-               if (uspi->cs_total.cs_nffree < uspi->s_dsize *
-                   (uspi->s_minfree - 2) / 100)
-                       break;
-               usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
-               break;
+               if (uspi->cs_total.cs_nffree > uspi->s_time_to_space)
+                       usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE);
        }
        result = ufs_alloc_fragments (inode, cgno, goal, request, err);
        if (result) {
                ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
                                locked_page != NULL);
+               mutex_unlock(&UFS_SB(sb)->s_lock);
                ufs_change_blocknr(inode, fragment - oldcount, oldcount,
                                   uspi->s_sbbase + tmp,
                                   uspi->s_sbbase + result, locked_page);
+               *err = 0;
                write_seqlock(&UFS_I(inode)->meta_lock);
                ufs_cpu_to_data_ptr(sb, p, result);
-               write_sequnlock(&UFS_I(inode)->meta_lock);
-               *err = 0;
                UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag,
                                                fragment + count);
-               mutex_unlock(&UFS_SB(sb)->s_lock);
+               write_sequnlock(&UFS_I(inode)->meta_lock);
                if (newcount < request)
                        ufs_free_fragments (inode, result + newcount, request - newcount);
                ufs_free_fragments (inode, tmp, oldcount);
index da553ffec85b459f0675c25033f173bbaeccb772..f36d6a53687d13fd817f65f99913a54d425e8048 100644 (file)
@@ -401,13 +401,20 @@ static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buff
        u64 phys64 = 0;
        unsigned frag = fragment & uspi->s_fpbmask;
 
-       if (!create) {
-               phys64 = ufs_frag_map(inode, offsets, depth);
-               if (phys64)
-                       map_bh(bh_result, sb, phys64 + frag);
-               return 0;
-       }
+       phys64 = ufs_frag_map(inode, offsets, depth);
+       if (!create)
+               goto done;
 
+       if (phys64) {
+               if (fragment >= UFS_NDIR_FRAGMENT)
+                       goto done;
+               read_seqlock_excl(&UFS_I(inode)->meta_lock);
+               if (fragment < UFS_I(inode)->i_lastfrag) {
+                       read_sequnlock_excl(&UFS_I(inode)->meta_lock);
+                       goto done;
+               }
+               read_sequnlock_excl(&UFS_I(inode)->meta_lock);
+       }
         /* This code entered only while writing ....? */
 
        mutex_lock(&UFS_I(inode)->truncate_mutex);
@@ -451,6 +458,11 @@ out:
        }
        mutex_unlock(&UFS_I(inode)->truncate_mutex);
        return err;
+
+done:
+       if (phys64)
+               map_bh(bh_result, sb, phys64 + frag);
+       return 0;
 }
 
 static int ufs_writepage(struct page *page, struct writeback_control *wbc)
@@ -554,10 +566,8 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
         */
        inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
        set_nlink(inode, fs16_to_cpu(sb, ufs_inode->ui_nlink));
-       if (inode->i_nlink == 0) {
-               ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
-               return -1;
-       }
+       if (inode->i_nlink == 0)
+               return -ESTALE;
 
        /*
         * Linux now has 32-bit uid and gid, so we can support EFT.
@@ -566,9 +576,9 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
        i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode));
 
        inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size);
-       inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec);
-       inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec);
-       inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec);
+       inode->i_atime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec);
+       inode->i_ctime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec);
+       inode->i_mtime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec);
        inode->i_mtime.tv_nsec = 0;
        inode->i_atime.tv_nsec = 0;
        inode->i_ctime.tv_nsec = 0;
@@ -602,10 +612,8 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
         */
        inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode);
        set_nlink(inode, fs16_to_cpu(sb, ufs2_inode->ui_nlink));
-       if (inode->i_nlink == 0) {
-               ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
-               return -1;
-       }
+       if (inode->i_nlink == 0)
+               return -ESTALE;
 
         /*
          * Linux now has 32-bit uid and gid, so we can support EFT.
@@ -645,7 +653,7 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
        struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        struct buffer_head * bh;
        struct inode *inode;
-       int err;
+       int err = -EIO;
 
        UFSD("ENTER, ino %lu\n", ino);
 
@@ -680,9 +688,10 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
                err = ufs1_read_inode(inode,
                                      ufs_inode + ufs_inotofsbo(inode->i_ino));
        }
-
+       brelse(bh);
        if (err)
                goto bad_inode;
+
        inode->i_version++;
        ufsi->i_lastfrag =
                (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -691,15 +700,13 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
 
        ufs_set_inode_ops(inode);
 
-       brelse(bh);
-
        UFSD("EXIT\n");
        unlock_new_inode(inode);
        return inode;
 
 bad_inode:
        iget_failed(inode);
-       return ERR_PTR(-EIO);
+       return ERR_PTR(err);
 }
 
 static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
@@ -874,7 +881,6 @@ static inline void free_data(struct to_free *ctx, u64 from, unsigned count)
        ctx->to = from + count;
 }
 
-#define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift)
 #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
 
 static void ufs_trunc_direct(struct inode *inode)
@@ -1112,19 +1118,24 @@ static void ufs_truncate_blocks(struct inode *inode)
        struct super_block *sb = inode->i_sb;
        struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        unsigned offsets[4];
-       int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets);
+       int depth;
        int depth2;
        unsigned i;
        struct ufs_buffer_head *ubh[3];
        void *p;
        u64 block;
 
-       if (!depth)
-               return;
+       if (inode->i_size) {
+               sector_t last = (inode->i_size - 1) >> uspi->s_bshift;
+               depth = ufs_block_to_path(inode, last, offsets);
+               if (!depth)
+                       return;
+       } else {
+               depth = 1;
+       }
 
-       /* find the last non-zero in offsets[] */
        for (depth2 = depth - 1; depth2; depth2--)
-               if (offsets[depth2])
+               if (offsets[depth2] != uspi->s_apb - 1)
                        break;
 
        mutex_lock(&ufsi->truncate_mutex);
@@ -1133,9 +1144,8 @@ static void ufs_truncate_blocks(struct inode *inode)
                offsets[0] = UFS_IND_BLOCK;
        } else {
                /* get the blocks that should be partially emptied */
-               p = ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]);
+               p = ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]++);
                for (i = 0; i < depth2; i++) {
-                       offsets[i]++;   /* next branch is fully freed */
                        block = ufs_data_ptr_to_cpu(sb, p);
                        if (!block)
                                break;
@@ -1146,7 +1156,7 @@ static void ufs_truncate_blocks(struct inode *inode)
                                write_sequnlock(&ufsi->meta_lock);
                                break;
                        }
-                       p = ubh_get_data_ptr(uspi, ubh[i], offsets[i + 1]);
+                       p = ubh_get_data_ptr(uspi, ubh[i], offsets[i + 1]++);
                }
                while (i--)
                        free_branch_tail(inode, offsets[i + 1], ubh[i], depth - i - 1);
@@ -1161,7 +1171,9 @@ static void ufs_truncate_blocks(struct inode *inode)
                        free_full_branch(inode, block, i - UFS_IND_BLOCK + 1);
                }
        }
+       read_seqlock_excl(&ufsi->meta_lock);
        ufsi->i_lastfrag = DIRECT_FRAGMENT;
+       read_sequnlock_excl(&ufsi->meta_lock);
        mark_inode_dirty(inode);
        mutex_unlock(&ufsi->truncate_mutex);
 }
index 878cc6264f1af4a87bf68bb71f2cb031bdb4b1a1..0a4f58a5073cb63feb94c2174c56d9889d2a37a4 100644 (file)
@@ -480,7 +480,7 @@ static void ufs_setup_cstotal(struct super_block *sb)
        usb3 = ubh_get_usb_third(uspi);
 
        if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
-            (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
+            (usb2->fs_un.fs_u2.fs_maxbsize == usb1->fs_bsize)) ||
            mtype == UFS_MOUNT_UFSTYPE_UFS2) {
                /*we have statistic in different place, then usual*/
                uspi->cs_total.cs_ndir = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir);
@@ -596,9 +596,7 @@ static void ufs_put_cstotal(struct super_block *sb)
        usb2 = ubh_get_usb_second(uspi);
        usb3 = ubh_get_usb_third(uspi);
 
-       if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
-            (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
-           mtype == UFS_MOUNT_UFSTYPE_UFS2) {
+       if (mtype == UFS_MOUNT_UFSTYPE_UFS2) {
                /*we have statistic in different place, then usual*/
                usb2->fs_un.fs_u2.cs_ndir =
                        cpu_to_fs64(sb, uspi->cs_total.cs_ndir);
@@ -608,16 +606,26 @@ static void ufs_put_cstotal(struct super_block *sb)
                        cpu_to_fs64(sb, uspi->cs_total.cs_nifree);
                usb3->fs_un1.fs_u2.cs_nffree =
                        cpu_to_fs64(sb, uspi->cs_total.cs_nffree);
-       } else {
-               usb1->fs_cstotal.cs_ndir =
-                       cpu_to_fs32(sb, uspi->cs_total.cs_ndir);
-               usb1->fs_cstotal.cs_nbfree =
-                       cpu_to_fs32(sb, uspi->cs_total.cs_nbfree);
-               usb1->fs_cstotal.cs_nifree =
-                       cpu_to_fs32(sb, uspi->cs_total.cs_nifree);
-               usb1->fs_cstotal.cs_nffree =
-                       cpu_to_fs32(sb, uspi->cs_total.cs_nffree);
+               goto out;
+       }
+
+       if (mtype == UFS_MOUNT_UFSTYPE_44BSD &&
+            (usb2->fs_un.fs_u2.fs_maxbsize == usb1->fs_bsize)) {
+               /* store stats in both old and new places */
+               usb2->fs_un.fs_u2.cs_ndir =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_ndir);
+               usb2->fs_un.fs_u2.cs_nbfree =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_nbfree);
+               usb3->fs_un1.fs_u2.cs_nifree =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_nifree);
+               usb3->fs_un1.fs_u2.cs_nffree =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_nffree);
        }
+       usb1->fs_cstotal.cs_ndir = cpu_to_fs32(sb, uspi->cs_total.cs_ndir);
+       usb1->fs_cstotal.cs_nbfree = cpu_to_fs32(sb, uspi->cs_total.cs_nbfree);
+       usb1->fs_cstotal.cs_nifree = cpu_to_fs32(sb, uspi->cs_total.cs_nifree);
+       usb1->fs_cstotal.cs_nffree = cpu_to_fs32(sb, uspi->cs_total.cs_nffree);
+out:
        ubh_mark_buffer_dirty(USPI_UBH(uspi));
        ufs_print_super_stuff(sb, usb1, usb2, usb3);
        UFSD("EXIT\n");
@@ -996,6 +1004,13 @@ again:
                flags |=  UFS_ST_SUN;
        }
 
+       if ((flags & UFS_ST_MASK) == UFS_ST_44BSD &&
+           uspi->s_postblformat == UFS_42POSTBLFMT) {
+               if (!silent)
+                       pr_err("this is not a 44bsd filesystem");
+               goto failed;
+       }
+
        /*
         * Check ufs magic number
         */
@@ -1143,8 +1158,8 @@ magic_found:
        uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask);
 
        if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
-               uspi->s_u2_size  = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size);
-               uspi->s_u2_dsize = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
+               uspi->s_size  = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size);
+               uspi->s_dsize = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
        } else {
                uspi->s_size  =  fs32_to_cpu(sb, usb1->fs_size);
                uspi->s_dsize =  fs32_to_cpu(sb, usb1->fs_dsize);
@@ -1193,6 +1208,18 @@ magic_found:
        uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
        uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);
 
+       uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize,
+                                             uspi->s_minfree, 100);
+       if (uspi->s_minfree <= 5) {
+               uspi->s_time_to_space = ~0ULL;
+               uspi->s_space_to_time = 0;
+               usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE);
+       } else {
+               uspi->s_time_to_space = (uspi->s_root_blocks / 2) + 1;
+               uspi->s_space_to_time = mul_u64_u32_div(uspi->s_dsize,
+                                             uspi->s_minfree - 2, 100) - 1;
+       }
+
        /*
         * Compute another frequently used values
         */
@@ -1382,19 +1409,17 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf)
        mutex_lock(&UFS_SB(sb)->s_lock);
        usb3 = ubh_get_usb_third(uspi);
        
-       if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
+       if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
                buf->f_type = UFS2_MAGIC;
-               buf->f_blocks = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
-       } else {
+       else
                buf->f_type = UFS_MAGIC;
-               buf->f_blocks = uspi->s_dsize;
-       }
-       buf->f_bfree = ufs_blkstofrags(uspi->cs_total.cs_nbfree) +
-               uspi->cs_total.cs_nffree;
+
+       buf->f_blocks = uspi->s_dsize;
+       buf->f_bfree = ufs_freefrags(uspi);
        buf->f_ffree = uspi->cs_total.cs_nifree;
        buf->f_bsize = sb->s_blocksize;
-       buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree))
-               ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;
+       buf->f_bavail = (buf->f_bfree > uspi->s_root_blocks)
+               ? (buf->f_bfree - uspi->s_root_blocks) : 0;
        buf->f_files = uspi->s_ncg * uspi->s_ipg;
        buf->f_namelen = UFS_MAXNAMLEN;
        buf->f_fsid.val[0] = (u32)id;
index 0cbd5d340b6705b9c6e22ff0a60a49891c302860..150eef6f12331a034dab0c48bee530fdc73c821e 100644 (file)
@@ -733,10 +733,8 @@ struct ufs_sb_private_info {
        __u32   s_dblkno;       /* offset of first data after cg */
        __u32   s_cgoffset;     /* cylinder group offset in cylinder */
        __u32   s_cgmask;       /* used to calc mod fs_ntrak */
-       __u32   s_size;         /* number of blocks (fragments) in fs */
-       __u32   s_dsize;        /* number of data blocks in fs */
-       __u64   s_u2_size;      /* ufs2: number of blocks (fragments) in fs */
-       __u64   s_u2_dsize;     /*ufs2:  number of data blocks in fs */
+       __u64   s_size;         /* number of blocks (fragments) in fs */
+       __u64   s_dsize;        /* number of data blocks in fs */
        __u32   s_ncg;          /* number of cylinder groups */
        __u32   s_bsize;        /* size of basic blocks */
        __u32   s_fsize;        /* size of fragments */
@@ -793,6 +791,9 @@ struct ufs_sb_private_info {
        __u32   s_maxsymlinklen;/* upper limit on fast symlinks' size */
        __s32   fs_magic;       /* filesystem magic */
        unsigned int s_dirblksize;
+       __u64   s_root_blocks;
+       __u64   s_time_to_space;
+       __u64   s_space_to_time;
 };
 
 /*
index f41ad0a6106f28a2165c94068f6c7c3d71a67b3e..02497a492eb25085fc7fcefc446ad0e9cd0f967a 100644 (file)
@@ -243,9 +243,8 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev
 struct page *ufs_get_locked_page(struct address_space *mapping,
                                 pgoff_t index)
 {
-       struct page *page;
-
-       page = find_lock_page(mapping, index);
+       struct inode *inode = mapping->host;
+       struct page *page = find_lock_page(mapping, index);
        if (!page) {
                page = read_mapping_page(mapping, index, NULL);
 
@@ -253,7 +252,7 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
                        printk(KERN_ERR "ufs_change_blocknr: "
                               "read_mapping_page error: ino %lu, index: %lu\n",
                               mapping->host->i_ino, index);
-                       goto out;
+                       return page;
                }
 
                lock_page(page);
@@ -262,8 +261,7 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
                        /* Truncate got there first */
                        unlock_page(page);
                        put_page(page);
-                       page = NULL;
-                       goto out;
+                       return NULL;
                }
 
                if (!PageUptodate(page) || PageError(page)) {
@@ -272,11 +270,12 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
 
                        printk(KERN_ERR "ufs_change_blocknr: "
                               "can not read page: ino %lu, index: %lu\n",
-                              mapping->host->i_ino, index);
+                              inode->i_ino, index);
 
-                       page = ERR_PTR(-EIO);
+                       return ERR_PTR(-EIO);
                }
        }
-out:
+       if (!page_has_buffers(page))
+               create_empty_buffers(page, 1 << inode->i_blkbits, 0);
        return page;
 }
index 398019fb144816875f2c717c2252823a4dd76b99..9fc7119a1551f8ff82a02e9d89d05d6e60024c55 100644 (file)
@@ -350,16 +350,11 @@ static inline void *ubh_get_data_ptr(struct ufs_sb_private_info *uspi,
 #define ubh_blkmap(ubh,begin,bit) \
        ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb)))
 
-/*
- * Determine the number of available frags given a
- * percentage to hold in reserve.
- */
 static inline u64
-ufs_freespace(struct ufs_sb_private_info *uspi, int percentreserved)
+ufs_freefrags(struct ufs_sb_private_info *uspi)
 {
        return ufs_blkstofrags(uspi->cs_total.cs_nbfree) +
-               uspi->cs_total.cs_nffree -
-               (uspi->s_dsize * (percentreserved) / 100);
+               uspi->cs_total.cs_nffree;
 }
 
 /*
index f7555fc25877435e13b65cbe597ae9bdb11c6528..1d622f276e3a2c0fba23d979d7ae18cf6a899f30 100644 (file)
@@ -340,9 +340,28 @@ int handle_userfault(struct vm_fault *vmf, unsigned long reason)
        bool must_wait, return_to_userland;
        long blocking_state;
 
-       BUG_ON(!rwsem_is_locked(&mm->mmap_sem));
-
        ret = VM_FAULT_SIGBUS;
+
+       /*
+        * We don't do userfault handling for the final child pid update.
+        *
+        * We also don't do userfault handling during
+        * coredumping. hugetlbfs has the special
+        * follow_hugetlb_page() to skip missing pages in the
+        * FOLL_DUMP case, anon memory also checks for FOLL_DUMP with
+        * the no_page_table() helper in follow_page_mask(), but the
+        * shmem_vm_ops->fault method is invoked even during
+        * coredumping without mmap_sem and it ends up here.
+        */
+       if (current->flags & (PF_EXITING|PF_DUMPCORE))
+               goto out;
+
+       /*
+        * Coredumping runs without mmap_sem so we can only check that
+        * the mmap_sem is held, if PF_DUMPCORE was not set.
+        */
+       WARN_ON_ONCE(!rwsem_is_locked(&mm->mmap_sem));
+
        ctx = vmf->vma->vm_userfaultfd_ctx.ctx;
        if (!ctx)
                goto out;
@@ -360,12 +379,6 @@ int handle_userfault(struct vm_fault *vmf, unsigned long reason)
        if (unlikely(ACCESS_ONCE(ctx->released)))
                goto out;
 
-       /*
-        * We don't do userfault handling for the final child pid update.
-        */
-       if (current->flags & PF_EXITING)
-               goto out;
-
        /*
         * Check that we can return VM_FAULT_RETRY.
         *
index 09af0f7cd55e278312881999755d3d8d0793d5c8..3b91faacc1baeaff2ac762e2438e5fcbe48cc76b 100644 (file)
@@ -1316,9 +1316,12 @@ xfs_vm_bmap(
         * The swap code (ab-)uses ->bmap to get a block mapping and then
         * bypasseÑ• the file system for actual I/O.  We really can't allow
         * that on reflinks inodes, so we have to skip out here.  And yes,
-        * 0 is the magic code for a bmap error..
+        * 0 is the magic code for a bmap error.
+        *
+        * Since we don't pass back blockdev info, we can't return bmap
+        * information for rt files either.
         */
-       if (xfs_is_reflink_inode(ip))
+       if (xfs_is_reflink_inode(ip) || XFS_IS_REALTIME_INODE(ip))
                return 0;
 
        filemap_write_and_wait(mapping);
index 07b77b73b0240c5cca4187d29e8e403cbf4f0714..16d6a578fc160528651d522359eb6e9ccecac78d 100644 (file)
@@ -117,7 +117,7 @@ static inline void
 __xfs_buf_ioacct_dec(
        struct xfs_buf  *bp)
 {
-       ASSERT(spin_is_locked(&bp->b_lock));
+       lockdep_assert_held(&bp->b_lock);
 
        if (bp->b_state & XFS_BSTATE_IN_FLIGHT) {
                bp->b_state &= ~XFS_BSTATE_IN_FLIGHT;
index f61c84f8e31a363ce144424336359630647eac07..990210fcb9c326f923c0c25a86557a0aba3bb40f 100644 (file)
@@ -66,7 +66,6 @@ xfs_inode_alloc(
 
        XFS_STATS_INC(mp, vn_active);
        ASSERT(atomic_read(&ip->i_pincount) == 0);
-       ASSERT(!spin_is_locked(&ip->i_flags_lock));
        ASSERT(!xfs_isiflocked(ip));
        ASSERT(ip->i_ino == 0);
 
@@ -190,7 +189,7 @@ xfs_perag_set_reclaim_tag(
 {
        struct xfs_mount        *mp = pag->pag_mount;
 
-       ASSERT(spin_is_locked(&pag->pag_ici_lock));
+       lockdep_assert_held(&pag->pag_ici_lock);
        if (pag->pag_ici_reclaimable++)
                return;
 
@@ -212,7 +211,7 @@ xfs_perag_clear_reclaim_tag(
 {
        struct xfs_mount        *mp = pag->pag_mount;
 
-       ASSERT(spin_is_locked(&pag->pag_ici_lock));
+       lockdep_assert_held(&pag->pag_ici_lock);
        if (--pag->pag_ici_reclaimable)
                return;
 
index 197f3fffc9a7151ed61d0b960f5e452f6beccb5c..408c7820e200f99e50d978c342dd67cc55166d0c 100644 (file)
@@ -210,7 +210,8 @@ struct acpi_device_flags {
        u32 of_compatible_ok:1;
        u32 coherent_dma:1;
        u32 cca_seen:1;
-       u32 reserved:20;
+       u32 spi_i2c_slave:1;
+       u32 reserved:19;
 };
 
 /* File System */
index d92543f3bbfdcaaeac47252729af30ba428eb371..bdc55c0da19cd06c65e589d9071f65c2eb5c2332 100644 (file)
@@ -374,6 +374,20 @@ struct acpi_table_desc {
        u16 validation_count;
 };
 
+/*
+ * Maximum value of the validation_count field in struct acpi_table_desc.
+ * When reached, validation_count cannot be changed any more and the table will
+ * be permanently regarded as validated.
+ *
+ * This is to prevent situations in which unbalanced table get/put operations
+ * may cause premature table unmapping in the OS to happen.
+ *
+ * The maximum validation count can be defined to any value, but should be
+ * greater than the maximum number of OS early stage mapping slots to avoid
+ * leaking early stage table mappings to the late stage.
+ */
+#define ACPI_MAX_TABLE_VALIDATIONS          ACPI_UINT16_MAX
+
 /* Masks for Flags field above */
 
 #define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL  (0)        /* Virtual address, external maintained */
index 370c0a0473fcb80948decaeba03d092f1c24ca74..d66432c6e6759730fff0a705edacb88be94fd40b 100644 (file)
@@ -43,6 +43,8 @@
 #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_
 #define _DT_BINDINGS_CLK_SUN50I_A64_H_
 
+#define CLK_PLL_PERIPH0                11
+
 #define CLK_BUS_MIPI_DSI       28
 #define CLK_BUS_CE             29
 #define CLK_BUS_DMA            30
index c2afc41d69644af3d9f920a56341d62003630883..e139fe5c62ecd5c8375e7bc8fd503465e475985b 100644 (file)
@@ -43,6 +43,8 @@
 #ifndef _DT_BINDINGS_CLK_SUN8I_H3_H_
 #define _DT_BINDINGS_CLK_SUN8I_H3_H_
 
+#define CLK_PLL_PERIPH0                9
+
 #define CLK_CPUX               14
 
 #define CLK_BUS_CE             20
index d1b04b0e99cf8c293d4ded6eccb2b0aa2fce0d41..a7e29fa0981f148602dcb11dd53e07e1c46147d3 100644 (file)
@@ -426,6 +426,7 @@ extern void bio_advance(struct bio *, unsigned);
 
 extern void bio_init(struct bio *bio, struct bio_vec *table,
                     unsigned short max_vecs);
+extern void bio_uninit(struct bio *);
 extern void bio_reset(struct bio *);
 void bio_chain(struct bio *, struct bio *);
 
index ab92c4ea138b7c665c45b765c0e1f8a4958339ca..1ddd36bd2173b98e925eabdf083a796bfcabdd07 100644 (file)
@@ -391,6 +391,8 @@ struct request_queue {
        int                     nr_rqs[2];      /* # allocated [a]sync rqs */
        int                     nr_rqs_elvpriv; /* # allocated rqs w/ elvpriv */
 
+       atomic_t                shared_hctx_restart;
+
        struct blk_queue_stats  *stats;
        struct rq_wb            *rq_wb;
 
@@ -586,6 +588,8 @@ struct request_queue {
 
        size_t                  cmd_size;
        void                    *rq_alloc_data;
+
+       struct work_struct      release_work;
 };
 
 #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
index 2319b8c108e87b9e87c11cc4c9aa314d24eb0364..c9670904968329ce3032825d55b28a72cb8b223c 100644 (file)
@@ -74,7 +74,8 @@ extern void config_item_init_type_name(struct config_item *item,
                                       const char *name,
                                       struct config_item_type *type);
 
-extern struct config_item * config_item_get(struct config_item *);
+extern struct config_item *config_item_get(struct config_item *);
+extern struct config_item *config_item_get_unless_zero(struct config_item *);
 extern void config_item_put(struct config_item *);
 
 struct config_item_type {
index 5e9c74cf889481ddbf6ae3a9caef166bd6ae6dee..9bbf21a516e4aa339aff03e9c2091043bb265fba 100644 (file)
@@ -136,7 +136,7 @@ static inline int dmi_name_in_vendors(const char *s) { return 0; }
 static inline int dmi_name_in_serial(const char *s) { return 0; }
 #define dmi_available 0
 static inline int dmi_walk(void (*decode)(const struct dmi_header *, void *),
-       void *private_data) { return -1; }
+       void *private_data) { return -ENXIO; }
 static inline bool dmi_match(enum dmi_field f, const char *str)
        { return false; }
 static inline void dmi_memdev_name(u16 handle, const char **bank,
index b892e95d4929d311b51877dfb9eb3de67780bbdf..6f543a47fc92ecc89cdd49c00f4c0e9acf0ea2eb 100644 (file)
@@ -1393,12 +1393,6 @@ int clear_page_dirty_for_io(struct page *page);
 
 int get_cmdline(struct task_struct *task, char *buffer, int buflen);
 
-/* Is the vma a continuation of the stack vma above it? */
-static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr)
-{
-       return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN);
-}
-
 static inline bool vma_is_anonymous(struct vm_area_struct *vma)
 {
        return !vma->vm_ops;
@@ -1414,28 +1408,6 @@ bool vma_is_shmem(struct vm_area_struct *vma);
 static inline bool vma_is_shmem(struct vm_area_struct *vma) { return false; }
 #endif
 
-static inline int stack_guard_page_start(struct vm_area_struct *vma,
-                                            unsigned long addr)
-{
-       return (vma->vm_flags & VM_GROWSDOWN) &&
-               (vma->vm_start == addr) &&
-               !vma_growsdown(vma->vm_prev, addr);
-}
-
-/* Is the vma a continuation of the stack vma below it? */
-static inline int vma_growsup(struct vm_area_struct *vma, unsigned long addr)
-{
-       return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP);
-}
-
-static inline int stack_guard_page_end(struct vm_area_struct *vma,
-                                          unsigned long addr)
-{
-       return (vma->vm_flags & VM_GROWSUP) &&
-               (vma->vm_end == addr) &&
-               !vma_growsup(vma->vm_next, addr);
-}
-
 int vma_is_stack_for_current(struct vm_area_struct *vma);
 
 extern unsigned long move_page_tables(struct vm_area_struct *vma,
@@ -2222,6 +2194,7 @@ void page_cache_async_readahead(struct address_space *mapping,
                                pgoff_t offset,
                                unsigned long size);
 
+extern unsigned long stack_guard_gap;
 /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */
 extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
 
@@ -2250,6 +2223,30 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m
        return vma;
 }
 
+static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
+{
+       unsigned long vm_start = vma->vm_start;
+
+       if (vma->vm_flags & VM_GROWSDOWN) {
+               vm_start -= stack_guard_gap;
+               if (vm_start > vma->vm_start)
+                       vm_start = 0;
+       }
+       return vm_start;
+}
+
+static inline unsigned long vm_end_gap(struct vm_area_struct *vma)
+{
+       unsigned long vm_end = vma->vm_end;
+
+       if (vma->vm_flags & VM_GROWSUP) {
+               vm_end += stack_guard_gap;
+               if (vm_end < vma->vm_end)
+                       vm_end = -PAGE_SIZE;
+       }
+       return vm_end;
+}
+
 static inline unsigned long vma_pages(struct vm_area_struct *vma)
 {
        return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
index 3f39d27decf4d72e734734edec4403b00ca95657..4ed952c17fc7757965c26d2eba1c56c39d5b4ccc 100644 (file)
@@ -914,8 +914,7 @@ struct xfrmdev_ops {
  *
  * int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
  *     Called when a user wants to change the Maximum Transfer Unit
- *     of a device. If not defined, any request to change MTU will
- *     will return an error.
+ *     of a device.
  *
  * void (*ndo_tx_timeout)(struct net_device *dev);
  *     Callback used when the transmitter has not made any progress
@@ -1596,8 +1595,8 @@ enum netdev_priv_flags {
  *     @rtnl_link_state:       This enum represents the phases of creating
  *                             a new link
  *
- *     @destructor:            Called from unregister,
- *                             can be used to call free_netdev
+ *     @needs_free_netdev:     Should unregister perform free_netdev?
+ *     @priv_destructor:       Called from unregister
  *     @npinfo:                XXX: need comments on this one
  *     @nd_net:                Network namespace this network device is inside
  *
@@ -1858,7 +1857,8 @@ struct net_device {
                RTNL_LINK_INITIALIZING,
        } rtnl_link_state:16;
 
-       void (*destructor)(struct net_device *dev);
+       bool needs_free_netdev;
+       void (*priv_destructor)(struct net_device *dev);
 
 #ifdef CONFIG_NETPOLL
        struct netpoll_info __rcu       *npinfo;
@@ -4261,6 +4261,11 @@ static inline const char *netdev_name(const struct net_device *dev)
        return dev->name;
 }
 
+static inline bool netdev_unregistering(const struct net_device *dev)
+{
+       return dev->reg_state == NETREG_UNREGISTERING;
+}
+
 static inline const char *netdev_reg_state(const struct net_device *dev)
 {
        switch (dev->reg_state) {
index 07ef550c662708035459293fe39fa895cca9fce5..93315d6b21a85fea729970574eecd66027f8f520 100644 (file)
@@ -84,6 +84,7 @@ struct kmem_cache {
        int red_left_pad;       /* Left redzone padding size */
 #ifdef CONFIG_SYSFS
        struct kobject kobj;    /* For sysfs */
+       struct work_struct kobj_remove_work;
 #endif
 #ifdef CONFIG_MEMCG
        struct memcg_cache_params memcg_params;
index 110f4532188c7b6c50cf1ce4dcd5dc525beae9a1..f7043ccca81cc65f15c252158e745dc4c2948155 100644 (file)
@@ -29,7 +29,6 @@
  */
 struct tk_read_base {
        struct clocksource      *clock;
-       u64                     (*read)(struct clocksource *cs);
        u64                     mask;
        u64                     cycle_last;
        u32                     mult;
@@ -58,7 +57,7 @@ struct tk_read_base {
  *                     interval.
  * @xtime_remainder:   Shifted nano seconds left over when rounding
  *                     @cycle_interval
- * @raw_interval:      Raw nano seconds accumulated per NTP interval.
+ * @raw_interval:      Shifted raw nano seconds accumulated per NTP interval.
  * @ntp_error:         Difference between accumulated time and NTP time in ntp
  *                     shifted nano seconds.
  * @ntp_error_shift:   Shift conversion between clock shifted nano seconds and
@@ -100,7 +99,7 @@ struct timekeeper {
        u64                     cycle_interval;
        u64                     xtime_interval;
        s64                     xtime_remainder;
-       u32                     raw_interval;
+       u64                     raw_interval;
        /* The ntp_tick_length() value currently being used.
         * This cached copy ensures we consistently apply the tick
         * length for an entire tick, as ntp_tick_length may change
index 413335c8cb529a8506a2f934577c3413512d8c97..298f996969df632ba41b6c68f3d815678c89e079 100644 (file)
@@ -106,6 +106,16 @@ static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
 {
 }
 
+static inline void cec_notifier_register(struct cec_notifier *n,
+                        struct cec_adapter *adap,
+                        void (*callback)(struct cec_adapter *adap, u16 pa))
+{
+}
+
+static inline void cec_notifier_unregister(struct cec_notifier *n)
+{
+}
+
 #endif
 
 #endif
index bfa88d4d67e1d6663da4952a6a097e32f5e573a8..201f060978da2d5f8f49ad3fb31ac514c55e60c2 100644 (file)
@@ -206,7 +206,7 @@ static inline bool cec_is_sink(const struct cec_adapter *adap)
 #define cec_phys_addr_exp(pa) \
        ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
 
-#if IS_ENABLED(CONFIG_CEC_CORE)
+#if IS_REACHABLE(CONFIG_CEC_CORE)
 struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
                void *priv, const char *name, u32 caps, u8 available_las);
 int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
index 345911965dbb8f53289d63535828969454ae3333..454ff763eeba9b829051862d7cce278be7d77b42 100644 (file)
@@ -6,7 +6,7 @@
 struct net;
 
 #ifdef CONFIG_WEXT_CORE
-int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
+int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
                      void __user *arg);
 int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
                             unsigned long arg);
@@ -14,7 +14,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
 struct iw_statistics *get_wireless_stats(struct net_device *dev);
 int call_commit_handler(struct net_device *dev);
 #else
-static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
+static inline int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
                                    void __user *arg)
 {
        return -EINVAL;
index d179d7767f519829a50395f47749360f88cd3d2d..7d4a594d5d58147e3cf4b56eb992268a619badf3 100644 (file)
@@ -1486,8 +1486,10 @@ enum ethtool_link_mode_bit_indices {
  * it was forced up into this mode or autonegotiated.
  */
 
-/* The forced speed, in units of 1Mb. All values 0 to INT_MAX are legal. */
-/* Update drivers/net/phy/phy.c:phy_speed_to_str() when adding new values */
+/* The forced speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+ * Update drivers/net/phy/phy.c:phy_speed_to_str() and
+ * drivers/net/bonding/bond_3ad.c:__get_link_speed() when adding new values.
+ */
 #define SPEED_10               10
 #define SPEED_100              100
 #define SPEED_1000             1000
index 61b7d36dfe34394f7cbed64217a8a9a1e7f55cfe..156ee4cab82e5e73bc2705a4707c04c1cf788b98 100644 (file)
@@ -343,6 +343,7 @@ enum ovs_key_attr {
 #define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
 
 enum ovs_tunnel_key_attr {
+       /* OVS_TUNNEL_KEY_ATTR_NONE, standard nl API requires this attribute! */
        OVS_TUNNEL_KEY_ATTR_ID,                 /* be64 Tunnel ID */
        OVS_TUNNEL_KEY_ATTR_IPV4_SRC,           /* be32 src IP address. */
        OVS_TUNNEL_KEY_ATTR_IPV4_DST,           /* be32 dst IP address. */
index 2831480c63a28b8e9b8cee1c0b30968860b3fcd0..ee97196bb1510e4f95cfd6ddc039fa9700cdc828 100644 (file)
@@ -580,7 +580,7 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
        int ret = -ENOMEM, max_order = 0;
 
        if (!has_aux(event))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (event->pmu->capabilities & PERF_PMU_CAP_AUX_NO_SG) {
                /*
index 070be980c37a57d91f86099d2be1b81db80176bc..425170d4439be5926a63ef9be50c71c1dd5878a9 100644 (file)
@@ -1312,8 +1312,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                        ret = __irq_set_trigger(desc,
                                                new->flags & IRQF_TRIGGER_MASK);
 
-                       if (ret)
+                       if (ret) {
+                               irq_release_resources(desc);
                                goto out_mask;
+                       }
                }
 
                desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \
index f8269036bf0b84f89faa2db3b5dc5fe4c259a019..52c4e907c14b0d4a7896d7ca9a6fa6fbc17451ba 100644 (file)
@@ -59,7 +59,11 @@ static void notrace klp_ftrace_handler(unsigned long ip,
 
        ops = container_of(fops, struct klp_ops, fops);
 
-       rcu_read_lock();
+       /*
+        * A variant of synchronize_sched() is used to allow patching functions
+        * where RCU is not watching, see klp_synchronize_transition().
+        */
+       preempt_disable_notrace();
 
        func = list_first_or_null_rcu(&ops->func_stack, struct klp_func,
                                      stack_node);
@@ -115,7 +119,7 @@ static void notrace klp_ftrace_handler(unsigned long ip,
 
        klp_arch_set_pc(regs, (unsigned long)func->new_func);
 unlock:
-       rcu_read_unlock();
+       preempt_enable_notrace();
 }
 
 /*
index adc0cc64aa4b6ae199e5f4a5b2af0ad59c382175..b004a1fb603236f31cd5780962c098bfcf8fe743 100644 (file)
@@ -48,6 +48,28 @@ static void klp_transition_work_fn(struct work_struct *work)
 }
 static DECLARE_DELAYED_WORK(klp_transition_work, klp_transition_work_fn);
 
+/*
+ * This function is just a stub to implement a hard force
+ * of synchronize_sched(). This requires synchronizing
+ * tasks even in userspace and idle.
+ */
+static void klp_sync(struct work_struct *work)
+{
+}
+
+/*
+ * We allow to patch also functions where RCU is not watching,
+ * e.g. before user_exit(). We can not rely on the RCU infrastructure
+ * to do the synchronization. Instead hard force the sched synchronization.
+ *
+ * This approach allows to use RCU functions for manipulating func_stack
+ * safely.
+ */
+static void klp_synchronize_transition(void)
+{
+       schedule_on_each_cpu(klp_sync);
+}
+
 /*
  * The transition to the target patch state is complete.  Clean up the data
  * structures.
@@ -73,7 +95,7 @@ static void klp_complete_transition(void)
                 * func->transition gets cleared, the handler may choose a
                 * removed function.
                 */
-               synchronize_rcu();
+               klp_synchronize_transition();
        }
 
        if (klp_transition_patch->immediate)
@@ -92,7 +114,7 @@ static void klp_complete_transition(void)
 
        /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */
        if (klp_target_state == KLP_PATCHED)
-               synchronize_rcu();
+               klp_synchronize_transition();
 
        read_lock(&tasklist_lock);
        for_each_process_thread(g, task) {
@@ -136,7 +158,11 @@ void klp_cancel_transition(void)
  */
 void klp_update_patch_state(struct task_struct *task)
 {
-       rcu_read_lock();
+       /*
+        * A variant of synchronize_sched() is used to allow patching functions
+        * where RCU is not watching, see klp_synchronize_transition().
+        */
+       preempt_disable_notrace();
 
        /*
         * This test_and_clear_tsk_thread_flag() call also serves as a read
@@ -153,7 +179,7 @@ void klp_update_patch_state(struct task_struct *task)
        if (test_and_clear_tsk_thread_flag(task, TIF_PATCH_PENDING))
                task->patch_state = READ_ONCE(klp_target_state);
 
-       rcu_read_unlock();
+       preempt_enable_notrace();
 }
 
 /*
@@ -539,7 +565,7 @@ void klp_reverse_transition(void)
                clear_tsk_thread_flag(idle_task(cpu), TIF_PATCH_PENDING);
 
        /* Let any remaining calls to klp_update_patch_state() complete */
-       synchronize_rcu();
+       klp_synchronize_transition();
 
        klp_start_transition();
 }
index 803c3bc274c4660bb672c2522331db967883aee4..326d4f88e2b1dbda470c7730c6ae1a67cc095f99 100644 (file)
@@ -5605,7 +5605,7 @@ void idle_task_exit(void)
        BUG_ON(cpu_online(smp_processor_id()));
 
        if (mm != &init_mm) {
-               switch_mm_irqs_off(mm, &init_mm, current);
+               switch_mm(mm, &init_mm, current);
                finish_arch_post_lock_switch();
        }
        mmdrop(mm);
index 622eed1b7658301a94a645c4426598b0096a8ab9..076a2e31951ccbb538e8004a85cf1f247818d57e 100644 (file)
@@ -101,9 +101,6 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
        if (sg_policy->next_freq == next_freq)
                return;
 
-       if (sg_policy->next_freq > next_freq)
-               next_freq = (sg_policy->next_freq + next_freq) >> 1;
-
        sg_policy->next_freq = next_freq;
        sg_policy->last_freq_update_time = time;
 
index d711093218415d77ead6405004dd9e41323ad924..c77e4b1d51c09d1fc948d0bb105cd97b50fc6a42 100644 (file)
@@ -3563,7 +3563,7 @@ static inline void check_schedstat_required(void)
                        trace_sched_stat_runtime_enabled())  {
                printk_deferred_once("Scheduler tracepoints stat_sleep, stat_iowait, "
                             "stat_blocked and stat_runtime require the "
-                            "kernel parameter schedstats=enabled or "
+                            "kernel parameter schedstats=enable or "
                             "kernel.sched_schedstats=1\n");
        }
 #endif
index ca92bcfeb322f3f836031ec8b3ab21867f39adf5..45b4c1ffe14ef4334a918d0fc9ed407d801cafe6 100644 (file)
@@ -510,7 +510,8 @@ int unhandled_signal(struct task_struct *tsk, int sig)
        return !tsk->ptrace;
 }
 
-static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static void collect_signal(int sig, struct sigpending *list, siginfo_t *info,
+                          bool *resched_timer)
 {
        struct sigqueue *q, *first = NULL;
 
@@ -532,6 +533,12 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
 still_pending:
                list_del_init(&first->list);
                copy_siginfo(info, &first->info);
+
+               *resched_timer =
+                       (first->flags & SIGQUEUE_PREALLOC) &&
+                       (info->si_code == SI_TIMER) &&
+                       (info->si_sys_private);
+
                __sigqueue_free(first);
        } else {
                /*
@@ -548,12 +555,12 @@ still_pending:
 }
 
 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
-                       siginfo_t *info)
+                       siginfo_t *info, bool *resched_timer)
 {
        int sig = next_signal(pending, mask);
 
        if (sig)
-               collect_signal(sig, pending, info);
+               collect_signal(sig, pending, info, resched_timer);
        return sig;
 }
 
@@ -565,15 +572,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
  */
 int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
 {
+       bool resched_timer = false;
        int signr;
 
        /* We only dequeue private signals from ourselves, we don't let
         * signalfd steal them
         */
-       signr = __dequeue_signal(&tsk->pending, mask, info);
+       signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
        if (!signr) {
                signr = __dequeue_signal(&tsk->signal->shared_pending,
-                                        mask, info);
+                                        mask, info, &resched_timer);
 #ifdef CONFIG_POSIX_TIMERS
                /*
                 * itimer signal ?
@@ -621,7 +629,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
                current->jobctl |= JOBCTL_STOP_DEQUEUED;
        }
 #ifdef CONFIG_POSIX_TIMERS
-       if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) {
+       if (resched_timer) {
                /*
                 * Release the siglock to ensure proper locking order
                 * of timer locks outside of siglocks.  Note, we leave
index 5cb5b0008d9710c95c1af7ab8312b5e308b2c5d0..ee2f4202d82aa2acec5e438218a2405a4315f166 100644 (file)
@@ -387,7 +387,7 @@ void alarm_start_relative(struct alarm *alarm, ktime_t start)
 {
        struct alarm_base *base = &alarm_bases[alarm->type];
 
-       start = ktime_add(start, base->gettime());
+       start = ktime_add_safe(start, base->gettime());
        alarm_start(alarm, start);
 }
 EXPORT_SYMBOL_GPL(alarm_start_relative);
@@ -475,7 +475,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
                overrun++;
        }
 
-       alarm->node.expires = ktime_add(alarm->node.expires, interval);
+       alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);
        return overrun;
 }
 EXPORT_SYMBOL_GPL(alarm_forward);
@@ -660,13 +660,21 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 
        /* start the timer */
        timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
+
+       /*
+        * Rate limit to the tick as a hot fix to prevent DOS. Will be
+        * mopped up later.
+        */
+       if (timr->it.alarm.interval < TICK_NSEC)
+               timr->it.alarm.interval = TICK_NSEC;
+
        exp = timespec64_to_ktime(new_setting->it_value);
        /* Convert (if necessary) to absolute time */
        if (flags != TIMER_ABSTIME) {
                ktime_t now;
 
                now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-               exp = ktime_add(now, exp);
+               exp = ktime_add_safe(now, exp);
        }
 
        alarm_start(&timr->it.alarm.alarmtimer, exp);
index 987e496bb51a9cc84c92bedc62cf8d69e8e85668..b398c2ea69b290cdaec1769b7d11cbc501646652 100644 (file)
@@ -37,9 +37,11 @@ static int tick_broadcast_forced;
 static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
 
 #ifdef CONFIG_TICK_ONESHOT
+static void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
 static void tick_broadcast_clear_oneshot(int cpu);
 static void tick_resume_broadcast_oneshot(struct clock_event_device *bc);
 #else
+static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
 static inline void tick_broadcast_clear_oneshot(int cpu) { }
 static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { }
 #endif
@@ -867,7 +869,7 @@ static void tick_broadcast_init_next_event(struct cpumask *mask,
 /**
  * tick_broadcast_setup_oneshot - setup the broadcast device
  */
-void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
+static void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
        int cpu = smp_processor_id();
 
index f738251000fe6b07de4f3d54ee78d8f78408c5d7..be0ac01f2e1225b6d4bb814029854dfdba3cd5cb 100644 (file)
@@ -126,7 +126,6 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 
 /* Functions related to oneshot broadcasting */
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
-extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int cpu);
 extern int tick_broadcast_oneshot_active(void);
@@ -134,7 +133,6 @@ extern void tick_check_oneshot_broadcast_this_cpu(void);
 bool tick_broadcast_oneshot_available(void);
 extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
 #else /* !(BROADCAST && ONESHOT): */
-static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int cpu) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }
index 9652bc57fd09811fa4e3ffbabc81b9139e75f125..b602c48cb84123890dbdc40b9a3da94439ba3a9d 100644 (file)
@@ -118,6 +118,26 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta)
        tk->offs_boot = ktime_add(tk->offs_boot, delta);
 }
 
+/*
+ * tk_clock_read - atomic clocksource read() helper
+ *
+ * This helper is necessary to use in the read paths because, while the
+ * seqlock ensures we don't return a bad value while structures are updated,
+ * it doesn't protect from potential crashes. There is the possibility that
+ * the tkr's clocksource may change between the read reference, and the
+ * clock reference passed to the read function.  This can cause crashes if
+ * the wrong clocksource is passed to the wrong read function.
+ * This isn't necessary to use when holding the timekeeper_lock or doing
+ * a read of the fast-timekeeper tkrs (which is protected by its own locking
+ * and update logic).
+ */
+static inline u64 tk_clock_read(struct tk_read_base *tkr)
+{
+       struct clocksource *clock = READ_ONCE(tkr->clock);
+
+       return clock->read(clock);
+}
+
 #ifdef CONFIG_DEBUG_TIMEKEEPING
 #define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */
 
@@ -175,7 +195,7 @@ static inline u64 timekeeping_get_delta(struct tk_read_base *tkr)
         */
        do {
                seq = read_seqcount_begin(&tk_core.seq);
-               now = tkr->read(tkr->clock);
+               now = tk_clock_read(tkr);
                last = tkr->cycle_last;
                mask = tkr->mask;
                max = tkr->clock->max_cycles;
@@ -209,7 +229,7 @@ static inline u64 timekeeping_get_delta(struct tk_read_base *tkr)
        u64 cycle_now, delta;
 
        /* read clocksource */
-       cycle_now = tkr->read(tkr->clock);
+       cycle_now = tk_clock_read(tkr);
 
        /* calculate the delta since the last update_wall_time */
        delta = clocksource_delta(cycle_now, tkr->cycle_last, tkr->mask);
@@ -238,12 +258,10 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
        ++tk->cs_was_changed_seq;
        old_clock = tk->tkr_mono.clock;
        tk->tkr_mono.clock = clock;
-       tk->tkr_mono.read = clock->read;
        tk->tkr_mono.mask = clock->mask;
-       tk->tkr_mono.cycle_last = tk->tkr_mono.read(clock);
+       tk->tkr_mono.cycle_last = tk_clock_read(&tk->tkr_mono);
 
        tk->tkr_raw.clock = clock;
-       tk->tkr_raw.read = clock->read;
        tk->tkr_raw.mask = clock->mask;
        tk->tkr_raw.cycle_last = tk->tkr_mono.cycle_last;
 
@@ -262,7 +280,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
        /* Go back from cycles -> shifted ns */
        tk->xtime_interval = interval * clock->mult;
        tk->xtime_remainder = ntpinterval - tk->xtime_interval;
-       tk->raw_interval = (interval * clock->mult) >> clock->shift;
+       tk->raw_interval = interval * clock->mult;
 
         /* if changing clocks, convert xtime_nsec shift units */
        if (old_clock) {
@@ -404,7 +422,7 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf)
 
                now += timekeeping_delta_to_ns(tkr,
                                clocksource_delta(
-                                       tkr->read(tkr->clock),
+                                       tk_clock_read(tkr),
                                        tkr->cycle_last,
                                        tkr->mask));
        } while (read_seqcount_retry(&tkf->seq, seq));
@@ -461,6 +479,10 @@ static u64 dummy_clock_read(struct clocksource *cs)
        return cycles_at_suspend;
 }
 
+static struct clocksource dummy_clock = {
+       .read = dummy_clock_read,
+};
+
 /**
  * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
  * @tk: Timekeeper to snapshot.
@@ -477,13 +499,13 @@ static void halt_fast_timekeeper(struct timekeeper *tk)
        struct tk_read_base *tkr = &tk->tkr_mono;
 
        memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
-       cycles_at_suspend = tkr->read(tkr->clock);
-       tkr_dummy.read = dummy_clock_read;
+       cycles_at_suspend = tk_clock_read(tkr);
+       tkr_dummy.clock = &dummy_clock;
        update_fast_timekeeper(&tkr_dummy, &tk_fast_mono);
 
        tkr = &tk->tkr_raw;
        memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
-       tkr_dummy.read = dummy_clock_read;
+       tkr_dummy.clock = &dummy_clock;
        update_fast_timekeeper(&tkr_dummy, &tk_fast_raw);
 }
 
@@ -649,11 +671,10 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
  */
 static void timekeeping_forward_now(struct timekeeper *tk)
 {
-       struct clocksource *clock = tk->tkr_mono.clock;
        u64 cycle_now, delta;
        u64 nsec;
 
-       cycle_now = tk->tkr_mono.read(clock);
+       cycle_now = tk_clock_read(&tk->tkr_mono);
        delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
        tk->tkr_mono.cycle_last = cycle_now;
        tk->tkr_raw.cycle_last  = cycle_now;
@@ -929,8 +950,7 @@ void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot)
 
        do {
                seq = read_seqcount_begin(&tk_core.seq);
-
-               now = tk->tkr_mono.read(tk->tkr_mono.clock);
+               now = tk_clock_read(&tk->tkr_mono);
                systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq;
                systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq;
                base_real = ktime_add(tk->tkr_mono.base,
@@ -1108,7 +1128,7 @@ int get_device_system_crosststamp(int (*get_time_fn)
                 * Check whether the system counter value provided by the
                 * device driver is on the current timekeeping interval.
                 */
-               now = tk->tkr_mono.read(tk->tkr_mono.clock);
+               now = tk_clock_read(&tk->tkr_mono);
                interval_start = tk->tkr_mono.cycle_last;
                if (!cycle_between(interval_start, cycles, now)) {
                        clock_was_set_seq = tk->clock_was_set_seq;
@@ -1629,7 +1649,7 @@ void timekeeping_resume(void)
         * The less preferred source will only be tried if there is no better
         * usable source. The rtc part is handled separately in rtc core code.
         */
-       cycle_now = tk->tkr_mono.read(clock);
+       cycle_now = tk_clock_read(&tk->tkr_mono);
        if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) &&
                cycle_now > tk->tkr_mono.cycle_last) {
                u64 nsec, cyc_delta;
@@ -1976,7 +1996,7 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
                                    u32 shift, unsigned int *clock_set)
 {
        u64 interval = tk->cycle_interval << shift;
-       u64 raw_nsecs;
+       u64 snsec_per_sec;
 
        /* If the offset is smaller than a shifted interval, do nothing */
        if (offset < interval)
@@ -1991,14 +2011,15 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
        *clock_set |= accumulate_nsecs_to_secs(tk);
 
        /* Accumulate raw time */
-       raw_nsecs = (u64)tk->raw_interval << shift;
-       raw_nsecs += tk->raw_time.tv_nsec;
-       if (raw_nsecs >= NSEC_PER_SEC) {
-               u64 raw_secs = raw_nsecs;
-               raw_nsecs = do_div(raw_secs, NSEC_PER_SEC);
-               tk->raw_time.tv_sec += raw_secs;
+       tk->tkr_raw.xtime_nsec += (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
+       tk->tkr_raw.xtime_nsec += tk->raw_interval << shift;
+       snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
+       while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) {
+               tk->tkr_raw.xtime_nsec -= snsec_per_sec;
+               tk->raw_time.tv_sec++;
        }
-       tk->raw_time.tv_nsec = raw_nsecs;
+       tk->raw_time.tv_nsec = tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift;
+       tk->tkr_raw.xtime_nsec -= (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
 
        /* Accumulate error between NTP and clock interval */
        tk->ntp_error += tk->ntp_tick << shift;
@@ -2030,7 +2051,7 @@ void update_wall_time(void)
 #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
        offset = real_tk->cycle_interval;
 #else
-       offset = clocksource_delta(tk->tkr_mono.read(tk->tkr_mono.clock),
+       offset = clocksource_delta(tk_clock_read(&tk->tkr_mono),
                                   tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
 #endif
 
index 3c6432df7e63466a24d41dead807c7ef14c0ab86..4c0888c4a68d9621717f9012d3ca4cc0b72df20b 100644 (file)
  *     the values[M, M+1, ..., N] into the ints array in get_options.
  */
 
-static int get_range(char **str, int *pint)
+static int get_range(char **str, int *pint, int n)
 {
        int x, inc_counter, upper_range;
 
        (*str)++;
        upper_range = simple_strtol((*str), NULL, 0);
        inc_counter = upper_range - *pint;
-       for (x = *pint; x < upper_range; x++)
+       for (x = *pint; n && x < upper_range; x++, n--)
                *pint++ = x;
        return inc_counter;
 }
@@ -97,7 +97,7 @@ char *get_options(const char *str, int nints, int *ints)
                        break;
                if (res == 3) {
                        int range_nums;
-                       range_nums = get_range((char **)&str, ints + i);
+                       range_nums = get_range((char **)&str, ints + i, nints - i);
                        if (range_nums < 0)
                                break;
                        /*
index 74a54b7f25626e8c6d224af2b7384f7dcbf2e72f..9f79547d1b9782237a563f6a2e838655f6adf6dc 100644 (file)
@@ -43,7 +43,7 @@ static struct crypto_shash *tfm;
 u32 crc32c(u32 crc, const void *address, unsigned int length)
 {
        SHASH_DESC_ON_STACK(shash, tfm);
-       u32 *ctx = (u32 *)shash_desc_ctx(shash);
+       u32 ret, *ctx = (u32 *)shash_desc_ctx(shash);
        int err;
 
        shash->tfm = tfm;
@@ -53,7 +53,9 @@ u32 crc32c(u32 crc, const void *address, unsigned int length)
        err = crypto_shash_update(shash, address, length);
        BUG_ON(err);
 
-       return *ctx;
+       ret = *ctx;
+       barrier_data(ctx);
+       return ret;
 }
 
 EXPORT_SYMBOL(crc32c);
index b3c7214d710d5ea8bab8648b5182c53d882f3c31..576c4df588823ab948c4a5d0dd12b6d54b94b430 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -387,11 +387,6 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
        /* mlock all present pages, but do not fault in new pages */
        if ((*flags & (FOLL_POPULATE | FOLL_MLOCK)) == FOLL_MLOCK)
                return -ENOENT;
-       /* For mm_populate(), just skip the stack guard page. */
-       if ((*flags & FOLL_POPULATE) &&
-                       (stack_guard_page_start(vma, address) ||
-                        stack_guard_page_end(vma, address + PAGE_SIZE)))
-               return -ENOENT;
        if (*flags & FOLL_WRITE)
                fault_flags |= FAULT_FLAG_WRITE;
        if (*flags & FOLL_REMOTE)
index a84909cf20d36b3d84f00d8529127f78f6b5981d..88c6167f194db0ec07d707329569c2d4a9d34876 100644 (file)
@@ -1426,8 +1426,11 @@ int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
         */
        if (unlikely(pmd_trans_migrating(*vmf->pmd))) {
                page = pmd_page(*vmf->pmd);
+               if (!get_page_unless_zero(page))
+                       goto out_unlock;
                spin_unlock(vmf->ptl);
                wait_on_page_locked(page);
+               put_page(page);
                goto out;
        }
 
@@ -1459,9 +1462,12 @@ int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
 
        /* Migration could have started since the pmd_trans_migrating check */
        if (!page_locked) {
+               page_nid = -1;
+               if (!get_page_unless_zero(page))
+                       goto out_unlock;
                spin_unlock(vmf->ptl);
                wait_on_page_locked(page);
-               page_nid = -1;
+               put_page(page);
                goto out;
        }
 
index 945fd1ca49b5af0bc3b87dbfe8098f0f602775a2..df4ebdb2b10a373723330dc0124957cd2cb1c021 100644 (file)
@@ -652,7 +652,6 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page,
                        spin_unlock(ptl);
                        free_page_and_swap_cache(src_page);
                }
-               cond_resched();
        }
 }
 
index 342fac9ba89b0da3e207b1fdaef2be71c9837a24..ecc183fd94f36f35e91b69c6a06930bb456a7e86 100644 (file)
@@ -1184,7 +1184,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
         * page_remove_rmap() in try_to_unmap_one(). So to determine page status
         * correctly, we save a copy of the page flags at this time.
         */
-       page_flags = p->flags;
+       if (PageHuge(p))
+               page_flags = hpage->flags;
+       else
+               page_flags = p->flags;
 
        /*
         * unpoison always clear PG_hwpoison inside page lock
index 2e65df1831d941dcd1282c56312bdbd153df0a79..bb11c474857e5ff2a3756724ca30139ff41ebbab 100644 (file)
@@ -2854,40 +2854,6 @@ out_release:
        return ret;
 }
 
-/*
- * This is like a special single-page "expand_{down|up}wards()",
- * except we must first make sure that 'address{-|+}PAGE_SIZE'
- * doesn't hit another vma.
- */
-static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
-{
-       address &= PAGE_MASK;
-       if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
-               struct vm_area_struct *prev = vma->vm_prev;
-
-               /*
-                * Is there a mapping abutting this one below?
-                *
-                * That's only ok if it's the same stack mapping
-                * that has gotten split..
-                */
-               if (prev && prev->vm_end == address)
-                       return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
-
-               return expand_downwards(vma, address - PAGE_SIZE);
-       }
-       if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
-               struct vm_area_struct *next = vma->vm_next;
-
-               /* As VM_GROWSDOWN but s/below/above/ */
-               if (next && next->vm_start == address + PAGE_SIZE)
-                       return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
-
-               return expand_upwards(vma, address + PAGE_SIZE);
-       }
-       return 0;
-}
-
 /*
  * We enter with non-exclusive mmap_sem (to exclude vma changes,
  * but allow concurrent faults), and pte mapped but not yet locked.
@@ -2904,10 +2870,6 @@ static int do_anonymous_page(struct vm_fault *vmf)
        if (vma->vm_flags & VM_SHARED)
                return VM_FAULT_SIGBUS;
 
-       /* Check if we need to add a guard page to the stack */
-       if (check_stack_guard_page(vma, vmf->address) < 0)
-               return VM_FAULT_SIGSEGV;
-
        /*
         * Use pte_alloc() instead of pte_alloc_map().  We can't run
         * pte_offset_map() on pmds where a huge pmd might be created
index f82741e199c0b06d971bd30d4503bc3e6e6f9dc5..a5e3dcd75e79f40557cefc1bd5338d34eb4fa2f2 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -183,6 +183,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
        unsigned long retval;
        unsigned long newbrk, oldbrk;
        struct mm_struct *mm = current->mm;
+       struct vm_area_struct *next;
        unsigned long min_brk;
        bool populate;
        LIST_HEAD(uf);
@@ -229,7 +230,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
        }
 
        /* Check against existing mmap mappings. */
-       if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
+       next = find_vma(mm, oldbrk);
+       if (next && newbrk + PAGE_SIZE > vm_start_gap(next))
                goto out;
 
        /* Ok, looks good - let it rip. */
@@ -253,10 +255,22 @@ out:
 
 static long vma_compute_subtree_gap(struct vm_area_struct *vma)
 {
-       unsigned long max, subtree_gap;
-       max = vma->vm_start;
-       if (vma->vm_prev)
-               max -= vma->vm_prev->vm_end;
+       unsigned long max, prev_end, subtree_gap;
+
+       /*
+        * Note: in the rare case of a VM_GROWSDOWN above a VM_GROWSUP, we
+        * allow two stack_guard_gaps between them here, and when choosing
+        * an unmapped area; whereas when expanding we only require one.
+        * That's a little inconsistent, but keeps the code here simpler.
+        */
+       max = vm_start_gap(vma);
+       if (vma->vm_prev) {
+               prev_end = vm_end_gap(vma->vm_prev);
+               if (max > prev_end)
+                       max -= prev_end;
+               else
+                       max = 0;
+       }
        if (vma->vm_rb.rb_left) {
                subtree_gap = rb_entry(vma->vm_rb.rb_left,
                                struct vm_area_struct, vm_rb)->rb_subtree_gap;
@@ -352,7 +366,7 @@ static void validate_mm(struct mm_struct *mm)
                        anon_vma_unlock_read(anon_vma);
                }
 
-               highest_address = vma->vm_end;
+               highest_address = vm_end_gap(vma);
                vma = vma->vm_next;
                i++;
        }
@@ -541,7 +555,7 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
        if (vma->vm_next)
                vma_gap_update(vma->vm_next);
        else
-               mm->highest_vm_end = vma->vm_end;
+               mm->highest_vm_end = vm_end_gap(vma);
 
        /*
         * vma->vm_prev wasn't known when we followed the rbtree to find the
@@ -856,7 +870,7 @@ again:
                        vma_gap_update(vma);
                if (end_changed) {
                        if (!next)
-                               mm->highest_vm_end = end;
+                               mm->highest_vm_end = vm_end_gap(vma);
                        else if (!adjust_next)
                                vma_gap_update(next);
                }
@@ -941,7 +955,7 @@ again:
                         * mm->highest_vm_end doesn't need any update
                         * in remove_next == 1 case.
                         */
-                       VM_WARN_ON(mm->highest_vm_end != end);
+                       VM_WARN_ON(mm->highest_vm_end != vm_end_gap(vma));
                }
        }
        if (insert && file)
@@ -1787,7 +1801,7 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 
        while (true) {
                /* Visit left subtree if it looks promising */
-               gap_end = vma->vm_start;
+               gap_end = vm_start_gap(vma);
                if (gap_end >= low_limit && vma->vm_rb.rb_left) {
                        struct vm_area_struct *left =
                                rb_entry(vma->vm_rb.rb_left,
@@ -1798,12 +1812,13 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info)
                        }
                }
 
-               gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
+               gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
 check_current:
                /* Check if current node has a suitable gap */
                if (gap_start > high_limit)
                        return -ENOMEM;
-               if (gap_end >= low_limit && gap_end - gap_start >= length)
+               if (gap_end >= low_limit &&
+                   gap_end > gap_start && gap_end - gap_start >= length)
                        goto found;
 
                /* Visit right subtree if it looks promising */
@@ -1825,8 +1840,8 @@ check_current:
                        vma = rb_entry(rb_parent(prev),
                                       struct vm_area_struct, vm_rb);
                        if (prev == vma->vm_rb.rb_left) {
-                               gap_start = vma->vm_prev->vm_end;
-                               gap_end = vma->vm_start;
+                               gap_start = vm_end_gap(vma->vm_prev);
+                               gap_end = vm_start_gap(vma);
                                goto check_current;
                        }
                }
@@ -1890,7 +1905,7 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
 
        while (true) {
                /* Visit right subtree if it looks promising */
-               gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
+               gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
                if (gap_start <= high_limit && vma->vm_rb.rb_right) {
                        struct vm_area_struct *right =
                                rb_entry(vma->vm_rb.rb_right,
@@ -1903,10 +1918,11 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
 
 check_current:
                /* Check if current node has a suitable gap */
-               gap_end = vma->vm_start;
+               gap_end = vm_start_gap(vma);
                if (gap_end < low_limit)
                        return -ENOMEM;
-               if (gap_start <= high_limit && gap_end - gap_start >= length)
+               if (gap_start <= high_limit &&
+                   gap_end > gap_start && gap_end - gap_start >= length)
                        goto found;
 
                /* Visit left subtree if it looks promising */
@@ -1929,7 +1945,7 @@ check_current:
                                       struct vm_area_struct, vm_rb);
                        if (prev == vma->vm_rb.rb_right) {
                                gap_start = vma->vm_prev ?
-                                       vma->vm_prev->vm_end : 0;
+                                       vm_end_gap(vma->vm_prev) : 0;
                                goto check_current;
                        }
                }
@@ -1967,7 +1983,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
                unsigned long len, unsigned long pgoff, unsigned long flags)
 {
        struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
+       struct vm_area_struct *vma, *prev;
        struct vm_unmapped_area_info info;
 
        if (len > TASK_SIZE - mmap_min_addr)
@@ -1978,9 +1994,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
        if (addr) {
                addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
+               vma = find_vma_prev(mm, addr, &prev);
                if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-                   (!vma || addr + len <= vma->vm_start))
+                   (!vma || addr + len <= vm_start_gap(vma)) &&
+                   (!prev || addr >= vm_end_gap(prev)))
                        return addr;
        }
 
@@ -2003,7 +2020,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                          const unsigned long len, const unsigned long pgoff,
                          const unsigned long flags)
 {
-       struct vm_area_struct *vma;
+       struct vm_area_struct *vma, *prev;
        struct mm_struct *mm = current->mm;
        unsigned long addr = addr0;
        struct vm_unmapped_area_info info;
@@ -2018,9 +2035,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        /* requesting a specific address */
        if (addr) {
                addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
+               vma = find_vma_prev(mm, addr, &prev);
                if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-                               (!vma || addr + len <= vma->vm_start))
+                               (!vma || addr + len <= vm_start_gap(vma)) &&
+                               (!prev || addr >= vm_end_gap(prev)))
                        return addr;
        }
 
@@ -2155,21 +2173,19 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr,
  * update accounting. This is shared with both the
  * grow-up and grow-down cases.
  */
-static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, unsigned long grow)
+static int acct_stack_growth(struct vm_area_struct *vma,
+                            unsigned long size, unsigned long grow)
 {
        struct mm_struct *mm = vma->vm_mm;
        struct rlimit *rlim = current->signal->rlim;
-       unsigned long new_start, actual_size;
+       unsigned long new_start;
 
        /* address space limit tests */
        if (!may_expand_vm(mm, vma->vm_flags, grow))
                return -ENOMEM;
 
        /* Stack limit test */
-       actual_size = size;
-       if (size && (vma->vm_flags & (VM_GROWSUP | VM_GROWSDOWN)))
-               actual_size -= PAGE_SIZE;
-       if (actual_size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur))
+       if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur))
                return -ENOMEM;
 
        /* mlock limit tests */
@@ -2207,16 +2223,32 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
 {
        struct mm_struct *mm = vma->vm_mm;
+       struct vm_area_struct *next;
+       unsigned long gap_addr;
        int error = 0;
 
        if (!(vma->vm_flags & VM_GROWSUP))
                return -EFAULT;
 
-       /* Guard against wrapping around to address 0. */
-       if (address < PAGE_ALIGN(address+4))
-               address = PAGE_ALIGN(address+4);
-       else
+       /* Guard against exceeding limits of the address space. */
+       address &= PAGE_MASK;
+       if (address >= TASK_SIZE)
                return -ENOMEM;
+       address += PAGE_SIZE;
+
+       /* Enforce stack_guard_gap */
+       gap_addr = address + stack_guard_gap;
+
+       /* Guard against overflow */
+       if (gap_addr < address || gap_addr > TASK_SIZE)
+               gap_addr = TASK_SIZE;
+
+       next = vma->vm_next;
+       if (next && next->vm_start < gap_addr) {
+               if (!(next->vm_flags & VM_GROWSUP))
+                       return -ENOMEM;
+               /* Check that both stack segments have the same anon_vma? */
+       }
 
        /* We must make sure the anon_vma is allocated. */
        if (unlikely(anon_vma_prepare(vma)))
@@ -2261,7 +2293,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
                                if (vma->vm_next)
                                        vma_gap_update(vma->vm_next);
                                else
-                                       mm->highest_vm_end = address;
+                                       mm->highest_vm_end = vm_end_gap(vma);
                                spin_unlock(&mm->page_table_lock);
 
                                perf_event_mmap(vma);
@@ -2282,6 +2314,8 @@ int expand_downwards(struct vm_area_struct *vma,
                                   unsigned long address)
 {
        struct mm_struct *mm = vma->vm_mm;
+       struct vm_area_struct *prev;
+       unsigned long gap_addr;
        int error;
 
        address &= PAGE_MASK;
@@ -2289,6 +2323,17 @@ int expand_downwards(struct vm_area_struct *vma,
        if (error)
                return error;
 
+       /* Enforce stack_guard_gap */
+       gap_addr = address - stack_guard_gap;
+       if (gap_addr > address)
+               return -ENOMEM;
+       prev = vma->vm_prev;
+       if (prev && prev->vm_end > gap_addr) {
+               if (!(prev->vm_flags & VM_GROWSDOWN))
+                       return -ENOMEM;
+               /* Check that both stack segments have the same anon_vma? */
+       }
+
        /* We must make sure the anon_vma is allocated. */
        if (unlikely(anon_vma_prepare(vma)))
                return -ENOMEM;
@@ -2343,28 +2388,25 @@ int expand_downwards(struct vm_area_struct *vma,
        return error;
 }
 
-/*
- * Note how expand_stack() refuses to expand the stack all the way to
- * abut the next virtual mapping, *unless* that mapping itself is also
- * a stack mapping. We want to leave room for a guard page, after all
- * (the guard page itself is not added here, that is done by the
- * actual page faulting logic)
- *
- * This matches the behavior of the guard page logic (see mm/memory.c:
- * check_stack_guard_page()), which only allows the guard page to be
- * removed under these circumstances.
- */
+/* enforced gap between the expanding stack and other mappings. */
+unsigned long stack_guard_gap = 256UL<<PAGE_SHIFT;
+
+static int __init cmdline_parse_stack_guard_gap(char *p)
+{
+       unsigned long val;
+       char *endptr;
+
+       val = simple_strtoul(p, &endptr, 10);
+       if (!*endptr)
+               stack_guard_gap = val << PAGE_SHIFT;
+
+       return 0;
+}
+__setup("stack_guard_gap=", cmdline_parse_stack_guard_gap);
+
 #ifdef CONFIG_STACK_GROWSUP
 int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
-       struct vm_area_struct *next;
-
-       address &= PAGE_MASK;
-       next = vma->vm_next;
-       if (next && next->vm_start == address + PAGE_SIZE) {
-               if (!(next->vm_flags & VM_GROWSUP))
-                       return -ENOMEM;
-       }
        return expand_upwards(vma, address);
 }
 
@@ -2386,14 +2428,6 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
 #else
 int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
-       struct vm_area_struct *prev;
-
-       address &= PAGE_MASK;
-       prev = vma->vm_prev;
-       if (prev && prev->vm_end == address) {
-               if (!(prev->vm_flags & VM_GROWSDOWN))
-                       return -ENOMEM;
-       }
        return expand_downwards(vma, address);
 }
 
@@ -2491,7 +2525,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
                vma->vm_prev = prev;
                vma_gap_update(vma);
        } else
-               mm->highest_vm_end = prev ? prev->vm_end : 0;
+               mm->highest_vm_end = prev ? vm_end_gap(prev) : 0;
        tail_vma->vm_next = NULL;
 
        /* Kill the cache */
index 7449593fca724147cef5b8f7a46752333e5e0585..8addc535bcdc58794fe40e72a729e4589d44d2b6 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5625,6 +5625,28 @@ static char *create_unique_id(struct kmem_cache *s)
        return name;
 }
 
+static void sysfs_slab_remove_workfn(struct work_struct *work)
+{
+       struct kmem_cache *s =
+               container_of(work, struct kmem_cache, kobj_remove_work);
+
+       if (!s->kobj.state_in_sysfs)
+               /*
+                * For a memcg cache, this may be called during
+                * deactivation and again on shutdown.  Remove only once.
+                * A cache is never shut down before deactivation is
+                * complete, so no need to worry about synchronization.
+                */
+               return;
+
+#ifdef CONFIG_MEMCG
+       kset_unregister(s->memcg_kset);
+#endif
+       kobject_uevent(&s->kobj, KOBJ_REMOVE);
+       kobject_del(&s->kobj);
+       kobject_put(&s->kobj);
+}
+
 static int sysfs_slab_add(struct kmem_cache *s)
 {
        int err;
@@ -5632,6 +5654,8 @@ static int sysfs_slab_add(struct kmem_cache *s)
        struct kset *kset = cache_kset(s);
        int unmergeable = slab_unmergeable(s);
 
+       INIT_WORK(&s->kobj_remove_work, sysfs_slab_remove_workfn);
+
        if (!kset) {
                kobject_init(&s->kobj, &slab_ktype);
                return 0;
@@ -5695,20 +5719,8 @@ static void sysfs_slab_remove(struct kmem_cache *s)
                 */
                return;
 
-       if (!s->kobj.state_in_sysfs)
-               /*
-                * For a memcg cache, this may be called during
-                * deactivation and again on shutdown.  Remove only once.
-                * A cache is never shut down before deactivation is
-                * complete, so no need to worry about synchronization.
-                */
-               return;
-
-#ifdef CONFIG_MEMCG
-       kset_unregister(s->memcg_kset);
-#endif
-       kobject_uevent(&s->kobj, KOBJ_REMOVE);
-       kobject_del(&s->kobj);
+       kobject_get(&s->kobj);
+       schedule_work(&s->kobj_remove_work);
 }
 
 void sysfs_slab_release(struct kmem_cache *s)
index ac6318a064d35e6dcc5385d1dc8062ff6e46554c..3405b4ee1757e3deb196c93e49b9641dad8d56fb 100644 (file)
@@ -48,6 +48,9 @@ static int swap_cgroup_prepare(int type)
                if (!page)
                        goto not_enough_page;
                ctrl->map[idx] = page;
+
+               if (!(idx % SWAP_CLUSTER_MAX))
+                       cond_resched();
        }
        return 0;
 not_enough_page:
index 34a1c3e46ed72594b499e7f61e8aacdd4c5fe818..ecc97f74ab182fe9aeb7d7eda5166dfdb5b03095 100644 (file)
@@ -287,10 +287,21 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
        if (p4d_none(*p4d))
                return NULL;
        pud = pud_offset(p4d, addr);
-       if (pud_none(*pud))
+
+       /*
+        * Don't dereference bad PUD or PMD (below) entries. This will also
+        * identify huge mappings, which we may encounter on architectures
+        * that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be
+        * identified as vmalloc addresses by is_vmalloc_addr(), but are
+        * not [unambiguously] associated with a struct page, so there is
+        * no correct value to return for them.
+        */
+       WARN_ON_ONCE(pud_bad(*pud));
+       if (pud_none(*pud) || pud_bad(*pud))
                return NULL;
        pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd))
+       WARN_ON_ONCE(pmd_bad(*pmd));
+       if (pmd_none(*pmd) || pmd_bad(*pmd))
                return NULL;
 
        ptep = pte_offset_map(pmd, addr);
index 6063581f705c48b97a78a087d8c67127af9c8d68..ce0618bfa8d0643d0e65263ad65a9e7a7a4c92ed 100644 (file)
@@ -115,9 +115,9 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
        unsigned long pressure = 0;
 
        /*
-        * reclaimed can be greater than scanned in cases
-        * like THP, where the scanned is 1 and reclaimed
-        * could be 512
+        * reclaimed can be greater than scanned for things such as reclaimed
+        * slab pages. shrink_node() just adds reclaimed pages without a
+        * related increment to scanned pages.
         */
        if (reclaimed >= scanned)
                goto out;
index 467069b73ce1b89e5a7b72904a878ef1f3412c67..9649579b5b9f38aff6ce7a990d2dc1ddb1d85e12 100644 (file)
@@ -277,7 +277,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
        return 0;
 
 out_free_newdev:
-       free_netdev(new_dev);
+       if (new_dev->reg_state == NETREG_UNINITIALIZED)
+               free_netdev(new_dev);
        return err;
 }
 
index 953b6728bd00c8ca7a4a20f2d2036c6f8f27f8e3..abc5f400fc71f2f57f3a029d1c196890ee4e39e0 100644 (file)
@@ -813,7 +813,6 @@ static void vlan_dev_free(struct net_device *dev)
 
        free_percpu(vlan->vlan_pcpu_stats);
        vlan->vlan_pcpu_stats = NULL;
-       free_netdev(dev);
 }
 
 void vlan_setup(struct net_device *dev)
@@ -826,7 +825,8 @@ void vlan_setup(struct net_device *dev)
        netif_keep_dst(dev);
 
        dev->netdev_ops         = &vlan_netdev_ops;
-       dev->destructor         = vlan_dev_free;
+       dev->needs_free_netdev  = true;
+       dev->priv_destructor    = vlan_dev_free;
        dev->ethtool_ops        = &vlan_ethtool_ops;
 
        dev->min_mtu            = 0;
index 013e970eff393e0550aa250f7e72c27301071552..000ca2f113ab857b4969a95b8fe1134806b05f15 100644 (file)
@@ -1064,8 +1064,9 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
 
                skb_new->protocol = eth_type_trans(skb_new, soft_iface);
 
-               soft_iface->stats.rx_packets++;
-               soft_iface->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size;
+               batadv_inc_counter(bat_priv, BATADV_CNT_RX);
+               batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
+                                  skb->len + ETH_HLEN + hdr_size);
 
                netif_rx(skb_new);
                batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
index e1ebe14ee2a6e21cc8d6b4a42552cae4bd15061f..ae9f4d37d34f07182c3d2527186a0999fe5b639d 100644 (file)
@@ -987,7 +987,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
                                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                                           "recv_unicast_packet(): Dropped unicast pkt received from another backbone gw %pM.\n",
                                           orig_addr_gw);
-                               return NET_RX_DROP;
+                               goto free_skb;
                        }
                }
 
index b25789abf7b9e10aec7af1dfc41a5c9ff805284a..10f7edfb176ebd49c680ff4132db87aa00d3f04e 100644 (file)
@@ -1034,8 +1034,6 @@ static void batadv_softif_free(struct net_device *dev)
         * netdev and its private data (bat_priv)
         */
        rcu_barrier();
-
-       free_netdev(dev);
 }
 
 /**
@@ -1047,7 +1045,8 @@ static void batadv_softif_init_early(struct net_device *dev)
        ether_setup(dev);
 
        dev->netdev_ops = &batadv_netdev_ops;
-       dev->destructor = batadv_softif_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = batadv_softif_free;
        dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
        dev->priv_flags |= IFF_NO_QUEUE;
 
index 608959989f8eddbfc9b97279a7fba61fd7381d04..ab3b654b05cc87e19a965d0419efb7d45bd4b94e 100644 (file)
@@ -598,7 +598,7 @@ static void netdev_setup(struct net_device *dev)
 
        dev->netdev_ops         = &netdev_ops;
        dev->header_ops         = &header_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 }
 
 static struct device_type bt_type = {
index 430b53e7d941def09220a1c97a2e82d288304595..f0f3447e8aa48ff02c3f11f6da0e65e79cb28e90 100644 (file)
@@ -379,7 +379,7 @@ void br_dev_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->netdev_ops = &br_netdev_ops;
-       dev->destructor = free_netdev;
+       dev->needs_free_netdev = true;
        dev->ethtool_ops = &br_ethtool_ops;
        SET_NETDEV_DEVTYPE(dev, &br_type);
        dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
index adcad344c843985435958890583761e865a25374..21f18ea2fce440c1a0c8dcddc335e327dbf9bced 100644 (file)
@@ -754,6 +754,10 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
 
        lock_sock(sk);
 
+       err = -EINVAL;
+       if (addr_len < offsetofend(struct sockaddr, sa_family))
+               goto out;
+
        err = -EAFNOSUPPORT;
        if (uaddr->sa_family != AF_CAIF)
                goto out;
index 59ce1fcc220ce0a71fb57733be7cc91e6b8ac7fc..71b6ab240dea26b228be35ba24ec3f43772f19f7 100644 (file)
@@ -81,11 +81,7 @@ static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
 {
        struct sk_buff *skb;
 
-       if (likely(in_interrupt()))
-               skb = alloc_skb(len + pfx, GFP_ATOMIC);
-       else
-               skb = alloc_skb(len + pfx, GFP_KERNEL);
-
+       skb = alloc_skb(len + pfx, GFP_ATOMIC);
        if (unlikely(skb == NULL))
                return NULL;
 
index 1816fc9f1ee779f85874e886a9ba6db721c60680..fe3c53efb949ef29a3dc1f6278d9abc05b50f579 100644 (file)
@@ -392,14 +392,14 @@ static void chnl_net_destructor(struct net_device *dev)
 {
        struct chnl_net *priv = netdev_priv(dev);
        caif_free_client(&priv->chnl);
-       free_netdev(dev);
 }
 
 static void ipcaif_net_setup(struct net_device *dev)
 {
        struct chnl_net *priv;
        dev->netdev_ops = &netdev_ops;
-       dev->destructor = chnl_net_destructor;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = chnl_net_destructor;
        dev->flags |= IFF_NOARP;
        dev->flags |= IFF_POINTOPOINT;
        dev->mtu = GPRS_PDP_MTU;
index b6406fe33c76d1e7ca5f439e9b7409ad3a680e6d..88edac0f3e366398d0c1e0de023b90b0669498f9 100644 (file)
@@ -872,8 +872,7 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg,
 
 static int can_pernet_init(struct net *net)
 {
-       net->can.can_rcvlists_lock =
-               __SPIN_LOCK_UNLOCKED(net->can.can_rcvlists_lock);
+       spin_lock_init(&net->can.can_rcvlists_lock);
        net->can.can_rx_alldev_list =
                kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL);
 
index fca407b4a6ea178d9224949bc57f89a26c97c5c1..7243421c9783bf060dac1938fc1f2f59a4afafea 100644 (file)
@@ -1253,8 +1253,9 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
        if (!new_ifalias)
                return -ENOMEM;
        dev->ifalias = new_ifalias;
+       memcpy(dev->ifalias, alias, len);
+       dev->ifalias[len] = 0;
 
-       strlcpy(dev->ifalias, alias, len+1);
        return len;
 }
 
@@ -4948,6 +4949,19 @@ __sum16 __skb_gro_checksum_complete(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(__skb_gro_checksum_complete);
 
+static void net_rps_send_ipi(struct softnet_data *remsd)
+{
+#ifdef CONFIG_RPS
+       while (remsd) {
+               struct softnet_data *next = remsd->rps_ipi_next;
+
+               if (cpu_online(remsd->cpu))
+                       smp_call_function_single_async(remsd->cpu, &remsd->csd);
+               remsd = next;
+       }
+#endif
+}
+
 /*
  * net_rps_action_and_irq_enable sends any pending IPI's for rps.
  * Note: called with local irq disabled, but exits with local irq enabled.
@@ -4963,14 +4977,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
                local_irq_enable();
 
                /* Send pending IPI's to kick RPS processing on remote cpus. */
-               while (remsd) {
-                       struct softnet_data *next = remsd->rps_ipi_next;
-
-                       if (cpu_online(remsd->cpu))
-                               smp_call_function_single_async(remsd->cpu,
-                                                          &remsd->csd);
-                       remsd = next;
-               }
+               net_rps_send_ipi(remsd);
        } else
 #endif
                local_irq_enable();
@@ -5199,8 +5206,6 @@ static void busy_poll_stop(struct napi_struct *napi, void *have_poll_lock)
        if (rc == BUSY_POLL_BUDGET)
                __napi_schedule(napi);
        local_bh_enable();
-       if (local_softirq_pending())
-               do_softirq();
 }
 
 void napi_busy_loop(unsigned int napi_id,
@@ -7501,6 +7506,8 @@ out:
 err_uninit:
        if (dev->netdev_ops->ndo_uninit)
                dev->netdev_ops->ndo_uninit(dev);
+       if (dev->priv_destructor)
+               dev->priv_destructor(dev);
        goto out;
 }
 EXPORT_SYMBOL(register_netdevice);
@@ -7708,8 +7715,10 @@ void netdev_run_todo(void)
                WARN_ON(rcu_access_pointer(dev->ip6_ptr));
                WARN_ON(dev->dn_ptr);
 
-               if (dev->destructor)
-                       dev->destructor(dev);
+               if (dev->priv_destructor)
+                       dev->priv_destructor(dev);
+               if (dev->needs_free_netdev)
+                       free_netdev(dev);
 
                /* Report a network device has been unregistered */
                rtnl_lock();
@@ -8192,7 +8201,7 @@ static int dev_cpu_dead(unsigned int oldcpu)
        struct sk_buff **list_skb;
        struct sk_buff *skb;
        unsigned int cpu;
-       struct softnet_data *sd, *oldsd;
+       struct softnet_data *sd, *oldsd, *remsd = NULL;
 
        local_irq_disable();
        cpu = smp_processor_id();
@@ -8233,6 +8242,13 @@ static int dev_cpu_dead(unsigned int oldcpu)
        raise_softirq_irqoff(NET_TX_SOFTIRQ);
        local_irq_enable();
 
+#ifdef CONFIG_RPS
+       remsd = oldsd->rps_ipi_list;
+       oldsd->rps_ipi_list = NULL;
+#endif
+       /* send out pending IPI's on offline CPU */
+       net_rps_send_ipi(remsd);
+
        /* Process offline CPU's input_pkt_queue */
        while ((skb = __skb_dequeue(&oldsd->process_queue))) {
                netif_rx_ni(skb);
index b94b1d29350603e19c3db8e6fd740d3f89440771..27fad31784a83861f942f3b4f82f44985a946645 100644 (file)
@@ -410,6 +410,22 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
        if (cmd == SIOCGIFNAME)
                return dev_ifname(net, (struct ifreq __user *)arg);
 
+       /*
+        * Take care of Wireless Extensions. Unfortunately struct iwreq
+        * isn't a proper subset of struct ifreq (it's 8 byte shorter)
+        * so we need to treat it specially, otherwise applications may
+        * fault if the struct they're passing happens to land at the
+        * end of a mapped page.
+        */
+       if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
+               struct iwreq iwr;
+
+               if (copy_from_user(&iwr, arg, sizeof(iwr)))
+                       return -EFAULT;
+
+               return wext_handle_ioctl(net, &iwr, cmd, arg);
+       }
+
        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
                return -EFAULT;
 
@@ -559,9 +575,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
                                ret = -EFAULT;
                        return ret;
                }
-               /* Take care of Wireless Extensions */
-               if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
-                       return wext_handle_ioctl(net, &ifr, cmd, arg);
                return -ENOTTY;
        }
 }
index 6192f11beec9077de964e2aeff4f78547f08b8da..13ba4a090c410e40853178df4ffca85f02b71b03 100644 (file)
@@ -469,6 +469,20 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event,
                spin_lock_bh(&dst_garbage.lock);
                dst = dst_garbage.list;
                dst_garbage.list = NULL;
+               /* The code in dst_ifdown places a hold on the loopback device.
+                * If the gc entry processing is set to expire after a lengthy
+                * interval, this hold can cause netdev_wait_allrefs() to hang
+                * out and wait for a long time -- until the the loopback
+                * interface is released.  If we're really unlucky, it'll emit
+                * pr_emerg messages to console too.  Reset the interval here,
+                * so dst cleanups occur in a more timely fashion.
+                */
+               if (dst_garbage.timer_inc > DST_GC_INC) {
+                       dst_garbage.timer_inc = DST_GC_INC;
+                       dst_garbage.timer_expires = DST_GC_MIN;
+                       mod_delayed_work(system_wq, &dst_gc_work,
+                                        dst_garbage.timer_expires);
+               }
                spin_unlock_bh(&dst_garbage.lock);
 
                if (last)
index f21c4d3aeae0cf59a8d9239cf1e581e6d136c740..3bba291c6c32e4359a6d626fbd492f7d07fd3e4c 100644 (file)
@@ -568,7 +568,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct net *net = sock_net(skb->sk);
        struct fib_rule_hdr *frh = nlmsg_data(nlh);
        struct fib_rules_ops *ops = NULL;
-       struct fib_rule *rule, *tmp;
+       struct fib_rule *rule, *r;
        struct nlattr *tb[FRA_MAX+1];
        struct fib_kuid_range range;
        int err = -EINVAL;
@@ -668,16 +668,23 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
 
                /*
                 * Check if this rule is a target to any of them. If so,
+                * adjust to the next one with the same preference or
                 * disable them. As this operation is eventually very
-                * expensive, it is only performed if goto rules have
-                * actually been added.
+                * expensive, it is only performed if goto rules, except
+                * current if it is goto rule, have actually been added.
                 */
                if (ops->nr_goto_rules > 0) {
-                       list_for_each_entry(tmp, &ops->rules_list, list) {
-                               if (rtnl_dereference(tmp->ctarget) == rule) {
-                                       RCU_INIT_POINTER(tmp->ctarget, NULL);
+                       struct fib_rule *n;
+
+                       n = list_next_entry(rule, list);
+                       if (&n->list == &ops->rules_list || n->pref != rule->pref)
+                               n = NULL;
+                       list_for_each_entry(r, &ops->rules_list, list) {
+                               if (rtnl_dereference(r->ctarget) != rule)
+                                       continue;
+                               rcu_assign_pointer(r->ctarget, n);
+                               if (!n)
                                        ops->unresolved_rules++;
-                               }
                        }
                }
 
index 9e2c0a7cb3256e8cb2af1d65aaf293db96b9a418..467a2f4510a74cad48209b696532838d1edcf96e 100644 (file)
@@ -931,6 +931,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
               + nla_total_size(1) /* IFLA_LINKMODE */
               + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
               + nla_total_size(4) /* IFLA_LINK_NETNSID */
+              + nla_total_size(4) /* IFLA_GROUP */
               + nla_total_size(ext_filter_mask
                                & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
               + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
@@ -1124,6 +1125,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
        struct ifla_vf_mac vf_mac;
        struct ifla_vf_info ivi;
 
+       memset(&ivi, 0, sizeof(ivi));
+
        /* Not all SR-IOV capable drivers support the
         * spoofcheck and "RSS query enable" query.  Preset to
         * -1 so the user space tool can detect that the driver
@@ -1132,7 +1135,6 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
        ivi.spoofchk = -1;
        ivi.rss_query_en = -1;
        ivi.trusted = -1;
-       memset(ivi.mac, 0, sizeof(ivi.mac));
        /* The default value for VF link state is "auto"
         * IFLA_VF_LINK_STATE_AUTO which equals zero
         */
@@ -1467,6 +1469,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_LINK_NETNSID]     = { .type = NLA_S32 },
        [IFLA_PROTO_DOWN]       = { .type = NLA_U8 },
        [IFLA_XDP]              = { .type = NLA_NESTED },
+       [IFLA_GROUP]            = { .type = NLA_U32 },
 };
 
 static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
index 4b9518a0d2489494ed88b6808f95803cf1b543ad..6f95612b4d321d63e39b37f881f0e46331999ad2 100644 (file)
@@ -188,12 +188,6 @@ static inline void dnrt_free(struct dn_route *rt)
        call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
 }
 
-static inline void dnrt_drop(struct dn_route *rt)
-{
-       dst_release(&rt->dst);
-       call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
 static void dn_dst_check_expire(unsigned long dummy)
 {
        int i;
@@ -248,7 +242,7 @@ static int dn_dst_gc(struct dst_ops *ops)
                        }
                        *rtp = rt->dst.dn_next;
                        rt->dst.dn_next = NULL;
-                       dnrt_drop(rt);
+                       dnrt_free(rt);
                        break;
                }
                spin_unlock_bh(&dn_rt_hash_table[i].lock);
@@ -350,7 +344,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned int hash, struct dn_rou
                        dst_use(&rth->dst, now);
                        spin_unlock_bh(&dn_rt_hash_table[hash].lock);
 
-                       dnrt_drop(rt);
+                       dst_free(&rt->dst);
                        *rp = rth;
                        return 0;
                }
@@ -380,7 +374,7 @@ static void dn_run_flush(unsigned long dummy)
                for(; rt; rt = next) {
                        next = rcu_dereference_raw(rt->dst.dn_next);
                        RCU_INIT_POINTER(rt->dst.dn_next, NULL);
-                       dst_free((struct dst_entry *)rt);
+                       dnrt_free(rt);
                }
 
 nothing_to_declare:
@@ -1187,7 +1181,7 @@ make_route:
        if (dev_out->flags & IFF_LOOPBACK)
                flags |= RTCF_LOCAL;
 
-       rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
+       rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST);
        if (rt == NULL)
                goto e_nobufs;
 
index 1ed81ac6dd1a28b79dff9f9f4e8c1d0f99306a33..aa8ffecc46a439fa129dfea9c1f4d4e525ad3796 100644 (file)
@@ -102,7 +102,9 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
 {
        struct nlmsghdr *nlh = nlmsg_hdr(skb);
 
-       if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
+       if (skb->len < sizeof(*nlh) ||
+           nlh->nlmsg_len < sizeof(*nlh) ||
+           skb->len < nlh->nlmsg_len)
                return;
 
        if (!netlink_capable(skb, CAP_NET_ADMIN))
index c73160fb11e7c666f8ac8ed4103b7312ff769a58..0a0a392dc2bd64b8c4202cc1361d828f9f984dd1 100644 (file)
@@ -378,7 +378,6 @@ static void hsr_dev_destroy(struct net_device *hsr_dev)
        del_timer_sync(&hsr->announce_timer);
 
        synchronize_rcu();
-       free_netdev(hsr_dev);
 }
 
 static const struct net_device_ops hsr_device_ops = {
@@ -404,7 +403,8 @@ void hsr_dev_setup(struct net_device *dev)
        SET_NETDEV_DEVTYPE(dev, &hsr_type);
        dev->priv_flags |= IFF_NO_QUEUE;
 
-       dev->destructor = hsr_dev_destroy;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = hsr_dev_destroy;
 
        dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
                           NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
index 4ebe2aa3e7d3e944295e9d53890e3cb9b7a90139..04b5450c5a5572e875f7900a3676fd80259b9b4b 100644 (file)
@@ -324,8 +324,7 @@ static int hsr_fill_frame_info(struct hsr_frame_info *frame,
        unsigned long irqflags;
 
        frame->is_supervision = is_supervision_frame(port->hsr, skb);
-       frame->node_src = hsr_get_node(&port->hsr->node_db, skb,
-                                      frame->is_supervision);
+       frame->node_src = hsr_get_node(port, skb, frame->is_supervision);
        if (frame->node_src == NULL)
                return -1; /* Unknown node and !is_supervision, or no mem */
 
index 7ea925816f79d8a0e547a0feb1257fda23097ba4..284a9b820df8db51a0dbee9737db5a8127eeaad7 100644 (file)
@@ -158,9 +158,10 @@ struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[],
 
 /* Get the hsr_node from which 'skb' was sent.
  */
-struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,
+struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb,
                              bool is_sup)
 {
+       struct list_head *node_db = &port->hsr->node_db;
        struct hsr_node *node;
        struct ethhdr *ethhdr;
        u16 seq_out;
@@ -186,7 +187,11 @@ struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,
                 */
                seq_out = hsr_get_skb_sequence_nr(skb) - 1;
        } else {
-               WARN_ONCE(1, "%s: Non-HSR frame\n", __func__);
+               /* this is called also for frames from master port and
+                * so warn only for non master ports
+                */
+               if (port->type != HSR_PT_MASTER)
+                       WARN_ONCE(1, "%s: Non-HSR frame\n", __func__);
                seq_out = HSR_SEQNR_START;
        }
 
index 438b40f98f5a986e50180c351d55c9dbb0b66977..4e04f0e868e95044ac27f77ca11d004d928326cd 100644 (file)
@@ -18,7 +18,7 @@ struct hsr_node;
 
 struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[],
                              u16 seq_out);
-struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,
+struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb,
                              bool is_sup);
 void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr,
                          struct hsr_port *port);
index d7efbf0dad20f8c4d3c42d039eff528c678bc04c..0a866f3322901e357091955bf24ac16fc5f6b94f 100644 (file)
@@ -107,7 +107,7 @@ static void lowpan_setup(struct net_device *ldev)
 
        ldev->netdev_ops        = &lowpan_netdev_ops;
        ldev->header_ops        = &lowpan_header_ops;
-       ldev->destructor        = free_netdev;
+       ldev->needs_free_netdev = true;
        ldev->features          |= NETIF_F_NETNS_LOCAL;
 }
 
index 43318b5f56474bc15253e74e156962dd2c8df01f..9144fa7df2ad51372ba1c1debf54a41460a8cbec 100644 (file)
@@ -657,8 +657,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
        /* Needed by both icmp_global_allow and icmp_xmit_lock */
        local_bh_disable();
 
-       /* Check global sysctl_icmp_msgs_per_sec ratelimit */
-       if (!icmpv4_global_allow(net, type, code))
+       /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless
+        * incoming dev is loopback.  If outgoing dev change to not be
+        * loopback, then peer ratelimit still work (in icmpv4_xrlim_allow)
+        */
+       if (!(skb_in->dev && (skb_in->dev->flags&IFF_LOOPBACK)) &&
+             !icmpv4_global_allow(net, type, code))
                goto out_bh_enable;
 
        sk = icmp_xmit_lock(net);
index 44fd86de2823dd17de16276a8ec01b190e69b8b4..ec9a396fa4660272f96602e78c5c3b0603068d66 100644 (file)
@@ -1112,6 +1112,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
        pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
        if (!pmc)
                return;
+       spin_lock_init(&pmc->lock);
        spin_lock_bh(&im->lock);
        pmc->interface = im->interface;
        in_dev_hold(in_dev);
@@ -2071,21 +2072,26 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
 
 static void ip_mc_clear_src(struct ip_mc_list *pmc)
 {
-       struct ip_sf_list *psf, *nextpsf;
+       struct ip_sf_list *psf, *nextpsf, *tomb, *sources;
 
-       for (psf = pmc->tomb; psf; psf = nextpsf) {
+       spin_lock_bh(&pmc->lock);
+       tomb = pmc->tomb;
+       pmc->tomb = NULL;
+       sources = pmc->sources;
+       pmc->sources = NULL;
+       pmc->sfmode = MCAST_EXCLUDE;
+       pmc->sfcount[MCAST_INCLUDE] = 0;
+       pmc->sfcount[MCAST_EXCLUDE] = 1;
+       spin_unlock_bh(&pmc->lock);
+
+       for (psf = tomb; psf; psf = nextpsf) {
                nextpsf = psf->sf_next;
                kfree(psf);
        }
-       pmc->tomb = NULL;
-       for (psf = pmc->sources; psf; psf = nextpsf) {
+       for (psf = sources; psf; psf = nextpsf) {
                nextpsf = psf->sf_next;
                kfree(psf);
        }
-       pmc->sources = NULL;
-       pmc->sfmode = MCAST_EXCLUDE;
-       pmc->sfcount[MCAST_INCLUDE] = 0;
-       pmc->sfcount[MCAST_EXCLUDE] = 1;
 }
 
 /* Join a multicast group
index b878ecbc0608fb433ae858b70e6e0101aa20fc4e..129d1a3616f838c9b487cf2392d1d9eb09dcfa5a 100644 (file)
@@ -446,6 +446,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
        return 0;
 
 drop:
+       if (tun_dst)
+               dst_release((struct dst_entry *)tun_dst);
        kfree_skb(skb);
        return 0;
 }
@@ -967,7 +969,6 @@ static void ip_tunnel_dev_free(struct net_device *dev)
        gro_cells_destroy(&tunnel->gro_cells);
        dst_cache_destroy(&tunnel->dst_cache);
        free_percpu(dev->tstats);
-       free_netdev(dev);
 }
 
 void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
@@ -1155,7 +1156,8 @@ int ip_tunnel_init(struct net_device *dev)
        struct iphdr *iph = &tunnel->parms.iph;
        int err;
 
-       dev->destructor = ip_tunnel_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = ip_tunnel_dev_free;
        dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
        if (!dev->tstats)
                return -ENOMEM;
index 551de4d023a8edbf74835b43cb32d9173eedae36..8ae425cad81858b3a79719d47b43f8baa346a06a 100644 (file)
@@ -101,8 +101,8 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id);
 static void ipmr_free_table(struct mr_table *mrt);
 
 static void ip_mr_forward(struct net *net, struct mr_table *mrt,
-                         struct sk_buff *skb, struct mfc_cache *cache,
-                         int local);
+                         struct net_device *dev, struct sk_buff *skb,
+                         struct mfc_cache *cache, int local);
 static int ipmr_cache_report(struct mr_table *mrt,
                             struct sk_buff *pkt, vifi_t vifi, int assert);
 static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
@@ -501,7 +501,7 @@ static void reg_vif_setup(struct net_device *dev)
        dev->mtu                = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
        dev->flags              = IFF_NOARP;
        dev->netdev_ops         = &reg_vif_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->features           |= NETIF_F_NETNS_LOCAL;
 }
 
@@ -988,7 +988,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
 
                        rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
                } else {
-                       ip_mr_forward(net, mrt, skb, c, 0);
+                       ip_mr_forward(net, mrt, skb->dev, skb, c, 0);
                }
        }
 }
@@ -1073,7 +1073,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
 
 /* Queue a packet for resolution. It gets locked cache entry! */
 static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
-                                struct sk_buff *skb)
+                                struct sk_buff *skb, struct net_device *dev)
 {
        const struct iphdr *iph = ip_hdr(skb);
        struct mfc_cache *c;
@@ -1130,6 +1130,10 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
                kfree_skb(skb);
                err = -ENOBUFS;
        } else {
+               if (dev) {
+                       skb->dev = dev;
+                       skb->skb_iif = dev->ifindex;
+               }
                skb_queue_tail(&c->mfc_un.unres.unresolved, skb);
                err = 0;
        }
@@ -1828,10 +1832,10 @@ static int ipmr_find_vif(struct mr_table *mrt, struct net_device *dev)
 
 /* "local" means that we should preserve one skb (for local delivery) */
 static void ip_mr_forward(struct net *net, struct mr_table *mrt,
-                         struct sk_buff *skb, struct mfc_cache *cache,
-                         int local)
+                         struct net_device *dev, struct sk_buff *skb,
+                         struct mfc_cache *cache, int local)
 {
-       int true_vifi = ipmr_find_vif(mrt, skb->dev);
+       int true_vifi = ipmr_find_vif(mrt, dev);
        int psend = -1;
        int vif, ct;
 
@@ -1853,13 +1857,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
        }
 
        /* Wrong interface: drop packet and (maybe) send PIM assert. */
-       if (mrt->vif_table[vif].dev != skb->dev) {
-               struct net_device *mdev;
-
-               mdev = l3mdev_master_dev_rcu(mrt->vif_table[vif].dev);
-               if (mdev == skb->dev)
-                       goto forward;
-
+       if (mrt->vif_table[vif].dev != dev) {
                if (rt_is_output_route(skb_rtable(skb))) {
                        /* It is our own packet, looped back.
                         * Very complicated situation...
@@ -2053,7 +2051,7 @@ int ip_mr_input(struct sk_buff *skb)
                read_lock(&mrt_lock);
                vif = ipmr_find_vif(mrt, dev);
                if (vif >= 0) {
-                       int err2 = ipmr_cache_unresolved(mrt, vif, skb);
+                       int err2 = ipmr_cache_unresolved(mrt, vif, skb, dev);
                        read_unlock(&mrt_lock);
 
                        return err2;
@@ -2064,7 +2062,7 @@ int ip_mr_input(struct sk_buff *skb)
        }
 
        read_lock(&mrt_lock);
-       ip_mr_forward(net, mrt, skb, cache, local);
+       ip_mr_forward(net, mrt, dev, skb, cache, local);
        read_unlock(&mrt_lock);
 
        if (local)
@@ -2238,7 +2236,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
                iph->saddr = saddr;
                iph->daddr = daddr;
                iph->version = 0;
-               err = ipmr_cache_unresolved(mrt, vif, skb2);
+               err = ipmr_cache_unresolved(mrt, vif, skb2, dev);
                read_unlock(&mrt_lock);
                rcu_read_unlock();
                return err;
index 6a4fb1e629fb7609048156974ae2eb322cebddae..686c92375e81d50787adbfb423afba76903948ad 100644 (file)
@@ -332,9 +332,9 @@ static void addrconf_mod_rs_timer(struct inet6_dev *idev,
 static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
                                   unsigned long delay)
 {
-       if (!delayed_work_pending(&ifp->dad_work))
-               in6_ifa_hold(ifp);
-       mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
+       in6_ifa_hold(ifp);
+       if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay))
+               in6_ifa_put(ifp);
 }
 
 static int snmp6_alloc_dev(struct inet6_dev *idev)
index eea23b57c6a5a000aec234cc9bf6f9411d98001f..ec849d88a66205742b1a58c4959c08eeffc3f6d7 100644 (file)
@@ -32,7 +32,6 @@ struct fib6_rule {
 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
                                   int flags, pol_lookup_t lookup)
 {
-       struct rt6_info *rt;
        struct fib_lookup_arg arg = {
                .lookup_ptr = lookup,
                .flags = FIB_LOOKUP_NOREF,
@@ -44,21 +43,11 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
        fib_rules_lookup(net->ipv6.fib6_rules_ops,
                         flowi6_to_flowi(fl6), flags, &arg);
 
-       rt = arg.result;
+       if (arg.result)
+               return arg.result;
 
-       if (!rt) {
-               dst_hold(&net->ipv6.ip6_null_entry->dst);
-               return &net->ipv6.ip6_null_entry->dst;
-       }
-
-       if (rt->rt6i_flags & RTF_REJECT &&
-           rt->dst.error == -EAGAIN) {
-               ip6_rt_put(rt);
-               rt = net->ipv6.ip6_null_entry;
-               dst_hold(&rt->dst);
-       }
-
-       return &rt->dst;
+       dst_hold(&net->ipv6.ip6_null_entry->dst);
+       return &net->ipv6.ip6_null_entry->dst;
 }
 
 static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
@@ -121,7 +110,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
                        flp6->saddr = saddr;
                }
                err = rt->dst.error;
-               goto out;
+               if (err != -EAGAIN)
+                       goto out;
        }
 again:
        ip6_rt_put(rt);
index 230b5aac9f03eadb775eea9cb3d9b4cce571cc32..8d7b113958b1332be11545069fafa8072a64e6a2 100644 (file)
@@ -491,7 +491,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
        local_bh_disable();
 
        /* Check global sysctl_icmp_msgs_per_sec ratelimit */
-       if (!icmpv6_global_allow(type))
+       if (!(skb->dev->flags&IFF_LOOPBACK) && !icmpv6_global_allow(type))
                goto out_bh_enable;
 
        mip6_addr_swap(skb);
index 2fd5ca151dcfca6034b0b0b27a3fe9abc7899e75..77f7f8c7d93d67483f241616123380f9d8e6ba84 100644 (file)
@@ -62,6 +62,7 @@ static inline u32 ila_locator_hash(struct ila_locator loc)
 {
        u32 *v = (u32 *)loc.v32;
 
+       __ila_hash_secret_init();
        return jhash_2words(v[0], v[1], hashrnd);
 }
 
index d4bf2c68a545b44873e433930e4e999920de78c9..e6b78ba0e6360ea40be58f07ea1c6657efcca93e 100644 (file)
@@ -289,8 +289,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
        struct rt6_info *rt;
 
        rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
-       if (rt->rt6i_flags & RTF_REJECT &&
-           rt->dst.error == -EAGAIN) {
+       if (rt->dst.error == -EAGAIN) {
                ip6_rt_put(rt);
                rt = net->ipv6.ip6_null_entry;
                dst_hold(&rt->dst);
index 0c5b4caa19491eb04bc755032611c76f03008acb..64eea3962733a323fbae25b3c7b6de658a8cfdea 100644 (file)
@@ -991,13 +991,13 @@ static void ip6gre_dev_free(struct net_device *dev)
 
        dst_cache_destroy(&t->dst_cache);
        free_percpu(dev->tstats);
-       free_netdev(dev);
 }
 
 static void ip6gre_tunnel_setup(struct net_device *dev)
 {
        dev->netdev_ops = &ip6gre_netdev_ops;
-       dev->destructor = ip6gre_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = ip6gre_dev_free;
 
        dev->type = ARPHRD_IP6GRE;
 
@@ -1148,7 +1148,7 @@ static int __net_init ip6gre_init_net(struct net *net)
        return 0;
 
 err_reg_dev:
-       ip6gre_dev_free(ign->fb_tunnel_dev);
+       free_netdev(ign->fb_tunnel_dev);
 err_alloc_dev:
        return err;
 }
@@ -1300,7 +1300,8 @@ static void ip6gre_tap_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->netdev_ops = &ip6gre_tap_netdev_ops;
-       dev->destructor = ip6gre_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = ip6gre_dev_free;
 
        dev->features |= NETIF_F_NETNS_LOCAL;
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;
index 9b37f9747fc6a6fbabb0740188bc98b5c95c41c4..8c6c3c8e7eef26899ea22ff85997230c8fd17e7e 100644 (file)
@@ -254,7 +254,6 @@ static void ip6_dev_free(struct net_device *dev)
        gro_cells_destroy(&t->gro_cells);
        dst_cache_destroy(&t->dst_cache);
        free_percpu(dev->tstats);
-       free_netdev(dev);
 }
 
 static int ip6_tnl_create2(struct net_device *dev)
@@ -322,7 +321,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
        return t;
 
 failed_free:
-       ip6_dev_free(dev);
+       free_netdev(dev);
 failed:
        return ERR_PTR(err);
 }
@@ -859,6 +858,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
        return 0;
 
 drop:
+       if (tun_dst)
+               dst_release((struct dst_entry *)tun_dst);
        kfree_skb(skb);
        return 0;
 }
@@ -1247,7 +1248,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
                fl6.flowi6_proto = IPPROTO_IPIP;
                fl6.daddr = key->u.ipv6.dst;
                fl6.flowlabel = key->label;
-               dsfield = ip6_tclass(key->label);
+               dsfield =  key->tos;
        } else {
                if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
                        encap_limit = t->parms.encap_limit;
@@ -1318,7 +1319,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
                fl6.flowi6_proto = IPPROTO_IPV6;
                fl6.daddr = key->u.ipv6.dst;
                fl6.flowlabel = key->label;
-               dsfield = ip6_tclass(key->label);
+               dsfield = key->tos;
        } else {
                offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
                /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */
@@ -1777,7 +1778,8 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
 static void ip6_tnl_dev_setup(struct net_device *dev)
 {
        dev->netdev_ops = &ip6_tnl_netdev_ops;
-       dev->destructor = ip6_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = ip6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
        dev->flags |= IFF_NOARP;
@@ -2224,7 +2226,7 @@ static int __net_init ip6_tnl_init_net(struct net *net)
        return 0;
 
 err_register:
-       ip6_dev_free(ip6n->fb_tnl_dev);
+       free_netdev(ip6n->fb_tnl_dev);
 err_alloc_dev:
        return err;
 }
index d67ef56454b25a088768e88fcd1f878a8c498f12..837ea1eefe7f8cc85924a9604d58cd702af94667 100644 (file)
@@ -180,7 +180,6 @@ vti6_tnl_unlink(struct vti6_net *ip6n, struct ip6_tnl *t)
 static void vti6_dev_free(struct net_device *dev)
 {
        free_percpu(dev->tstats);
-       free_netdev(dev);
 }
 
 static int vti6_tnl_create2(struct net_device *dev)
@@ -235,7 +234,7 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p
        return t;
 
 failed_free:
-       vti6_dev_free(dev);
+       free_netdev(dev);
 failed:
        return NULL;
 }
@@ -842,7 +841,8 @@ static const struct net_device_ops vti6_netdev_ops = {
 static void vti6_dev_setup(struct net_device *dev)
 {
        dev->netdev_ops = &vti6_netdev_ops;
-       dev->destructor = vti6_dev_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = vti6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
        dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
@@ -1100,7 +1100,7 @@ static int __net_init vti6_init_net(struct net *net)
        return 0;
 
 err_register:
-       vti6_dev_free(ip6n->fb_tnl_dev);
+       free_netdev(ip6n->fb_tnl_dev);
 err_alloc_dev:
        return err;
 }
index 374997d26488ea38db7ed42ff7e6a55ede249021..2ecb39b943b5002e63bfa5b045919fbfd9fd64f6 100644 (file)
@@ -733,7 +733,7 @@ static void reg_vif_setup(struct net_device *dev)
        dev->mtu                = 1500 - sizeof(struct ipv6hdr) - 8;
        dev->flags              = IFF_NOARP;
        dev->netdev_ops         = &reg_vif_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->features           |= NETIF_F_NETNS_LOCAL;
 }
 
index cc8e3ae9ca736490c3f689297d190f930fdd2ac9..e88bcb8ff0fd73b8377f5e0d3c3d1fa524ef1da8 100644 (file)
@@ -219,7 +219,7 @@ static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu *mib,
        u64 buff64[SNMP_MIB_MAX];
        int i;
 
-       memset(buff64, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
+       memset(buff64, 0, sizeof(u64) * SNMP_MIB_MAX);
 
        snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
        for (i = 0; itemlist[i].name; i++)
index dc61b0b5e64edf7bd69ab905573e38415abf2346..7cebd954d5bb4263017f8f2d577ecfb88ca7c093 100644 (file)
@@ -2804,6 +2804,7 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg)
        if ((rt->dst.dev == dev || !dev) &&
            rt != adn->net->ipv6.ip6_null_entry &&
            (rt->rt6i_nsiblings == 0 ||
+            (dev && netdev_unregistering(dev)) ||
             !rt->rt6i_idev->cnf.ignore_routes_with_linkdown))
                return -1;
 
index 61e5902f068732b10f734c7937c7539d418820d7..2378503577b0c8823049b7d17f857466481077b3 100644 (file)
@@ -265,7 +265,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
        return nt;
 
 failed_free:
-       ipip6_dev_free(dev);
+       free_netdev(dev);
 failed:
        return NULL;
 }
@@ -1336,7 +1336,6 @@ static void ipip6_dev_free(struct net_device *dev)
 
        dst_cache_destroy(&tunnel->dst_cache);
        free_percpu(dev->tstats);
-       free_netdev(dev);
 }
 
 #define SIT_FEATURES (NETIF_F_SG          | \
@@ -1351,7 +1350,8 @@ static void ipip6_tunnel_setup(struct net_device *dev)
        int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
        dev->netdev_ops         = &ipip6_netdev_ops;
-       dev->destructor         = ipip6_dev_free;
+       dev->needs_free_netdev  = true;
+       dev->priv_destructor    = ipip6_dev_free;
 
        dev->type               = ARPHRD_SIT;
        dev->hard_header_len    = LL_MAX_HEADER + t_hlen;
index 74d09f91709e6121ed80b8f089283615a5ffce5e..3be852808a9d1f7a2767f482b334279a95e90642 100644 (file)
@@ -65,7 +65,7 @@ static void irlan_eth_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->netdev_ops         = &irlan_eth_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
        dev->min_mtu            = 0;
        dev->max_mtu            = ETH_MAX_MTU;
 
index 8b21af7321b928b4dcc5d7af3a6667380e9a949a..4de2ec94b08cbf5aba016da754b799c46d5f378a 100644 (file)
@@ -114,12 +114,13 @@ static void l2tp_eth_get_stats64(struct net_device *dev,
 {
        struct l2tp_eth *priv = netdev_priv(dev);
 
-       stats->tx_bytes   = atomic_long_read(&priv->tx_bytes);
-       stats->tx_packets = atomic_long_read(&priv->tx_packets);
-       stats->tx_dropped = atomic_long_read(&priv->tx_dropped);
-       stats->rx_bytes   = atomic_long_read(&priv->rx_bytes);
-       stats->rx_packets = atomic_long_read(&priv->rx_packets);
-       stats->rx_errors  = atomic_long_read(&priv->rx_errors);
+       stats->tx_bytes   = (unsigned long) atomic_long_read(&priv->tx_bytes);
+       stats->tx_packets = (unsigned long) atomic_long_read(&priv->tx_packets);
+       stats->tx_dropped = (unsigned long) atomic_long_read(&priv->tx_dropped);
+       stats->rx_bytes   = (unsigned long) atomic_long_read(&priv->rx_bytes);
+       stats->rx_packets = (unsigned long) atomic_long_read(&priv->rx_packets);
+       stats->rx_errors  = (unsigned long) atomic_long_read(&priv->rx_errors);
+
 }
 
 static const struct net_device_ops l2tp_eth_netdev_ops = {
@@ -141,7 +142,7 @@ static void l2tp_eth_dev_setup(struct net_device *dev)
        dev->priv_flags         &= ~IFF_TX_SKB_SHARING;
        dev->features           |= NETIF_F_LLTX;
        dev->netdev_ops         = &l2tp_eth_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 }
 
 static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
index 6c2e6060cd549e3c4c39e78cc20ca9302472c4ac..4a388fe8c2d1363b300becd61664d333b128e845 100644 (file)
@@ -902,6 +902,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
        default:
                return -EINVAL;
        }
+       sdata->u.ap.req_smps = sdata->smps_mode;
+
        sdata->needed_rx_chains = sdata->local->rx_chains;
 
        sdata->vif.bss_conf.beacon_int = params->beacon_interval;
index 665501ac358f8d83630f2727fe6249dcfeeb9689..5e002f62c235fbae4c5154ef9eab65c0e5f842b8 100644 (file)
@@ -1531,7 +1531,7 @@ ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
                return true;
        /* can't handle non-legacy preamble yet */
        if (status->flag & RX_FLAG_MACTIME_PLCP_START &&
-           status->encoding != RX_ENC_LEGACY)
+           status->encoding == RX_ENC_LEGACY)
                return true;
        return false;
 }
index 8fae1a72e6a7c7ea4f71ec3a3beb215b987a715f..f5f50150ba1cd7f53689a4e5efac3235f04679cf 100644 (file)
@@ -1213,7 +1213,6 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
 static void ieee80211_if_free(struct net_device *dev)
 {
        free_percpu(dev->tstats);
-       free_netdev(dev);
 }
 
 static void ieee80211_if_setup(struct net_device *dev)
@@ -1221,7 +1220,8 @@ static void ieee80211_if_setup(struct net_device *dev)
        ether_setup(dev);
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops = &ieee80211_dataif_ops;
-       dev->destructor = ieee80211_if_free;
+       dev->needs_free_netdev = true;
+       dev->priv_destructor = ieee80211_if_free;
 }
 
 static void ieee80211_if_setup_no_queue(struct net_device *dev)
@@ -1816,6 +1816,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
                ret = dev_alloc_name(ndev, ndev->name);
                if (ret < 0) {
                        ieee80211_if_free(ndev);
+                       free_netdev(ndev);
                        return ret;
                }
 
@@ -1905,7 +1906,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 
                ret = register_netdevice(ndev);
                if (ret) {
-                       ieee80211_if_free(ndev);
+                       free_netdev(ndev);
                        return ret;
                }
        }
index 0ea9712bd99ea698f40b068d5ee31a69133224a3..cc8e6ea1b27e95e36412d840cd394039f5df4d5d 100644 (file)
@@ -601,7 +601,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_supported_band *sband;
        struct ieee80211_chanctx_conf *chanctx_conf;
        struct ieee80211_channel *chan;
-       u32 rate_flags, rates = 0;
+       u32 rates = 0;
 
        sdata_assert_lock(sdata);
 
@@ -612,7 +612,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                return;
        }
        chan = chanctx_conf->def.chan;
-       rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
        rcu_read_unlock();
        sband = local->hw.wiphy->bands[chan->band];
        shift = ieee80211_vif_get_shift(&sdata->vif);
@@ -636,9 +635,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                 */
                rates_len = 0;
                for (i = 0; i < sband->n_bitrates; i++) {
-                       if ((rate_flags & sband->bitrates[i].flags)
-                           != rate_flags)
-                               continue;
                        rates |= BIT(i);
                        rates_len++;
                }
@@ -2818,7 +2814,7 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
                                u32 *rates, u32 *basic_rates,
                                bool *have_higher_than_11mbit,
                                int *min_rate, int *min_rate_index,
-                               int shift, u32 rate_flags)
+                               int shift)
 {
        int i, j;
 
@@ -2846,8 +2842,6 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
                        int brate;
 
                        br = &sband->bitrates[j];
-                       if ((rate_flags & br->flags) != rate_flags)
-                               continue;
 
                        brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
                        if (brate == rate) {
@@ -4398,40 +4392,32 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
                        return -ENOMEM;
        }
 
-       if (new_sta || override) {
-               err = ieee80211_prep_channel(sdata, cbss);
-               if (err) {
-                       if (new_sta)
-                               sta_info_free(local, new_sta);
-                       return -EINVAL;
-               }
-       }
-
+       /*
+        * Set up the information for the new channel before setting the
+        * new channel. We can't - completely race-free - change the basic
+        * rates bitmap and the channel (sband) that it refers to, but if
+        * we set it up before we at least avoid calling into the driver's
+        * bss_info_changed() method with invalid information (since we do
+        * call that from changing the channel - only for IDLE and perhaps
+        * some others, but ...).
+        *
+        * So to avoid that, just set up all the new information before the
+        * channel, but tell the driver to apply it only afterwards, since
+        * it might need the new channel for that.
+        */
        if (new_sta) {
                u32 rates = 0, basic_rates = 0;
                bool have_higher_than_11mbit;
                int min_rate = INT_MAX, min_rate_index = -1;
-               struct ieee80211_chanctx_conf *chanctx_conf;
                const struct cfg80211_bss_ies *ies;
                int shift = ieee80211_vif_get_shift(&sdata->vif);
-               u32 rate_flags;
-
-               rcu_read_lock();
-               chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-               if (WARN_ON(!chanctx_conf)) {
-                       rcu_read_unlock();
-                       sta_info_free(local, new_sta);
-                       return -EINVAL;
-               }
-               rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
-               rcu_read_unlock();
 
                ieee80211_get_rates(sband, bss->supp_rates,
                                    bss->supp_rates_len,
                                    &rates, &basic_rates,
                                    &have_higher_than_11mbit,
                                    &min_rate, &min_rate_index,
-                                   shift, rate_flags);
+                                   shift);
 
                /*
                 * This used to be a workaround for basic rates missing
@@ -4489,8 +4475,22 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
                        sdata->vif.bss_conf.sync_dtim_count = 0;
                }
                rcu_read_unlock();
+       }
 
-               /* tell driver about BSSID, basic rates and timing */
+       if (new_sta || override) {
+               err = ieee80211_prep_channel(sdata, cbss);
+               if (err) {
+                       if (new_sta)
+                               sta_info_free(local, new_sta);
+                       return -EINVAL;
+               }
+       }
+
+       if (new_sta) {
+               /*
+                * tell driver about BSSID, basic rates and timing
+                * this was set up above, before setting the channel
+                */
                ieee80211_bss_info_change_notify(sdata,
                        BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES |
                        BSS_CHANGED_BEACON_INT);
index 1f75280ba26c78b3ad9864d0b63305cbba43f8fe..3674fe3d67dc74ba9042e91920f43376325c6b6a 100644 (file)
@@ -1613,12 +1613,16 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
         */
        if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) &&
            !ieee80211_has_morefrags(hdr->frame_control) &&
+           !ieee80211_is_back_req(hdr->frame_control) &&
            !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
            (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
             rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
-           /* PM bit is only checked in frames where it isn't reserved,
+           /*
+            * PM bit is only checked in frames where it isn't reserved,
             * in AP mode it's reserved in non-bufferable management frames
             * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
+            * BAR frames should be ignored as specified in
+            * IEEE 802.11-2012 10.2.1.2.
             */
            (!ieee80211_is_mgmt(hdr->frame_control) ||
             ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
index c1ef22df865fe77bf7cf0a42d560f54db98a3edd..cc19614ff4e60bed9a351b8f8aa73792103665a0 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/unaligned.h>
 #include <net/mac80211.h>
 #include <crypto/aes.h>
+#include <crypto/algapi.h>
 
 #include "ieee80211_i.h"
 #include "michael.h"
@@ -153,7 +154,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
        data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
        key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
        michael_mic(key, hdr, data, data_len, mic);
-       if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
+       if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN))
                goto mic_fail;
 
        /* remove Michael MIC from payload */
@@ -1048,7 +1049,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
                bip_aad(skb, aad);
                ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
                                   skb->data + 24, skb->len - 24, mic);
-               if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
+               if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
                        key->u.aes_cmac.icverrors++;
                        return RX_DROP_UNUSABLE;
                }
@@ -1098,7 +1099,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
                bip_aad(skb, aad);
                ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
                                       skb->data + 24, skb->len - 24, mic);
-               if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
+               if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
                        key->u.aes_cmac.icverrors++;
                        return RX_DROP_UNUSABLE;
                }
@@ -1202,7 +1203,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
                if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
                                       skb->data + 24, skb->len - 24,
                                       mic) < 0 ||
-                   memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
+                   crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
                        key->u.aes_gmac.icverrors++;
                        return RX_DROP_UNUSABLE;
                }
index 06019dba4b10e3e0d079ee617707ae5412269144..bd88a9b80773e20e5de1f5a66ae7a3471387135e 100644 (file)
@@ -526,8 +526,6 @@ static void mac802154_wpan_free(struct net_device *dev)
        struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 
        mac802154_llsec_destroy(&sdata->sec);
-
-       free_netdev(dev);
 }
 
 static void ieee802154_if_setup(struct net_device *dev)
@@ -593,7 +591,8 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
                                        sdata->dev->dev_addr);
 
                sdata->dev->header_ops = &mac802154_header_ops;
-               sdata->dev->destructor = mac802154_wpan_free;
+               sdata->dev->needs_free_netdev = true;
+               sdata->dev->priv_destructor = mac802154_wpan_free;
                sdata->dev->netdev_ops = &mac802154_wpan_ops;
                sdata->dev->ml_priv = &mac802154_mlme_wpan;
                wpan_dev->promiscuous_mode = false;
@@ -608,7 +607,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
 
                break;
        case NL802154_IFTYPE_MONITOR:
-               sdata->dev->destructor = free_netdev;
+               sdata->dev->needs_free_netdev = true;
                sdata->dev->netdev_ops = &mac802154_monitor_ops;
                wpan_dev->promiscuous_mode = true;
                break;
index 89193a634da45bb78498ecd28ca39c455e32f2e4..04a3128adcf0adcc2603e45c9054cdd2fd0e7a0b 100644 (file)
@@ -94,7 +94,6 @@ static void internal_dev_destructor(struct net_device *dev)
        struct vport *vport = ovs_internal_dev_get_vport(dev);
 
        ovs_vport_free(vport);
-       free_netdev(dev);
 }
 
 static void
@@ -156,7 +155,8 @@ static void do_setup(struct net_device *netdev)
        netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
        netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH |
                              IFF_PHONY_HEADROOM | IFF_NO_QUEUE;
-       netdev->destructor = internal_dev_destructor;
+       netdev->needs_free_netdev = true;
+       netdev->priv_destructor = internal_dev_destructor;
        netdev->ethtool_ops = &internal_dev_ethtool_ops;
        netdev->rtnl_link_ops = &internal_dev_link_ops;
 
index 21c28b51be9439b20369b48077ac8392db7c3150..2c9337946e3038f130d198bb51d061a648ef1ed4 100644 (file)
@@ -236,7 +236,7 @@ static void gprs_setup(struct net_device *dev)
        dev->tx_queue_len       = 10;
 
        dev->netdev_ops         = &gprs_netdev_ops;
-       dev->destructor         = free_netdev;
+       dev->needs_free_netdev  = true;
 }
 
 /*
index 0a4e28477ad94012b4e7aeb526711076e6259995..54369225766ef8e43ff94f21b4fd670b2cc233a3 100644 (file)
@@ -217,7 +217,7 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
                                       unsigned int *_toklen)
 {
        const __be32 *xdr = *_xdr;
-       unsigned int toklen = *_toklen, n_parts, loop, tmp;
+       unsigned int toklen = *_toklen, n_parts, loop, tmp, paddedlen;
 
        /* there must be at least one name, and at least #names+1 length
         * words */
@@ -247,16 +247,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
                toklen -= 4;
                if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX)
                        return -EINVAL;
-               if (tmp > toklen)
+               paddedlen = (tmp + 3) & ~3;
+               if (paddedlen > toklen)
                        return -EINVAL;
                princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL);
                if (!princ->name_parts[loop])
                        return -ENOMEM;
                memcpy(princ->name_parts[loop], xdr, tmp);
                princ->name_parts[loop][tmp] = 0;
-               tmp = (tmp + 3) & ~3;
-               toklen -= tmp;
-               xdr += tmp >> 2;
+               toklen -= paddedlen;
+               xdr += paddedlen >> 2;
        }
 
        if (toklen < 4)
@@ -265,16 +265,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
        toklen -= 4;
        if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX)
                return -EINVAL;
-       if (tmp > toklen)
+       paddedlen = (tmp + 3) & ~3;
+       if (paddedlen > toklen)
                return -EINVAL;
        princ->realm = kmalloc(tmp + 1, GFP_KERNEL);
        if (!princ->realm)
                return -ENOMEM;
        memcpy(princ->realm, xdr, tmp);
        princ->realm[tmp] = 0;
-       tmp = (tmp + 3) & ~3;
-       toklen -= tmp;
-       xdr += tmp >> 2;
+       toklen -= paddedlen;
+       xdr += paddedlen >> 2;
 
        _debug("%s/...@%s", princ->name_parts[0], princ->realm);
 
@@ -293,7 +293,7 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
                                         unsigned int *_toklen)
 {
        const __be32 *xdr = *_xdr;
-       unsigned int toklen = *_toklen, len;
+       unsigned int toklen = *_toklen, len, paddedlen;
 
        /* there must be at least one tag and one length word */
        if (toklen <= 8)
@@ -307,15 +307,17 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
        toklen -= 8;
        if (len > max_data_size)
                return -EINVAL;
+       paddedlen = (len + 3) & ~3;
+       if (paddedlen > toklen)
+               return -EINVAL;
        td->data_len = len;
 
        if (len > 0) {
                td->data = kmemdup(xdr, len, GFP_KERNEL);
                if (!td->data)
                        return -ENOMEM;
-               len = (len + 3) & ~3;
-               toklen -= len;
-               xdr += len >> 2;
+               toklen -= paddedlen;
+               xdr += paddedlen >> 2;
        }
 
        _debug("tag %x len %x", td->tag, td->data_len);
@@ -387,7 +389,7 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
                                    const __be32 **_xdr, unsigned int *_toklen)
 {
        const __be32 *xdr = *_xdr;
-       unsigned int toklen = *_toklen, len;
+       unsigned int toklen = *_toklen, len, paddedlen;
 
        /* there must be at least one length word */
        if (toklen <= 4)
@@ -399,6 +401,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
        toklen -= 4;
        if (len > AFSTOKEN_K5_TIX_MAX)
                return -EINVAL;
+       paddedlen = (len + 3) & ~3;
+       if (paddedlen > toklen)
+               return -EINVAL;
        *_tktlen = len;
 
        _debug("ticket len %u", len);
@@ -407,9 +412,8 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
                *_ticket = kmemdup(xdr, len, GFP_KERNEL);
                if (!*_ticket)
                        return -ENOMEM;
-               len = (len + 3) & ~3;
-               toklen -= len;
-               xdr += len >> 2;
+               toklen -= paddedlen;
+               xdr += paddedlen >> 2;
        }
 
        *_xdr = xdr;
@@ -552,7 +556,7 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
 {
        const __be32 *xdr = prep->data, *token;
        const char *cp;
-       unsigned int len, tmp, loop, ntoken, toklen, sec_ix;
+       unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
        size_t datalen = prep->datalen;
        int ret;
 
@@ -578,22 +582,21 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
        if (len < 1 || len > AFSTOKEN_CELL_MAX)
                goto not_xdr;
        datalen -= 4;
-       tmp = (len + 3) & ~3;
-       if (tmp > datalen)
+       paddedlen = (len + 3) & ~3;
+       if (paddedlen > datalen)
                goto not_xdr;
 
        cp = (const char *) xdr;
        for (loop = 0; loop < len; loop++)
                if (!isprint(cp[loop]))
                        goto not_xdr;
-       if (len < tmp)
-               for (; loop < tmp; loop++)
-                       if (cp[loop])
-                               goto not_xdr;
+       for (; loop < paddedlen; loop++)
+               if (cp[loop])
+                       goto not_xdr;
        _debug("cellname: [%u/%u] '%*.*s'",
-              len, tmp, len, len, (const char *) xdr);
-       datalen -= tmp;
-       xdr += tmp >> 2;
+              len, paddedlen, len, len, (const char *) xdr);
+       datalen -= paddedlen;
+       xdr += paddedlen >> 2;
 
        /* get the token count */
        if (datalen < 12)
@@ -614,10 +617,11 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
                sec_ix = ntohl(*xdr);
                datalen -= 4;
                _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
-               if (toklen < 20 || toklen > datalen)
+               paddedlen = (toklen + 3) & ~3;
+               if (toklen < 20 || toklen > datalen || paddedlen > datalen)
                        goto not_xdr;
-               datalen -= (toklen + 3) & ~3;
-               xdr += (toklen + 3) >> 2;
+               datalen -= paddedlen;
+               xdr += paddedlen >> 2;
 
        } while (--loop > 0);
 
index 164b5ac094be6d8bbd7a04aa8aa962a3c693ab44..7dc5892671c818db55b024b10d56ec2252c2f826 100644 (file)
@@ -94,8 +94,10 @@ static struct tcf_pedit_key_ex *tcf_pedit_keys_ex_parse(struct nlattr *nla,
                k++;
        }
 
-       if (n)
+       if (n) {
+               err = -EINVAL;
                goto err_out;
+       }
 
        return keys_ex;
 
index f42008b293112d1a6da2bcf6ef8af564b382ba39..b062bc80c7cb11b0ea473916c58957b54db21594 100644 (file)
@@ -132,21 +132,21 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
                }
        }
 
-       spin_lock_bh(&police->tcf_lock);
        if (est) {
                err = gen_replace_estimator(&police->tcf_bstats, NULL,
                                            &police->tcf_rate_est,
                                            &police->tcf_lock,
                                            NULL, est);
                if (err)
-                       goto failure_unlock;
+                       goto failure;
        } else if (tb[TCA_POLICE_AVRATE] &&
                   (ret == ACT_P_CREATED ||
                    !gen_estimator_active(&police->tcf_rate_est))) {
                err = -EINVAL;
-               goto failure_unlock;
+               goto failure;
        }
 
+       spin_lock_bh(&police->tcf_lock);
        /* No failure allowed after this point */
        police->tcfp_mtu = parm->mtu;
        if (police->tcfp_mtu == 0) {
@@ -192,8 +192,6 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
 
        return ret;
 
-failure_unlock:
-       spin_unlock_bh(&police->tcf_lock);
 failure:
        qdisc_put_rtab(P_tab);
        qdisc_put_rtab(R_tab);
index 8c589230794f9394406d2a0ad2157b7a47d75757..3dcd0ecf3d99f74ec8ed4aad149bd32950ab23ef 100644 (file)
@@ -275,6 +275,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
                if (sctp_sk(sk)->bind_hash)
                        sctp_put_port(sk);
 
+               sctp_sk(sk)->ep = NULL;
                sock_put(sk);
        }
 
index 048954eee984f28e599084b32fad87b2bd6989d0..9a647214a91ebc583660db320307e0df1e13e5be 100644 (file)
@@ -278,7 +278,6 @@ out:
 
 static int sctp_sock_dump(struct sock *sk, void *p)
 {
-       struct sctp_endpoint *ep = sctp_sk(sk)->ep;
        struct sctp_comm_param *commp = p;
        struct sk_buff *skb = commp->skb;
        struct netlink_callback *cb = commp->cb;
@@ -287,7 +286,9 @@ static int sctp_sock_dump(struct sock *sk, void *p)
        int err = 0;
 
        lock_sock(sk);
-       list_for_each_entry(assoc, &ep->asocs, asocs) {
+       if (!sctp_sk(sk)->ep)
+               goto release;
+       list_for_each_entry(assoc, &sctp_sk(sk)->ep->asocs, asocs) {
                if (cb->args[4] < cb->args[1])
                        goto next;
 
index f16c8d97b7f313e9f671d8bb8620b0f9566e619f..3a8318e518f1c10a375dc3ff6ba6596579bb85a1 100644 (file)
@@ -4622,13 +4622,13 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
 
        for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
             hash++, head++) {
-               read_lock(&head->lock);
+               read_lock_bh(&head->lock);
                sctp_for_each_hentry(epb, &head->chain) {
                        err = cb(sctp_ep(epb), p);
                        if (err)
                                break;
                }
-               read_unlock(&head->lock);
+               read_unlock_bh(&head->lock);
        }
 
        return err;
@@ -4666,9 +4666,8 @@ int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
        if (err)
                return err;
 
-       sctp_transport_get_idx(net, &hti, pos);
-       obj = sctp_transport_get_next(net, &hti);
-       for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) {
+       obj = sctp_transport_get_idx(net, &hti, pos + 1);
+       for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) {
                struct sctp_transport *transport = obj;
 
                if (!sctp_transport_hold(transport))
index 312ef7de57d7ba27c58533df9edb2f4dd61cc864..ab3087687a32446ffa3bbfaccf206028886e6945 100644 (file)
@@ -508,7 +508,7 @@ bool tipc_msg_reverse(u32 own_node,  struct sk_buff **skb, int err)
        }
 
        if (skb_cloned(_skb) &&
-           pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_KERNEL))
+           pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
                goto exit;
 
        /* Now reverse the concerned fields */
index 6a7fe7660551f45c065a7f472b805c0b8073f6bb..1a0c961f4ffeef40abc5b980e004b01120e3c536 100644 (file)
@@ -999,7 +999,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct path path = { };
 
        err = -EINVAL;
-       if (sunaddr->sun_family != AF_UNIX)
+       if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
+           sunaddr->sun_family != AF_UNIX)
                goto out;
 
        if (addr_len == sizeof(short)) {
@@ -1110,6 +1111,10 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
        unsigned int hash;
        int err;
 
+       err = -EINVAL;
+       if (alen < offsetofend(struct sockaddr, sa_family))
+               goto out;
+
        if (addr->sa_family != AF_UNSPEC) {
                err = unix_mkname(sunaddr, alen, &hash);
                if (err < 0)
index 1a4db6790e2077d4ea922d1c32cde5352543fa2c..6cdb054484d66d40e4523965457a619bd1c9154f 100644 (file)
@@ -914,13 +914,12 @@ int call_commit_handler(struct net_device *dev)
  * Main IOCTl dispatcher.
  * Check the type of IOCTL and call the appropriate wrapper...
  */
-static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
+static int wireless_process_ioctl(struct net *net, struct iwreq *iwr,
                                  unsigned int cmd,
                                  struct iw_request_info *info,
                                  wext_ioctl_func standard,
                                  wext_ioctl_func private)
 {
-       struct iwreq *iwr = (struct iwreq *) ifr;
        struct net_device *dev;
        iw_handler      handler;
 
@@ -928,7 +927,7 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
         * The copy_to/from_user() of ifr is also dealt with in there */
 
        /* Make sure the device exist */
-       if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL)
+       if ((dev = __dev_get_by_name(net, iwr->ifr_name)) == NULL)
                return -ENODEV;
 
        /* A bunch of special cases, then the generic case...
@@ -957,9 +956,6 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
                else if (private)
                        return private(dev, iwr, cmd, info, handler);
        }
-       /* Old driver API : call driver ioctl handler */
-       if (dev->netdev_ops->ndo_do_ioctl)
-               return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
        return -EOPNOTSUPP;
 }
 
@@ -977,7 +973,7 @@ static int wext_permission_check(unsigned int cmd)
 }
 
 /* entry point from dev ioctl */
-static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr,
+static int wext_ioctl_dispatch(struct net *net, struct iwreq *iwr,
                               unsigned int cmd, struct iw_request_info *info,
                               wext_ioctl_func standard,
                               wext_ioctl_func private)
@@ -987,9 +983,9 @@ static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr,
        if (ret)
                return ret;
 
-       dev_load(net, ifr->ifr_name);
+       dev_load(net, iwr->ifr_name);
        rtnl_lock();
-       ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private);
+       ret = wireless_process_ioctl(net, iwr, cmd, info, standard, private);
        rtnl_unlock();
 
        return ret;
@@ -1039,18 +1035,18 @@ static int ioctl_standard_call(struct net_device *      dev,
 }
 
 
-int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
+int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
                      void __user *arg)
 {
        struct iw_request_info info = { .cmd = cmd, .flags = 0 };
        int ret;
 
-       ret = wext_ioctl_dispatch(net, ifr, cmd, &info,
+       ret = wext_ioctl_dispatch(net, iwr, cmd, &info,
                                  ioctl_standard_call,
                                  ioctl_private_call);
        if (ret >= 0 &&
            IW_IS_GET(cmd) &&
-           copy_to_user(arg, ifr, sizeof(struct iwreq)))
+           copy_to_user(arg, iwr, sizeof(struct iwreq)))
                return -EFAULT;
 
        return ret;
@@ -1107,7 +1103,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
        info.cmd = cmd;
        info.flags = IW_REQUEST_FLAG_COMPAT;
 
-       ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, &info,
+       ret = wext_ioctl_dispatch(net, &iwr, cmd, &info,
                                  compat_standard_call,
                                  compat_private_call);
 
index ce753a408c56823dbd1c4b5d4fb5cfe88e7054c4..c583a1e1bd3c16356cf67a772a3e680adec9681a 100644 (file)
@@ -14,7 +14,15 @@ __headers:
 include scripts/Kbuild.include
 
 srcdir        := $(srctree)/$(obj)
-subdirs       := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+
+# When make is run under a fakechroot environment, the function
+# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular
+# files. So, we are using a combination of sort/dir/wildcard which works
+# with fakechroot.
+subdirs       := $(patsubst $(srcdir)/%/,%,\
+                $(filter-out $(srcdir)/,\
+                $(sort $(dir $(wildcard $(srcdir)/*/)))))
+
 # caller may set destination dir (when installing to asm/)
 _dst          := $(if $(dst),$(dst),$(obj))
 
index 3bffdcaaa274e82271a98c65fa0bc43cef53ffe2..b724a0290c75e45cbc89134f2b9ae03166ff27a5 100644 (file)
@@ -75,7 +75,7 @@ struct string_list *copy_list_range(struct string_list *start,
 int yylex(void);
 int yyparse(void);
 
-void error_with_pos(const char *, ...);
+void error_with_pos(const char *, ...) __attribute__ ((format(printf, 1, 2)));
 
 /*----------------------------------------------------------------------*/
 #define xmalloc(size) ({ void *__ptr = malloc(size);           \
index 90a091b6ae4de74e6c070d77255b9f4b5655629a..eb8144643b78355cea07f301531333001cd1d608 100644 (file)
@@ -196,7 +196,7 @@ clean-files     += config.pot linux.pot
 
 # Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
 PHONY += $(obj)/dochecklxdialog
-$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
+$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog
 $(obj)/dochecklxdialog:
        $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
 
index a9bc5334a478d6774d1409a837665b4f143d8597..0031147798153bdd06aa5c1f3d6f2015298b5b5d 100644 (file)
@@ -271,7 +271,7 @@ static struct mitem k_menu_items[MAX_MENU_ITEMS];
 static int items_num;
 static int global_exit;
 /* the currently selected button */
-const char *current_instructions = menu_instructions;
+static const char *current_instructions = menu_instructions;
 
 static char *dialog_input_result;
 static int dialog_input_result_len;
@@ -305,7 +305,7 @@ struct function_keys {
 };
 
 static const int function_keys_num = 9;
-struct function_keys function_keys[] = {
+static struct function_keys function_keys[] = {
        {
                .key_str = "F1",
                .func = "Help",
@@ -508,7 +508,7 @@ static int get_mext_match(const char *match_str, match_f flag)
        index = (index + items_num) % items_num;
        while (true) {
                char *str = k_menu_items[index].str;
-               if (strcasestr(str, match_str) != 0)
+               if (strcasestr(str, match_str) != NULL)
                        return index;
                if (flag == FIND_NEXT_MATCH_UP ||
                    flag == MATCH_TINKER_PATTERN_UP)
@@ -1067,7 +1067,7 @@ static int do_match(int key, struct match_state *state, int *ans)
 
 static void conf(struct menu *menu)
 {
-       struct menu *submenu = 0;
+       struct menu *submenu = NULL;
        const char *prompt = menu_get_prompt(menu);
        struct symbol *sym;
        int res;
@@ -1234,7 +1234,7 @@ static void show_help(struct menu *menu)
 static void conf_choice(struct menu *menu)
 {
        const char *prompt = _(menu_get_prompt(menu));
-       struct menu *child = 0;
+       struct menu *child = NULL;
        struct symbol *active;
        int selected_index = 0;
        int last_top_row = 0;
@@ -1456,7 +1456,7 @@ static void conf_save(void)
        }
 }
 
-void setup_windows(void)
+static void setup_windows(void)
 {
        int lines, columns;
 
index 4b2f44c20caf8941d150f261074b40d589a10376..a64b1c31253e13b918fefe509e1cccf5b4ac248d 100644 (file)
@@ -129,7 +129,7 @@ static void no_colors_theme(void)
        mkattrn(FUNCTION_TEXT, A_REVERSE);
 }
 
-void set_colors()
+void set_colors(void)
 {
        start_color();
        use_default_colors();
@@ -192,7 +192,7 @@ const char *get_line(const char *text, int line_no)
        int lines = 0;
 
        if (!text)
-               return 0;
+               return NULL;
 
        for (i = 0; text[i] != '\0' && lines < line_no; i++)
                if (text[i] == '\n')
index d661f2f3ef614c41e22f2346ee9b41b238266715..d23dcbf17457c2c16cf56c73a1ffb3d07e03a257 100755 (executable)
@@ -106,6 +106,7 @@ all_compiled_sources()
                case "$i" in
                        *.[cS])
                                j=${i/\.[cS]/\.o}
+                               j="${j#$tree}"
                                if [ -e $j ]; then
                                        echo $i
                                fi
index e67a526d1f301e4b9f27cc1685875aef85e6e9c3..819fd6858b499dca6ad37e04d11230c4daad6ff5 100644 (file)
@@ -1106,10 +1106,8 @@ static int selinux_parse_opts_str(char *options,
 
        opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int),
                                       GFP_KERNEL);
-       if (!opts->mnt_opts_flags) {
-               kfree(opts->mnt_opts);
+       if (!opts->mnt_opts_flags)
                goto out_err;
-       }
 
        if (fscontext) {
                opts->mnt_opts[num_mnt_opts] = fscontext;
@@ -1132,6 +1130,7 @@ static int selinux_parse_opts_str(char *options,
        return 0;
 
 out_err:
+       security_free_mnt_opts(opts);
        kfree(context);
        kfree(defcontext);
        kfree(fscontext);
index 5088d4b8db2222e28a71baaa4db7c70a30997e48..009e6c98754e484e489ebcdde361e200ee0d6205 100644 (file)
@@ -2492,7 +2492,7 @@ static int pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
        struct snd_pcm_substream *substream;
        const struct snd_pcm_chmap_elem *map;
 
-       if (snd_BUG_ON(!info->chmap))
+       if (!info->chmap)
                return -EINVAL;
        substream = snd_pcm_chmap_substream(info, idx);
        if (!substream)
@@ -2524,7 +2524,7 @@ static int pcm_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
        unsigned int __user *dst;
        int c, count = 0;
 
-       if (snd_BUG_ON(!info->chmap))
+       if (!info->chmap)
                return -EINVAL;
        if (size < 8)
                return -ENOMEM;
index 9e6f54f8c45d2330ee339a7f4c7d1ac86c8e4774..1e26854b3425e23bd9d2942194f3665fa37e06cf 100644 (file)
@@ -682,7 +682,9 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
                cycle = increment_cycle_count(cycle, 1);
                if (s->handle_packet(s, 0, cycle, i) < 0) {
                        s->packet_index = -1;
-                       amdtp_stream_pcm_abort(s);
+                       if (in_interrupt())
+                               amdtp_stream_pcm_abort(s);
+                       WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN);
                        return;
                }
        }
@@ -734,7 +736,9 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
        /* Queueing error or detecting invalid payload. */
        if (i < packets) {
                s->packet_index = -1;
-               amdtp_stream_pcm_abort(s);
+               if (in_interrupt())
+                       amdtp_stream_pcm_abort(s);
+               WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN);
                return;
        }
 
index 7e88317228212a63ad38e6e9880655f6ea567c85..ea1a91e99875e1f06933142d607a8b9880d210b1 100644 (file)
@@ -135,7 +135,7 @@ struct amdtp_stream {
        /* For a PCM substream processing. */
        struct snd_pcm_substream *pcm;
        struct tasklet_struct period_tasklet;
-       unsigned int pcm_buffer_pointer;
+       snd_pcm_uframes_t pcm_buffer_pointer;
        unsigned int pcm_period_pointer;
 
        /* To wait for first packet. */
index 1770f085c2a694a398e2b30312cb79d6c3fd617a..01eb1dc7b5b3b5cf3c070a7656b81452890781e0 100644 (file)
@@ -370,10 +370,12 @@ enum {
 #define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
 #define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
 #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+#define IS_BXT_T(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x1a98)
 #define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)
-#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
-                       IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)  || \
-                       IS_GLK(pci)
+#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci) || \
+                         IS_BXT_T(pci) || IS_KBL(pci) || IS_KBL_LP(pci) || \
+                         IS_KBL_H(pci) || IS_GLK(pci) || IS_CFL(pci))
 
 static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
@@ -2378,6 +2380,9 @@ static const struct pci_device_id azx_ids[] = {
        /* Kabylake-H */
        { PCI_DEVICE(0x8086, 0xa2f0),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+       /* Coffelake */
+       { PCI_DEVICE(0x8086, 0xa348),
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE},
        /* Broxton-P(Apollolake) */
        { PCI_DEVICE(0x8086, 0x5a98),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
index 282a60368b14df9e88b304d7e60aac77fd8e6bc0..5f66697fe1e09a81b9fa8c5cb37c54331cf5888e 100644 (file)
@@ -192,7 +192,8 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
                "complete_and_exit",
                "kvm_spurious_fault",
                "__reiserfs_panic",
-               "lbug_with_loc"
+               "lbug_with_loc",
+               "fortify_panic",
        };
 
        if (func->bind == STB_WEAK)
index 8354d04b392fd9e94c0812731b55e7267b41504e..1f4fbc9a3292e06b6ae48c47297e795ccbc45809 100644 (file)
@@ -19,18 +19,18 @@ CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
 
 include $(srctree)/tools/scripts/Makefile.arch
 
-$(call detected_var,ARCH)
+$(call detected_var,SRCARCH)
 
 NO_PERF_REGS := 1
 
 # Additional ARCH settings for ppc
-ifeq ($(ARCH),powerpc)
+ifeq ($(SRCARCH),powerpc)
   NO_PERF_REGS := 0
   LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
 endif
 
 # Additional ARCH settings for x86
-ifeq ($(ARCH),x86)
+ifeq ($(SRCARCH),x86)
   $(call detected,CONFIG_X86)
   ifeq (${IS_64_BIT}, 1)
     CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated
@@ -43,12 +43,12 @@ ifeq ($(ARCH),x86)
   NO_PERF_REGS := 0
 endif
 
-ifeq ($(ARCH),arm)
+ifeq ($(SRCARCH),arm)
   NO_PERF_REGS := 0
   LIBUNWIND_LIBS = -lunwind -lunwind-arm
 endif
 
-ifeq ($(ARCH),arm64)
+ifeq ($(SRCARCH),arm64)
   NO_PERF_REGS := 0
   LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
 endif
@@ -61,7 +61,7 @@ endif
 # Disable it on all other architectures in case libdw unwind
 # support is detected in system. Add supported architectures
 # to the check.
-ifneq ($(ARCH),$(filter $(ARCH),x86 arm))
+ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm))
   NO_LIBDW_DWARF_UNWIND := 1
 endif
 
@@ -115,9 +115,9 @@ endif
 FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
 FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
 
-FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi
+FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi -I$(srctree)/tools/include/uapi
 # include ARCH specific config
--include $(src-perf)/arch/$(ARCH)/Makefile
+-include $(src-perf)/arch/$(SRCARCH)/Makefile
 
 ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
   CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
@@ -228,12 +228,12 @@ ifeq ($(DEBUG),0)
 endif
 
 INC_FLAGS += -I$(src-perf)/util/include
-INC_FLAGS += -I$(src-perf)/arch/$(ARCH)/include
+INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include
 INC_FLAGS += -I$(srctree)/tools/include/uapi
 INC_FLAGS += -I$(srctree)/tools/include/
-INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi
-INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/
-INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/
+INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi
+INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/
+INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/
 
 # $(obj-perf)      for generated common-cmds.h
 # $(obj-perf)/util for generated bison/flex headers
@@ -355,7 +355,7 @@ ifndef NO_LIBELF
 
   ifndef NO_DWARF
     ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
-      msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
+      msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled);
       NO_DWARF := 1
     else
       CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS)
@@ -380,7 +380,7 @@ ifndef NO_LIBELF
         CFLAGS += -DHAVE_BPF_PROLOGUE
         $(call detected,CONFIG_BPF_PROLOGUE)
       else
-        msg := $(warning BPF prologue is not supported by architecture $(ARCH), missing regs_query_register_offset());
+        msg := $(warning BPF prologue is not supported by architecture $(SRCARCH), missing regs_query_register_offset());
       endif
     else
       msg := $(warning DWARF support is off, BPF prologue is disabled);
@@ -406,7 +406,7 @@ ifdef PERF_HAVE_JITDUMP
   endif
 endif
 
-ifeq ($(ARCH),powerpc)
+ifeq ($(SRCARCH),powerpc)
   ifndef NO_DWARF
     CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX
   endif
@@ -487,7 +487,7 @@ else
 endif
 
 ifndef NO_LOCAL_LIBUNWIND
-  ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),arm arm64))
     $(call feature_check,libunwind-debug-frame)
     ifneq ($(feature-libunwind-debug-frame), 1)
       msg := $(warning No debug_frame support found in libunwind);
@@ -740,7 +740,7 @@ ifeq (${IS_64_BIT}, 1)
       NO_PERF_READ_VDSO32 := 1
     endif
   endif
-  ifneq ($(ARCH), x86)
+  ifneq ($(SRCARCH), x86)
     NO_PERF_READ_VDSOX32 := 1
   endif
   ifndef NO_PERF_READ_VDSOX32
@@ -769,7 +769,7 @@ ifdef LIBBABELTRACE
 endif
 
 ifndef NO_AUXTRACE
-  ifeq ($(ARCH),x86)
+  ifeq ($(SRCARCH),x86)
     ifeq ($(feature-get_cpuid), 0)
       msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc);
       NO_AUXTRACE := 1
@@ -872,7 +872,7 @@ sysconfdir = $(prefix)/etc
 ETC_PERFCONFIG = etc/perfconfig
 endif
 ifndef lib
-ifeq ($(ARCH)$(IS_64_BIT), x861)
+ifeq ($(SRCARCH)$(IS_64_BIT), x861)
 lib = lib64
 else
 lib = lib
index 79fe31f20a17644e416642bb9d3a213c97286479..5008f51a08a2118ca34723a87373acd231afb7c3 100644 (file)
@@ -226,7 +226,7 @@ endif
 
 ifeq ($(config),0)
 include $(srctree)/tools/scripts/Makefile.arch
--include arch/$(ARCH)/Makefile
+-include arch/$(SRCARCH)/Makefile
 endif
 
 # The FEATURE_DUMP_EXPORT holds location of the actual
index 109eb75cf7de4e97c855fe52c3d6437f454b5c8e..d9b6af837c7d392fce6168d9ce5ebe2b9a6b57d5 100644 (file)
@@ -1,2 +1,2 @@
 libperf-y += common.o
-libperf-y += $(ARCH)/
+libperf-y += $(SRCARCH)/
index 9213a1273697a801d6b75f4a8804424e68eb6ab7..999a4e8781621677821440e80ec8491689bbc6e3 100644 (file)
@@ -2,7 +2,7 @@ hostprogs := jevents
 
 jevents-y      += json.o jsmn.o jevents.o
 pmu-events-y   += pmu-events.o
-JDIR           =  pmu-events/arch/$(ARCH)
+JDIR           =  pmu-events/arch/$(SRCARCH)
 JSON           =  $(shell [ -d $(JDIR) ] &&                            \
                        find $(JDIR) -name '*.json' -o -name 'mapfile.csv')
 #
@@ -10,4 +10,4 @@ JSON          =  $(shell [ -d $(JDIR) ] &&                            \
 # directory and create tables in pmu-events.c.
 #
 $(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS)
-       $(Q)$(call echo-cmd,gen)$(JEVENTS) $(ARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
+       $(Q)$(call echo-cmd,gen)$(JEVENTS) $(SRCARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
index af58ebc243ef635ff2ddc6efcd26b377cc24a30b..84222bdb8689203924fc8f6a75f0baac4531d82c 100644 (file)
@@ -75,7 +75,7 @@ $(OUTPUT)tests/llvm-src-relocation.c: tests/bpf-script-test-relocation.c tests/B
        $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
        $(Q)echo ';' >> $@
 
-ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64 powerpc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc))
 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
 endif
 
index 32873ec91a4e1307b30884c1141fe0e8f1da154e..cf00ebad2ef5ccefabee6324e004fc9b4d2e601b 100644 (file)
@@ -83,7 +83,7 @@ int test__task_exit(int subtest __maybe_unused)
 
        evsel = perf_evlist__first(evlist);
        evsel->attr.task = 1;
-       evsel->attr.sample_freq = 0;
+       evsel->attr.sample_freq = 1;
        evsel->attr.inherit = 0;
        evsel->attr.watermark = 0;
        evsel->attr.wakeup_events = 1;
index e4f7902d5afa62f0aecab1103bc05ca4bcb226e9..cda44b0e821c63baea1f9da52123184768fdd2f4 100644 (file)
@@ -273,8 +273,20 @@ struct perf_evsel *perf_evsel__new_cycles(void)
        struct perf_evsel *evsel;
 
        event_attr_init(&attr);
+       /*
+        * Unnamed union member, not supported as struct member named
+        * initializer in older compilers such as gcc 4.4.7
+        *
+        * Just for probing the precise_ip:
+        */
+       attr.sample_period = 1;
 
        perf_event_attr__set_max_precise_ip(&attr);
+       /*
+        * Now let the usual logic to set up the perf_event_attr defaults
+        * to kick in when we return and before perf_evsel__open() is called.
+        */
+       attr.sample_period = 0;
 
        evsel = perf_evsel__new(&attr);
        if (evsel == NULL)
index 5cac8d5e009a88ff096d9e2f8026e39e8567c595..b5baff3007bbd477551cc2e62770e534d0919f33 100644 (file)
@@ -841,7 +841,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
 
 /*
  * default get_cpuid(): nothing gets recorded
- * actual implementation must be in arch/$(ARCH)/util/header.c
+ * actual implementation must be in arch/$(SRCARCH)/util/header.c
  */
 int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused)
 {
index 84e7e698411e6a80a39050514227cbb90556ca13..a2670e9d652dfa09eebb7e53a8ed2b63a7cea152 100644 (file)
@@ -619,7 +619,7 @@ static int post_process_probe_trace_point(struct probe_trace_point *tp,
                                           struct map *map, unsigned long offs)
 {
        struct symbol *sym;
-       u64 addr = tp->address + tp->offset - offs;
+       u64 addr = tp->address - offs;
 
        sym = map__find_symbol(map, addr);
        if (!sym)
index da45c4be5fb3e77ee59131602667b4d675bc3a40..7755a5e0fe5eb290c41502bf22725cce8a0b6935 100644 (file)
@@ -178,6 +178,14 @@ frame_callback(Dwfl_Frame *state, void *arg)
        Dwarf_Addr pc;
        bool isactivation;
 
+       if (!dwfl_frame_pc(state, &pc, NULL)) {
+               pr_err("%s", dwfl_errmsg(-1));
+               return DWARF_CB_ABORT;
+       }
+
+       // report the module before we query for isactivation
+       report_module(pc, ui);
+
        if (!dwfl_frame_pc(state, &pc, &isactivation)) {
                pr_err("%s", dwfl_errmsg(-1));
                return DWARF_CB_ABORT;
index 19d0604f86946824b04138e8bcaf29f3628ab808..487cbfb89beb5012816c7e4989b3f9ff4261995d 100644 (file)
@@ -1,23 +1,42 @@
 #ifndef __BPF_ENDIAN__
 #define __BPF_ENDIAN__
 
-#include <asm/byteorder.h>
+#include <linux/swab.h>
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define __bpf_ntohs(x)                __builtin_bswap16(x)
-# define __bpf_htons(x)                __builtin_bswap16(x)
-#elif __BYTE_ORDER == __BIG_ENDIAN
-# define __bpf_ntohs(x)                (x)
-# define __bpf_htons(x)                (x)
+/* LLVM's BPF target selects the endianness of the CPU
+ * it compiles on, or the user specifies (bpfel/bpfeb),
+ * respectively. The used __BYTE_ORDER__ is defined by
+ * the compiler, we cannot rely on __BYTE_ORDER from
+ * libc headers, since it doesn't reflect the actual
+ * requested byte order.
+ *
+ * Note, LLVM's BPF target has different __builtin_bswapX()
+ * semantics. It does map to BPF_ALU | BPF_END | BPF_TO_BE
+ * in bpfel and bpfeb case, which means below, that we map
+ * to cpu_to_be16(). We could use it unconditionally in BPF
+ * case, but better not rely on it, so that this header here
+ * can be used from application and BPF program side, which
+ * use different targets.
+ */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define __bpf_ntohs(x)                        __builtin_bswap16(x)
+# define __bpf_htons(x)                        __builtin_bswap16(x)
+# define __bpf_constant_ntohs(x)       ___constant_swab16(x)
+# define __bpf_constant_htons(x)       ___constant_swab16(x)
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define __bpf_ntohs(x)                        (x)
+# define __bpf_htons(x)                        (x)
+# define __bpf_constant_ntohs(x)       (x)
+# define __bpf_constant_htons(x)       (x)
 #else
-# error "Fix your __BYTE_ORDER?!"
+# error "Fix your compiler's __BYTE_ORDER__?!"
 #endif
 
 #define bpf_htons(x)                           \
        (__builtin_constant_p(x) ?              \
-        __constant_htons(x) : __bpf_htons(x))
+        __bpf_constant_htons(x) : __bpf_htons(x))
 #define bpf_ntohs(x)                           \
        (__builtin_constant_p(x) ?              \
-        __constant_ntohs(x) : __bpf_ntohs(x))
+        __bpf_constant_ntohs(x) : __bpf_ntohs(x))
 
-#endif
+#endif /* __BPF_ENDIAN__ */
index a676d3eefefbdd4b239d394a9b057f15c6a2cd7f..13f5198ba0ee737819b24cbc3538cc4b97e8d2f2 100755 (executable)
@@ -305,7 +305,7 @@ function perf_test()
        echo "Running remote perf test $WITH DMA"
        write_file "" $REMOTE_PERF/run
        echo -n "  "
-       read_file $LOCAL_PERF/run
+       read_file $REMOTE_PERF/run
        echo "  Passed"
 
        _modprobe -r ntb_perf