Merge tag 'devprop-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Mar 2021 21:09:29 +0000 (13:09 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Mar 2021 21:09:29 +0000 (13:09 -0800)
Pull device properties framework fixes from Rafael Wysocki:
 "Prevent software nodes from being registered before their parents and
  fix a recent mistake causing already registered software nodes to be
  registered again in some cases (Heikki Krogerus)"

* tag 'devprop-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  software node: Fix device_add_software_node()
  software node: Fix node registration

424 files changed:
Documentation/gpu/todo.rst
Documentation/networking/bonding.rst
Documentation/networking/netdev-FAQ.rst
Documentation/process/stable-kernel-rules.rst
Documentation/process/submitting-patches.rst
MAINTAINERS
arch/arm/xen/p2m.c
arch/arm64/Kconfig
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/mmu_context.h
arch/arm64/include/asm/pgtable-prot.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/sysreg.h
arch/arm64/kernel/head.S
arch/arm64/kernel/idreg-override.c
arch/arm64/kernel/perf_event.c
arch/arm64/kvm/reset.c
arch/arm64/mm/init.c
arch/arm64/mm/mmu.c
arch/m68k/include/asm/page_mm.h
arch/m68k/include/asm/page_no.h
arch/mips/boot/compressed/decompress.c
arch/mips/crypto/Makefile
arch/mips/include/asm/traps.h
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/cpu-r3k-probe.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/parisc/Kconfig
arch/parisc/kernel/ptrace.c
arch/powerpc/include/asm/dcr-native.h
arch/powerpc/include/asm/mmu.h
arch/powerpc/include/asm/vio.h
arch/powerpc/kernel/head_book3s_32.S
arch/powerpc/kernel/interrupt.c
arch/powerpc/lib/sstep.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/pseries/msi.c
arch/powerpc/platforms/pseries/vio.c
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/configs/zfcpdump_defconfig
arch/s390/include/asm/idle.h
arch/s390/include/asm/timex.h
arch/s390/include/uapi/asm/hwctrset.h [new file with mode: 0644]
arch/s390/include/uapi/asm/perf_cpum_cf_diag.h [deleted file]
arch/s390/kernel/idle.c
arch/s390/kernel/perf_cpum_cf.c
arch/s390/kernel/perf_cpum_cf_diag.c
arch/s390/kernel/time.c
arch/s390/kernel/topology.c
arch/s390/kvm/interrupt.c
arch/sparc/configs/sparc64_defconfig
arch/sparc/include/asm/elf_64.h
arch/sparc/include/asm/extable.h [new file with mode: 0644]
arch/sparc/include/asm/extable_64.h [deleted file]
arch/sparc/include/asm/processor_32.h
arch/sparc/include/asm/thread_info_64.h
arch/sparc/include/asm/uaccess.h
arch/sparc/include/asm/uaccess_32.h
arch/sparc/include/asm/uaccess_64.h
arch/sparc/kernel/head_32.S
arch/sparc/kernel/head_64.S
arch/sparc/kernel/process_32.c
arch/sparc/kernel/setup_32.c
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/traps_64.c
arch/sparc/kernel/unaligned_32.c
arch/sparc/lib/checksum_32.S
arch/sparc/lib/copy_user.S
arch/sparc/lib/memset.S
arch/sparc/mm/Makefile
arch/sparc/mm/extable.c [deleted file]
arch/sparc/mm/fault_32.c
arch/sparc/mm/mm_32.h
arch/x86/net/bpf_jit_comp.c
arch/x86/xen/p2m.c
crypto/Kconfig
drivers/atm/eni.c
drivers/atm/idt77105.c
drivers/atm/lanai.c
drivers/atm/uPD98402.c
drivers/char/hw_random/pseries-rng.c
drivers/char/tpm/tpm_ibmvtpm.c
drivers/cpufreq/cpufreq-dt-platdev.c
drivers/cpufreq/qcom-cpufreq-hw.c
drivers/crypto/nx/nx-842-pseries.c
drivers/crypto/nx/nx.c
drivers/firmware/efi/libstub/arm64-stub.c
drivers/gpio/gpio-pca953x.c
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_gem_shmem_helper.c
drivers/gpu/drm/drm_ioc32.c
drivers/gpu/drm/i915/gt/intel_engine_cs.c
drivers/gpu/drm/i915/i915_cmd_parser.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/meson/meson_drv.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/qxl/qxl_display.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_prime.c
drivers/gpu/drm/tiny/gm12u320.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_pool.c
drivers/gpu/drm/udl/udl_drv.c
drivers/gpu/drm/udl/udl_drv.h
drivers/gpu/drm/udl/udl_main.c
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/rc/Makefile
drivers/media/rc/keymaps/Makefile
drivers/media/rc/keymaps/rc-cec.c
drivers/media/rc/rc-main.c
drivers/media/usb/usbtv/usbtv-audio.c
drivers/misc/ibmvmc.c
drivers/mmc/core/bus.c
drivers/mmc/core/mmc.c
drivers/mmc/host/mmci.c
drivers/net/Kconfig
drivers/net/bonding/bond_main.c
drivers/net/can/flexcan.c
drivers/net/can/m_can/tcan4x5x-core.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
drivers/net/dsa/bcm_sf2.c
drivers/net/dsa/mt7530.c
drivers/net/dsa/sja1105/sja1105_main.c
drivers/net/dsa/xrs700x/xrs700x.c
drivers/net/ethernet/atheros/alx/main.c
drivers/net/ethernet/broadcom/bcm4908_enet.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
drivers/net/ethernet/davicom/dm9000.c
drivers/net/ethernet/freescale/enetc/enetc.c
drivers/net/ethernet/freescale/enetc/enetc.h
drivers/net/ethernet/freescale/enetc/enetc_hw.h
drivers/net/ethernet/freescale/enetc/enetc_pf.c
drivers/net/ethernet/freescale/enetc/enetc_vf.c
drivers/net/ethernet/freescale/fec_ptp.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ipsec.c
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
drivers/net/ethernet/mediatek/mtk_star_emac.c
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/mellanox/mlxsw/reg.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/switchx2.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/mscc/Kconfig
drivers/net/ethernet/mscc/ocelot_flower.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
drivers/net/ethernet/stmicro/stmmac/enh_desc.c
drivers/net/ethernet/stmicro/stmmac/hwif.h
drivers/net/ethernet/stmicro/stmmac/norm_desc.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/niu.c
drivers/net/ethernet/tehuti/tehuti.c
drivers/net/hamradio/6pack.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/netdevsim/netdev.c
drivers/net/phy/dp83822.c
drivers/net/phy/dp83tc811.c
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/usb/usbnet.c
drivers/net/wan/fsl_ucc_hdlc.c
drivers/net/wan/lapbether.c
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath11k/qmi.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/intel/iwlwifi/pcie/rx.c
drivers/net/wireless/mediatek/mt76/dma.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/xen-netback/netback.c
drivers/opp/core.c
drivers/opp/opp.h
drivers/pci/xen-pcifront.c
drivers/perf/arm_dmc620_pmu.c
drivers/regulator/mt6315-regulator.c
drivers/regulator/pca9450-regulator.c
drivers/regulator/qcom-rpmh-regulator.c
drivers/regulator/rt4831-regulator.c
drivers/s390/char/tty3270.c
drivers/s390/char/zcore.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/vfio_ccw_ops.c
drivers/s390/crypto/vfio_ap_ops.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
drivers/tty/hvc/hvcs.c
drivers/usb/core/usb.c
drivers/video/fbdev/aty/atyfb.h
drivers/video/fbdev/aty/atyfb_base.c
drivers/xen/events/events_2l.c
drivers/xen/events/events_base.c
drivers/xen/events/events_fifo.c
drivers/xen/events/events_internal.h
drivers/xen/gntdev.c
fs/Kconfig
fs/cifs/cifs_debug.c
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/sess.c
fs/cifs/smb2inode.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2proto.h
fs/cifs/transport.c
fs/configfs/file.c
fs/gfs2/log.c
fs/gfs2/ops_fstype.c
fs/gfs2/super.c
fs/gfs2/super.h
fs/gfs2/trans.c
fs/gfs2/util.c
fs/pnode.h
include/linux/acpi.h
include/linux/atmdev.h
include/linux/can/skb.h
include/linux/gpio/consumer.h
include/linux/netdevice.h
include/linux/pgtable.h
include/linux/regulator/pca9450.h
include/linux/textsearch.h
include/linux/usb.h
include/linux/virtio_net.h
include/media/rc-map.h
include/uapi/linux/bpf.h
include/uapi/linux/l2tp.h
include/uapi/linux/netfilter/nfnetlink_cthelper.h
include/xen/grant_table.h
include/xen/xenbus.h
kernel/bpf/btf.c
kernel/bpf/core.c
kernel/bpf/verifier.c
lib/extable.c
mm/memory_hotplug.c
mm/slub.c
net/9p/client.c
net/core/rtnetlink.c
net/core/skbuff.c
net/dsa/Kconfig
net/dsa/dsa_priv.h
net/dsa/slave.c
net/dsa/tag_mtk.c
net/dsa/tag_rtl4_a.c
net/ethtool/channels.c
net/ipv4/cipso_ipv4.c
net/ipv4/inetpeer.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_vti.c
net/ipv4/nexthop.c
net/ipv4/tcp.c
net/ipv4/udp_offload.c
net/ipv6/calipso.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/sit.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_netlink.c
net/mpls/mpls_gso.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_nat_proto.c
net/netfilter/nf_tables_api.c
net/netfilter/x_tables.c
net/netlabel/netlabel_cipso_v4.c
net/qrtr/qrtr.c
net/sched/sch_api.c
net/sctp/tsnmap.c
samples/bpf/xdpsock_user.c
sound/hda/intel-nhlt.c
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/usb/card.c
sound/usb/quirks.c
sound/usb/usbaudio.h
tools/arch/s390/include/uapi/asm/ptrace.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/vmx.h
tools/bpf/resolve_btfids/main.c
tools/build/Makefile
tools/include/linux/coresight-pmu.h
tools/include/uapi/drm/drm.h
tools/include/uapi/drm/i915_drm.h
tools/include/uapi/linux/bpf.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/mount.h
tools/include/uapi/linux/openat2.h
tools/lib/bpf/xsk.c
tools/lib/perf/evlist.c
tools/lib/perf/include/internal/evlist.h
tools/perf/Documentation/perf-evlist.txt
tools/perf/Documentation/perf-ftrace.txt
tools/perf/Documentation/perf-kallsyms.txt
tools/perf/Documentation/perf-trace.txt
tools/perf/Makefile.perf
tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
tools/perf/arch/s390/entry/syscalls/syscall.tbl
tools/perf/arch/x86/Makefile
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
tools/perf/arch/x86/include/arch-tests.h
tools/perf/arch/x86/tests/Build
tools/perf/arch/x86/tests/arch-tests.c
tools/perf/arch/x86/tests/insn-x86.c
tools/perf/arch/x86/tests/sample-parsing.c [new file with mode: 0644]
tools/perf/arch/x86/util/archinsn.c
tools/perf/bench/numa.c
tools/perf/bench/sched-messaging.c
tools/perf/bench/sched-pipe.c
tools/perf/bench/syscall.c
tools/perf/builtin-daemon.c
tools/perf/builtin-diff.c
tools/perf/builtin-trace.c
tools/perf/perf-archive.sh
tools/perf/tests/attr.c
tools/perf/tests/code-reading.c
tools/perf/tests/cpumap.c
tools/perf/tests/keep-tracking.c
tools/perf/tests/mmap-basic.c
tools/perf/tests/perf-time-to-tsc.c
tools/perf/tests/sample-parsing.c
tools/perf/tests/shell/daemon.sh
tools/perf/tests/sw-clock.c
tools/perf/tests/switch-tracking.c
tools/perf/tests/task-exit.c
tools/perf/tests/thread-map.c
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/header.c
tools/perf/util/map.c
tools/perf/util/parse-events.y
tools/perf/util/python-ext-sources
tools/perf/util/sort.c
tools/perf/util/stat-display.c
tools/perf/util/stat.c
tools/perf/util/trace-event-read.c
tools/testing/selftests/arm64/fp/sve-ptrace.c
tools/testing/selftests/bpf/progs/netif_receive_skb.c
tools/testing/selftests/bpf/progs/test_global_func11.c
tools/testing/selftests/bpf/progs/test_tunnel_kern.c
tools/testing/selftests/bpf/verifier/array_access.c
tools/testing/selftests/bpf/verifier/atomic_and.c
tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c
tools/testing/selftests/bpf/verifier/atomic_or.c
tools/testing/selftests/gpio/.gitignore
tools/testing/selftests/net/fib_nexthops.sh
tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh
tools/testing/selftests/net/ipsec.c
tools/testing/selftests/netfilter/Makefile
tools/testing/selftests/netfilter/nf_nat_edemux.sh [new file with mode: 0755]

index 40ccac61137e27f936128d037e1fe4c52dc721fd..22ce801e3a8d94ca0db6e21289a0c475df7437d5 100644 (file)
@@ -613,6 +613,27 @@ Some of these date from the very introduction of KMS in 2008 ...
 
 Level: Intermediate
 
+Remove automatic page mapping from dma-buf importing
+----------------------------------------------------
+
+When importing dma-bufs, the dma-buf and PRIME frameworks automatically map
+imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and
+drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach()
+even if they never do actual device DMA, but only CPU access through
+dma_buf_vmap(). This is a problem for USB devices, which do not support DMA
+operations.
+
+To fix the issue, automatic page mappings should be removed from the
+buffer-sharing code. Fixing this is a bit more involved, since the import/export
+cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over
+this problem for USB devices by fishing out the USB host controller device, as
+long as that supports DMA. Otherwise importing can still needlessly fail.
+
+Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter
+
+Level: Advanced
+
+
 Better Testing
 ==============
 
index 5f690f0ad0e4f136b29da05e4475af0830eabf4f..62f2aab8eaec0b65a7c4be0178241a74562bd93f 100644 (file)
@@ -1988,7 +1988,7 @@ netif_carrier.
 If use_carrier is 0, then the MII monitor will first query the
 device's (via ioctl) MII registers and check the link state.  If that
 request fails (not just that it returns carrier down), then the MII
-monitor will make an ethtool ETHOOL_GLINK request to attempt to obtain
+monitor will make an ethtool ETHTOOL_GLINK request to attempt to obtain
 the same information.  If both methods fail (i.e., the driver either
 does not support or had some error in processing both the MII register
 and ethtool requests), then the MII monitor will assume the link is
index a64c01b52b4c55286632a05b1578c4b6b833d8be..91b2cf7128012826ea3cddf526b8aafbd7955abf 100644 (file)
@@ -142,73 +142,13 @@ Please send incremental versions on top of what has been merged in order to fix
 the patches the way they would look like if your latest patch series was to be
 merged.
 
-How can I tell what patches are queued up for backporting to the various stable releases?
------------------------------------------------------------------------------------------
-Normally Greg Kroah-Hartman collects stable commits himself, but for
-networking, Dave collects up patches he deems critical for the
-networking subsystem, and then hands them off to Greg.
-
-There is a patchworks queue that you can see here:
-
-  https://patchwork.kernel.org/bundle/netdev/stable/?state=*
-
-It contains the patches which Dave has selected, but not yet handed off
-to Greg.  If Greg already has the patch, then it will be here:
-
-  https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git
-
-A quick way to find whether the patch is in this stable-queue is to
-simply clone the repo, and then git grep the mainline commit ID, e.g.
-::
-
-  stable-queue$ git grep -l 284041ef21fdf2e
-  releases/3.0.84/ipv6-fix-possible-crashes-in-ip6_cork_release.patch
-  releases/3.4.51/ipv6-fix-possible-crashes-in-ip6_cork_release.patch
-  releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch
-  stable/stable-queue$
-
-I see a network patch and I think it should be backported to stable. Should I request it via stable@vger.kernel.org like the references in the kernel's Documentation/process/stable-kernel-rules.rst file say?
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-No, not for networking.  Check the stable queues as per above first
-to see if it is already queued.  If not, then send a mail to netdev,
-listing the upstream commit ID and why you think it should be a stable
-candidate.
-
-Before you jump to go do the above, do note that the normal stable rules
-in :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
-still apply.  So you need to explicitly indicate why it is a critical
-fix and exactly what users are impacted.  In addition, you need to
-convince yourself that you *really* think it has been overlooked,
-vs. having been considered and rejected.
-
-Generally speaking, the longer it has had a chance to "soak" in
-mainline, the better the odds that it is an OK candidate for stable.  So
-scrambling to request a commit be added the day after it appears should
-be avoided.
-
-I have created a network patch and I think it should be backported to stable. Should I add a Cc: stable@vger.kernel.org like the references in the kernel's Documentation/ directory say?
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-No.  See above answer.  In short, if you think it really belongs in
-stable, then ensure you write a decent commit log that describes who
-gets impacted by the bug fix and how it manifests itself, and when the
-bug was introduced.  If you do that properly, then the commit will get
-handled appropriately and most likely get put in the patchworks stable
-queue if it really warrants it.
-
-If you think there is some valid information relating to it being in
-stable that does *not* belong in the commit log, then use the three dash
-marker line as described in
-:ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>`
-to temporarily embed that information into the patch that you send.
-
-Are all networking bug fixes backported to all stable releases?
+Are there special rules regarding stable submissions on netdev?
 ---------------------------------------------------------------
-Due to capacity, Dave could only take care of the backports for the
-last two stable releases. For earlier stable releases, each stable
-branch maintainer is supposed to take care of them. If you find any
-patch is missing from an earlier stable branch, please notify
-stable@vger.kernel.org with either a commit ID or a formal patch
-backported, and CC Dave and other relevant networking developers.
+While it used to be the case that netdev submissions were not supposed
+to carry explicit ``CC: stable@vger.kernel.org`` tags that is no longer
+the case today. Please follow the standard stable rules in
+:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`,
+and make sure you include appropriate Fixes tags!
 
 Is the comment style convention different for the networking content?
 ---------------------------------------------------------------------
index 3973556250e17050a32309edd7b225554c81e394..003c865e9c212342ecac53c42eddd6848077de4f 100644 (file)
@@ -35,12 +35,6 @@ Rules on what kind of patches are accepted, and which ones are not, into the
 Procedure for submitting patches to the -stable tree
 ----------------------------------------------------
 
- - If the patch covers files in net/ or drivers/net please follow netdev stable
-   submission guidelines as described in
-   :ref:`Documentation/networking/netdev-FAQ.rst <netdev-FAQ>`
-   after first checking the stable networking queue at
-   https://patchwork.kernel.org/bundle/netdev/stable/?state=*
-   to ensure the requested patch is not already queued up.
  - Security patches should not be handled (solely) by the -stable review
    process but should follow the procedures in
    :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`.
index 8c991c8636280e47fc80be27f08479b3e13f5b56..91de63b201c126ed19551cb2a35c9c29f9d55fe4 100644 (file)
@@ -250,11 +250,6 @@ should also read
 :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
 in addition to this file.
 
-Note, however, that some subsystem maintainers want to come to their own
-conclusions on which patches should go to the stable trees.  The networking
-maintainer, in particular, would rather not see individual developers
-adding lines like the above to their patches.
-
 If changes affect userland-kernel interfaces, please send the MAN-PAGES
 maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at
 least a notification of the change, so that some information makes its way
index d92f85ca831d30d658fef768575ba538be4d4b93..72e5b9db5050ba96b8b589c1926d331b7ae739de 100644 (file)
@@ -5835,7 +5835,7 @@ M:        David Airlie <airlied@linux.ie>
 M:     Daniel Vetter <daniel@ffwll.ch>
 L:     dri-devel@lists.freedesktop.org
 S:     Maintained
-B:     https://bugs.freedesktop.org/
+B:     https://gitlab.freedesktop.org/drm
 C:     irc://chat.freenode.net/dri-devel
 T:     git git://anongit.freedesktop.org/drm/drm
 F:     Documentation/devicetree/bindings/display/
@@ -10716,7 +10716,8 @@ F:      drivers/net/ethernet/marvell/mvpp2/
 
 MARVELL MWIFIEX WIRELESS DRIVER
 M:     Amitkumar Karwar <amitkarwar@gmail.com>
-M:     Ganapathi Bhat <ganapathi.bhat@nxp.com>
+M:     Ganapathi Bhat <ganapathi017@gmail.com>
+M:     Sharvari Harisangam <sharvari.harisangam@nxp.com>
 M:     Xinming Hu <huxinming820@gmail.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
index acb464547a54f45d90a05437517ce14e5448f21a..84a1cea1f43b9a3331b35093e4c57cb78d670815 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <xen/xen.h>
 #include <xen/interface/memory.h>
+#include <xen/grant_table.h>
 #include <xen/page.h>
 #include <xen/swiotlb-xen.h>
 
@@ -109,7 +110,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
                map_ops[i].status = GNTST_general_error;
                unmap.host_addr = map_ops[i].host_addr,
                unmap.handle = map_ops[i].handle;
-               map_ops[i].handle = ~0;
+               map_ops[i].handle = INVALID_GRANT_HANDLE;
                if (map_ops[i].flags & GNTMAP_device_map)
                        unmap.dev_bus_addr = map_ops[i].dev_bus_addr;
                else
@@ -130,7 +131,6 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
 
 int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
                              struct gnttab_unmap_grant_ref *kunmap_ops,
@@ -145,7 +145,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping);
 
 bool __set_phys_to_machine_multi(unsigned long pfn,
                unsigned long mfn, unsigned long nr_pages)
index 1f212b47a48a1033d1799c946f0bb0b9dca96fd2..5656e7aacd698436c8b8046d9d01280ea02fda3e 100644 (file)
@@ -1055,8 +1055,6 @@ config HW_PERF_EVENTS
 config SYS_SUPPORTS_HUGETLBFS
        def_bool y
 
-config ARCH_WANT_HUGE_PMD_SHARE
-
 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
 
@@ -1157,8 +1155,8 @@ config XEN
 
 config FORCE_MAX_ZONEORDER
        int
-       default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
-       default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
+       default "14" if ARM64_64K_PAGES
+       default "12" if ARM64_16K_PAGES
        default "11"
        help
          The kernel memory allocator divides physically contiguous memory
@@ -1855,12 +1853,6 @@ config CMDLINE_FROM_BOOTLOADER
          the boot loader doesn't provide any, the default kernel command
          string provided in CMDLINE will be used.
 
-config CMDLINE_EXTEND
-       bool "Extend bootloader kernel arguments"
-       help
-         The command-line arguments provided by the boot loader will be
-         appended to the default kernel command string.
-
 config CMDLINE_FORCE
        bool "Always use the default kernel command string"
        help
index c759faf7a1ff9a59299e4aad27af246f4c228cec..0aabc3be9a75953fe02b48d535198cc9eed7f6bf 100644 (file)
@@ -328,6 +328,11 @@ static inline void *phys_to_virt(phys_addr_t x)
 #define ARCH_PFN_OFFSET                ((unsigned long)PHYS_PFN_OFFSET)
 
 #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL)
+#define page_to_virt(x)        ({                                              \
+       __typeof__(x) __page = x;                                       \
+       void *__addr = __va(page_to_phys(__page));                      \
+       (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\
+})
 #define virt_to_page(x)                pfn_to_page(virt_to_pfn(x))
 #else
 #define page_to_virt(x)        ({                                              \
index 70ce8c1d2b078b0431d7e4ce519b386a1a5f3c0f..bd02e99b1a4c54972f871ebe4d0c81650b965abb 100644 (file)
@@ -63,23 +63,6 @@ static inline void cpu_switch_mm(pgd_t *pgd, struct mm_struct *mm)
 extern u64 idmap_t0sz;
 extern u64 idmap_ptrs_per_pgd;
 
-static inline bool __cpu_uses_extended_idmap(void)
-{
-       if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52))
-               return false;
-
-       return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS));
-}
-
-/*
- * True if the extended ID map requires an extra level of translation table
- * to be configured.
- */
-static inline bool __cpu_uses_extended_idmap_level(void)
-{
-       return ARM64_HW_PGTABLE_LEVELS(64 - idmap_t0sz) > CONFIG_PGTABLE_LEVELS;
-}
-
 /*
  * Ensure TCR.T0SZ is set to the provided value.
  */
index 046be789fbb479967067cbc13e55693701f394fd..9a65fb5281100a7e08b29ee380c91b84cd887ca6 100644 (file)
@@ -66,7 +66,6 @@ extern bool arm64_use_ng_mappings;
 #define _PAGE_DEFAULT          (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
 
 #define PAGE_KERNEL            __pgprot(PROT_NORMAL)
-#define PAGE_KERNEL_TAGGED     __pgprot(PROT_NORMAL_TAGGED)
 #define PAGE_KERNEL_RO         __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
 #define PAGE_KERNEL_ROX                __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
 #define PAGE_KERNEL_EXEC       __pgprot(PROT_NORMAL & ~PTE_PXN)
index e17b96d0e4b59845f293cb3f3a050b90fc596520..47027796c2f934a0207013044dcaee2f9e58078c 100644 (file)
@@ -486,6 +486,9 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
        __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define pgprot_device(prot) \
        __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+#define pgprot_tagged(prot) \
+       __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_TAGGED))
+#define pgprot_mhp     pgprot_tagged
 /*
  * DMA allocations for non-coherent devices use what the Arm architecture calls
  * "Normal non-cacheable" memory, which permits speculation, unaligned accesses
index dfd4edbfe36086df7c67bafe532929970c73dcb7..d4a5fca984c3e228594e19a80fa68bc37e43e16c 100644 (file)
 #define ID_AA64MMFR0_PARANGE_48                0x5
 #define ID_AA64MMFR0_PARANGE_52                0x6
 
+#define ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT 0x0
+#define ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE    0x1
+#define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN     0x2
+#define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MAX     0x7
+
 #ifdef CONFIG_ARM64_PA_BITS_52
 #define ID_AA64MMFR0_PARANGE_MAX       ID_AA64MMFR0_PARANGE_52
 #else
 #define ID_PFR1_PROGMOD_SHIFT          0
 
 #if defined(CONFIG_ARM64_4K_PAGES)
-#define ID_AA64MMFR0_TGRAN_SHIFT       ID_AA64MMFR0_TGRAN4_SHIFT
-#define ID_AA64MMFR0_TGRAN_SUPPORTED   ID_AA64MMFR0_TGRAN4_SUPPORTED
+#define ID_AA64MMFR0_TGRAN_SHIFT               ID_AA64MMFR0_TGRAN4_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN       ID_AA64MMFR0_TGRAN4_SUPPORTED
+#define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX       0x7
 #elif defined(CONFIG_ARM64_16K_PAGES)
-#define ID_AA64MMFR0_TGRAN_SHIFT       ID_AA64MMFR0_TGRAN16_SHIFT
-#define ID_AA64MMFR0_TGRAN_SUPPORTED   ID_AA64MMFR0_TGRAN16_SUPPORTED
+#define ID_AA64MMFR0_TGRAN_SHIFT               ID_AA64MMFR0_TGRAN16_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN       ID_AA64MMFR0_TGRAN16_SUPPORTED
+#define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX       0xF
 #elif defined(CONFIG_ARM64_64K_PAGES)
-#define ID_AA64MMFR0_TGRAN_SHIFT       ID_AA64MMFR0_TGRAN64_SHIFT
-#define ID_AA64MMFR0_TGRAN_SUPPORTED   ID_AA64MMFR0_TGRAN64_SUPPORTED
+#define ID_AA64MMFR0_TGRAN_SHIFT               ID_AA64MMFR0_TGRAN64_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN       ID_AA64MMFR0_TGRAN64_SUPPORTED
+#define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX       0x7
 #endif
 
 #define MVFR2_FPMISC_SHIFT             4
index 66b0e0b66e3122a9ba94a7ce648525b7f048bdca..840bda1869e9ccb0d88b2e6bb0cb63ea1eb1f0c6 100644 (file)
@@ -319,7 +319,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
         */
        adrp    x5, __idmap_text_end
        clz     x5, x5
-       cmp     x5, TCR_T0SZ(VA_BITS)   // default T0SZ small enough?
+       cmp     x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough?
        b.ge    1f                      // .. then skip VA range extension
 
        adr_l   x6, idmap_t0sz
@@ -655,8 +655,10 @@ SYM_FUNC_END(__secondary_too_slow)
 SYM_FUNC_START(__enable_mmu)
        mrs     x2, ID_AA64MMFR0_EL1
        ubfx    x2, x2, #ID_AA64MMFR0_TGRAN_SHIFT, 4
-       cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
-       b.ne    __no_granule_support
+       cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED_MIN
+       b.lt    __no_granule_support
+       cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED_MAX
+       b.gt    __no_granule_support
        update_early_cpu_boot_status 0, x2, x3
        adrp    x2, idmap_pg_dir
        phys_to_ttbr x1, x1
index dffb16682330e657c6ce3d80f495c7bae48a8425..83f1c4b92095e9a6acf0c2eac454f965228bf040 100644 (file)
@@ -163,33 +163,36 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases)
        } while (1);
 }
 
-static __init void parse_cmdline(void)
+static __init const u8 *get_bootargs_cmdline(void)
 {
-       if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
-               const u8 *prop;
-               void *fdt;
-               int node;
+       const u8 *prop;
+       void *fdt;
+       int node;
 
-               fdt = get_early_fdt_ptr();
-               if (!fdt)
-                       goto out;
+       fdt = get_early_fdt_ptr();
+       if (!fdt)
+               return NULL;
 
-               node = fdt_path_offset(fdt, "/chosen");
-               if (node < 0)
-                       goto out;
+       node = fdt_path_offset(fdt, "/chosen");
+       if (node < 0)
+               return NULL;
 
-               prop = fdt_getprop(fdt, node, "bootargs", NULL);
-               if (!prop)
-                       goto out;
+       prop = fdt_getprop(fdt, node, "bootargs", NULL);
+       if (!prop)
+               return NULL;
 
-               __parse_cmdline(prop, true);
+       return strlen(prop) ? prop : NULL;
+}
 
-               if (!IS_ENABLED(CONFIG_CMDLINE_EXTEND))
-                       return;
-       }
+static __init void parse_cmdline(void)
+{
+       const u8 *prop = get_bootargs_cmdline();
 
-out:
-       __parse_cmdline(CONFIG_CMDLINE, true);
+       if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop)
+               __parse_cmdline(CONFIG_CMDLINE, true);
+
+       if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && prop)
+               __parse_cmdline(prop, true);
 }
 
 /* Keep checkers quiet */
index 7d2318f80955cc8ae7d9891edd0e5b06a3b6fe73..4658fcf88c2b4ddff069e3f47858c6443eac0198 100644 (file)
@@ -460,7 +460,7 @@ static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
        return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx));
 }
 
-static inline u32 armv8pmu_read_evcntr(int idx)
+static inline u64 armv8pmu_read_evcntr(int idx)
 {
        u32 counter = ARMV8_IDX_TO_COUNTER(idx);
 
index 47f3f035f3eac5aaf9b4d590e25ebbff7eb8dd95..e81c7ec9e10202af2c737957b713f4a2277c0ce3 100644 (file)
@@ -311,16 +311,18 @@ int kvm_set_ipa_limit(void)
        }
 
        switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) {
-       default:
-       case 1:
+       case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE:
                kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");
                return -EINVAL;
-       case 0:
+       case ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT:
                kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n");
                break;
-       case 2:
+       case ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN ... ID_AA64MMFR0_TGRAN_2_SUPPORTED_MAX:
                kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n");
                break;
+       default:
+               kvm_err("Unsupported value for TGRAN_2, giving up\n");
+               return -EINVAL;
        }
 
        kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);
index 0ace5e68efba0ea05b32c989ac6ae987364fc89c..3685e12aba9b62b170cbd285dae412c339cae350 100644 (file)
@@ -219,17 +219,40 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 
 int pfn_valid(unsigned long pfn)
 {
-       phys_addr_t addr = pfn << PAGE_SHIFT;
+       phys_addr_t addr = PFN_PHYS(pfn);
 
-       if ((addr >> PAGE_SHIFT) != pfn)
+       /*
+        * Ensure the upper PAGE_SHIFT bits are clear in the
+        * pfn. Else it might lead to false positives when
+        * some of the upper bits are set, but the lower bits
+        * match a valid pfn.
+        */
+       if (PHYS_PFN(addr) != pfn)
                return 0;
 
 #ifdef CONFIG_SPARSEMEM
+{
+       struct mem_section *ms;
+
        if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
                return 0;
 
-       if (!valid_section(__pfn_to_section(pfn)))
+       ms = __pfn_to_section(pfn);
+       if (!valid_section(ms))
                return 0;
+
+       /*
+        * ZONE_DEVICE memory does not have the memblock entries.
+        * memblock_is_map_memory() check for ZONE_DEVICE based
+        * addresses will always fail. Even the normal hotplugged
+        * memory will never have MEMBLOCK_NOMAP flag set in their
+        * memblock entries. Skip memblock search for all non early
+        * memory sections covering all of hotplug memory including
+        * both normal and ZONE_DEVICE based.
+        */
+       if (!early_section(ms))
+               return pfn_section_valid(ms, pfn);
+}
 #endif
        return memblock_is_map_memory(addr);
 }
index 3802cfbdd20d12e93388cb8f5f2029eafdc9f60f..7484ea4f6ba07300a25a4c0689309f9332e9913a 100644 (file)
@@ -40,7 +40,7 @@
 #define NO_BLOCK_MAPPINGS      BIT(0)
 #define NO_CONT_MAPPINGS       BIT(1)
 
-u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
+u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN);
 u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
 
 u64 __section(".mmuoff.data.write") vabits_actual;
@@ -512,7 +512,8 @@ static void __init map_mem(pgd_t *pgdp)
                 * if MTE is present. Otherwise, it has the same attributes as
                 * PAGE_KERNEL.
                 */
-               __map_memblock(pgdp, start, end, PAGE_KERNEL_TAGGED, flags);
+               __map_memblock(pgdp, start, end, pgprot_tagged(PAGE_KERNEL),
+                              flags);
        }
 
        /*
index 7f5912af2a52ea0a033ca4155d8604d2fc53df51..9e8f0cc30a2ccb9d2459228f1fef4ae28d4ca0ff 100644 (file)
@@ -171,7 +171,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
 #include <asm-generic/memory_model.h>
 #endif
 
-#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
+#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
 #define pfn_valid(pfn)         virt_addr_valid(pfn_to_virt(pfn))
 
 #endif /* __ASSEMBLY__ */
index 6bbe52025de3c5c68518371a7d41e23003b6ece1..8d0f862ee9d7953236fc315f840e5c98db21d36c 100644 (file)
@@ -30,8 +30,8 @@ extern unsigned long memory_end;
 #define page_to_pfn(page)      virt_to_pfn(page_to_virt(page))
 #define pfn_valid(pfn)         ((pfn) < max_mapnr)
 
-#define        virt_addr_valid(kaddr)  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
-                               ((void *)(kaddr) < (void *)memory_end))
+#define        virt_addr_valid(kaddr)  (((unsigned long)(kaddr) >= PAGE_OFFSET) && \
+                               ((unsigned long)(kaddr) < memory_end))
 
 #endif /* __ASSEMBLY__ */
 
index e3946b06e840a6b2e6c5a297e81f16db50a4c914..3d70d15ada286cbb8928befdcf966e1723c380f8 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <asm/addrspace.h>
 #include <asm/unaligned.h>
+#include <asm-generic/vmlinux.lds.h>
 
 /*
  * These two variables specify the free mem region
@@ -120,6 +121,13 @@ void decompress_kernel(unsigned long boot_heap_start)
                /* last four bytes is always image size in little endian */
                image_size = get_unaligned_le32((void *)&__image_end - 4);
 
+               /* The device tree's address must be properly aligned  */
+               image_size = ALIGN(image_size, STRUCT_ALIGNMENT);
+
+               puts("Copy device tree to address  ");
+               puthex(VMLINUX_LOAD_ADDRESS_ULL + image_size);
+               puts("\n");
+
                /* copy dtb to where the booted kernel will expect it */
                memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size,
                       __appended_dtb, dtb_size);
index 8e1deaf00e0c0b7722ba48b5b9bf1d9582b03298..5e4105cccf9fa9dde2b3f495b89156e3700c04de 100644 (file)
@@ -12,8 +12,8 @@ AFLAGS_chacha-core.o += -O2 # needed to fill branch delay slots
 obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o
 poly1305-mips-y := poly1305-core.o poly1305-glue.o
 
-perlasm-flavour-$(CONFIG_CPU_MIPS32) := o32
-perlasm-flavour-$(CONFIG_CPU_MIPS64) := 64
+perlasm-flavour-$(CONFIG_32BIT) := o32
+perlasm-flavour-$(CONFIG_64BIT) := 64
 
 quiet_cmd_perlasm = PERLASM $@
       cmd_perlasm = $(PERL) $(<) $(perlasm-flavour-y) $(@)
index 6aa8f126a43d89b3e71747a4ce3a295c798025c4..b710e76c9c658f7baaef01601cef79277020d7ef 100644 (file)
@@ -24,8 +24,11 @@ extern void (*board_ebase_setup)(void);
 extern void (*board_cache_error_setup)(void);
 
 extern int register_nmi_notifier(struct notifier_block *nb);
+extern void reserve_exception_space(phys_addr_t addr, unsigned long size);
 extern char except_vec_nmi[];
 
+#define VECTORSPACING 0x100    /* for EI/VI mode */
+
 #define nmi_notifier(fn, pri)                                          \
 ({                                                                     \
        static struct notifier_block fn##_nb = {                        \
index 9a89637b4ecfa8331a496f89c653ba1d1fcd6d68..b71892064f2733cfad153c4834e89f29517cb231 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/elf.h>
 #include <asm/pgtable-bits.h>
 #include <asm/spram.h>
+#include <asm/traps.h>
 #include <linux/uaccess.h>
 
 #include "fpu-probe.h"
@@ -1628,6 +1629,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_BMIPS3300;
                __cpu_name[cpu] = "Broadcom BMIPS3300";
                set_elf_platform(cpu, "bmips3300");
+               reserve_exception_space(0x400, VECTORSPACING * 64);
                break;
        case PRID_IMP_BMIPS43XX: {
                int rev = c->processor_id & PRID_REV_MASK;
@@ -1638,6 +1640,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                        __cpu_name[cpu] = "Broadcom BMIPS4380";
                        set_elf_platform(cpu, "bmips4380");
                        c->options |= MIPS_CPU_RIXI;
+                       reserve_exception_space(0x400, VECTORSPACING * 64);
                } else {
                        c->cputype = CPU_BMIPS4350;
                        __cpu_name[cpu] = "Broadcom BMIPS4350";
@@ -1654,6 +1657,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                        __cpu_name[cpu] = "Broadcom BMIPS5000";
                set_elf_platform(cpu, "bmips5000");
                c->options |= MIPS_CPU_ULRI | MIPS_CPU_RIXI;
+               reserve_exception_space(0x1000, VECTORSPACING * 64);
                break;
        }
 }
@@ -2133,6 +2137,8 @@ void cpu_probe(void)
        if (cpu == 0)
                __ua_limit = ~((1ull << cpu_vmbits) - 1);
 #endif
+
+       reserve_exception_space(0, 0x1000);
 }
 
 void cpu_report(void)
index abdbbe8c5a43a98b3c41474f33f3a240aba668aa..af654771918cdd0873b5046310c5a0fc77253075 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
 #include <asm/elf.h>
+#include <asm/traps.h>
 
 #include "fpu-probe.h"
 
@@ -158,6 +159,8 @@ void cpu_probe(void)
                cpu_set_fpu_opts(c);
        else
                cpu_set_nofpu_opts(c);
+
+       reserve_exception_space(0, 0x400);
 }
 
 void cpu_report(void)
index e0352958e2f720be5b9bd407e208f249716f7cad..808b8b61ded155195f57d6b21140beaaa30fc746 100644 (file)
@@ -2009,13 +2009,16 @@ void __noreturn nmi_exception_handler(struct pt_regs *regs)
        nmi_exit();
 }
 
-#define VECTORSPACING 0x100    /* for EI/VI mode */
-
 unsigned long ebase;
 EXPORT_SYMBOL_GPL(ebase);
 unsigned long exception_handlers[32];
 unsigned long vi_handlers[64];
 
+void reserve_exception_space(phys_addr_t addr, unsigned long size)
+{
+       memblock_reserve(addr, size);
+}
+
 void __init *set_except_vector(int n, void *addr)
 {
        unsigned long handler = (unsigned long) addr;
@@ -2367,10 +2370,7 @@ void __init trap_init(void)
 
        if (!cpu_has_mips_r2_r6) {
                ebase = CAC_BASE;
-               ebase_pa = virt_to_phys((void *)ebase);
                vec_size = 0x400;
-
-               memblock_reserve(ebase_pa, vec_size);
        } else {
                if (cpu_has_veic || cpu_has_vint)
                        vec_size = 0x200 + VECTORSPACING*64;
index c1c345be04ffd5c08e47ab0c474341c57c1eb225..1234834cc4c44d55d2efc3ed9a8701935b5f4054 100644 (file)
@@ -145,6 +145,7 @@ SECTIONS
        }
 
 #ifdef CONFIG_MIPS_ELF_APPENDED_DTB
+       STRUCT_ALIGN();
        .appended_dtb : AT(ADDR(.appended_dtb) - LOAD_OFFSET) {
                *(.appended_dtb)
                KEEP(*(.appended_dtb))
@@ -172,6 +173,11 @@ SECTIONS
 #endif
 
 #ifdef CONFIG_MIPS_RAW_APPENDED_DTB
+       .fill : {
+               FILL(0);
+               BYTE(0);
+               . = ALIGN(8);
+       }
        __appended_dtb = .;
        /* leave space for appended DTB */
        . += 0x100000;
index 4e53ac46e857e5d9485ce8fcd2d011eea5cd0dae..afc3b8d03572684d649e7fe82ef88839c0e0714e 100644 (file)
@@ -203,9 +203,12 @@ config PREFETCH
        def_bool y
        depends on PA8X00 || PA7200
 
+config PARISC_HUGE_KERNEL
+       def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST
+
 config MLONGCALLS
-       def_bool y if !MODULES || UBSAN || FTRACE
-       bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE
+       def_bool y if PARISC_HUGE_KERNEL
+       bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL
        depends on PA8X00
        help
          If you configure the kernel to include many drivers built-in instead
index 2127974982df9a029b9c8819a257debb30bb5f0c..65de6c4c9354d6754091435943146acc8a726483 100644 (file)
@@ -567,8 +567,6 @@ static const struct user_regset_view user_parisc_native_view = {
 };
 
 #ifdef CONFIG_64BIT
-#include <linux/compat.h>
-
 static int gpr32_get(struct task_struct *target,
                     const struct user_regset *regset,
                     struct membuf to)
index 7141ccea8c94e6b2ba571607999a0384ce60a7bd..a92059964579b877334e683177593588b7144429 100644 (file)
@@ -53,8 +53,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
 #define mfdcr(rn)                                              \
        ({unsigned int rval;                                    \
        if (__builtin_constant_p(rn) && rn < 1024)              \
-               asm volatile("mfdcr %0," __stringify(rn)        \
-                             : "=r" (rval));                   \
+               asm volatile("mfdcr %0, %1" : "=r" (rval)       \
+                             : "n" (rn));                      \
        else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR)))  \
                rval = mfdcrx(rn);                              \
        else                                                    \
@@ -64,8 +64,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
 #define mtdcr(rn, v)                                           \
 do {                                                           \
        if (__builtin_constant_p(rn) && rn < 1024)              \
-               asm volatile("mtdcr " __stringify(rn) ",%0"     \
-                             : : "r" (v));                     \
+               asm volatile("mtdcr %0, %1"                     \
+                             : : "n" (rn), "r" (v));           \
        else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR)))  \
                mtdcrx(rn, v);                                  \
        else                                                    \
index 80b27f5d96486227206c4503d388892821e569cd..607168b1aef46a936540a43601960ae6b17eb5bb 100644 (file)
@@ -228,7 +228,7 @@ enum {
 #define MMU_FTRS_ALWAYS                0
 #endif
 
-static inline bool early_mmu_has_feature(unsigned long feature)
+static __always_inline bool early_mmu_has_feature(unsigned long feature)
 {
        if (MMU_FTRS_ALWAYS & feature)
                return true;
@@ -286,7 +286,7 @@ static inline void mmu_feature_keys_init(void)
 
 }
 
-static inline bool mmu_has_feature(unsigned long feature)
+static __always_inline bool mmu_has_feature(unsigned long feature)
 {
        return early_mmu_has_feature(feature);
 }
index 0cf52746531bedb28ae6b0b439ea483b3b06f3fa..721c0d6715ac8f7599740355b312d397adc28894 100644 (file)
@@ -113,7 +113,7 @@ struct vio_driver {
        const char *name;
        const struct vio_device_id *id_table;
        int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
-       int (*remove)(struct vio_dev *dev);
+       void (*remove)(struct vio_dev *dev);
        /* A driver must have a get_desired_dma() function to
         * be loaded in a CMO environment if it uses DMA.
         */
index 727fdab557c9b70ab6c2dc350b8ba9b786da0adb..565e84e20a7214c5485fa143b33755e22ab0542a 100644 (file)
@@ -457,11 +457,12 @@ InstructionTLBMiss:
        cmplw   0,r1,r3
 #endif
        mfspr   r2, SPRN_SDR1
-       li      r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
+       li      r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER
        rlwinm  r2, r2, 28, 0xfffff000
 #ifdef CONFIG_MODULES
        bgt-    112f
        lis     r2, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
+       li      r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
        addi    r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
 #endif
 112:   rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
@@ -520,10 +521,11 @@ DataLoadTLBMiss:
        lis     r1, TASK_SIZE@h         /* check if kernel address */
        cmplw   0,r1,r3
        mfspr   r2, SPRN_SDR1
-       li      r1, _PAGE_PRESENT | _PAGE_ACCESSED
+       li      r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
        rlwinm  r2, r2, 28, 0xfffff000
        bgt-    112f
        lis     r2, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
+       li      r1, _PAGE_PRESENT | _PAGE_ACCESSED
        addi    r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
 112:   rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
        lwz     r2,0(r2)                /* get pmd entry */
@@ -597,10 +599,11 @@ DataStoreTLBMiss:
        lis     r1, TASK_SIZE@h         /* check if kernel address */
        cmplw   0,r1,r3
        mfspr   r2, SPRN_SDR1
-       li      r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
+       li      r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
        rlwinm  r2, r2, 28, 0xfffff000
        bgt-    112f
        lis     r2, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
+       li      r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
        addi    r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
 112:   rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
        lwz     r2,0(r2)                /* get pmd entry */
index 398cd86b6ada15514774666dbcfcebc7bd178a33..2ef3c4051bb936edfd230c90574ee97772b3a709 100644 (file)
@@ -149,7 +149,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
  * enabled when the interrupt handler returns (indicating a process-context /
  * synchronous interrupt) then irqs_enabled should be true.
  */
-static notrace inline bool __prep_irq_for_enabled_exit(bool clear_ri)
+static notrace __always_inline bool __prep_irq_for_enabled_exit(bool clear_ri)
 {
        /* This must be done with RI=1 because tracing may touch vmaps */
        trace_hardirqs_on();
index bb5c20d4ca91c2423869372306d3d12e95d576fe..c6aebc149d14129ca17a23a1d289bb8cde827131 100644 (file)
@@ -904,7 +904,7 @@ static nokprobe_inline int do_vsx_load(struct instruction_op *op,
        if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
                return -EFAULT;
 
-       nr_vsx_regs = size / sizeof(__vector128);
+       nr_vsx_regs = max(1ul, size / sizeof(__vector128));
        emulate_vsx_load(op, buf, mem, cross_endian);
        preempt_disable();
        if (reg < 32) {
@@ -951,7 +951,7 @@ static nokprobe_inline int do_vsx_store(struct instruction_op *op,
        if (!address_ok(regs, ea, size))
                return -EFAULT;
 
-       nr_vsx_regs = size / sizeof(__vector128);
+       nr_vsx_regs = max(1ul, size / sizeof(__vector128));
        preempt_disable();
        if (reg < 32) {
                /* FP regs + extensions */
index 6817331e22ffcbea822fa293fbe122c73e5fbd02..766f064f00fbf25322016546e2bd0c81fe3466eb 100644 (file)
@@ -222,7 +222,7 @@ static inline void perf_get_data_addr(struct perf_event *event, struct pt_regs *
        if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
                *addrp = mfspr(SPRN_SDAR);
 
-       if (is_kernel_addr(mfspr(SPRN_SDAR)) && perf_allow_kernel(&event->attr) != 0)
+       if (is_kernel_addr(mfspr(SPRN_SDAR)) && event->attr.exclude_kernel)
                *addrp = 0;
 }
 
@@ -507,7 +507,7 @@ static void power_pmu_bhrb_read(struct perf_event *event, struct cpu_hw_events *
                         * addresses, hence include a check before filtering code
                         */
                        if (!(ppmu->flags & PPMU_ARCH_31) &&
-                               is_kernel_addr(addr) && perf_allow_kernel(&event->attr) != 0)
+                           is_kernel_addr(addr) && event->attr.exclude_kernel)
                                continue;
 
                        /* Branches are read most recent first (ie. mfbhrb 0 is
index b3ac2455faadc51cdfcb45a251dc112d1df0a5d4..637300330507fe5a678a5f98d28c94ec5d8e8c77 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2006-2007 Michael Ellerman, IBM Corp.
  */
 
+#include <linux/crash_dump.h>
 #include <linux/device.h>
 #include <linux/irq.h>
 #include <linux/msi.h>
@@ -458,8 +459,28 @@ again:
                        return hwirq;
                }
 
-               virq = irq_create_mapping_affinity(NULL, hwirq,
-                                                  entry->affinity);
+               /*
+                * Depending on the number of online CPUs in the original
+                * kernel, it is likely for CPU #0 to be offline in a kdump
+                * kernel. The associated IRQs in the affinity mappings
+                * provided by irq_create_affinity_masks() are thus not
+                * started by irq_startup(), as per-design for managed IRQs.
+                * This can be a problem with multi-queue block devices driven
+                * by blk-mq : such a non-started IRQ is very likely paired
+                * with the single queue enforced by blk-mq during kdump (see
+                * blk_mq_alloc_tag_set()). This causes the device to remain
+                * silent and likely hangs the guest at some point.
+                *
+                * We don't really care for fine-grained affinity when doing
+                * kdump actually : simply ignore the pre-computed affinity
+                * masks in this case and let the default mask with all CPUs
+                * be used when creating the IRQ mappings.
+                */
+               if (is_kdump_kernel())
+                       virq = irq_create_mapping(NULL, hwirq);
+               else
+                       virq = irq_create_mapping_affinity(NULL, hwirq,
+                                                          entry->affinity);
 
                if (!virq) {
                        pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
index b2797cfe4e2b087535a23c13b2132f4e08324419..9cb4fc839fd5d89b3ec9426cfce7fe82742757d6 100644 (file)
@@ -1261,7 +1261,6 @@ static int vio_bus_remove(struct device *dev)
        struct vio_dev *viodev = to_vio_dev(dev);
        struct vio_driver *viodrv = to_vio_driver(dev->driver);
        struct device *devptr;
-       int ret = 1;
 
        /*
         * Hold a reference to the device after the remove function is called
@@ -1270,13 +1269,13 @@ static int vio_bus_remove(struct device *dev)
        devptr = get_device(dev);
 
        if (viodrv->remove)
-               ret = viodrv->remove(viodev);
+               viodrv->remove(viodev);
 
-       if (!ret && firmware_has_feature(FW_FEATURE_CMO))
+       if (firmware_has_feature(FW_FEATURE_CMO))
                vio_cmo_bus_remove(viodev);
 
        put_device(devptr);
-       return ret;
+       return 0;
 }
 
 /**
index 02056b024091eb95ade5612922fa1616e9077b3d..dc0b69058ac47556b91846f1aae702d05b8e52e6 100644 (file)
@@ -275,9 +275,9 @@ CONFIG_IP_VS_DH=m
 CONFIG_IP_VS_SH=m
 CONFIG_IP_VS_SED=m
 CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_TWOS=m
 CONFIG_IP_VS_FTP=m
 CONFIG_IP_VS_PE_SIP=m
-CONFIG_NF_TABLES_IPV4=y
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
 CONFIG_IP_NF_IPTABLES=m
@@ -298,7 +298,6 @@ CONFIG_IP_NF_SECURITY=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_TABLES_IPV6=y
 CONFIG_NFT_FIB_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
@@ -481,7 +480,6 @@ CONFIG_NLMON=m
 # CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_VENDOR_ATHEROS is not set
-# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_BROCADE is not set
 # CONFIG_NET_VENDOR_CADENCE is not set
@@ -581,7 +579,6 @@ CONFIG_VIRTIO_BALLOON=m
 CONFIG_VIRTIO_INPUT=y
 CONFIG_VHOST_NET=m
 CONFIG_VHOST_VSOCK=m
-# CONFIG_SURFACE_PLATFORMS is not set
 CONFIG_S390_CCW_IOMMU=y
 CONFIG_S390_AP_IOMMU=y
 CONFIG_EXT4_FS=y
@@ -635,6 +632,7 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_INODE64=y
 CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=m
 CONFIG_ECRYPT_FS=m
@@ -714,12 +712,8 @@ CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_CRC32=m
 CONFIG_CRYPTO_BLAKE2S=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA3=m
-CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
@@ -731,7 +725,6 @@ CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
 CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_SM4=m
@@ -796,12 +789,9 @@ CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
 CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
 CONFIG_SLUB_DEBUG_ON=y
 CONFIG_SLUB_STATS=y
-CONFIG_DEBUG_KMEMLEAK=y
-CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_VM=y
 CONFIG_DEBUG_VM_VMACACHE=y
-CONFIG_DEBUG_VM_RB=y
 CONFIG_DEBUG_VM_PGFLAGS=y
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
@@ -838,6 +828,7 @@ CONFIG_BPF_KPROBE_OVERRIDE=y
 CONFIG_HIST_TRIGGERS=y
 CONFIG_FTRACE_STARTUP_TEST=y
 # CONFIG_EVENT_TRACE_STARTUP_TEST is not set
+CONFIG_DEBUG_ENTRY=y
 CONFIG_NOTIFIER_ERROR_INJECTION=m
 CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
 CONFIG_FAULT_INJECTION=y
@@ -861,4 +852,3 @@ CONFIG_PERCPU_TEST=m
 CONFIG_ATOMIC64_SELFTEST=y
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_BPF=m
-CONFIG_DEBUG_ENTRY=y
index bac721a501da16a47313922369f4a61fff427a18..320379da96d97536fe563a5c09c0aa53acc642ef 100644 (file)
@@ -266,9 +266,9 @@ CONFIG_IP_VS_DH=m
 CONFIG_IP_VS_SH=m
 CONFIG_IP_VS_SED=m
 CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_TWOS=m
 CONFIG_IP_VS_FTP=m
 CONFIG_IP_VS_PE_SIP=m
-CONFIG_NF_TABLES_IPV4=y
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
 CONFIG_IP_NF_IPTABLES=m
@@ -289,7 +289,6 @@ CONFIG_IP_NF_SECURITY=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_TABLES_IPV6=y
 CONFIG_NFT_FIB_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
@@ -473,7 +472,6 @@ CONFIG_NLMON=m
 # CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_VENDOR_ATHEROS is not set
-# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_BROCADE is not set
 # CONFIG_NET_VENDOR_CADENCE is not set
@@ -573,7 +571,6 @@ CONFIG_VIRTIO_BALLOON=m
 CONFIG_VIRTIO_INPUT=y
 CONFIG_VHOST_NET=m
 CONFIG_VHOST_VSOCK=m
-# CONFIG_SURFACE_PLATFORMS is not set
 CONFIG_S390_CCW_IOMMU=y
 CONFIG_S390_AP_IOMMU=y
 CONFIG_EXT4_FS=y
@@ -623,6 +620,7 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_INODE64=y
 CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=m
 CONFIG_ECRYPT_FS=m
@@ -703,12 +701,8 @@ CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_CRC32=m
 CONFIG_CRYPTO_BLAKE2S=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA3=m
-CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
@@ -720,7 +714,6 @@ CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
 CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_SM4=m
index acf982a2ae4c5eb1e86bdc837243adfa6da41274..76123a4b26ab06f221c209734b1b97b38cc1e46a 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_CRASH_DUMP=y
 # CONFIG_SECCOMP is not set
 # CONFIG_GCC_PLUGINS is not set
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_COMPACTION is not set
 # CONFIG_MIGRATION is not set
@@ -61,11 +60,9 @@ CONFIG_RAW_DRIVER=y
 # CONFIG_HID is not set
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_VHOST_MENU is not set
-# CONFIG_SURFACE_PLATFORMS is not set
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY_USER is not set
-CONFIG_CONFIGFS_FS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_LSM="yama,loadpin,safesetid,integrity"
index b04f6a794cdfb5d696c9c9dc29e9e35f66e3a00b..5cea629c548e2d53635b4a1a6e175e98e38ca908 100644 (file)
 
 struct s390_idle_data {
        seqcount_t seqcount;
-       unsigned long long idle_count;
-       unsigned long long idle_time;
-       unsigned long long clock_idle_enter;
-       unsigned long long clock_idle_exit;
-       unsigned long long timer_idle_enter;
-       unsigned long long timer_idle_exit;
+       unsigned long idle_count;
+       unsigned long idle_time;
+       unsigned long clock_idle_enter;
+       unsigned long clock_idle_exit;
+       unsigned long timer_idle_enter;
+       unsigned long timer_idle_exit;
        unsigned long mt_cycles_enter[8];
 };
 
index c4e23e92566546ffe7d082202e33c3fc576d6bc5..f6326c6d2abe83536a340f0829b95cdd6cdb4f7b 100644 (file)
@@ -98,10 +98,10 @@ extern unsigned char ptff_function_mask[16];
 
 /* Query TOD offset result */
 struct ptff_qto {
-       unsigned long long physical_clock;
-       unsigned long long tod_offset;
-       unsigned long long logical_tod_offset;
-       unsigned long long tod_epoch_difference;
+       unsigned long physical_clock;
+       unsigned long tod_offset;
+       unsigned long logical_tod_offset;
+       unsigned long tod_epoch_difference;
 } __packed;
 
 static inline int ptff_query(unsigned int nr)
@@ -151,9 +151,9 @@ struct ptff_qui {
        rc;                                                             \
 })
 
-static inline unsigned long long local_tick_disable(void)
+static inline unsigned long local_tick_disable(void)
 {
-       unsigned long long old;
+       unsigned long old;
 
        old = S390_lowcore.clock_comparator;
        S390_lowcore.clock_comparator = clock_comparator_max;
@@ -161,7 +161,7 @@ static inline unsigned long long local_tick_disable(void)
        return old;
 }
 
-static inline void local_tick_enable(unsigned long long comp)
+static inline void local_tick_enable(unsigned long comp)
 {
        S390_lowcore.clock_comparator = comp;
        set_clock_comparator(S390_lowcore.clock_comparator);
@@ -169,9 +169,9 @@ static inline void local_tick_enable(unsigned long long comp)
 
 #define CLOCK_TICK_RATE                1193180 /* Underlying HZ */
 
-typedef unsigned long long cycles_t;
+typedef unsigned long cycles_t;
 
-static inline unsigned long long get_tod_clock(void)
+static inline unsigned long get_tod_clock(void)
 {
        union tod_clock clk;
 
@@ -179,10 +179,10 @@ static inline unsigned long long get_tod_clock(void)
        return clk.tod;
 }
 
-static inline unsigned long long get_tod_clock_fast(void)
+static inline unsigned long get_tod_clock_fast(void)
 {
 #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
-       unsigned long long clk;
+       unsigned long clk;
 
        asm volatile("stckf %0" : "=Q" (clk) : : "cc");
        return clk;
@@ -208,9 +208,9 @@ extern union tod_clock tod_clock_base;
  * Therefore preemption must be disabled, otherwise the returned
  * value is not guaranteed to be monotonic.
  */
-static inline unsigned long long get_tod_clock_monotonic(void)
+static inline unsigned long get_tod_clock_monotonic(void)
 {
-       unsigned long long tod;
+       unsigned long tod;
 
        preempt_disable_notrace();
        tod = get_tod_clock() - tod_clock_base.tod;
@@ -237,7 +237,7 @@ static inline unsigned long long get_tod_clock_monotonic(void)
  * -> ns = (th * 125) + ((tl * 125) >> 9);
  *
  */
-static inline unsigned long long tod_to_ns(unsigned long long todval)
+static inline unsigned long tod_to_ns(unsigned long todval)
 {
        return ((todval >> 9) * 125) + (((todval & 0x1ff) * 125) >> 9);
 }
@@ -249,10 +249,10 @@ static inline unsigned long long tod_to_ns(unsigned long long todval)
  *
  * Returns: true if a is later than b
  */
-static inline int tod_after(unsigned long long a, unsigned long long b)
+static inline int tod_after(unsigned long a, unsigned long b)
 {
        if (MACHINE_HAS_SCC)
-               return (long long) a > (long long) b;
+               return (long) a > (long) b;
        return a > b;
 }
 
@@ -263,10 +263,10 @@ static inline int tod_after(unsigned long long a, unsigned long long b)
  *
  * Returns: true if a is later than b
  */
-static inline int tod_after_eq(unsigned long long a, unsigned long long b)
+static inline int tod_after_eq(unsigned long a, unsigned long b)
 {
        if (MACHINE_HAS_SCC)
-               return (long long) a >= (long long) b;
+               return (long) a >= (long) b;
        return a >= b;
 }
 
diff --git a/arch/s390/include/uapi/asm/hwctrset.h b/arch/s390/include/uapi/asm/hwctrset.h
new file mode 100644 (file)
index 0000000..3d8284b
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Copyright IBM Corp. 2021
+ * Interface implementation for communication with the CPU Measurement
+ * counter facility device driver.
+ *
+ * Author(s): Thomas Richter <tmricht@linux.ibm.com>
+ *
+ * Define for ioctl() commands to communicate with the CPU Measurement
+ * counter facility device driver.
+ */
+
+#ifndef _PERF_CPUM_CF_DIAG_H
+#define _PERF_CPUM_CF_DIAG_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define S390_HWCTR_DEVICE              "hwctr"
+#define S390_HWCTR_START_VERSION       1
+
+struct s390_ctrset_start {             /* Set CPUs to operate on */
+       __u64 version;                  /* Version of interface */
+       __u64 data_bytes;               /* # of bytes required */
+       __u64 cpumask_len;              /* Length of CPU mask in bytes */
+       __u64 *cpumask;                 /* Pointer to CPU mask */
+       __u64 counter_sets;             /* Bit mask of counter sets to get */
+};
+
+struct s390_ctrset_setdata {           /* Counter set data */
+       __u32 set;                      /* Counter set number */
+       __u32 no_cnts;                  /* # of counters stored in cv[] */
+       __u64 cv[0];                    /* Counter values (variable length) */
+};
+
+struct s390_ctrset_cpudata {           /* Counter set data per CPU */
+       __u32 cpu_nr;                   /* CPU number */
+       __u32 no_sets;                  /* # of counters sets in data[] */
+       struct s390_ctrset_setdata data[0];
+};
+
+struct s390_ctrset_read {              /* Structure to get all ctr sets */
+       __u64 no_cpus;                  /* Total # of CPUs data taken from */
+       struct s390_ctrset_cpudata data[0];
+};
+
+#define S390_HWCTR_MAGIC       'C'     /* Random magic # for ioctls */
+#define        S390_HWCTR_START        _IOWR(S390_HWCTR_MAGIC, 1, struct s390_ctrset_start)
+#define        S390_HWCTR_STOP         _IO(S390_HWCTR_MAGIC, 2)
+#define        S390_HWCTR_READ         _IOWR(S390_HWCTR_MAGIC, 3, struct s390_ctrset_read)
+#endif
diff --git a/arch/s390/include/uapi/asm/perf_cpum_cf_diag.h b/arch/s390/include/uapi/asm/perf_cpum_cf_diag.h
deleted file mode 100644 (file)
index 3d8284b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright IBM Corp. 2021
- * Interface implementation for communication with the CPU Measurement
- * counter facility device driver.
- *
- * Author(s): Thomas Richter <tmricht@linux.ibm.com>
- *
- * Define for ioctl() commands to communicate with the CPU Measurement
- * counter facility device driver.
- */
-
-#ifndef _PERF_CPUM_CF_DIAG_H
-#define _PERF_CPUM_CF_DIAG_H
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-#define S390_HWCTR_DEVICE              "hwctr"
-#define S390_HWCTR_START_VERSION       1
-
-struct s390_ctrset_start {             /* Set CPUs to operate on */
-       __u64 version;                  /* Version of interface */
-       __u64 data_bytes;               /* # of bytes required */
-       __u64 cpumask_len;              /* Length of CPU mask in bytes */
-       __u64 *cpumask;                 /* Pointer to CPU mask */
-       __u64 counter_sets;             /* Bit mask of counter sets to get */
-};
-
-struct s390_ctrset_setdata {           /* Counter set data */
-       __u32 set;                      /* Counter set number */
-       __u32 no_cnts;                  /* # of counters stored in cv[] */
-       __u64 cv[0];                    /* Counter values (variable length) */
-};
-
-struct s390_ctrset_cpudata {           /* Counter set data per CPU */
-       __u32 cpu_nr;                   /* CPU number */
-       __u32 no_sets;                  /* # of counters sets in data[] */
-       struct s390_ctrset_setdata data[0];
-};
-
-struct s390_ctrset_read {              /* Structure to get all ctr sets */
-       __u64 no_cpus;                  /* Total # of CPUs data taken from */
-       struct s390_ctrset_cpudata data[0];
-};
-
-#define S390_HWCTR_MAGIC       'C'     /* Random magic # for ioctls */
-#define        S390_HWCTR_START        _IOWR(S390_HWCTR_MAGIC, 1, struct s390_ctrset_start)
-#define        S390_HWCTR_STOP         _IO(S390_HWCTR_MAGIC, 2)
-#define        S390_HWCTR_READ         _IOWR(S390_HWCTR_MAGIC, 3, struct s390_ctrset_read)
-#endif
index 812073ea073ee23e571041d12e528ab2769c4395..4bf1ee293f2b31ee3d5ae06cbe9afd7baa6d37db 100644 (file)
@@ -47,7 +47,7 @@ void account_idle_time_irq(void)
 void arch_cpu_idle(void)
 {
        struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
-       unsigned long long idle_time;
+       unsigned long idle_time;
        unsigned long psw_mask;
 
        /* Wait for external, I/O or machine check interrupt. */
@@ -73,7 +73,7 @@ static ssize_t show_idle_count(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
-       unsigned long long idle_count;
+       unsigned long idle_count;
        unsigned int seq;
 
        do {
@@ -82,14 +82,14 @@ static ssize_t show_idle_count(struct device *dev,
                if (READ_ONCE(idle->clock_idle_enter))
                        idle_count++;
        } while (read_seqcount_retry(&idle->seqcount, seq));
-       return sprintf(buf, "%llu\n", idle_count);
+       return sprintf(buf, "%lu\n", idle_count);
 }
 DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
 
 static ssize_t show_idle_time(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
-       unsigned long long now, idle_time, idle_enter, idle_exit, in_idle;
+       unsigned long now, idle_time, idle_enter, idle_exit, in_idle;
        struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
        unsigned int seq;
 
@@ -109,14 +109,14 @@ static ssize_t show_idle_time(struct device *dev,
                }
        }
        idle_time += in_idle;
-       return sprintf(buf, "%llu\n", idle_time >> 12);
+       return sprintf(buf, "%lu\n", idle_time >> 12);
 }
 DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
 
 u64 arch_cpu_idle_time(int cpu)
 {
        struct s390_idle_data *idle = &per_cpu(s390_idle, cpu);
-       unsigned long long now, idle_enter, idle_exit, in_idle;
+       unsigned long now, idle_enter, idle_exit, in_idle;
        unsigned int seq;
 
        do {
index 0eb1d1cc53a88380421468f5daa6ec1f842328e2..b3beef64d3d48776667c5d8d851d83ff98f545d2 100644 (file)
@@ -269,7 +269,7 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
        case CPUMF_CTR_SET_MAX:
                /* The counter could not be associated to a counter set */
                return -EINVAL;
-       };
+       }
 
        /* Initialize for using the CPU-measurement counter facility */
        if (!atomic_inc_not_zero(&num_events)) {
index db4877bbb9aa5626702bf6068de92accdaa9e81a..bc302b86ce28fcd88cd5341d390a6360ce3d265b 100644 (file)
 #include <asm/timex.h>
 #include <asm/debug.h>
 
-#include <asm/perf_cpum_cf_diag.h>
+#include <asm/hwctrset.h>
 
 #define        CF_DIAG_CTRSET_DEF              0xfeef  /* Counter set header mark */
-#define CF_DIAG_MIN_INTERVAL           60      /* Minimum counter set read */
                                                /* interval in seconds */
-static unsigned long cf_diag_interval = CF_DIAG_MIN_INTERVAL;
 static unsigned int cf_diag_cpu_speed;
 static debug_info_t *cf_diag_dbg;
 
@@ -729,7 +727,6 @@ static DEFINE_MUTEX(cf_diag_ctrset_mutex);
 static struct cf_diag_ctrset {
        unsigned long ctrset;           /* Bit mask of counter set to read */
        cpumask_t mask;                 /* CPU mask to read from */
-       time64_t lastread;              /* Epoch counter set last read */
 } cf_diag_ctrset;
 
 static void cf_diag_ctrset_clear(void)
@@ -866,27 +863,16 @@ static int cf_diag_all_read(unsigned long arg)
 {
        struct cf_diag_call_on_cpu_parm p;
        cpumask_var_t mask;
-       time64_t now;
-       int rc = 0;
+       int rc;
 
        debug_sprintf_event(cf_diag_dbg, 5, "%s\n", __func__);
        if (!alloc_cpumask_var(&mask, GFP_KERNEL))
                return -ENOMEM;
-       now = ktime_get_seconds();
-       if (cf_diag_ctrset.lastread + cf_diag_interval > now) {
-               debug_sprintf_event(cf_diag_dbg, 5, "%s now %lld "
-                                   " lastread %lld\n", __func__, now,
-                                   cf_diag_ctrset.lastread);
-               rc = -EAGAIN;
-               goto out;
-       } else {
-               cf_diag_ctrset.lastread = now;
-       }
+
        p.sets = cf_diag_ctrset.ctrset;
        cpumask_and(mask, &cf_diag_ctrset.mask, cpu_online_mask);
        on_each_cpu_mask(mask, cf_diag_cpu_read, &p, 1);
        rc = cf_diag_all_copy(arg, mask);
-out:
        free_cpumask_var(mask);
        debug_sprintf_event(cf_diag_dbg, 5, "%s rc %d\n", __func__, rc);
        return rc;
index 06bcfa6366384e3145e4dd469d4dfa6641a7d924..165da961f9019adf641c6568a2cc4c853862a007 100644 (file)
@@ -68,10 +68,10 @@ EXPORT_SYMBOL(s390_epoch_delta_notifier);
 
 unsigned char ptff_function_mask[16];
 
-static unsigned long long lpar_offset;
-static unsigned long long initial_leap_seconds;
-static unsigned long long tod_steering_end;
-static long long tod_steering_delta;
+static unsigned long lpar_offset;
+static unsigned long initial_leap_seconds;
+static unsigned long tod_steering_end;
+static long tod_steering_delta;
 
 /*
  * Get time offsets with PTFF
@@ -96,7 +96,7 @@ void __init time_early_init(void)
 
        /* get initial leap seconds */
        if (ptff_query(PTFF_QUI) && ptff(&qui, sizeof(qui), PTFF_QUI) == 0)
-               initial_leap_seconds = (unsigned long long)
+               initial_leap_seconds = (unsigned long)
                        ((long) qui.old_leap * 4096000000L);
 }
 
@@ -222,7 +222,7 @@ void __init read_persistent_wall_and_boot_offset(struct timespec64 *wall_time,
 
 static u64 read_tod_clock(struct clocksource *cs)
 {
-       unsigned long long now, adj;
+       unsigned long now, adj;
 
        preempt_disable(); /* protect from changes to steering parameters */
        now = get_tod_clock();
@@ -362,7 +362,7 @@ static inline int check_sync_clock(void)
  * Apply clock delta to the global data structures.
  * This is called once on the CPU that performed the clock sync.
  */
-static void clock_sync_global(unsigned long long delta)
+static void clock_sync_global(unsigned long delta)
 {
        unsigned long now, adj;
        struct ptff_qto qto;
@@ -378,7 +378,7 @@ static void clock_sync_global(unsigned long long delta)
                        -(adj >> 15) : (adj >> 15);
        tod_steering_delta += delta;
        if ((abs(tod_steering_delta) >> 48) != 0)
-               panic("TOD clock sync offset %lli is too large to drift\n",
+               panic("TOD clock sync offset %li is too large to drift\n",
                      tod_steering_delta);
        tod_steering_end = now + (abs(tod_steering_delta) << 15);
        vdso_data->arch_data.tod_steering_end = tod_steering_end;
@@ -394,7 +394,7 @@ static void clock_sync_global(unsigned long long delta)
  * Apply clock delta to the per-CPU data structures of this CPU.
  * This is called for each online CPU after the call to clock_sync_global.
  */
-static void clock_sync_local(unsigned long long delta)
+static void clock_sync_local(unsigned long delta)
 {
        /* Add the delta to the clock comparator. */
        if (S390_lowcore.clock_comparator != clock_comparator_max) {
@@ -418,7 +418,7 @@ static void __init time_init_wq(void)
 struct clock_sync_data {
        atomic_t cpus;
        int in_sync;
-       unsigned long long clock_delta;
+       unsigned long clock_delta;
 };
 
 /*
@@ -538,7 +538,7 @@ static int stpinfo_valid(void)
 static int stp_sync_clock(void *data)
 {
        struct clock_sync_data *sync = data;
-       unsigned long long clock_delta, flags;
+       u64 clock_delta, flags;
        static int first;
        int rc;
 
@@ -720,8 +720,8 @@ static ssize_t ctn_id_show(struct device *dev,
 
        mutex_lock(&stp_mutex);
        if (stpinfo_valid())
-               ret = sprintf(buf, "%016llx\n",
-                             *(unsigned long long *) stp_info.ctnid);
+               ret = sprintf(buf, "%016lx\n",
+                             *(unsigned long *) stp_info.ctnid);
        mutex_unlock(&stp_mutex);
        return ret;
 }
@@ -794,7 +794,7 @@ static ssize_t leap_seconds_scheduled_show(struct device *dev,
        if (!stzi.lsoib.p)
                return sprintf(buf, "0,0\n");
 
-       return sprintf(buf, "%llu,%d\n",
+       return sprintf(buf, "%lu,%d\n",
                       tod_to_ns(stzi.lsoib.nlsout - TOD_UNIX_EPOCH) / NSEC_PER_SEC,
                       stzi.lsoib.nlso - stzi.lsoib.also);
 }
index e7ce447651b905c20dce60dfc41555ee359d5d55..bfcc327acc6b2ebfec38f7fe0e3a3bd39e73f4f6 100644 (file)
@@ -76,8 +76,6 @@ static void cpu_group_map(cpumask_t *dst, struct mask_info *info, unsigned int c
                        }
                        info = info->next;
                }
-               if (cpumask_empty(&mask))
-                       cpumask_copy(&mask, cpumask_of(cpu));
                break;
        case TOPOLOGY_MODE_PACKAGE:
                cpumask_copy(&mask, cpu_present_mask);
index e3183bd059107a04f7695ee707da18f1bea2153d..d548d60caed252021c6abb532e546a79184741fb 100644 (file)
@@ -1287,7 +1287,7 @@ static u64 __calculate_sltime(struct kvm_vcpu *vcpu)
                        /* already expired? */
                        if (cputm >> 63)
                                return 0;
-                       return min(sltime, tod_to_ns(cputm));
+                       return min_t(u64, sltime, tod_to_ns(cputm));
                }
        } else if (cpu_timer_interrupts_enabled(vcpu)) {
                sltime = kvm_s390_get_cpu_timer(vcpu);
index 148f44b33890e220039f1f345b8ccfaf4a9f0006..12a4fb0bd52aa41d2865e49450b7c4b6ad4b1656 100644 (file)
@@ -93,7 +93,7 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 CONFIG_SUNLANCE=m
-CONFIG_HAPPYMEAL=m
+CONFIG_HAPPYMEAL=y
 CONFIG_SUNGEM=m
 CONFIG_SUNVNET=m
 CONFIG_LDMVSW=m
@@ -234,9 +234,7 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRC16=m
 CONFIG_LIBCRC32C=m
 CONFIG_VCC=m
-CONFIG_ATA=y
 CONFIG_PATA_CMD64X=y
-CONFIG_HAPPYMEAL=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_DEVTMPFS=y
index 7e078bc73ef5616d8f0a94f070246d203c4f6e14..8fb09eec8c3e796a9a79aa0a7877842ceb7ea6d3 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
-#include <asm/extable_64.h>
 #include <asm/spitfire.h>
 #include <asm/adi.h>
 
diff --git a/arch/sparc/include/asm/extable.h b/arch/sparc/include/asm/extable.h
new file mode 100644 (file)
index 0000000..554a9dc
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_EXTABLE_H
+#define __ASM_EXTABLE_H
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+        unsigned int insn, fixup;
+};
+
+#endif
diff --git a/arch/sparc/include/asm/extable_64.h b/arch/sparc/include/asm/extable_64.h
deleted file mode 100644 (file)
index 5a01719..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_EXTABLE64_H
-#define __ASM_EXTABLE64_H
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry {
-        unsigned int insn, fixup;
-};
-
-#endif
index 3c4bc2189092d350b7b6e2c794714f6c7249f692..b6242f7771e9e845ab9a24720e99f66a86c8ae51 100644 (file)
@@ -50,16 +50,12 @@ struct thread_struct {
        unsigned long   fsr;
        unsigned long   fpqdepth;
        struct fpq      fpqueue[16];
-       unsigned long flags;
        mm_segment_t current_ds;
 };
 
-#define SPARC_FLAG_KTHREAD      0x1    /* task is a kernel thread */
-#define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
-
 #define INIT_THREAD  { \
-       .flags = SPARC_FLAG_KTHREAD, \
        .current_ds = KERNEL_DS, \
+       .kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
 }
 
 /* Do necessary setup to start up a newly executed thread. */
index 42cd4cd3892e32a9adacad7ba1d4fb208369691c..8047a9caab2fc86a35e684a98e2c1deff54e923a 100644 (file)
@@ -118,6 +118,7 @@ struct thread_info {
        .task           =       &tsk,                   \
        .current_ds     =       ASI_P,                  \
        .preempt_count  =       INIT_PREEMPT_COUNT,     \
+       .kregs          =       (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
 }
 
 /* how to get the thread information struct from C */
index dd85bc2c2cad5211c19695362bba874e0ce17b3c..390094200fc44212187f7909d74b3079ed639d6e 100644 (file)
@@ -1,6 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef ___ASM_SPARC_UACCESS_H
 #define ___ASM_SPARC_UACCESS_H
+
+#include <asm/extable.h>
+
 #if defined(__sparc__) && defined(__arch64__)
 #include <asm/uaccess_64.h>
 #else
index 0a2d3ebc4bb86d349bf5455bc05d7868f6da495e..4a12346bb69c335d06bc4e30b98244ced13a46e3 100644 (file)
@@ -13,9 +13,6 @@
 
 #include <asm/processor.h>
 
-#define ARCH_HAS_SORT_EXTABLE
-#define ARCH_HAS_SEARCH_EXTABLE
-
 /* Sparc is not segmented, however we need to be able to fool access_ok()
  * when doing system calls from kernel mode legitimately.
  *
 #define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size)))
 #define access_ok(addr, size) __access_ok((unsigned long)(addr), size)
 
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
- *
- * There is a special way how to put a range of potentially faulting
- * insns (like twenty ldd/std's with now intervening other instructions)
- * You specify address of first in insn and 0 in fixup and in the next
- * exception_table_entry you specify last potentially faulting insn + 1
- * and in fixup the routine which should handle the fault.
- * That fixup code will get
- * (faulting_insn_address - first_insn_in_the_range_address)/4
- * in %g2 (ie. index of the faulting instruction in the range).
- */
-
-struct exception_table_entry
-{
-        unsigned long insn, fixup;
-};
-
-/* Returns 0 if exception not found and fixup otherwise.  */
-unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
-
 /* Uh, these should become the main single-value transfer routines..
  * They automatically use the right size if we just have the right
  * pointer type..
@@ -252,12 +219,7 @@ static inline unsigned long __clear_user(void __user *addr, unsigned long size)
        unsigned long ret;
 
        __asm__ __volatile__ (
-               ".section __ex_table,#alloc\n\t"
-               ".align 4\n\t"
-               ".word 1f,3\n\t"
-               ".previous\n\t"
                "mov %2, %%o1\n"
-               "1:\n\t"
                "call __bzero\n\t"
                " mov %1, %%o0\n\t"
                "mov %%o0, %0\n"
index 698cf69f74e9984d54bca056bcd6470df7b88c1e..30eb4c6414d1baf9ae792726bf8c652d6085e61e 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/string.h>
 #include <asm/asi.h>
 #include <asm/spitfire.h>
-#include <asm/extable_64.h>
 
 #include <asm/processor.h>
 
index be30c8d4cc7373490ed5f8c2ff716aae22f56574..6044b82b976751a8ccbe43ac424bafe8de36af42 100644 (file)
@@ -515,7 +515,7 @@ continue_boot:
 
                /* I want a kernel stack NOW! */
                set     init_thread_union, %g1
-               set     (THREAD_SIZE - STACKFRAME_SZ), %g2
+               set     (THREAD_SIZE - STACKFRAME_SZ - TRACEREG_SZ), %g2
                add     %g1, %g2, %sp
                mov     0, %fp                  /* And for good luck */
 
index c5ff2472b3d9d4e53385da0536802b387f123f75..72a5bdc833ea22f0800663c354cba188fad83243 100644 (file)
@@ -706,7 +706,7 @@ tlb_fixup_done:
        wr      %g0, ASI_P, %asi
        mov     1, %g1
        sllx    %g1, THREAD_SHIFT, %g1
-       sub     %g1, (STACKFRAME_SZ + STACK_BIAS), %g1
+       sub     %g1, (STACKFRAME_SZ + STACK_BIAS + TRACEREG_SZ), %g1
        add     %g6, %g1, %sp
 
        /* Set per-cpu pointer initially to zero, this makes
index b91e88058e0ce39675eb095c9c4876e4ea44ad97..3b9794978e5bc97c3cc4c536dc43e2dacb6d5a58 100644 (file)
@@ -216,16 +216,6 @@ void flush_thread(void)
                clear_thread_flag(TIF_USEDFPU);
 #endif
        }
-
-       /* This task is no longer a kernel thread. */
-       if (current->thread.flags & SPARC_FLAG_KTHREAD) {
-               current->thread.flags &= ~SPARC_FLAG_KTHREAD;
-
-               /* We must fixup kregs as well. */
-               /* XXX This was not fixed for ti for a while, worked. Unused? */
-               current->thread.kregs = (struct pt_regs *)
-                   (task_stack_page(current) + (THREAD_SIZE - TRACEREG_SZ));
-       }
 }
 
 static inline struct sparc_stackf __user *
@@ -313,7 +303,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
                extern int nwindows;
                unsigned long psr;
                memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ);
-               p->thread.flags |= SPARC_FLAG_KTHREAD;
                p->thread.current_ds = KERNEL_DS;
                ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8);
                childregs->u_regs[UREG_G1] = sp; /* function */
@@ -325,7 +314,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
        }
        memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ);
        childregs->u_regs[UREG_FP] = sp;
-       p->thread.flags &= ~SPARC_FLAG_KTHREAD;
        p->thread.current_ds = USER_DS;
        ti->kpc = (((unsigned long) ret_from_fork) - 0x8);
        ti->kpsr = current->thread.fork_kpsr | PSR_PIL;
index eea43a1aef1b9a6fd1e4139dbf118d8e4eafc2ee..c8e0dd99f3700e73851878ca44102f1c7d24fe8f 100644 (file)
@@ -266,7 +266,6 @@ static __init void leon_patch(void)
 }
 
 struct tt_entry *sparc_ttable;
-static struct pt_regs fake_swapper_regs;
 
 /* Called from head_32.S - before we have setup anything
  * in the kernel. Be very careful with what you do here.
@@ -363,8 +362,6 @@ void __init setup_arch(char **cmdline_p)
                (*(linux_dbvec->teach_debugger))();
        }
 
-       init_task.thread.kregs = &fake_swapper_regs;
-
        /* Run-time patch instructions to match the cpu model */
        per_cpu_patch();
 
index d87244197d5cbb56fec92223c3b5c7ead0352b63..48abee4eee29d8589d9452029f109e102f63f91a 100644 (file)
@@ -165,8 +165,6 @@ extern int root_mountflags;
 
 char reboot_command[COMMAND_LINE_SIZE];
 
-static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
-
 static void __init per_cpu_patch(void)
 {
        struct cpuid_patch_entry *p;
@@ -661,8 +659,6 @@ void __init setup_arch(char **cmdline_p)
        rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
 #endif
 
-       task_thread_info(&init_task)->kregs = &fake_swapper_regs;
-
 #ifdef CONFIG_IP_PNP
        if (!ic_set_manually) {
                phandle chosen = prom_finddevice("/chosen");
index d92e5eaa4c1d704be7115f3ab23785153fde1194..a850dccd78ea19c8a9e30f9140884d3d0091b82a 100644 (file)
@@ -275,14 +275,13 @@ bool is_no_fault_exception(struct pt_regs *regs)
                        asi = (regs->tstate >> 24); /* saved %asi       */
                else
                        asi = (insn >> 5);          /* immediate asi    */
-               if ((asi & 0xf2) == ASI_PNF) {
-                       if (insn & 0x1000000) {     /* op3[5:4]=3       */
-                               handle_ldf_stq(insn, regs);
-                               return true;
-                       } else if (insn & 0x200000) { /* op3[2], stores */
+               if ((asi & 0xf6) == ASI_PNF) {
+                       if (insn & 0x200000)        /* op3[2], stores   */
                                return false;
-                       }
-                       handle_ld_nf(insn, regs);
+                       if (insn & 0x1000000)       /* op3[5:4]=3 (fp)  */
+                               handle_ldf_stq(insn, regs);
+                       else
+                               handle_ld_nf(insn, regs);
                        return true;
                }
        }
index 83db94c0b43189e4c938d30878368ee2cbf41c08..ef5c5207c9ffbbee5ef2b339cb0d073d1cc55d2a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/uaccess.h>
 #include <linux/smp.h>
 #include <linux/perf_event.h>
+#include <linux/extable.h>
 
 #include <asm/setup.h>
 
@@ -213,10 +214,10 @@ static inline int ok_for_kernel(unsigned int insn)
 
 static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
 {
-       unsigned long g2 = regs->u_regs [UREG_G2];
-       unsigned long fixup = search_extables_range(regs->pc, &g2);
+       const struct exception_table_entry *entry;
 
-       if (!fixup) {
+       entry = search_exception_tables(regs->pc);
+       if (!entry) {
                unsigned long address = compute_effective_address(regs, insn);
                if(address < PAGE_SIZE) {
                        printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler");
@@ -232,9 +233,8 @@ static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
                die_if_kernel("Oops", regs);
                /* Not reached */
        }
-       regs->pc = fixup;
+       regs->pc = entry->fixup;
        regs->npc = regs->pc + 4;
-       regs->u_regs [UREG_G2] = g2;
 }
 
 asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
@@ -274,103 +274,9 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
        }
 }
 
-static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
-                             enum direction dir)
-{
-       unsigned int reg;
-       int size = ((insn >> 19) & 3) == 3 ? 8 : 4;
-
-       if ((regs->pc | regs->npc) & 3)
-               return 0;
-
-       /* Must access_ok() in all the necessary places. */
-#define WINREG_ADDR(regnum) \
-       ((void __user *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))
-
-       reg = (insn >> 25) & 0x1f;
-       if (reg >= 16) {
-               if (!access_ok(WINREG_ADDR(reg - 16), size))
-                       return -EFAULT;
-       }
-       reg = (insn >> 14) & 0x1f;
-       if (reg >= 16) {
-               if (!access_ok(WINREG_ADDR(reg - 16), size))
-                       return -EFAULT;
-       }
-       if (!(insn & 0x2000)) {
-               reg = (insn & 0x1f);
-               if (reg >= 16) {
-                       if (!access_ok(WINREG_ADDR(reg - 16), size))
-                               return -EFAULT;
-               }
-       }
-#undef WINREG_ADDR
-       return 0;
-}
-
-static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
 {
        send_sig_fault(SIGBUS, BUS_ADRALN,
                       (void __user *)safe_compute_effective_address(regs, insn),
                       0, current);
 }
-
-asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
-{
-       enum direction dir;
-
-       if(!(current->thread.flags & SPARC_FLAG_UNALIGNED) ||
-          (((insn >> 30) & 3) != 3))
-               goto kill_user;
-       dir = decode_direction(insn);
-       if(!ok_for_user(regs, insn, dir)) {
-               goto kill_user;
-       } else {
-               int err, size = decode_access_size(insn);
-               unsigned long addr;
-
-               if(floating_point_load_or_store_p(insn)) {
-                       printk("User FPU load/store unaligned unsupported.\n");
-                       goto kill_user;
-               }
-
-               addr = compute_effective_address(regs, insn);
-               perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
-               switch(dir) {
-               case load:
-                       err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
-                                                        regs),
-                                         size, (unsigned long *) addr,
-                                         decode_signedness(insn));
-                       break;
-
-               case store:
-                       err = do_int_store(((insn>>25)&0x1f), size,
-                                          (unsigned long *) addr, regs);
-                       break;
-
-               case both:
-                       /*
-                        * This was supported in 2.4. However, we question
-                        * the value of SWAP instruction across word boundaries.
-                        */
-                       printk("Unaligned SWAP unsupported.\n");
-                       err = -EFAULT;
-                       break;
-
-               default:
-                       unaligned_panic("Impossible user unaligned trap.");
-                       goto out;
-               }
-               if (err)
-                       goto kill_user;
-               else
-                       advance(regs);
-               goto out;
-       }
-
-kill_user:
-       user_mna_trap_fault(regs, insn);
-out:
-       ;
-}
index 7488d130faf730d6e96414ce987ff4a5e8b37ca6..781e39b3c009f9b27e886f6a6e07e6d2f5545108 100644 (file)
@@ -155,13 +155,6 @@ cpout:     retl                                            ! get outta here
         .text;                                  \
         .align  4
 
-#define EXT(start,end)                         \
-        .section __ex_table,ALLOC;             \
-        .align  4;                              \
-        .word   start, 0, end, cc_fault;         \
-        .text;                                  \
-        .align  4
-
        /* This aligned version executes typically in 8.5 superscalar cycles, this
         * is the best I can do.  I say 8.5 because the final add will pair with
         * the next ldd in the main unrolled loop.  Thus the pipe is always full.
@@ -169,20 +162,20 @@ cpout:    retl                                            ! get outta here
         * please check the fixup code below as well.
         */
 #define CSUMCOPY_BIGCHUNK_ALIGNED(src, dst, sum, off, t0, t1, t2, t3, t4, t5, t6, t7)  \
-       ldd     [src + off + 0x00], t0;                                                 \
-       ldd     [src + off + 0x08], t2;                                                 \
+       EX(ldd  [src + off + 0x00], t0);                                                \
+       EX(ldd  [src + off + 0x08], t2);                                                \
        addxcc  t0, sum, sum;                                                           \
-       ldd     [src + off + 0x10], t4;                                                 \
+       EX(ldd  [src + off + 0x10], t4);                                                \
        addxcc  t1, sum, sum;                                                           \
-       ldd     [src + off + 0x18], t6;                                                 \
+       EX(ldd  [src + off + 0x18], t6);                                                \
        addxcc  t2, sum, sum;                                                           \
-       std     t0, [dst + off + 0x00];                                                 \
+       EX(std  t0, [dst + off + 0x00]);                                                \
        addxcc  t3, sum, sum;                                                           \
-       std     t2, [dst + off + 0x08];                                                 \
+       EX(std  t2, [dst + off + 0x08]);                                                \
        addxcc  t4, sum, sum;                                                           \
-       std     t4, [dst + off + 0x10];                                                 \
+       EX(std  t4, [dst + off + 0x10]);                                                \
        addxcc  t5, sum, sum;                                                           \
-       std     t6, [dst + off + 0x18];                                                 \
+       EX(std  t6, [dst + off + 0x18]);                                                \
        addxcc  t6, sum, sum;                                                           \
        addxcc  t7, sum, sum;
 
@@ -191,39 +184,39 @@ cpout:    retl                                            ! get outta here
         * Viking MXCC into streaming mode.  Ho hum...
         */
 #define CSUMCOPY_BIGCHUNK(src, dst, sum, off, t0, t1, t2, t3, t4, t5, t6, t7)  \
-       ldd     [src + off + 0x00], t0;                                         \
-       ldd     [src + off + 0x08], t2;                                         \
-       ldd     [src + off + 0x10], t4;                                         \
-       ldd     [src + off + 0x18], t6;                                         \
-       st      t0, [dst + off + 0x00];                                         \
+       EX(ldd  [src + off + 0x00], t0);                                        \
+       EX(ldd  [src + off + 0x08], t2);                                        \
+       EX(ldd  [src + off + 0x10], t4);                                        \
+       EX(ldd  [src + off + 0x18], t6);                                        \
+       EX(st   t0, [dst + off + 0x00]);                                        \
        addxcc  t0, sum, sum;                                                   \
-       st      t1, [dst + off + 0x04];                                         \
+       EX(st   t1, [dst + off + 0x04]);                                        \
        addxcc  t1, sum, sum;                                                   \
-       st      t2, [dst + off + 0x08];                                         \
+       EX(st   t2, [dst + off + 0x08]);                                        \
        addxcc  t2, sum, sum;                                                   \
-       st      t3, [dst + off + 0x0c];                                         \
+       EX(st   t3, [dst + off + 0x0c]);                                        \
        addxcc  t3, sum, sum;                                                   \
-       st      t4, [dst + off + 0x10];                                         \
+       EX(st   t4, [dst + off + 0x10]);                                        \
        addxcc  t4, sum, sum;                                                   \
-       st      t5, [dst + off + 0x14];                                         \
+       EX(st   t5, [dst + off + 0x14]);                                        \
        addxcc  t5, sum, sum;                                                   \
-       st      t6, [dst + off + 0x18];                                         \
+       EX(st   t6, [dst + off + 0x18]);                                        \
        addxcc  t6, sum, sum;                                                   \
-       st      t7, [dst + off + 0x1c];                                         \
+       EX(st   t7, [dst + off + 0x1c]);                                        \
        addxcc  t7, sum, sum;
 
        /* Yuck, 6 superscalar cycles... */
 #define CSUMCOPY_LASTCHUNK(src, dst, sum, off, t0, t1, t2, t3) \
-       ldd     [src - off - 0x08], t0;                         \
-       ldd     [src - off - 0x00], t2;                         \
+       EX(ldd  [src - off - 0x08], t0);                        \
+       EX(ldd  [src - off - 0x00], t2);                        \
        addxcc  t0, sum, sum;                                   \
-       st      t0, [dst - off - 0x08];                         \
+       EX(st   t0, [dst - off - 0x08]);                        \
        addxcc  t1, sum, sum;                                   \
-       st      t1, [dst - off - 0x04];                         \
+       EX(st   t1, [dst - off - 0x04]);                        \
        addxcc  t2, sum, sum;                                   \
-       st      t2, [dst - off - 0x00];                         \
+       EX(st   t2, [dst - off - 0x00]);                        \
        addxcc  t3, sum, sum;                                   \
-       st      t3, [dst - off + 0x04];
+       EX(st   t3, [dst - off + 0x04]);
 
        /* Handle the end cruft code out of band for better cache patterns. */
 cc_end_cruft:
@@ -331,7 +324,6 @@ __csum_partial_copy_sparc_generic:
        CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
        CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
        CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
-10:    EXT(5b, 10b)                    ! note for exception handling
        sub     %g1, 128, %g1           ! detract from length
        addx    %g0, %g7, %g7           ! add in last carry bit
        andcc   %g1, 0xffffff80, %g0    ! more to csum?
@@ -356,8 +348,7 @@ cctbl:      CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x68,%g2,%g3,%g4,%g5)
        CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x28,%g2,%g3,%g4,%g5)
        CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x18,%g2,%g3,%g4,%g5)
        CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x08,%g2,%g3,%g4,%g5)
-12:    EXT(cctbl, 12b)                 ! note for exception table handling
-       addx    %g0, %g7, %g7
+12:    addx    %g0, %g7, %g7
        andcc   %o3, 0xf, %g0           ! check for low bits set
 ccte:  bne     cc_end_cruft            ! something left, handle it out of band
         andcc  %o3, 8, %g0             ! begin checks for that code
@@ -367,7 +358,6 @@ ccdbl:      CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x00,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o
        CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
        CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
        CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
-11:    EXT(ccdbl, 11b)                 ! note for exception table handling
        sub     %g1, 128, %g1           ! detract from length
        addx    %g0, %g7, %g7           ! add in last carry bit
        andcc   %g1, 0xffffff80, %g0    ! more to csum?
index dc72f2b970b7b3328b0ccc1566c2d64951669abf..954572c78539aeff5a84fedd211d3dfb4465bfea 100644 (file)
 /* Work around cpp -rob */
 #define ALLOC #alloc
 #define EXECINSTR #execinstr
+
+#define EX_ENTRY(l1, l2)                       \
+       .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   l1, l2;                         \
+       .text;
+
 #define EX(x,y,a,b)                            \
 98:    x,y;                                    \
        .section .fixup,ALLOC,EXECINSTR;        \
        .align  4;                              \
-99:    ba fixupretl;                           \
-        a, b, %g3;                             \
-       .section __ex_table,ALLOC;              \
-       .align  4;                              \
-       .word   98b, 99b;                       \
-       .text;                                  \
-       .align  4
+99:    retl;                                   \
+        a, b, %o0;                             \
+       EX_ENTRY(98b, 99b)
 
 #define EX2(x,y,c,d,e,a,b)                     \
 98:    x,y;                                    \
        .section .fixup,ALLOC,EXECINSTR;        \
        .align  4;                              \
 99:    c, d, e;                                \
-       ba fixupretl;                           \
-        a, b, %g3;                             \
-       .section __ex_table,ALLOC;              \
-       .align  4;                              \
-       .word   98b, 99b;                       \
-       .text;                                  \
-       .align  4
+       retl;                                   \
+        a, b, %o0;                             \
+       EX_ENTRY(98b, 99b)
 
 #define EXO2(x,y)                              \
 98:    x, y;                                   \
-       .section __ex_table,ALLOC;              \
-       .align  4;                              \
-       .word   98b, 97f;                       \
-       .text;                                  \
-       .align  4
+       EX_ENTRY(98b, 97f)
 
-#define EXT(start,end,handler)                 \
-       .section __ex_table,ALLOC;              \
-       .align  4;                              \
-       .word   start, 0, end, handler;         \
-       .text;                                  \
-       .align  4
+#define LD(insn, src, offset, reg, label)      \
+98:    insn [%src + (offset)], %reg;           \
+       .section .fixup,ALLOC,EXECINSTR;        \
+99:    ba      label;                          \
+        mov    offset, %g5;                    \
+       EX_ENTRY(98b, 99b)
 
-/* Please do not change following macros unless you change logic used
- * in .fixup at the end of this file as well
- */
+#define ST(insn, dst, offset, reg, label)      \
+98:    insn %reg, [%dst + (offset)];           \
+       .section .fixup,ALLOC,EXECINSTR;        \
+99:    ba      label;                          \
+        mov    offset, %g5;                    \
+       EX_ENTRY(98b, 99b)
 
 /* Both these macros have to start with exactly the same insn */
+/* left: g7 + (g1 % 128) - offset */
 #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
-       ldd     [%src + (offset) + 0x00], %t0; \
-       ldd     [%src + (offset) + 0x08], %t2; \
-       ldd     [%src + (offset) + 0x10], %t4; \
-       ldd     [%src + (offset) + 0x18], %t6; \
-       st      %t0, [%dst + (offset) + 0x00]; \
-       st      %t1, [%dst + (offset) + 0x04]; \
-       st      %t2, [%dst + (offset) + 0x08]; \
-       st      %t3, [%dst + (offset) + 0x0c]; \
-       st      %t4, [%dst + (offset) + 0x10]; \
-       st      %t5, [%dst + (offset) + 0x14]; \
-       st      %t6, [%dst + (offset) + 0x18]; \
-       st      %t7, [%dst + (offset) + 0x1c];
-
+       LD(ldd, src, offset + 0x00, t0, bigchunk_fault) \
+       LD(ldd, src, offset + 0x08, t2, bigchunk_fault) \
+       LD(ldd, src, offset + 0x10, t4, bigchunk_fault) \
+       LD(ldd, src, offset + 0x18, t6, bigchunk_fault) \
+       ST(st, dst, offset + 0x00, t0, bigchunk_fault)  \
+       ST(st, dst, offset + 0x04, t1, bigchunk_fault)  \
+       ST(st, dst, offset + 0x08, t2, bigchunk_fault)  \
+       ST(st, dst, offset + 0x0c, t3, bigchunk_fault)  \
+       ST(st, dst, offset + 0x10, t4, bigchunk_fault)  \
+       ST(st, dst, offset + 0x14, t5, bigchunk_fault)  \
+       ST(st, dst, offset + 0x18, t6, bigchunk_fault)  \
+       ST(st, dst, offset + 0x1c, t7, bigchunk_fault)
+
+/* left: g7 + (g1 % 128) - offset */
 #define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
-       ldd     [%src + (offset) + 0x00], %t0; \
-       ldd     [%src + (offset) + 0x08], %t2; \
-       ldd     [%src + (offset) + 0x10], %t4; \
-       ldd     [%src + (offset) + 0x18], %t6; \
-       std     %t0, [%dst + (offset) + 0x00]; \
-       std     %t2, [%dst + (offset) + 0x08]; \
-       std     %t4, [%dst + (offset) + 0x10]; \
-       std     %t6, [%dst + (offset) + 0x18];
+       LD(ldd, src, offset + 0x00, t0, bigchunk_fault) \
+       LD(ldd, src, offset + 0x08, t2, bigchunk_fault) \
+       LD(ldd, src, offset + 0x10, t4, bigchunk_fault) \
+       LD(ldd, src, offset + 0x18, t6, bigchunk_fault) \
+       ST(std, dst, offset + 0x00, t0, bigchunk_fault) \
+       ST(std, dst, offset + 0x08, t2, bigchunk_fault) \
+       ST(std, dst, offset + 0x10, t4, bigchunk_fault) \
+       ST(std, dst, offset + 0x18, t6, bigchunk_fault)
 
+       .section .fixup,#alloc,#execinstr
+bigchunk_fault:
+       sub     %g7, %g5, %o0
+       and     %g1, 127, %g1
+       retl
+        add    %o0, %g1, %o0
+
+/* left: offset + 16 + (g1 % 16) */
 #define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
-       ldd     [%src - (offset) - 0x10], %t0; \
-       ldd     [%src - (offset) - 0x08], %t2; \
-       st      %t0, [%dst - (offset) - 0x10]; \
-       st      %t1, [%dst - (offset) - 0x0c]; \
-       st      %t2, [%dst - (offset) - 0x08]; \
-       st      %t3, [%dst - (offset) - 0x04];
+       LD(ldd, src, -(offset + 0x10), t0, lastchunk_fault)     \
+       LD(ldd, src, -(offset + 0x08), t2, lastchunk_fault)     \
+       ST(st, dst, -(offset + 0x10), t0, lastchunk_fault)      \
+       ST(st, dst, -(offset + 0x0c), t1, lastchunk_fault)      \
+       ST(st, dst, -(offset + 0x08), t2, lastchunk_fault)      \
+       ST(st, dst, -(offset + 0x04), t3, lastchunk_fault)
 
-#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \
-       lduh    [%src + (offset) + 0x00], %t0; \
-       lduh    [%src + (offset) + 0x02], %t1; \
-       lduh    [%src + (offset) + 0x04], %t2; \
-       lduh    [%src + (offset) + 0x06], %t3; \
-       sth     %t0, [%dst + (offset) + 0x00]; \
-       sth     %t1, [%dst + (offset) + 0x02]; \
-       sth     %t2, [%dst + (offset) + 0x04]; \
-       sth     %t3, [%dst + (offset) + 0x06];
+       .section .fixup,#alloc,#execinstr
+lastchunk_fault:
+       and     %g1, 15, %g1
+       retl
+        sub    %g1, %g5, %o0
 
+/* left: o3 + (o2 % 16) - offset */
+#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \
+       LD(lduh, src, offset + 0x00, t0, halfchunk_fault)       \
+       LD(lduh, src, offset + 0x02, t1, halfchunk_fault)       \
+       LD(lduh, src, offset + 0x04, t2, halfchunk_fault)       \
+       LD(lduh, src, offset + 0x06, t3, halfchunk_fault)       \
+       ST(sth, dst, offset + 0x00, t0, halfchunk_fault)        \
+       ST(sth, dst, offset + 0x02, t1, halfchunk_fault)        \
+       ST(sth, dst, offset + 0x04, t2, halfchunk_fault)        \
+       ST(sth, dst, offset + 0x06, t3, halfchunk_fault)
+
+/* left: o3 + (o2 % 16) + offset + 2 */
 #define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
-       ldub    [%src - (offset) - 0x02], %t0; \
-       ldub    [%src - (offset) - 0x01], %t1; \
-       stb     %t0, [%dst - (offset) - 0x02]; \
-       stb     %t1, [%dst - (offset) - 0x01];
+       LD(ldub, src, -(offset + 0x02), t0, halfchunk_fault)    \
+       LD(ldub, src, -(offset + 0x01), t1, halfchunk_fault)    \
+       ST(stb, dst, -(offset + 0x02), t0, halfchunk_fault)     \
+       ST(stb, dst, -(offset + 0x01), t1, halfchunk_fault)
+
+       .section .fixup,#alloc,#execinstr
+halfchunk_fault:
+       and     %o2, 15, %o2
+       sub     %o3, %g5, %o3
+       retl
+        add    %o2, %o3, %o0
+
+/* left: offset + 2 + (o2 % 2) */
+#define MOVE_LAST_SHORTCHUNK(src, dst, offset, t0, t1) \
+       LD(ldub, src, -(offset + 0x02), t0, last_shortchunk_fault)      \
+       LD(ldub, src, -(offset + 0x01), t1, last_shortchunk_fault)      \
+       ST(stb, dst, -(offset + 0x02), t0, last_shortchunk_fault)       \
+       ST(stb, dst, -(offset + 0x01), t1, last_shortchunk_fault)
+
+       .section .fixup,#alloc,#execinstr
+last_shortchunk_fault:
+       and     %o2, 1, %o2
+       retl
+        sub    %o2, %g5, %o0
 
        .text
        .align  4
@@ -182,8 +218,6 @@ __copy_user:        /* %o0=dst %o1=src %o2=len */
        MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
        MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
        MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-80:
-       EXT(5b, 80b, 50f)
        subcc   %g7, 128, %g7
        add     %o1, 128, %o1
        bne     5b
@@ -201,7 +235,6 @@ __copy_user:        /* %o0=dst %o1=src %o2=len */
        jmpl    %o5 + %lo(copy_user_table_end), %g0
         add    %o0, %g7, %o0
 
-copy_user_table:
        MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
        MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
        MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
@@ -210,7 +243,6 @@ copy_user_table:
        MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
        MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
 copy_user_table_end:
-       EXT(copy_user_table, copy_user_table_end, 51f)
        be      copy_user_last7
         andcc  %g1, 4, %g0
 
@@ -250,8 +282,6 @@ ldd_std:
        MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
        MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
        MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-81:
-       EXT(ldd_std, 81b, 52f)
        subcc   %g7, 128, %g7
        add     %o1, 128, %o1
        bne     ldd_std
@@ -290,8 +320,6 @@ cannot_optimize:
 10:
        MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
        MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5)
-82:
-       EXT(10b, 82b, 53f)
        subcc   %o3, 0x10, %o3
        add     %o1, 0x10, %o1
        bne     10b
@@ -308,8 +336,6 @@ byte_chunk:
        MOVE_SHORTCHUNK(o1, o0, -0x0c, g2, g3)
        MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3)
        MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3)
-83:
-       EXT(byte_chunk, 83b, 54f)
        subcc   %o3, 0x10, %o3
        add     %o1, 0x10, %o1
        bne     byte_chunk
@@ -325,16 +351,14 @@ short_end:
        add     %o1, %o3, %o1
        jmpl    %o5 + %lo(short_table_end), %g0
         andcc  %o2, 1, %g0
-84:
-       MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
-       MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
-       MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
-       MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
-       MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
-       MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
-       MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x08, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x06, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x04, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x02, g2, g3)
+       MOVE_LAST_SHORTCHUNK(o1, o0, 0x00, g2, g3)
 short_table_end:
-       EXT(84b, short_table_end, 55f)
        be      1f
         nop
        EX(ldub [%o1], %g2, add %g0, 1)
@@ -363,123 +387,8 @@ short_aligned_end:
        .section .fixup,#alloc,#execinstr
        .align  4
 97:
-       mov     %o2, %g3
-fixupretl:
        retl
-        mov    %g3, %o0
-
-/* exception routine sets %g2 to (broken_insn - first_insn)>>2 */
-50:
-/* This magic counts how many bytes are left when crash in MOVE_BIGCHUNK
- * happens. This is derived from the amount ldd reads, st stores, etc.
- * x = g2 % 12;
- * g3 = g1 + g7 - ((g2 / 12) * 32 + (x < 4) ? 0 : (x - 4) * 4);
- * o0 += (g2 / 12) * 32;
- */
-       cmp     %g2, 12
-       add     %o0, %g7, %o0
-       bcs     1f
-        cmp    %g2, 24
-       bcs     2f
-        cmp    %g2, 36
-       bcs     3f
-        nop
-       sub     %g2, 12, %g2
-       sub     %g7, 32, %g7
-3:     sub     %g2, 12, %g2
-       sub     %g7, 32, %g7
-2:     sub     %g2, 12, %g2
-       sub     %g7, 32, %g7
-1:     cmp     %g2, 4
-       bcs,a   60f
-        clr    %g2
-       sub     %g2, 4, %g2
-       sll     %g2, 2, %g2
-60:    and     %g1, 0x7f, %g3
-       sub     %o0, %g7, %o0
-       add     %g3, %g7, %g3
-       ba      fixupretl
-        sub    %g3, %g2, %g3
-51:
-/* i = 41 - g2; j = i % 6;
- * g3 = (g1 & 15) + (i / 6) * 16 + (j < 4) ? (j + 1) * 4 : 16;
- * o0 -= (i / 6) * 16 + 16;
- */
-       neg     %g2
-       and     %g1, 0xf, %g1
-       add     %g2, 41, %g2
-       add     %o0, %g1, %o0
-1:     cmp     %g2, 6
-       bcs,a   2f
-        cmp    %g2, 4
-       add     %g1, 16, %g1
-       b       1b
-        sub    %g2, 6, %g2
-2:     bcc,a   2f
-        mov    16, %g2
-       inc     %g2
-       sll     %g2, 2, %g2
-2:     add     %g1, %g2, %g3
-       ba      fixupretl
-        sub    %o0, %g3, %o0
-52:
-/* g3 = g1 + g7 - (g2 / 8) * 32 + (g2 & 4) ? (g2 & 3) * 8 : 0;
-   o0 += (g2 / 8) * 32 */
-       andn    %g2, 7, %g4
-       add     %o0, %g7, %o0
-       andcc   %g2, 4, %g0
-       and     %g2, 3, %g2
-       sll     %g4, 2, %g4
-       sll     %g2, 3, %g2
-       bne     60b
-        sub    %g7, %g4, %g7
-       ba      60b
-        clr    %g2
-53:
-/* g3 = o3 + (o2 & 15) - (g2 & 8) - (g2 & 4) ? (g2 & 3) * 2 : 0;
-   o0 += (g2 & 8) */
-       and     %g2, 3, %g4
-       andcc   %g2, 4, %g0
-       and     %g2, 8, %g2
-       sll     %g4, 1, %g4
-       be      1f
-        add    %o0, %g2, %o0
-       add     %g2, %g4, %g2
-1:     and     %o2, 0xf, %g3
-       add     %g3, %o3, %g3
-       ba      fixupretl
-        sub    %g3, %g2, %g3
-54:
-/* g3 = o3 + (o2 & 15) - (g2 / 4) * 2 - (g2 & 2) ? (g2 & 1) : 0;
-   o0 += (g2 / 4) * 2 */
-       srl     %g2, 2, %o4
-       and     %g2, 1, %o5
-       srl     %g2, 1, %g2
-       add     %o4, %o4, %o4
-       and     %o5, %g2, %o5
-       and     %o2, 0xf, %o2
-       add     %o0, %o4, %o0
-       sub     %o3, %o5, %o3
-       sub     %o2, %o4, %o2
-       ba      fixupretl
-        add    %o2, %o3, %g3
-55:
-/* i = 27 - g2;
-   g3 = (o2 & 1) + i / 4 * 2 + !(i & 3);
-   o0 -= i / 4 * 2 + 1 */
-       neg     %g2
-       and     %o2, 1, %o2
-       add     %g2, 27, %g2
-       srl     %g2, 2, %o5
-       andcc   %g2, 3, %g0
-       mov     1, %g2
-       add     %o5, %o5, %o5
-       be,a    1f
-        clr    %g2
-1:     add     %g2, %o5, %g3
-       sub     %o0, %g3, %o0
-       ba      fixupretl
-        add    %g3, %o2, %g3
+        mov    %o2, %o0
 
        .globl  __copy_user_end
 __copy_user_end:
index f427f34b8b79bd6798fb90f756035d8f989d3909..eaff68213fdf58b86fb297d2ab844ad858da5dc0 100644 (file)
@@ -19,7 +19,7 @@
 98:    x,y;                                    \
        .section .fixup,ALLOC,EXECINSTR;        \
        .align  4;                              \
-99:    ba 30f;                                 \
+99:    retl;                                   \
         a, b, %o0;                             \
        .section __ex_table,ALLOC;              \
        .align  4;                              \
        .text;                                  \
        .align  4
 
-#define EXT(start,end,handler)                         \
+#define STORE(source, base, offset, n)         \
+98:    std source, [base + offset + n];        \
+       .section .fixup,ALLOC,EXECINSTR;        \
+       .align  4;                              \
+99:    ba 30f;                                 \
+        sub %o3, n - offset, %o3;              \
        .section __ex_table,ALLOC;              \
        .align  4;                              \
-       .word   start, 0, end, handler;         \
+       .word   98b, 99b;                       \
        .text;                                  \
-       .align  4
+       .align  4;
+
+#define STORE_LAST(source, base, offset, n)    \
+       EX(std source, [base - offset - n],     \
+          add %o1, offset + n);
 
 /* Please don't change these macros, unless you change the logic
  * in the .fixup section below as well.
  * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
-#define ZERO_BIG_BLOCK(base, offset, source)    \
-       std     source, [base + offset + 0x00]; \
-       std     source, [base + offset + 0x08]; \
-       std     source, [base + offset + 0x10]; \
-       std     source, [base + offset + 0x18]; \
-       std     source, [base + offset + 0x20]; \
-       std     source, [base + offset + 0x28]; \
-       std     source, [base + offset + 0x30]; \
-       std     source, [base + offset + 0x38];
+#define ZERO_BIG_BLOCK(base, offset, source)   \
+       STORE(source, base, offset, 0x00);      \
+       STORE(source, base, offset, 0x08);      \
+       STORE(source, base, offset, 0x10);      \
+       STORE(source, base, offset, 0x18);      \
+       STORE(source, base, offset, 0x20);      \
+       STORE(source, base, offset, 0x28);      \
+       STORE(source, base, offset, 0x30);      \
+       STORE(source, base, offset, 0x38);
 
 #define ZERO_LAST_BLOCKS(base, offset, source) \
-       std     source, [base - offset - 0x38]; \
-       std     source, [base - offset - 0x30]; \
-       std     source, [base - offset - 0x28]; \
-       std     source, [base - offset - 0x20]; \
-       std     source, [base - offset - 0x18]; \
-       std     source, [base - offset - 0x10]; \
-       std     source, [base - offset - 0x08]; \
-       std     source, [base - offset - 0x00];
+       STORE_LAST(source, base, offset, 0x38); \
+       STORE_LAST(source, base, offset, 0x30); \
+       STORE_LAST(source, base, offset, 0x28); \
+       STORE_LAST(source, base, offset, 0x20); \
+       STORE_LAST(source, base, offset, 0x18); \
+       STORE_LAST(source, base, offset, 0x10); \
+       STORE_LAST(source, base, offset, 0x08); \
+       STORE_LAST(source, base, offset, 0x00);
 
        .text
        .align 4
@@ -68,8 +77,6 @@ __bzero_begin:
        .globl  memset
        EXPORT_SYMBOL(__bzero)
        EXPORT_SYMBOL(memset)
-       .globl  __memset_start, __memset_end
-__memset_start:
 memset:
        mov     %o0, %g1
        mov     1, %g4
@@ -122,8 +129,6 @@ __bzero:
        ZERO_BIG_BLOCK(%o0, 0x00, %g2)
        subcc   %o3, 128, %o3
        ZERO_BIG_BLOCK(%o0, 0x40, %g2)
-11:
-       EXT(10b, 11b, 20f)
        bne     10b
         add    %o0, 128, %o0
 
@@ -138,11 +143,9 @@ __bzero:
        jmp     %o4
         add    %o0, %o2, %o0
 
-12:
        ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
        ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
 13:
-       EXT(12b, 13b, 21f)
        be      8f
         andcc  %o1, 4, %g0
 
@@ -182,37 +185,13 @@ __bzero:
 5:
        retl
         clr    %o0
-__memset_end:
 
        .section .fixup,#alloc,#execinstr
        .align  4
-20:
-       cmp     %g2, 8
-       bleu    1f
-        and    %o1, 0x7f, %o1
-       sub     %g2, 9, %g2
-       add     %o3, 64, %o3
-1:
-       sll     %g2, 3, %g2
-       add     %o3, %o1, %o0
-       b 30f
-        sub    %o0, %g2, %o0
-21:
-       mov     8, %o0
-       and     %o1, 7, %o1
-       sub     %o0, %g2, %o0
-       sll     %o0, 3, %o0
-       b 30f
-        add    %o0, %o1, %o0
 30:
-/* %o4 is faulting address, %o5 is %pc where fault occurred */
-       save    %sp, -104, %sp
-       mov     %i5, %o0
-       mov     %i7, %o1
-       call    lookup_fault
-        mov    %i4, %o2
-       ret
-        restore
+       and     %o1, 0x7f, %o1
+       retl
+        add    %o3, %o1, %o0
 
        .globl __bzero_end
 __bzero_end:
index 68db1f859b02857e979539d0b4408a6b0d26fe64..871354aa3c002b875defade17825d7600066fee4 100644 (file)
@@ -8,7 +8,7 @@ ccflags-y := -Werror
 obj-$(CONFIG_SPARC64)   += ultra.o tlb.o tsb.o
 obj-y                   += fault_$(BITS).o
 obj-y                   += init_$(BITS).o
-obj-$(CONFIG_SPARC32)   += extable.o srmmu.o iommu.o io-unit.o
+obj-$(CONFIG_SPARC32)   += srmmu.o iommu.o io-unit.o
 obj-$(CONFIG_SPARC32)   += srmmu_access.o
 obj-$(CONFIG_SPARC32)   += hypersparc.o viking.o tsunami.o swift.o
 obj-$(CONFIG_SPARC32)   += leon_mm.o
diff --git a/arch/sparc/mm/extable.c b/arch/sparc/mm/extable.c
deleted file mode 100644 (file)
index 241b406..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/sparc/mm/extable.c
- */
-
-#include <linux/module.h>
-#include <linux/extable.h>
-#include <linux/uaccess.h>
-
-void sort_extable(struct exception_table_entry *start,
-                 struct exception_table_entry *finish)
-{
-}
-
-/* Caller knows they are in a range if ret->fixup == 0 */
-const struct exception_table_entry *
-search_extable(const struct exception_table_entry *base,
-              const size_t num,
-              unsigned long value)
-{
-       int i;
-
-       /* Single insn entries are encoded as:
-        *      word 1: insn address
-        *      word 2: fixup code address
-        *
-        * Range entries are encoded as:
-        *      word 1: first insn address
-        *      word 2: 0
-        *      word 3: last insn address + 4 bytes
-        *      word 4: fixup code address
-        *
-        * Deleted entries are encoded as:
-        *      word 1: unused
-        *      word 2: -1
-        *
-        * See asm/uaccess.h for more details.
-        */
-
-       /* 1. Try to find an exact match. */
-       for (i = 0; i < num; i++) {
-               if (base[i].fixup == 0) {
-                       /* A range entry, skip both parts. */
-                       i++;
-                       continue;
-               }
-
-               /* A deleted entry; see trim_init_extable */
-               if (base[i].fixup == -1)
-                       continue;
-
-               if (base[i].insn == value)
-                       return &base[i];
-       }
-
-       /* 2. Try to find a range match. */
-       for (i = 0; i < (num - 1); i++) {
-               if (base[i].fixup)
-                       continue;
-
-               if (base[i].insn <= value && base[i + 1].insn > value)
-                       return &base[i];
-
-               i++;
-       }
-
-        return NULL;
-}
-
-#ifdef CONFIG_MODULES
-/* We could memmove them around; easier to mark the trimmed ones. */
-void trim_init_extable(struct module *m)
-{
-       unsigned int i;
-       bool range;
-
-       for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
-               range = m->extable[i].fixup == 0;
-
-               if (within_module_init(m->extable[i].insn, m)) {
-                       m->extable[i].fixup = -1;
-                       if (range)
-                               m->extable[i+1].fixup = -1;
-               }
-               if (range)
-                       i++;
-       }
-}
-#endif /* CONFIG_MODULES */
-
-/* Special extable search, which handles ranges.  Returns fixup */
-unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
-{
-       const struct exception_table_entry *entry;
-
-       entry = search_exception_tables(addr);
-       if (!entry)
-               return 0;
-
-       /* Inside range?  Fix g2 and return correct fixup */
-       if (!entry->fixup) {
-               *g2 = (addr - entry->insn) / 4;
-               return (entry + 1)->fixup;
-       }
-
-       return entry->fixup;
-}
index 40ce087dfecf24709ea6e5a5e6694970cbac1340..de2031c2b2d7982ebe39af78654e463c1cbfc5cd 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/kdebug.h>
 #include <linux/uaccess.h>
+#include <linux/extable.h>
 
 #include <asm/page.h>
 #include <asm/openprom.h>
@@ -54,54 +55,6 @@ static void __noreturn unhandled_fault(unsigned long address,
        die_if_kernel("Oops", regs);
 }
 
-asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
-                           unsigned long address)
-{
-       struct pt_regs regs;
-       unsigned long g2;
-       unsigned int insn;
-       int i;
-
-       i = search_extables_range(ret_pc, &g2);
-       switch (i) {
-       case 3:
-               /* load & store will be handled by fixup */
-               return 3;
-
-       case 1:
-               /* store will be handled by fixup, load will bump out */
-               /* for _to_ macros */
-               insn = *((unsigned int *) pc);
-               if ((insn >> 21) & 1)
-                       return 1;
-               break;
-
-       case 2:
-               /* load will be handled by fixup, store will bump out */
-               /* for _from_ macros */
-               insn = *((unsigned int *) pc);
-               if (!((insn >> 21) & 1) || ((insn>>19)&0x3f) == 15)
-                       return 2;
-               break;
-
-       default:
-               break;
-       }
-
-       memset(&regs, 0, sizeof(regs));
-       regs.pc = pc;
-       regs.npc = pc + 4;
-       __asm__ __volatile__(
-               "rd %%psr, %0\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n" : "=r" (regs.psr));
-       unhandled_fault(address, current, &regs);
-
-       /* Not reached */
-       return 0;
-}
-
 static inline void
 show_signal_msg(struct pt_regs *regs, int sig, int code,
                unsigned long address, struct task_struct *tsk)
@@ -162,8 +115,6 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
        struct vm_area_struct *vma;
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
-       unsigned int fixup;
-       unsigned long g2;
        int from_user = !(regs->psr & PSR_PS);
        int code;
        vm_fault_t fault;
@@ -281,30 +232,19 @@ bad_area_nosemaphore:
 
        /* Is this in ex_table? */
 no_context:
-       g2 = regs->u_regs[UREG_G2];
        if (!from_user) {
-               fixup = search_extables_range(regs->pc, &g2);
-               /* Values below 10 are reserved for other things */
-               if (fixup > 10) {
-                       extern const unsigned int __memset_start[];
-                       extern const unsigned int __memset_end[];
+               const struct exception_table_entry *entry;
 
+               entry = search_exception_tables(regs->pc);
 #ifdef DEBUG_EXCEPTIONS
-                       printk("Exception: PC<%08lx> faddr<%08lx>\n",
-                              regs->pc, address);
-                       printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n",
-                               regs->pc, fixup, g2);
+               printk("Exception: PC<%08lx> faddr<%08lx>\n",
+                      regs->pc, address);
+               printk("EX_TABLE: insn<%08lx> fixup<%08x>\n",
+                       regs->pc, entry->fixup);
 #endif
-                       if ((regs->pc >= (unsigned long)__memset_start &&
-                            regs->pc < (unsigned long)__memset_end)) {
-                               regs->u_regs[UREG_I4] = address;
-                               regs->u_regs[UREG_I5] = regs->pc;
-                       }
-                       regs->u_regs[UREG_G2] = g2;
-                       regs->pc = fixup;
-                       regs->npc = regs->pc + 4;
-                       return;
-               }
+               regs->pc = entry->fixup;
+               regs->npc = regs->pc + 4;
+               return;
        }
 
        unhandled_fault(address, tsk, regs);
index ce750a99eea96bb968bea7b2f4414dac752a7922..ee55f10806343aa07fa405b4452fc591c5ab22b6 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* fault_32.c - visible as they are called from assembler */
-asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
-                            unsigned long address);
 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
                                unsigned long address);
 
index 79e7a0ec1da584c39f6ce8a4d243324ce00a5b6e..6926d0ca6c71797ffcbbf4e3c3e532f80c8244c3 100644 (file)
@@ -1349,6 +1349,7 @@ st:                       if (is_imm8(insn->off))
                            insn->imm == (BPF_XOR | BPF_FETCH)) {
                                u8 *branch_target;
                                bool is64 = BPF_SIZE(insn->code) == BPF_DW;
+                               u32 real_src_reg = src_reg;
 
                                /*
                                 * Can't be implemented with a single x86 insn.
@@ -1357,6 +1358,9 @@ st:                       if (is_imm8(insn->off))
 
                                /* Will need RAX as a CMPXCHG operand so save R0 */
                                emit_mov_reg(&prog, true, BPF_REG_AX, BPF_REG_0);
+                               if (src_reg == BPF_REG_0)
+                                       real_src_reg = BPF_REG_AX;
+
                                branch_target = prog;
                                /* Load old value */
                                emit_ldx(&prog, BPF_SIZE(insn->code),
@@ -1366,9 +1370,9 @@ st:                       if (is_imm8(insn->off))
                                 * put the result in the AUX_REG.
                                 */
                                emit_mov_reg(&prog, is64, AUX_REG, BPF_REG_0);
-                               maybe_emit_mod(&prog, AUX_REG, src_reg, is64);
+                               maybe_emit_mod(&prog, AUX_REG, real_src_reg, is64);
                                EMIT2(simple_alu_opcodes[BPF_OP(insn->imm)],
-                                     add_2reg(0xC0, AUX_REG, src_reg));
+                                     add_2reg(0xC0, AUX_REG, real_src_reg));
                                /* Attempt to swap in new value */
                                err = emit_atomic(&prog, BPF_CMPXCHG,
                                                  dst_reg, AUX_REG, insn->off,
@@ -1381,7 +1385,7 @@ st:                       if (is_imm8(insn->off))
                                 */
                                EMIT2(X86_JNE, -(prog - branch_target) - 2);
                                /* Return the pre-modification value */
-                               emit_mov_reg(&prog, is64, src_reg, BPF_REG_0);
+                               emit_mov_reg(&prog, is64, real_src_reg, BPF_REG_0);
                                /* Restore R0 after clobbering RAX */
                                emit_mov_reg(&prog, true, BPF_REG_0, BPF_REG_AX);
                                break;
index a3cc33091f46c1039d48eeeeda2af6ec648caea7..17d80f751fcb2477fa16799261c6db8823941fcc 100644 (file)
@@ -741,7 +741,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
                map_ops[i].status = GNTST_general_error;
                unmap[0].host_addr = map_ops[i].host_addr,
                unmap[0].handle = map_ops[i].handle;
-               map_ops[i].handle = ~0;
+               map_ops[i].handle = INVALID_GRANT_HANDLE;
                if (map_ops[i].flags & GNTMAP_device_map)
                        unmap[0].dev_bus_addr = map_ops[i].dev_bus_addr;
                else
@@ -751,7 +751,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
                        kmap_ops[i].status = GNTST_general_error;
                        unmap[1].host_addr = kmap_ops[i].host_addr,
                        unmap[1].handle = kmap_ops[i].handle;
-                       kmap_ops[i].handle = ~0;
+                       kmap_ops[i].handle = INVALID_GRANT_HANDLE;
                        if (kmap_ops[i].flags & GNTMAP_device_map)
                                unmap[1].dev_bus_addr = kmap_ops[i].dev_bus_addr;
                        else
@@ -776,7 +776,6 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
 out:
        return ret;
 }
-EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
 
 int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
                              struct gnttab_unmap_grant_ref *kunmap_ops,
@@ -802,7 +801,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping);
 
 #ifdef CONFIG_XEN_DEBUG_FS
 #include <linux/debugfs.h>
index 15c9c28d9f5333866cd179accc1bb030741aca2d..5809cc198fa7c35dcc087447e8e7c244a41a885a 100644 (file)
@@ -767,7 +767,7 @@ config CRYPTO_POLY1305_X86_64
 
 config CRYPTO_POLY1305_MIPS
        tristate "Poly1305 authenticator algorithm (MIPS optimized)"
-       depends on CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
+       depends on MIPS
        select CRYPTO_ARCH_HAVE_LIB_POLY1305
 
 config CRYPTO_MD4
index 316a9947541fe005fac119697fe93c70f70f9051..b574cce98dc3686ce473b1f2cc132b4de8616ed2 100644 (file)
@@ -2260,7 +2260,8 @@ out:
        return rc;
 
 err_eni_release:
-       eni_do_release(dev);
+       dev->phy = NULL;
+       iounmap(ENI_DEV(dev)->ioaddr);
 err_unregister:
        atm_dev_deregister(dev);
 err_free_consistent:
index 3c081b6171a8fc39ffd3ac2535533861ffc14d9f..bfca7b8a6f31e8c04b3dd6be960c45bbb8029021 100644 (file)
@@ -262,7 +262,7 @@ static int idt77105_start(struct atm_dev *dev)
 {
        unsigned long flags;
 
-       if (!(dev->dev_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL)))
+       if (!(dev->phy_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL)))
                return -ENOMEM;
        PRIV(dev)->dev = dev;
        spin_lock_irqsave(&idt77105_priv_lock, flags);
@@ -337,7 +337,7 @@ static int idt77105_stop(struct atm_dev *dev)
                 else
                     idt77105_all = walk->next;
                dev->phy = NULL;
-                dev->dev_data = NULL;
+                dev->phy_data = NULL;
                 kfree(walk);
                 break;
             }
index d7277c26e423239e6e6971b7c6ba5f44a9e33d54..32d7aa141d96633dd9198cd1a6a0ded5baf3bcf5 100644 (file)
@@ -2233,6 +2233,7 @@ static int lanai_dev_open(struct atm_dev *atmdev)
        conf1_write(lanai);
 #endif
        iounmap(lanai->base);
+       lanai->base = NULL;
     error_pci:
        pci_disable_device(lanai->pci);
     error:
@@ -2245,6 +2246,8 @@ static int lanai_dev_open(struct atm_dev *atmdev)
 static void lanai_dev_close(struct atm_dev *atmdev)
 {
        struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
+       if (lanai->base==NULL)
+               return;
        printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n",
            lanai->number);
        lanai_timed_poll_stop(lanai);
@@ -2552,7 +2555,7 @@ static int lanai_init_one(struct pci_dev *pci,
        struct atm_dev *atmdev;
        int result;
 
-       lanai = kmalloc(sizeof(*lanai), GFP_KERNEL);
+       lanai = kzalloc(sizeof(*lanai), GFP_KERNEL);
        if (lanai == NULL) {
                printk(KERN_ERR DEV_LABEL
                       ": couldn't allocate dev_data structure!\n");
index 7850758b5bb82bb736adf02c8f438076846786f2..239852d855589440f41075bd5e919627bc34fcf1 100644 (file)
@@ -211,7 +211,7 @@ static void uPD98402_int(struct atm_dev *dev)
 static int uPD98402_start(struct atm_dev *dev)
 {
        DPRINTK("phy_start\n");
-       if (!(dev->dev_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL)))
+       if (!(dev->phy_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL)))
                return -ENOMEM;
        spin_lock_init(&PRIV(dev)->lock);
        memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
index 8038a8a9fb581a457dedcc48353b2a092e0b614e..f4949b689bd5ad5a6fe6633a4b812f1d92c8e818 100644 (file)
@@ -54,10 +54,9 @@ static int pseries_rng_probe(struct vio_dev *dev,
        return hwrng_register(&pseries_rng);
 }
 
-static int pseries_rng_remove(struct vio_dev *dev)
+static void pseries_rng_remove(struct vio_dev *dev)
 {
        hwrng_unregister(&pseries_rng);
-       return 0;
 }
 
 static const struct vio_device_id pseries_rng_driver_ids[] = {
index 994385bf37c0c044181f0ec2743779d80e09b38b..903604769de99cf2aa98e68145a3caa9f8a23e30 100644 (file)
@@ -343,7 +343,7 @@ static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
  *
  * Return: Always 0.
  */
-static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
+static void tpm_ibmvtpm_remove(struct vio_dev *vdev)
 {
        struct tpm_chip *chip = dev_get_drvdata(&vdev->dev);
        struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
@@ -372,8 +372,6 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
        kfree(ibmvtpm);
        /* For tpm_ibmvtpm_get_desired_dma */
        dev_set_drvdata(&vdev->dev, NULL);
-
-       return 0;
 }
 
 /**
index 3ba2f716fe9783c829e99b6bff345098ba0b477f..5e07065ec22f7420483897314247834567800ae1 100644 (file)
@@ -103,6 +103,8 @@ static const struct of_device_id whitelist[] __initconst = {
 static const struct of_device_id blacklist[] __initconst = {
        { .compatible = "allwinner,sun50i-h6", },
 
+       { .compatible = "arm,vexpress", },
+
        { .compatible = "calxeda,highbank", },
        { .compatible = "calxeda,ecx-2000", },
 
index d3c23447b892d3e87c0fadb25351c5404aa3485b..f86859bf76f11d9f68b8d64a7b33ab75e274f3d5 100644 (file)
@@ -317,9 +317,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
        }
 
        base = ioremap(res->start, resource_size(res));
-       if (IS_ERR(base)) {
+       if (!base) {
                dev_err(dev, "failed to map resource %pR\n", res);
-               ret = PTR_ERR(base);
+               ret = -ENOMEM;
                goto release_region;
        }
 
@@ -374,7 +374,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 error:
        kfree(data);
 unmap_base:
-       iounmap(data->base);
+       iounmap(base);
 release_region:
        release_mem_region(res->start, resource_size(res));
        return ret;
index 2de5e3672e4233e0ab3673c04627146129ff5d64..cc8dd3072b8b77f0b9acb4971d80a68d1e3718fc 100644 (file)
@@ -1042,7 +1042,7 @@ error:
        return ret;
 }
 
-static int nx842_remove(struct vio_dev *viodev)
+static void nx842_remove(struct vio_dev *viodev)
 {
        struct nx842_devdata *old_devdata;
        unsigned long flags;
@@ -1063,8 +1063,6 @@ static int nx842_remove(struct vio_dev *viodev)
        if (old_devdata)
                kfree(old_devdata->counters);
        kfree(old_devdata);
-
-       return 0;
 }
 
 static const struct vio_device_id nx842_vio_driver_ids[] = {
index 0d2dc5be7f1925f55f930edc651b2e7c8483c56a..1d0e8a1ba160507337f71ebb8d541ec7c09d76e5 100644 (file)
@@ -783,7 +783,7 @@ static int nx_probe(struct vio_dev *viodev, const struct vio_device_id *id)
        return nx_register_algs();
 }
 
-static int nx_remove(struct vio_dev *viodev)
+static void nx_remove(struct vio_dev *viodev)
 {
        dev_dbg(&viodev->dev, "entering nx_remove for UA 0x%x\n",
                viodev->unit_address);
@@ -811,8 +811,6 @@ static int nx_remove(struct vio_dev *viodev)
                nx_unregister_skcipher(&nx_ecb_aes_alg, NX_FC_AES,
                                       NX_MODE_AES_ECB);
        }
-
-       return 0;
 }
 
 
index b69d63143e0d833449f5701cd114257987109e4a..7bf0a7acae5e689f8f3470ead6b67dc54ac08f2c 100644 (file)
@@ -24,7 +24,7 @@ efi_status_t check_platform_features(void)
                return EFI_SUCCESS;
 
        tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_TGRAN_SHIFT) & 0xf;
-       if (tg != ID_AA64MMFR0_TGRAN_SUPPORTED) {
+       if (tg < ID_AA64MMFR0_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_TGRAN_SUPPORTED_MAX) {
                if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
                        efi_err("This 64 KB granular kernel is not supported by your CPU\n");
                else
index 5ea09fd01544482aaadda083a0dae7de0f54a924..c91d0565159661967faa6a73ae0dfc9834fcfada 100644 (file)
@@ -113,8 +113,29 @@ MODULE_DEVICE_TABLE(i2c, pca953x_id);
 #ifdef CONFIG_GPIO_PCA953X_IRQ
 
 #include <linux/dmi.h>
-#include <linux/gpio.h>
-#include <linux/list.h>
+
+static const struct acpi_gpio_params pca953x_irq_gpios = { 0, 0, true };
+
+static const struct acpi_gpio_mapping pca953x_acpi_irq_gpios[] = {
+       { "irq-gpios", &pca953x_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER },
+       { }
+};
+
+static int pca953x_acpi_get_irq(struct device *dev)
+{
+       int ret;
+
+       ret = devm_acpi_dev_add_driver_gpios(dev, pca953x_acpi_irq_gpios);
+       if (ret)
+               dev_warn(dev, "can't add GPIO ACPI mapping\n");
+
+       ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0);
+       if (ret < 0)
+               return ret;
+
+       dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret);
+       return ret;
+}
 
 static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = {
        {
@@ -133,59 +154,6 @@ static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = {
        },
        {}
 };
-
-#ifdef CONFIG_ACPI
-static int pca953x_acpi_get_pin(struct acpi_resource *ares, void *data)
-{
-       struct acpi_resource_gpio *agpio;
-       int *pin = data;
-
-       if (acpi_gpio_get_irq_resource(ares, &agpio))
-               *pin = agpio->pin_table[0];
-       return 1;
-}
-
-static int pca953x_acpi_find_pin(struct device *dev)
-{
-       struct acpi_device *adev = ACPI_COMPANION(dev);
-       int pin = -ENOENT, ret;
-       LIST_HEAD(r);
-
-       ret = acpi_dev_get_resources(adev, &r, pca953x_acpi_get_pin, &pin);
-       acpi_dev_free_resource_list(&r);
-       if (ret < 0)
-               return ret;
-
-       return pin;
-}
-#else
-static inline int pca953x_acpi_find_pin(struct device *dev) { return -ENXIO; }
-#endif
-
-static int pca953x_acpi_get_irq(struct device *dev)
-{
-       int pin, ret;
-
-       pin = pca953x_acpi_find_pin(dev);
-       if (pin < 0)
-               return pin;
-
-       dev_info(dev, "Applying ACPI interrupt quirk (GPIO %d)\n", pin);
-
-       if (!gpio_is_valid(pin))
-               return -EINVAL;
-
-       ret = gpio_request(pin, "pca953x interrupt");
-       if (ret)
-               return ret;
-
-       ret = gpio_to_irq(pin);
-
-       /* When pin is used as an IRQ, no need to keep it requested */
-       gpio_free(pin);
-
-       return ret;
-}
 #endif
 
 static const struct acpi_device_id pca953x_acpi_ids[] = {
index e37a57d0a2f07f44a2bf4426b3909f97c0ab7e8b..1aacd2a5a1fd53560469dbd3571a7929f4a4e4ca 100644 (file)
@@ -174,7 +174,7 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
        int ret, value;
 
        ret = request_threaded_irq(event->irq, NULL, event->handler,
-                                  event->irqflags, "ACPI:Event", event);
+                                  event->irqflags | IRQF_ONESHOT, "ACPI:Event", event);
        if (ret) {
                dev_err(acpi_gpio->chip->parent,
                        "Failed to setup interrupt handler for %d\n",
@@ -677,6 +677,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
        if (!lookup->desc) {
                const struct acpi_resource_gpio *agpio = &ares->data.gpio;
                bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
+               struct gpio_desc *desc;
                u16 pin_index;
 
                if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint)
@@ -689,8 +690,12 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
                if (pin_index >= agpio->pin_table_length)
                        return 1;
 
-               lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
+               if (lookup->info.quirks & ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER)
+                       desc = gpio_to_desc(agpio->pin_table[pin_index]);
+               else
+                       desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
                                              agpio->pin_table[pin_index]);
+               lookup->desc = desc;
                lookup->info.pin_config = agpio->pin_config;
                lookup->info.debounce = agpio->debounce_timeout;
                lookup->info.gpioint = gpioint;
@@ -940,8 +945,9 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
 }
 
 /**
- * acpi_dev_gpio_irq_get() - Find GpioInt and translate it to Linux IRQ number
+ * acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number
  * @adev: pointer to a ACPI device to get IRQ from
+ * @name: optional name of GpioInt resource
  * @index: index of GpioInt resource (starting from %0)
  *
  * If the device has one or more GpioInt resources, this function can be
@@ -951,9 +957,12 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
  * The function is idempotent, though each time it runs it will configure GPIO
  * pin direction according to the flags in GpioInt resource.
  *
+ * The function takes optional @name parameter. If the resource has a property
+ * name, then only those will be taken into account.
+ *
  * Return: Linux IRQ number (> %0) on success, negative errno on failure.
  */
-int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
+int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index)
 {
        int idx, i;
        unsigned int irq_flags;
@@ -963,7 +972,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
                struct acpi_gpio_info info;
                struct gpio_desc *desc;
 
-               desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
+               desc = acpi_get_gpiod_by_index(adev, name, i, &info);
 
                /* Ignore -EPROBE_DEFER, it only matters if idx matches */
                if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
@@ -1008,7 +1017,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
        }
        return -ENOENT;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
+EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by);
 
 static acpi_status
 acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
index adf55db080d86f1d3c07832972e2a468e53380e3..7ec0822c050553627a1414e7c5ac231d5d44a4a0 100644 (file)
@@ -367,22 +367,18 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc)
  *
  * Looks for device property "gpio-line-names" and if it exists assigns
  * GPIO line names for the chip. The memory allocated for the assigned
- * names belong to the underlying software node and should not be released
+ * names belong to the underlying firmware node and should not be released
  * by the caller.
  */
 static int devprop_gpiochip_set_names(struct gpio_chip *chip)
 {
        struct gpio_device *gdev = chip->gpiodev;
-       struct device *dev = chip->parent;
+       struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
        const char **names;
        int ret, i;
        int count;
 
-       /* GPIO chip may not have a parent device whose properties we inspect. */
-       if (!dev)
-               return 0;
-
-       count = device_property_string_array_count(dev, "gpio-line-names");
+       count = fwnode_property_string_array_count(fwnode, "gpio-line-names");
        if (count < 0)
                return 0;
 
@@ -396,7 +392,7 @@ static int devprop_gpiochip_set_names(struct gpio_chip *chip)
        if (!names)
                return -ENOMEM;
 
-       ret = device_property_read_string_array(dev, "gpio-line-names",
+       ret = fwnode_property_read_string_array(fwnode, "gpio-line-names",
                                                names, count);
        if (ret < 0) {
                dev_warn(&gdev->dev, "failed to read GPIO line names\n");
@@ -474,9 +470,13 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid);
 
 static void gpiodevice_release(struct device *dev)
 {
-       struct gpio_device *gdev = dev_get_drvdata(dev);
+       struct gpio_device *gdev = container_of(dev, struct gpio_device, dev);
+       unsigned long flags;
 
+       spin_lock_irqsave(&gpio_lock, flags);
        list_del(&gdev->list);
+       spin_unlock_irqrestore(&gpio_lock, flags);
+
        ida_free(&gpio_ida, gdev->id);
        kfree_const(gdev->label);
        kfree(gdev->descs);
@@ -605,7 +605,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
                goto err_free_ida;
 
        device_initialize(&gdev->dev);
-       dev_set_drvdata(&gdev->dev, gdev);
        if (gc->parent && gc->parent->driver)
                gdev->owner = gc->parent->driver->owner;
        else if (gc->owner)
index e392a90ca6876cc3dcec88baacb3bc4099bbac6c..85b79a7fee630b708868a1acb43ae61ea8accb10 100644 (file)
@@ -228,6 +228,7 @@ source "drivers/gpu/drm/arm/Kconfig"
 config DRM_RADEON
        tristate "ATI Radeon"
        depends on DRM && PCI && MMU
+       depends on AGP || !AGP
        select FW_LOADER
         select DRM_KMS_HELPER
         select DRM_TTM
index b6879d97c9c9c16fe055fb6c3cfee2f8491ab7fb..49267eb64302d28e010b23d15117d80f68693917 100644 (file)
@@ -180,6 +180,7 @@ extern uint amdgpu_smu_memory_pool_size;
 extern uint amdgpu_dc_feature_mask;
 extern uint amdgpu_dc_debug_mask;
 extern uint amdgpu_dm_abm_level;
+extern int amdgpu_backlight;
 extern struct amdgpu_mgpu_info mgpu_info;
 extern int amdgpu_ras_enable;
 extern uint amdgpu_ras_mask;
index 36a741d63ddcf602ca408e025b7b198b43157d2a..2e9b16fb3fcd149b2063b05a9c936e3f0e5a42f9 100644 (file)
@@ -903,7 +903,7 @@ void amdgpu_acpi_fini(struct amdgpu_device *adev)
  */
 bool amdgpu_acpi_is_s0ix_supported(struct amdgpu_device *adev)
 {
-#if defined(CONFIG_AMD_PMC)
+#if defined(CONFIG_AMD_PMC) || defined(CONFIG_AMD_PMC_MODULE)
        if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
                if (adev->flags & AMD_IS_APU)
                        return true;
index 4575192d9b087a0e0336ea3618a6a22b0c557a37..b26e2fd1c538433899a2f9ec8249317c8543e258 100644 (file)
@@ -781,6 +781,10 @@ uint amdgpu_dm_abm_level;
 MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
 module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
 
+int amdgpu_backlight = -1;
+MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))");
+module_param_named(backlight, amdgpu_backlight, bint, 0444);
+
 /**
  * DOC: tmz (int)
  * Trusted Memory Zone (TMZ) is a method to protect data being written
index 51cd49c6f38fd06f58369e3265cafa5367573a3f..24010cacf7d0ec87f37b41a45b1c820f3f85882c 100644 (file)
@@ -146,7 +146,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
        size = mode_cmd->pitches[0] * height;
        aligned_size = ALIGN(size, PAGE_SIZE);
        ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, flags,
-                                      ttm_bo_type_kernel, NULL, &gobj);
+                                      ttm_bo_type_device, NULL, &gobj);
        if (ret) {
                pr_err("failed to allocate framebuffer (%d)\n", aligned_size);
                return -ENOMEM;
index 3e1fd1e7d09f1d4e3c017d5607bef69c19948a58..573cf17262da4e116154dc0bb199ef2fc9de4add 100644 (file)
@@ -2267,6 +2267,11 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
            caps->ext_caps->bits.hdr_aux_backlight_control == 1)
                caps->aux_support = true;
 
+       if (amdgpu_backlight == 0)
+               caps->aux_support = false;
+       else if (amdgpu_backlight == 1)
+               caps->aux_support = true;
+
        /* From the specification (CTA-861-G), for calculating the maximum
         * luminance we need to use:
         *      Luminance = 50*2**(CV/32)
@@ -3185,19 +3190,6 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
 #endif
 }
 
-static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness)
-{
-       bool rc;
-
-       if (!link)
-               return 1;
-
-       rc = dc_link_set_backlight_level_nits(link, true, brightness,
-                                             AUX_BL_DEFAULT_TRANSITION_TIME_MS);
-
-       return rc ? 0 : 1;
-}
-
 static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
                                unsigned *min, unsigned *max)
 {
@@ -3260,9 +3252,10 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
        brightness = convert_brightness_from_user(&caps, bd->props.brightness);
        // Change brightness based on AUX property
        if (caps.aux_support)
-               return set_backlight_via_aux(link, brightness);
-
-       rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0);
+               rc = dc_link_set_backlight_level_nits(link, true, brightness,
+                                                     AUX_BL_DEFAULT_TRANSITION_TIME_MS);
+       else
+               rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0);
 
        return rc ? 0 : 1;
 }
@@ -3270,11 +3263,27 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
 static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
 {
        struct amdgpu_display_manager *dm = bl_get_data(bd);
-       int ret = dc_link_get_backlight_level(dm->backlight_link);
+       struct amdgpu_dm_backlight_caps caps;
+
+       amdgpu_dm_update_backlight_caps(dm);
+       caps = dm->backlight_caps;
+
+       if (caps.aux_support) {
+               struct dc_link *link = (struct dc_link *)dm->backlight_link;
+               u32 avg, peak;
+               bool rc;
 
-       if (ret == DC_ERROR_UNEXPECTED)
-               return bd->props.brightness;
-       return convert_brightness_to_user(&dm->backlight_caps, ret);
+               rc = dc_link_get_backlight_level_nits(link, &avg, &peak);
+               if (!rc)
+                       return bd->props.brightness;
+               return convert_brightness_to_user(&caps, avg);
+       } else {
+               int ret = dc_link_get_backlight_level(dm->backlight_link);
+
+               if (ret == DC_ERROR_UNEXPECTED)
+                       return bd->props.brightness;
+               return convert_brightness_to_user(&caps, ret);
+       }
 }
 
 static const struct backlight_ops amdgpu_dm_backlight_ops = {
@@ -4716,6 +4725,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
        dc_plane_state->global_alpha_value = plane_info.global_alpha_value;
        dc_plane_state->dcc = plane_info.dcc;
        dc_plane_state->layer_index = plane_info.layer_index; // Always returns 0
+       dc_plane_state->flip_int_enabled = true;
 
        /*
         * Always set input transfer function, since plane state is refreshed
index fa5059f71727a16463d990e1ebd54c7fcc480634..bd0101013ec8926307f0fb0b42d536434eb761db 100644 (file)
@@ -2602,7 +2602,6 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
                        if (pipe_ctx->plane_state == NULL)
                                frame_ramp = 0;
                } else {
-                       ASSERT(false);
                        return false;
                }
 
index 4eee3a55fa3018ad0f65bfe50f1e949fbf4de7ac..18ed0d3f247eaec26a0b797603242bbf5e2b9348 100644 (file)
@@ -887,6 +887,7 @@ struct dc_plane_state {
        int layer_index;
 
        union surface_update_flags update_flags;
+       bool flip_int_enabled;
        /* private to DC core */
        struct dc_plane_status status;
        struct dc_context *ctx;
index 9e796dfeac2040ea26699b0505c980aaa504c28e..714c71a5fbde3f34e1e16915b5a00583f99fa221 100644 (file)
@@ -1257,6 +1257,16 @@ void hubp1_soft_reset(struct hubp *hubp, bool reset)
        REG_UPDATE(DCHUBP_CNTL, HUBP_DISABLE, reset ? 1 : 0);
 }
 
+void hubp1_set_flip_int(struct hubp *hubp)
+{
+       struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+
+       REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT,
+               SURFACE_FLIP_INT_MASK, 1);
+
+       return;
+}
+
 void hubp1_init(struct hubp *hubp)
 {
        //do nothing
@@ -1290,6 +1300,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = {
        .dmdata_load = NULL,
        .hubp_soft_reset = hubp1_soft_reset,
        .hubp_in_blank = hubp1_in_blank,
+       .hubp_set_flip_int = hubp1_set_flip_int,
 };
 
 /*****************************************/
index a9a6ed7f4f9932345954fbbdd78dd49760330131..e2f2f6995935f062f09443f73d63dca626badc30 100644 (file)
@@ -74,6 +74,7 @@
        SRI(DCSURF_SURFACE_EARLIEST_INUSE_C, HUBPREQ, id),\
        SRI(DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, HUBPREQ, id),\
        SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\
+       SRI(DCSURF_SURFACE_FLIP_INTERRUPT, HUBPREQ, id),\
        SRI(HUBPRET_CONTROL, HUBPRET, id),\
        SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\
        SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\
        uint32_t DCSURF_SURFACE_EARLIEST_INUSE_C; \
        uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C; \
        uint32_t DCSURF_SURFACE_CONTROL; \
+       uint32_t DCSURF_SURFACE_FLIP_INTERRUPT; \
        uint32_t HUBPRET_CONTROL; \
        uint32_t DCN_EXPANSION_MODE; \
        uint32_t DCHUBP_REQ_SIZE_CONFIG; \
        HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_META_SURFACE_TMZ_C, mask_sh),\
        HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\
        HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\
+       HUBP_SF(HUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK, mask_sh),\
        HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\
        HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\
        HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\
        type PRIMARY_SURFACE_DCC_IND_64B_BLK;\
        type SECONDARY_SURFACE_DCC_EN;\
        type SECONDARY_SURFACE_DCC_IND_64B_BLK;\
+       type SURFACE_FLIP_INT_MASK;\
        type DET_BUF_PLANE1_BASE_ADDRESS;\
        type CROSSBAR_SRC_CB_B;\
        type CROSSBAR_SRC_CR_R;\
@@ -777,4 +781,6 @@ void hubp1_read_state_common(struct hubp *hubp);
 bool hubp1_in_blank(struct hubp *hubp);
 void hubp1_soft_reset(struct hubp *hubp, bool reset);
 
+void hubp1_set_flip_int(struct hubp *hubp);
+
 #endif
index 89912bb5014f86fe5c57d756b6c209ea8eb02155..9ba5c624770ded1cf08683545bddc1bf50c3661d 100644 (file)
@@ -2196,6 +2196,13 @@ static void dcn10_enable_plane(
        if (dc->debug.sanity_checks) {
                hws->funcs.verify_allow_pstate_change_high(dc);
        }
+
+       if (!pipe_ctx->top_pipe
+               && pipe_ctx->plane_state
+               && pipe_ctx->plane_state->flip_int_enabled
+               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
+                       pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
+
 }
 
 void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
index 0df0da2e6a4d05f3c3256913273e41d066bf165f..bec7059f6d5d1579ed84b905f4f2bcd993bfd579 100644 (file)
@@ -1597,6 +1597,7 @@ static struct hubp_funcs dcn20_hubp_funcs = {
        .validate_dml_output = hubp2_validate_dml_output,
        .hubp_in_blank = hubp1_in_blank,
        .hubp_soft_reset = hubp1_soft_reset,
+       .hubp_set_flip_int = hubp1_set_flip_int,
 };
 
 
index 0726fb435e2a3c175138262f9f3151223aabf77e..5342c309b78c78164b7ad4cfda7e7478e34e450b 100644 (file)
@@ -1146,6 +1146,12 @@ void dcn20_enable_plane(
                pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
        }
 
+       if (!pipe_ctx->top_pipe
+               && pipe_ctx->plane_state
+               && pipe_ctx->plane_state->flip_int_enabled
+               && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int)
+                       pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp);
+
 //     if (dc->debug.sanity_checks) {
 //             dcn10_verify_allow_pstate_change_high(dc);
 //     }
index f9045852728fe5fb0a0b6f8416a0ac188e51a737..b0c9180b808f6cf577bde2704331cad17b173451 100644 (file)
@@ -838,6 +838,7 @@ static struct hubp_funcs dcn21_hubp_funcs = {
        .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
        .hubp_init = hubp21_init,
        .validate_dml_output = hubp21_validate_dml_output,
+       .hubp_set_flip_int = hubp1_set_flip_int,
 };
 
 bool hubp21_construct(
index 072f8c880924366ffd42477a3ffd79886611748a..173488ab787ac9df2ca06612e9cf8a2753a2ad59 100644 (file)
@@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
        .num_banks = 8,
        .num_chans = 4,
        .vmm_page_size_bytes = 4096,
-       .dram_clock_change_latency_us = 11.72,
+       .dram_clock_change_latency_us = 23.84,
        .return_bus_width_bytes = 64,
        .dispclk_dppclk_vco_speed_mhz = 3600,
        .xfc_bus_transport_time_us = 4,
@@ -1062,8 +1062,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s
 {
        int i;
 
-       DC_FP_START();
-
        if (dc->bb_overrides.sr_exit_time_ns) {
                for (i = 0; i < WM_SET_COUNT; i++) {
                          dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
@@ -1088,8 +1086,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s
                                dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
                }
        }
-
-       DC_FP_END();
 }
 
 void dcn21_calculate_wm(
@@ -1339,7 +1335,7 @@ static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc,
        int vlevel = 0;
        int pipe_split_from[MAX_PIPES];
        int pipe_cnt = 0;
-       display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
+       display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
        DC_LOGGER_INIT(dc->ctx->logger);
 
        BW_VAL_TRACE_COUNT();
index 88ffa9ff1ed15bd5d7e8e7184832fa6c5bd840e6..f246125232482c894f5440c9c6682924577c7f49 100644 (file)
@@ -511,6 +511,7 @@ static struct hubp_funcs dcn30_hubp_funcs = {
        .hubp_init = hubp3_init,
        .hubp_in_blank = hubp1_in_blank,
        .hubp_soft_reset = hubp1_soft_reset,
+       .hubp_set_flip_int = hubp1_set_flip_int,
 };
 
 bool hubp3_construct(
index 8d0f663489ac5a915330f7f1d689d299daed647f..fb7f1dea3c467e4f33aaf1228a9d62f7e3da2fd3 100644 (file)
@@ -2508,6 +2508,19 @@ static const struct resource_funcs dcn30_res_pool_funcs = {
        .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
 };
 
+#define CTX ctx
+
+#define REG(reg_name) \
+       (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
+
+static uint32_t read_pipe_fuses(struct dc_context *ctx)
+{
+       uint32_t value = REG_READ(CC_DC_PIPE_DIS);
+       /* Support for max 6 pipes */
+       value = value & 0x3f;
+       return value;
+}
+
 static bool dcn30_resource_construct(
        uint8_t num_virtual_links,
        struct dc *dc,
@@ -2517,6 +2530,15 @@ static bool dcn30_resource_construct(
        struct dc_context *ctx = dc->ctx;
        struct irq_service_init_data init_data;
        struct ddc_service_init_data ddc_init_data;
+       uint32_t pipe_fuses = read_pipe_fuses(ctx);
+       uint32_t num_pipes = 0;
+
+       if (!(pipe_fuses == 0 || pipe_fuses == 0x3e)) {
+               BREAK_TO_DEBUGGER();
+               dm_error("DC: Unexpected fuse recipe for navi2x !\n");
+               /* fault to single pipe */
+               pipe_fuses = 0x3e;
+       }
 
        DC_FP_START();
 
@@ -2650,6 +2672,15 @@ static bool dcn30_resource_construct(
        /* PP Lib and SMU interfaces */
        init_soc_bounding_box(dc, pool);
 
+       num_pipes = dcn3_0_ip.max_num_dpp;
+
+       for (i = 0; i < dcn3_0_ip.max_num_dpp; i++)
+               if (pipe_fuses & 1 << i)
+                       num_pipes--;
+
+       dcn3_0_ip.max_num_dpp = num_pipes;
+       dcn3_0_ip.max_num_otg = num_pipes;
+
        dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
 
        /* IRQ */
index 5d4b2c60192ee49763f318777ce4271cf5554feb..c494235016e09aac6814ab6d2cbcc22659fe9529 100644 (file)
@@ -1619,12 +1619,106 @@ static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b
        dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
 }
 
+static void calculate_wm_set_for_vlevel(
+               int vlevel,
+               struct wm_range_table_entry *table_entry,
+               struct dcn_watermarks *wm_set,
+               struct display_mode_lib *dml,
+               display_e2e_pipe_params_st *pipes,
+               int pipe_cnt)
+{
+       double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
+
+       ASSERT(vlevel < dml->soc.num_states);
+       /* only pipe 0 is read for voltage and dcf/soc clocks */
+       pipes[0].clks_cfg.voltage = vlevel;
+       pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
+       pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
+
+       dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
+       dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
+       dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
+
+       wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
+       wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
+       wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
+       wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
+       wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
+       wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
+       wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
+       wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
+       dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
+
+}
+
+static void dcn301_calculate_wm_and_dlg(
+               struct dc *dc, struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               int pipe_cnt,
+               int vlevel_req)
+{
+       int i, pipe_idx;
+       int vlevel, vlevel_max;
+       struct wm_range_table_entry *table_entry;
+       struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
+
+       ASSERT(bw_params);
+
+       vlevel_max = bw_params->clk_table.num_entries - 1;
+
+       /* WM Set D */
+       table_entry = &bw_params->wm_table.entries[WM_D];
+       if (table_entry->wm_type == WM_TYPE_RETRAINING)
+               vlevel = 0;
+       else
+               vlevel = vlevel_max;
+       calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
+                                               &context->bw_ctx.dml, pipes, pipe_cnt);
+       /* WM Set C */
+       table_entry = &bw_params->wm_table.entries[WM_C];
+       vlevel = min(max(vlevel_req, 2), vlevel_max);
+       calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
+                                               &context->bw_ctx.dml, pipes, pipe_cnt);
+       /* WM Set B */
+       table_entry = &bw_params->wm_table.entries[WM_B];
+       vlevel = min(max(vlevel_req, 1), vlevel_max);
+       calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
+                                               &context->bw_ctx.dml, pipes, pipe_cnt);
+
+       /* WM Set A */
+       table_entry = &bw_params->wm_table.entries[WM_A];
+       vlevel = min(vlevel_req, vlevel_max);
+       calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
+                                               &context->bw_ctx.dml, pipes, pipe_cnt);
+
+       for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+               if (!context->res_ctx.pipe_ctx[i].stream)
+                       continue;
+
+               pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
+               pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+
+               if (dc->config.forced_clocks) {
+                       pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+                       pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+               }
+               if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
+                       pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
+               if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
+                       pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
+
+               pipe_idx++;
+       }
+
+       dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+}
+
 static struct resource_funcs dcn301_res_pool_funcs = {
        .destroy = dcn301_destroy_resource_pool,
        .link_enc_create = dcn301_link_encoder_create,
        .panel_cntl_create = dcn301_panel_cntl_create,
        .validate_bandwidth = dcn30_validate_bandwidth,
-       .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
+       .calculate_wm_and_dlg = dcn301_calculate_wm_and_dlg,
        .populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
        .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
        .add_stream_to_ctx = dcn30_add_stream_to_ctx,
index 22f3f643ed1b865ea64af0aadae66a580271bb35..346dcd87dc10651b28bab509b314f21cb89f4c8e 100644 (file)
@@ -191,6 +191,8 @@ struct hubp_funcs {
        bool (*hubp_in_blank)(struct hubp *hubp);
        void (*hubp_soft_reset)(struct hubp *hubp, bool reset);
 
+       void (*hubp_set_flip_int)(struct hubp *hubp);
+
 };
 
 #endif
index c57dc9ae81f2f4e7af3dc1dd3d9537cca3c18eb3..a2681fe875ed6fb4a7242e5e3d36356f7e012d2e 100644 (file)
@@ -5216,10 +5216,10 @@ static int smu7_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
                for (j = 0; j < dep_sclk_table->count; j++) {
                        valid_entry = false;
                        for (k = 0; k < watermarks->num_wm_sets; k++) {
-                               if (dep_sclk_table->entries[i].clk / 10 >= watermarks->wm_clk_ranges[k].wm_min_eng_clk_in_khz &&
-                                   dep_sclk_table->entries[i].clk / 10 < watermarks->wm_clk_ranges[k].wm_max_eng_clk_in_khz &&
-                                   dep_mclk_table->entries[i].clk / 10 >= watermarks->wm_clk_ranges[k].wm_min_mem_clk_in_khz &&
-                                   dep_mclk_table->entries[i].clk / 10 < watermarks->wm_clk_ranges[k].wm_max_mem_clk_in_khz) {
+                               if (dep_sclk_table->entries[i].clk >= watermarks->wm_clk_ranges[k].wm_min_eng_clk_in_khz / 10 &&
+                                   dep_sclk_table->entries[i].clk < watermarks->wm_clk_ranges[k].wm_max_eng_clk_in_khz / 10 &&
+                                   dep_mclk_table->entries[i].clk >= watermarks->wm_clk_ranges[k].wm_min_mem_clk_in_khz / 10 &&
+                                   dep_mclk_table->entries[i].clk < watermarks->wm_clk_ranges[k].wm_max_mem_clk_in_khz / 10) {
                                        valid_entry = true;
                                        table->DisplayWatermark[i][j] = watermarks->wm_clk_ranges[k].wm_set_id;
                                        break;
index 29c99642d22d407e5613aef1f1264efb9cc30f86..22b636e2b89bed7b7e08ec369e7daf298d318bca 100644 (file)
@@ -1505,6 +1505,48 @@ static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr,
        return 0;
 }
 
+static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
+       struct vega10_hwmgr *data =
+                       (struct vega10_hwmgr *)(hwmgr->backend);
+       uint32_t pcie_gen = 0, pcie_width = 0;
+       PPTable_t *pp_table = &(data->smc_state_table.pp_table);
+       int i;
+
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
+               pcie_gen = 3;
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
+               pcie_gen = 2;
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
+               pcie_gen = 1;
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
+               pcie_gen = 0;
+
+       if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
+               pcie_width = 6;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
+               pcie_width = 5;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
+               pcie_width = 4;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
+               pcie_width = 3;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
+               pcie_width = 2;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
+               pcie_width = 1;
+
+       for (i = 0; i < NUM_LINK_LEVELS; i++) {
+               if (pp_table->PcieGenSpeed[i] > pcie_gen)
+                       pp_table->PcieGenSpeed[i] = pcie_gen;
+
+               if (pp_table->PcieLaneCount[i] > pcie_width)
+                       pp_table->PcieLaneCount[i] = pcie_width;
+       }
+
+       return 0;
+}
+
 static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr)
 {
        int result = -1;
@@ -2556,6 +2598,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
                        "Failed to initialize Link Level!",
                        return result);
 
+       result = vega10_override_pcie_parameters(hwmgr);
+       PP_ASSERT_WITH_CODE(!result,
+                       "Failed to override pcie parameters!",
+                       return result);
+
        result = vega10_populate_all_graphic_levels(hwmgr);
        PP_ASSERT_WITH_CODE(!result,
                        "Failed to initialize Graphics Level!",
@@ -2922,6 +2969,7 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
        return 0;
 }
 
+
 static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable)
 {
        struct vega10_hwmgr *data = hwmgr->backend;
index c0753029a8e2a9f6b1039ab906a2d354b047a463..43e01d880f7ce8bdc1313ef1c0cfb73499238fb5 100644 (file)
@@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state)
        dpm_state->hard_max_level = 0xffff;
 }
 
+static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
+       struct vega12_hwmgr *data =
+                       (struct vega12_hwmgr *)(hwmgr->backend);
+       uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg;
+       PPTable_t *pp_table = &(data->smc_state_table.pp_table);
+       int i;
+       int ret;
+
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
+               pcie_gen = 3;
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
+               pcie_gen = 2;
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
+               pcie_gen = 1;
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
+               pcie_gen = 0;
+
+       if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
+               pcie_width = 6;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
+               pcie_width = 5;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
+               pcie_width = 4;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
+               pcie_width = 3;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
+               pcie_width = 2;
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
+               pcie_width = 1;
+
+       /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1
+        * Bit 15:8:  PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
+        * Bit 7:0:   PCIE lane width, 1 to 7 corresponds is x1 to x32
+        */
+       for (i = 0; i < NUM_LINK_LEVELS; i++) {
+               pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen :
+                       pp_table->PcieGenSpeed[i];
+               pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width :
+                       pp_table->PcieLaneCount[i];
+
+               if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg !=
+                   pp_table->PcieLaneCount[i]) {
+                       smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg;
+                       ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+                               PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
+                               NULL);
+                       PP_ASSERT_WITH_CODE(!ret,
+                               "[OverridePcieParameters] Attempt to override pcie params failed!",
+                               return ret);
+               }
+
+               /* update the pptable */
+               pp_table->PcieGenSpeed[i] = pcie_gen_arg;
+               pp_table->PcieLaneCount[i] = pcie_width_arg;
+       }
+
+       return 0;
+}
+
 static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
                PPCLK_e clk_id, uint32_t *num_of_levels)
 {
@@ -968,6 +1029,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
                        "Failed to enable all smu features!",
                        return result);
 
+       result = vega12_override_pcie_parameters(hwmgr);
+       PP_ASSERT_WITH_CODE(!result,
+                       "[EnableDPMTasks] Failed to override pcie parameters!",
+                       return result);
+
        tmp_result = vega12_power_control_set_level(hwmgr);
        PP_ASSERT_WITH_CODE(!tmp_result,
                        "Failed to power control set level!",
index 87811b005b85f314c3c9491533a6867fc3123791..f19964c69a0027aaef02c5419a98d490553aeb45 100644 (file)
@@ -831,7 +831,9 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
        struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
        struct vega20_hwmgr *data =
                        (struct vega20_hwmgr *)(hwmgr->backend);
-       uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
+       uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg;
+       PPTable_t *pp_table = &(data->smc_state_table.pp_table);
+       int i;
        int ret;
 
        if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
@@ -860,17 +862,27 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
         * Bit 15:8:  PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
         * Bit 7:0:   PCIE lane width, 1 to 7 corresponds is x1 to x32
         */
-       smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;
-       ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-                       PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
-                       NULL);
-       PP_ASSERT_WITH_CODE(!ret,
-               "[OverridePcieParameters] Attempt to override pcie params failed!",
-               return ret);
+       for (i = 0; i < NUM_LINK_LEVELS; i++) {
+               pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen :
+                       pp_table->PcieGenSpeed[i];
+               pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width :
+                       pp_table->PcieLaneCount[i];
+
+               if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg !=
+                   pp_table->PcieLaneCount[i]) {
+                       smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg;
+                       ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+                               PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
+                               NULL);
+                       PP_ASSERT_WITH_CODE(!ret,
+                               "[OverridePcieParameters] Attempt to override pcie params failed!",
+                               return ret);
+               }
 
-       data->pcie_parameters_override = true;
-       data->pcie_gen_level1 = pcie_gen;
-       data->pcie_width_level1 = pcie_width;
+               /* update the pptable */
+               pp_table->PcieGenSpeed[i] = pcie_gen_arg;
+               pp_table->PcieLaneCount[i] = pcie_width_arg;
+       }
 
        return 0;
 }
@@ -3319,9 +3331,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                        data->od8_settings.od8_settings_array;
        OverDriveTable_t *od_table =
                        &(data->smc_state_table.overdrive_table);
-       struct phm_ppt_v3_information *pptable_information =
-               (struct phm_ppt_v3_information *)hwmgr->pptable;
-       PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable;
+       PPTable_t *pptable = &(data->smc_state_table.pp_table);
        struct pp_clock_levels_with_latency clocks;
        struct vega20_single_dpm_table *fclk_dpm_table =
                        &(data->dpm_table.fclk_table);
@@ -3420,13 +3430,9 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                current_lane_width =
                        vega20_get_current_pcie_link_width_level(hwmgr);
                for (i = 0; i < NUM_LINK_LEVELS; i++) {
-                       if (i == 1 && data->pcie_parameters_override) {
-                               gen_speed = data->pcie_gen_level1;
-                               lane_width = data->pcie_width_level1;
-                       } else {
-                               gen_speed = pptable->PcieGenSpeed[i];
-                               lane_width = pptable->PcieLaneCount[i];
-                       }
+                       gen_speed = pptable->PcieGenSpeed[i];
+                       lane_width = pptable->PcieLaneCount[i];
+
                        size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
                                        (gen_speed == 0) ? "2.5GT/s," :
                                        (gen_speed == 1) ? "5.0GT/s," :
index b9a616737c0ee2e90b0cfc3bb3674f1004e7b3e2..f6baa2046124d1d7c8f9db9d34455db8c02bfb1b 100644 (file)
@@ -2048,7 +2048,7 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
 
        if (shadow)
                vfree(shadow);
-       else
+       else if (fb_helper->buffer)
                drm_client_buffer_vunmap(fb_helper->buffer);
 
        drm_client_framebuffer_delete(fb_helper->buffer);
index 9825c378dfa6dabfe0fcb26e7335134feb2ab03b..6d625cee7a6af2d1b908f0d28708b06d8625a7d5 100644 (file)
@@ -357,13 +357,14 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
        if (--shmem->vmap_use_count > 0)
                return;
 
-       if (obj->import_attach)
+       if (obj->import_attach) {
                dma_buf_vunmap(obj->import_attach->dmabuf, map);
-       else
+       } else {
                vunmap(shmem->vaddr);
+               drm_gem_shmem_put_pages(shmem);
+       }
 
        shmem->vaddr = NULL;
-       drm_gem_shmem_put_pages(shmem);
 }
 
 /*
@@ -525,14 +526,28 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
        struct drm_gem_object *obj = vma->vm_private_data;
        struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
        loff_t num_pages = obj->size >> PAGE_SHIFT;
+       vm_fault_t ret;
        struct page *page;
+       pgoff_t page_offset;
 
-       if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
-               return VM_FAULT_SIGBUS;
+       /* We don't use vmf->pgoff since that has the fake offset */
+       page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
 
-       page = shmem->pages[vmf->pgoff];
+       mutex_lock(&shmem->pages_lock);
 
-       return vmf_insert_page(vma, vmf->address, page);
+       if (page_offset >= num_pages ||
+           WARN_ON_ONCE(!shmem->pages) ||
+           shmem->madv < 0) {
+               ret = VM_FAULT_SIGBUS;
+       } else {
+               page = shmem->pages[page_offset];
+
+               ret = vmf_insert_page(vma, vmf->address, page);
+       }
+
+       mutex_unlock(&shmem->pages_lock);
+
+       return ret;
 }
 
 static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
@@ -581,9 +596,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
        struct drm_gem_shmem_object *shmem;
        int ret;
 
-       /* Remove the fake offset */
-       vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
-
        if (obj->import_attach) {
                /* Drop the reference drm_gem_mmap_obj() acquired.*/
                drm_gem_object_put(obj);
index f86448ab1fe045235b1a13f6e39eb3893fd04555..dc734d4828a179441a41e445962c82779fbf9c1a 100644 (file)
@@ -99,6 +99,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
        if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
                return -EFAULT;
 
+       memset(&v, 0, sizeof(v));
+
        v = (struct drm_version) {
                .name_len = v32.name_len,
                .name = compat_ptr(v32.name),
@@ -137,6 +139,9 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
 
        if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
                return -EFAULT;
+
+       memset(&uq, 0, sizeof(uq));
+
        uq = (struct drm_unique){
                .unique_len = uq32.unique_len,
                .unique = compat_ptr(uq32.unique),
@@ -265,6 +270,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
        if (copy_from_user(&c32, argp, sizeof(c32)))
                return -EFAULT;
 
+       memset(&client, 0, sizeof(client));
+
        client.idx = c32.idx;
 
        err = drm_ioctl_kernel(file, drm_getclient, &client, 0);
@@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
        if (copy_from_user(&req32, argp, sizeof(req32)))
                return -EFAULT;
 
+       memset(&req, 0, sizeof(req));
+
        req.request.type = req32.request.type;
        req.request.sequence = req32.request.sequence;
        req.request.signal = req32.request.signal;
@@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd,
        struct drm_mode_fb_cmd2 req64;
        int err;
 
+       memset(&req64, 0, sizeof(req64));
+
        if (copy_from_user(&req64, argp,
                           offsetof(drm_mode_fb_cmd232_t, modifier)))
                return -EFAULT;
index fb1b1d09697511ab88338ef8fe460a36e9d80265..9cf555d6842b71e2a99ace195eadc7f1cf0f0068 100644 (file)
@@ -713,9 +713,12 @@ static int engine_setup_common(struct intel_engine_cs *engine)
                goto err_status;
        }
 
+       err = intel_engine_init_cmd_parser(engine);
+       if (err)
+               goto err_cmd_parser;
+
        intel_engine_init_active(engine, ENGINE_PHYSICAL);
        intel_engine_init_execlists(engine);
-       intel_engine_init_cmd_parser(engine);
        intel_engine_init__pm(engine);
        intel_engine_init_retire(engine);
 
@@ -732,6 +735,8 @@ static int engine_setup_common(struct intel_engine_cs *engine)
 
        return 0;
 
+err_cmd_parser:
+       intel_breadcrumbs_free(engine->breadcrumbs);
 err_status:
        cleanup_status_page(engine);
        return err;
index ced9a96d7c34be0bb922240db86eda36b3690965..5f86f5b2caf6f19b1918b91a778c1fc3604cd9d9 100644 (file)
@@ -940,7 +940,7 @@ static void fini_hash_table(struct intel_engine_cs *engine)
  * struct intel_engine_cs based on whether the platform requires software
  * command parsing.
  */
-void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
+int intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
 {
        const struct drm_i915_cmd_table *cmd_tables;
        int cmd_table_count;
@@ -948,7 +948,7 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
 
        if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) &&
                                          engine->class == COPY_ENGINE_CLASS))
-               return;
+               return 0;
 
        switch (engine->class) {
        case RENDER_CLASS:
@@ -1013,19 +1013,19 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
                break;
        default:
                MISSING_CASE(engine->class);
-               return;
+               goto out;
        }
 
        if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) {
                drm_err(&engine->i915->drm,
                        "%s: command descriptions are not sorted\n",
                        engine->name);
-               return;
+               goto out;
        }
        if (!validate_regs_sorted(engine)) {
                drm_err(&engine->i915->drm,
                        "%s: registers are not sorted\n", engine->name);
-               return;
+               goto out;
        }
 
        ret = init_hash_table(engine, cmd_tables, cmd_table_count);
@@ -1033,10 +1033,17 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
                drm_err(&engine->i915->drm,
                        "%s: initialised failed!\n", engine->name);
                fini_hash_table(engine);
-               return;
+               goto out;
        }
 
        engine->flags |= I915_ENGINE_USING_CMD_PARSER;
+
+out:
+       if (intel_engine_requires_cmd_parser(engine) &&
+           !intel_engine_using_cmd_parser(engine))
+               return -EINVAL;
+
+       return 0;
 }
 
 /**
index 26d69d06aa6d131809fb6be42cba048d344e6768..cb62ddba203522f61501fd918179cc053a1eeb6c 100644 (file)
@@ -1952,7 +1952,7 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
 
 /* i915_cmd_parser.c */
 int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
-void intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
+int intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
 void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
 int intel_engine_cmd_parser(struct intel_engine_cs *engine,
                            struct i915_vma *batch,
index 42c5d3246cfcbd0147a48df83d4aa52c4c352291..453d8b4c5763d9b65665ad8cca3ab0dfd0d8f4b2 100644 (file)
@@ -482,6 +482,16 @@ static int meson_probe_remote(struct platform_device *pdev,
        return count;
 }
 
+static void meson_drv_shutdown(struct platform_device *pdev)
+{
+       struct meson_drm *priv = dev_get_drvdata(&pdev->dev);
+       struct drm_device *drm = priv->drm;
+
+       DRM_DEBUG_DRIVER("\n");
+       drm_kms_helper_poll_fini(drm);
+       drm_atomic_helper_shutdown(drm);
+}
+
 static int meson_drv_probe(struct platform_device *pdev)
 {
        struct component_match *match = NULL;
@@ -553,6 +563,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = {
 
 static struct platform_driver meson_drm_platform_driver = {
        .probe      = meson_drv_probe,
+       .shutdown   = meson_drv_shutdown,
        .driver     = {
                .name   = "meson-drm",
                .of_match_table = dt_match,
index 2375711877cf3ac6ebe4570b3541f25627659f1a..fabb314a0b2f8eaabb83c7160cfec948696b4091 100644 (file)
@@ -556,7 +556,8 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
        if (nvbo->force_coherent)
                return;
 
-       for (i = 0; i < ttm_dma->num_pages; ++i) {
+       i = 0;
+       while (i < ttm_dma->num_pages) {
                struct page *p = ttm_dma->pages[i];
                size_t num_pages = 1;
 
@@ -587,7 +588,8 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
        if (nvbo->force_coherent)
                return;
 
-       for (i = 0; i < ttm_dma->num_pages; ++i) {
+       i = 0;
+       while (i < ttm_dma->num_pages) {
                struct page *p = ttm_dma->pages[i];
                size_t num_pages = 1;
 
index 012bce0cdb65c101345e14121d193500d46f0252..10738e04c09b85bfd549ff35dd9bb7c078a2e1aa 100644 (file)
@@ -328,6 +328,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc,
 
        head.id = i;
        head.flags = 0;
+       head.surface_id = 0;
        oldcount = qdev->monitors_config->count;
        if (crtc->state->active) {
                struct drm_display_mode *mode = &crtc->mode;
index 0fcfc952d5e9e24ef1cd397116778b2b0cd976fb..b372455e272986fe09374d66d0fb9be96928cda6 100644 (file)
@@ -321,7 +321,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
                                       int type, struct qxl_release **release,
                                       struct qxl_bo **rbo)
 {
-       struct qxl_bo *bo;
+       struct qxl_bo *bo, *free_bo = NULL;
        int idr_ret;
        int ret = 0;
        union qxl_release_info *info;
@@ -347,7 +347,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 
        mutex_lock(&qdev->release_mutex);
        if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) {
-               qxl_bo_unref(&qdev->current_release_bo[cur_idx]);
+               free_bo = qdev->current_release_bo[cur_idx];
                qdev->current_release_bo_offset[cur_idx] = 0;
                qdev->current_release_bo[cur_idx] = NULL;
        }
@@ -355,6 +355,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
                ret = qxl_release_bo_alloc(qdev, &qdev->current_release_bo[cur_idx]);
                if (ret) {
                        mutex_unlock(&qdev->release_mutex);
+                       if (free_bo) {
+                               qxl_bo_unpin(free_bo);
+                               qxl_bo_unref(&free_bo);
+                       }
                        qxl_release_free(qdev, *release);
                        return ret;
                }
@@ -370,6 +374,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
                *rbo = bo;
 
        mutex_unlock(&qdev->release_mutex);
+       if (free_bo) {
+               qxl_bo_unpin(free_bo);
+               qxl_bo_unref(&free_bo);
+       }
 
        ret = qxl_release_list_add(*release, bo);
        qxl_bo_unref(&bo);
index f09989bdce9840a5c955d9a53d2fa9e25d2f61ba..3effc8c71494cd1313d49231a1c8ab7086b2759e 100644 (file)
@@ -574,6 +574,8 @@ struct radeon_gem {
        struct list_head        objects;
 };
 
+extern const struct drm_gem_object_funcs radeon_gem_object_funcs;
+
 int radeon_gem_init(struct radeon_device *rdev);
 void radeon_gem_fini(struct radeon_device *rdev);
 int radeon_gem_object_create(struct radeon_device *rdev, unsigned long size,
index 941826923247329b5da554a3d35d10a6083123ff..db14a82a2e4b258befcbde025c37bcdd603bb2a7 100644 (file)
@@ -43,7 +43,7 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj);
 int radeon_gem_prime_pin(struct drm_gem_object *obj);
 void radeon_gem_prime_unpin(struct drm_gem_object *obj);
 
-static const struct drm_gem_object_funcs radeon_gem_object_funcs;
+const struct drm_gem_object_funcs radeon_gem_object_funcs;
 
 static void radeon_gem_object_free(struct drm_gem_object *gobj)
 {
@@ -227,7 +227,7 @@ static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r)
        return r;
 }
 
-static const struct drm_gem_object_funcs radeon_gem_object_funcs = {
+const struct drm_gem_object_funcs radeon_gem_object_funcs = {
        .free = radeon_gem_object_free,
        .open = radeon_gem_object_open,
        .close = radeon_gem_object_close,
index ab29eb9e8667596cb525ae189b193f2f329a3910..42a87948e28c5bed77428455708c5f5a85b8743d 100644 (file)
@@ -56,6 +56,8 @@ struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev,
        if (ret)
                return ERR_PTR(ret);
 
+       bo->tbo.base.funcs = &radeon_gem_object_funcs;
+
        mutex_lock(&rdev->gem.mutex);
        list_add_tail(&bo->list, &rdev->gem.objects);
        mutex_unlock(&rdev->gem.mutex);
index 33f65f4626e5a3cb2e66722aa20a36300d0044d7..23866a54e3f919ec89af46e365c31dceb15f177d 100644 (file)
@@ -83,6 +83,7 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
 
 struct gm12u320_device {
        struct drm_device                dev;
+       struct device                   *dmadev;
        struct drm_simple_display_pipe   pipe;
        struct drm_connector             conn;
        unsigned char                   *cmd_buf;
@@ -601,6 +602,22 @@ static const uint64_t gm12u320_pipe_modifiers[] = {
        DRM_FORMAT_MOD_INVALID
 };
 
+/*
+ * FIXME: Dma-buf sharing requires DMA support by the importing device.
+ *        This function is a workaround to make USB devices work as well.
+ *        See todo.rst for how to fix the issue in the dma-buf framework.
+ */
+static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev,
+                                                       struct dma_buf *dma_buf)
+{
+       struct gm12u320_device *gm12u320 = to_gm12u320(dev);
+
+       if (!gm12u320->dmadev)
+               return ERR_PTR(-ENODEV);
+
+       return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev);
+}
+
 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
 
 static const struct drm_driver gm12u320_drm_driver = {
@@ -614,6 +631,7 @@ static const struct drm_driver gm12u320_drm_driver = {
 
        .fops            = &gm12u320_fops,
        DRM_GEM_SHMEM_DRIVER_OPS,
+       .gem_prime_import = gm12u320_gem_prime_import,
 };
 
 static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
@@ -640,15 +658,18 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
                                      struct gm12u320_device, dev);
        if (IS_ERR(gm12u320))
                return PTR_ERR(gm12u320);
+       dev = &gm12u320->dev;
+
+       gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
+       if (!gm12u320->dmadev)
+               drm_warn(dev, "buffer sharing not supported"); /* not an error */
 
        INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
        mutex_init(&gm12u320->fb_update.lock);
 
-       dev = &gm12u320->dev;
-
        ret = drmm_mode_config_init(dev);
        if (ret)
-               return ret;
+               goto err_put_device;
 
        dev->mode_config.min_width = GM12U320_USER_WIDTH;
        dev->mode_config.max_width = GM12U320_USER_WIDTH;
@@ -658,15 +679,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 
        ret = gm12u320_usb_alloc(gm12u320);
        if (ret)
-               return ret;
+               goto err_put_device;
 
        ret = gm12u320_set_ecomode(gm12u320);
        if (ret)
-               return ret;
+               goto err_put_device;
 
        ret = gm12u320_conn_init(gm12u320);
        if (ret)
-               return ret;
+               goto err_put_device;
 
        ret = drm_simple_display_pipe_init(&gm12u320->dev,
                                           &gm12u320->pipe,
@@ -676,24 +697,31 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
                                           gm12u320_pipe_modifiers,
                                           &gm12u320->conn);
        if (ret)
-               return ret;
+               goto err_put_device;
 
        drm_mode_config_reset(dev);
 
        usb_set_intfdata(interface, dev);
        ret = drm_dev_register(dev, 0);
        if (ret)
-               return ret;
+               goto err_put_device;
 
        drm_fbdev_generic_setup(dev, 0);
 
        return 0;
+
+err_put_device:
+       put_device(gm12u320->dmadev);
+       return ret;
 }
 
 static void gm12u320_usb_disconnect(struct usb_interface *interface)
 {
        struct drm_device *dev = usb_get_intfdata(interface);
+       struct gm12u320_device *gm12u320 = to_gm12u320(dev);
 
+       put_device(gm12u320->dmadev);
+       gm12u320->dmadev = NULL;
        drm_dev_unplug(dev);
        drm_atomic_helper_shutdown(dev);
 }
index 20a25660b35b8b630687912ef8f46f5959c5b5fd..101a68dc615b6032b8e5dd541c05ba00dc473e69 100644 (file)
@@ -136,7 +136,8 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo,
        struct ttm_bo_device *bdev = bo->bdev;
        struct ttm_resource_manager *man;
 
-       dma_resv_assert_held(bo->base.resv);
+       if (!bo->deleted)
+               dma_resv_assert_held(bo->base.resv);
 
        if (bo->pin_count) {
                ttm_bo_del_from_lru(bo);
@@ -508,8 +509,11 @@ static void ttm_bo_release(struct kref *kref)
                 * Make pinned bos immediately available to
                 * shrinkers, now that they are queued for
                 * destruction.
+                *
+                * FIXME: QXL is triggering this. Can be removed when the
+                * driver is fixed.
                 */
-               if (WARN_ON(bo->pin_count)) {
+               if (WARN_ON_ONCE(bo->pin_count)) {
                        bo->pin_count = 0;
                        ttm_bo_move_to_lru_tail(bo, &bo->mem, NULL);
                }
index 6e27cb1bf48b2effb0d9f14eac0d21483f712d49..4eb6efb8b8c026d4dc6988c3ea7a20fa8e124bf4 100644 (file)
@@ -268,13 +268,13 @@ static void ttm_pool_type_init(struct ttm_pool_type *pt, struct ttm_pool *pool,
 /* Remove a pool_type from the global shrinker list and free all pages */
 static void ttm_pool_type_fini(struct ttm_pool_type *pt)
 {
-       struct page *p, *tmp;
+       struct page *p;
 
        mutex_lock(&shrinker_lock);
        list_del(&pt->shrinker_list);
        mutex_unlock(&shrinker_lock);
 
-       list_for_each_entry_safe(p, tmp, &pt->pages, lru)
+       while ((p = ttm_pool_type_take(pt)))
                ttm_pool_free_page(pt->pool, pt->caching, pt->order, p);
 }
 
index 9269092697d8ca4faa574fd93fd05fd6d90ffac4..5703277c6f5276197f1d5a4c5d8d6ae76723456b 100644 (file)
@@ -32,6 +32,22 @@ static int udl_usb_resume(struct usb_interface *interface)
        return drm_mode_config_helper_resume(dev);
 }
 
+/*
+ * FIXME: Dma-buf sharing requires DMA support by the importing device.
+ *        This function is a workaround to make USB devices work as well.
+ *        See todo.rst for how to fix the issue in the dma-buf framework.
+ */
+static struct drm_gem_object *udl_driver_gem_prime_import(struct drm_device *dev,
+                                                         struct dma_buf *dma_buf)
+{
+       struct udl_device *udl = to_udl(dev);
+
+       if (!udl->dmadev)
+               return ERR_PTR(-ENODEV);
+
+       return drm_gem_prime_import_dev(dev, dma_buf, udl->dmadev);
+}
+
 DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 
 static const struct drm_driver driver = {
@@ -40,6 +56,7 @@ static const struct drm_driver driver = {
        /* GEM hooks */
        .fops = &udl_driver_fops,
        DRM_GEM_SHMEM_DRIVER_OPS,
+       .gem_prime_import = udl_driver_gem_prime_import,
 
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
index 875e73551ae981451501d0b3142bd5e9667ae5f5..cc16a13316e4e1f565331449b6ee17b6cee3b543 100644 (file)
@@ -50,6 +50,7 @@ struct urb_list {
 struct udl_device {
        struct drm_device drm;
        struct device *dev;
+       struct device *dmadev;
 
        struct drm_simple_display_pipe display_pipe;
 
index 0e2a376cb0752a33a659e7236969571077e12c42..853f147036f6b5c5ecda9598c0bbd8d0f010a8d0 100644 (file)
@@ -315,6 +315,10 @@ int udl_init(struct udl_device *udl)
 
        DRM_DEBUG("\n");
 
+       udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
+       if (!udl->dmadev)
+               drm_warn(dev, "buffer sharing not supported"); /* not an error */
+
        mutex_init(&udl->gem_lock);
 
        if (!udl_parse_vendor_descriptor(udl)) {
@@ -343,12 +347,18 @@ int udl_init(struct udl_device *udl)
 err:
        if (udl->urbs.count)
                udl_free_urb_list(dev);
+       put_device(udl->dmadev);
        DRM_ERROR("%d\n", ret);
        return ret;
 }
 
 int udl_drop_usb(struct drm_device *dev)
 {
+       struct udl_device *udl = to_udl(dev);
+
        udl_free_urb_list(dev);
+       put_device(udl->dmadev);
+       udl->dmadev = NULL;
+
        return 0;
 }
index aa5f45749543b3cc0282f3180aca8d6157762070..a60c302ef2676bdba97cbaf2325cb042ff5eb1d4 100644 (file)
@@ -1288,7 +1288,6 @@ static void rkisp1_params_config_parameter(struct rkisp1_params *params)
        memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
        rkisp1_hst_config(params, &hst);
        rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
-                             ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK |
                              rkisp1_hst_params_default_config.mode);
 
        /* set the  range */
index 86d5e3f4b1ffce357d57f29da4d50d080ccf4e22..06f74d410973eb3284142f66c261305404deda61 100644 (file)
@@ -245,7 +245,7 @@ static int vsp1_du_pipeline_setup_brx(struct vsp1_device *vsp1,
                brx = &vsp1->bru->entity;
        else if (pipe->brx && !drm_pipe->force_brx_release)
                brx = pipe->brx;
-       else if (!vsp1->bru->entity.pipe)
+       else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe)
                brx = &vsp1->bru->entity;
        else
                brx = &vsp1->brs->entity;
@@ -462,9 +462,9 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
         * make sure it is present in the pipeline's list of entities if it
         * wasn't already.
         */
-       if (!use_uif) {
+       if (drm_pipe->uif && !use_uif) {
                drm_pipe->uif->pipe = NULL;
-       } else if (!drm_pipe->uif->pipe) {
+       } else if (drm_pipe->uif && !drm_pipe->uif->pipe) {
                drm_pipe->uif->pipe = pipe;
                list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
        }
index 5bb2932ab11954dd51c1a6ffba75c7105a6a9ef6..ff6a8fc4c38e50ed0469032956e62cdddde44477 100644 (file)
@@ -5,6 +5,7 @@ obj-y += keymaps/
 obj-$(CONFIG_RC_CORE) += rc-core.o
 rc-core-y := rc-main.o rc-ir-raw.o
 rc-core-$(CONFIG_LIRC) += lirc_dev.o
+rc-core-$(CONFIG_MEDIA_CEC_RC) += keymaps/rc-cec.o
 rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o
 obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
index b252a1d2ebd66fa158cc99e6301f86f397e6bf3a..cc6662e1903f58923dc0a5ccc35b8b91eb6aab46 100644 (file)
@@ -21,7 +21,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
                        rc-behold.o \
                        rc-behold-columbus.o \
                        rc-budget-ci-old.o \
-                       rc-cec.o \
                        rc-cinergy-1400.o \
                        rc-cinergy.o \
                        rc-d680-dmb.o \
index 3e3bd11092b45d439f8cff6255f1b72210fbc130..068e22aeac8c38166f88d36cf22722a6b84e7b98 100644 (file)
@@ -1,5 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /* Keytable for the CEC remote control
+ *
+ * This keymap is unusual in that it can't be built as a module,
+ * instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC
+ * is set. This is because it can be called from drm_dp_cec_set_edid() via
+ * cec_register_adapter() in an asynchronous context, and it is not
+ * allowed to use request_module() to load rc-cec.ko in that case.
+ *
+ * Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we
+ * just compile this keymap into the rc-core module and never as a
+ * separate module.
  *
  * Copyright (c) 2015 by Kamil Debski
  */
@@ -152,7 +162,7 @@ static struct rc_map_table cec[] = {
        /* 0x77-0xff: Reserved */
 };
 
-static struct rc_map_list cec_map = {
+struct rc_map_list cec_map = {
        .map = {
                .scan           = cec,
                .size           = ARRAY_SIZE(cec),
@@ -160,19 +170,3 @@ static struct rc_map_list cec_map = {
                .name           = RC_MAP_CEC,
        }
 };
-
-static int __init init_rc_map_cec(void)
-{
-       return rc_map_register(&cec_map);
-}
-
-static void __exit exit_rc_map_cec(void)
-{
-       rc_map_unregister(&cec_map);
-}
-
-module_init(init_rc_map_cec);
-module_exit(exit_rc_map_cec);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kamil Debski");
index 1fd62c1dac768d705cffa725492d54d477e41f58..8e88dc8ea6c5ee99351dc44457ce3748dbc2d0c7 100644 (file)
@@ -2069,6 +2069,9 @@ static int __init rc_core_init(void)
 
        led_trigger_register_simple("rc-feedback", &led_feedback);
        rc_map_register(&empty_map);
+#ifdef CONFIG_MEDIA_CEC_RC
+       rc_map_register(&cec_map);
+#endif
 
        return 0;
 }
@@ -2078,6 +2081,9 @@ static void __exit rc_core_exit(void)
        lirc_dev_exit();
        class_unregister(&rc_class);
        led_trigger_unregister_simple(led_feedback);
+#ifdef CONFIG_MEDIA_CEC_RC
+       rc_map_unregister(&cec_map);
+#endif
        rc_map_unregister(&empty_map);
 }
 
index b57e94fb19770db90c870640489cb778930dfc59..333bd305a4f9fa387e4e5fcc4dec052caf53f022 100644 (file)
@@ -371,7 +371,7 @@ void usbtv_audio_free(struct usbtv *usbtv)
        cancel_work_sync(&usbtv->snd_trigger);
 
        if (usbtv->snd && usbtv->udev) {
-               snd_card_free(usbtv->snd);
+               snd_card_free_when_closed(usbtv->snd);
                usbtv->snd = NULL;
        }
 }
index 2d778d0f011e6ce5ce8a77745cfce600f69487cc..c0fe3295c3303fd00ee7b26d54a2bfd6ba80b849 100644 (file)
@@ -2288,15 +2288,13 @@ crq_failed:
        return -EPERM;
 }
 
-static int ibmvmc_remove(struct vio_dev *vdev)
+static void ibmvmc_remove(struct vio_dev *vdev)
 {
        struct crq_server_adapter *adapter = dev_get_drvdata(&vdev->dev);
 
        dev_info(adapter->dev, "Entering remove for UA 0x%x\n",
                 vdev->unit_address);
        ibmvmc_release_crq_queue(adapter);
-
-       return 0;
 }
 
 static struct vio_device_id ibmvmc_device_table[] = {
index c2e70b757dd12c603ad9a5cbe7086b24841eec99..4383c262b3f5a383a95a56cdf115571ae838118d 100644 (file)
@@ -399,11 +399,6 @@ void mmc_remove_card(struct mmc_card *card)
        mmc_remove_card_debugfs(card);
 #endif
 
-       if (host->cqe_enabled) {
-               host->cqe_ops->cqe_disable(host);
-               host->cqe_enabled = false;
-       }
-
        if (mmc_card_present(card)) {
                if (mmc_host_is_spi(card->host)) {
                        pr_info("%s: SPI card removed\n",
@@ -416,6 +411,10 @@ void mmc_remove_card(struct mmc_card *card)
                of_node_put(card->dev.of_node);
        }
 
+       if (host->cqe_enabled) {
+               host->cqe_ops->cqe_disable(host);
+               host->cqe_enabled = false;
+       }
+
        put_device(&card->dev);
 }
-
index 0d80b72ddde8199da3916f63d26ac4fd8551cb2d..8741271d39712b4950a039c3244c0f26fbb08575 100644 (file)
@@ -423,10 +423,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
 
                /* EXT_CSD value is in units of 10ms, but we store in ms */
                card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
-               /* Some eMMC set the value too low so set a minimum */
-               if (card->ext_csd.part_time &&
-                   card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME)
-                       card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME;
 
                /* Sleep / awake timeout in 100ns units */
                if (sa_shift > 0 && sa_shift <= 0x17)
@@ -616,6 +612,17 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
                card->ext_csd.data_sector_size = 512;
        }
 
+       /*
+        * GENERIC_CMD6_TIME is to be used "unless a specific timeout is defined
+        * when accessing a specific field", so use it here if there is no
+        * PARTITION_SWITCH_TIME.
+        */
+       if (!card->ext_csd.part_time)
+               card->ext_csd.part_time = card->ext_csd.generic_cmd6_time;
+       /* Some eMMC set the value too low so set a minimum */
+       if (card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME)
+               card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME;
+
        /* eMMC v5 or later */
        if (card->ext_csd.rev >= 7) {
                memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION],
index 17dbc81c221eb5ad20ad269adc9a91530fb641cc..984d350551567d1c7a299f76fd5b3739b7633ddd 100644 (file)
@@ -1242,7 +1242,11 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
                if (!cmd->busy_timeout)
                        cmd->busy_timeout = 10 * MSEC_PER_SEC;
 
-               clks = (unsigned long long)cmd->busy_timeout * host->cclk;
+               if (cmd->busy_timeout > host->mmc->max_busy_timeout)
+                       clks = (unsigned long long)host->mmc->max_busy_timeout * host->cclk;
+               else
+                       clks = (unsigned long long)cmd->busy_timeout * host->cclk;
+
                do_div(clks, MSEC_PER_SEC);
                writel_relaxed(clks, host->base + MMCIDATATIMER);
        }
@@ -2151,6 +2155,10 @@ static int mmci_probe(struct amba_device *dev,
                mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
        }
 
+       /* Variants with mandatory busy timeout in HW needs R1B responses. */
+       if (variant->busy_timeout)
+               mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
+
        /* Prepare a CMD12 - needed to clear the DPSM on some variants. */
        host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
        host->stop_abort.arg = 0;
index b09bed554f266c42884ce0152be22d9186b0c65d..bcd31f458d1acd76d9c79b1c5b84a76b457d3eb2 100644 (file)
@@ -94,7 +94,7 @@ config WIREGUARD
        select CRYPTO_BLAKE2S_ARM if ARM
        select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON
        select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2
-       select CRYPTO_POLY1305_MIPS if CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
+       select CRYPTO_POLY1305_MIPS if MIPS
        help
          WireGuard is a secure, fast, and easy to use replacement for IPSec
          that uses modern cryptography and clever networking tricks. It's
index 74cbbb22470b5ec22015bf5c7563a22edda0e1d3..456315bef3a8b7084960ab2e87a79cd09066b48b 100644 (file)
@@ -3978,11 +3978,15 @@ static int bond_neigh_init(struct neighbour *n)
 
        rcu_read_lock();
        slave = bond_first_slave_rcu(bond);
-       if (!slave)
+       if (!slave) {
+               ret = -EINVAL;
                goto out;
+       }
        slave_ops = slave->dev->netdev_ops;
-       if (!slave_ops->ndo_neigh_setup)
+       if (!slave_ops->ndo_neigh_setup) {
+               ret = -EINVAL;
                goto out;
+       }
 
        /* TODO: find another way [1] to implement this.
         * Passing a zeroed structure is fragile,
index 971ada36e37fa7987a101f74a6d4cfdf8957b7d1..134c05757a3bb19d2eeae17abe7d9232bc28743b 100644 (file)
@@ -701,7 +701,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
        u32 reg;
 
        reg = priv->read(&regs->mcr);
-       reg |= FLEXCAN_MCR_HALT;
+       reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT;
        priv->write(reg, &regs->mcr);
 
        while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
@@ -1480,10 +1480,13 @@ static int flexcan_chip_start(struct net_device *dev)
 
        flexcan_set_bittiming(dev);
 
+       /* set freeze, halt */
+       err = flexcan_chip_freeze(priv);
+       if (err)
+               goto out_chip_disable;
+
        /* MCR
         *
-        * enable freeze
-        * halt now
         * only supervisor access
         * enable warning int
         * enable individual RX masking
@@ -1492,9 +1495,8 @@ static int flexcan_chip_start(struct net_device *dev)
         */
        reg_mcr = priv->read(&regs->mcr);
        reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
-       reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
-               FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C |
-               FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+       reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ |
+               FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
 
        /* MCR
         *
@@ -1865,10 +1867,14 @@ static int register_flexcandev(struct net_device *dev)
        if (err)
                goto out_chip_disable;
 
-       /* set freeze, halt and activate FIFO, restrict register access */
+       /* set freeze, halt */
+       err = flexcan_chip_freeze(priv);
+       if (err)
+               goto out_chip_disable;
+
+       /* activate FIFO, restrict register access */
        reg = priv->read(&regs->mcr);
-       reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
-               FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
+       reg |=  FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
        priv->write(reg, &regs->mcr);
 
        /* Currently we only support newer versions of this core
index b7caec769ddb9b569c8376457cd3922337c1bf80..4147cecfbbd6dbd8e2207de82b728eed7dd2625d 100644 (file)
@@ -237,14 +237,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
        if (ret)
                return ret;
 
+       /* Zero out the MCAN buffers */
+       m_can_init_ram(cdev);
+
        ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
                                 TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL);
        if (ret)
                return ret;
 
-       /* Zero out the MCAN buffers */
-       m_can_init_ram(cdev);
-
        return ret;
 }
 
index 3c5b92911d469302d5ed864df47e58143e5c5be7..799e9d5d348133edaa806772498067545b752da3 100644 (file)
@@ -335,8 +335,6 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
        u8 len;
        int i, j;
 
-       netdev_reset_queue(priv->ndev);
-
        /* TEF */
        tef_ring = priv->tef;
        tef_ring->head = 0;
@@ -1249,8 +1247,7 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
 
 static int
 mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
-                          const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
-                          unsigned int *frame_len_ptr)
+                          const struct mcp251xfd_hw_tef_obj *hw_tef_obj)
 {
        struct net_device_stats *stats = &priv->ndev->stats;
        u32 seq, seq_masked, tef_tail_masked;
@@ -1272,8 +1269,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
        stats->tx_bytes +=
                can_rx_offload_get_echo_skb(&priv->offload,
                                            mcp251xfd_get_tef_tail(priv),
-                                           hw_tef_obj->ts,
-                                           frame_len_ptr);
+                                           hw_tef_obj->ts, NULL);
        stats->tx_packets++;
        priv->tef->tail++;
 
@@ -1331,7 +1327,6 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
 static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
 {
        struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
-       unsigned int total_frame_len = 0;
        u8 tef_tail, len, l;
        int err, i;
 
@@ -1353,9 +1348,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
        }
 
        for (i = 0; i < len; i++) {
-               unsigned int frame_len;
-
-               err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
+               err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i]);
                /* -EAGAIN means the Sequence Number in the TEF
                 * doesn't match our tef_tail. This can happen if we
                 * read the TEF objects too early. Leave loop let the
@@ -1365,8 +1358,6 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
                        goto out_netif_wake_queue;
                if (err)
                        return err;
-
-               total_frame_len += frame_len;
        }
 
  out_netif_wake_queue:
@@ -1397,7 +1388,6 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
                        return err;
 
                tx_ring->tail += len;
-               netdev_completed_queue(priv->ndev, len, total_frame_len);
 
                err = mcp251xfd_check_tef_tail(priv);
                if (err)
@@ -2443,7 +2433,6 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
        struct mcp251xfd_priv *priv = netdev_priv(ndev);
        struct mcp251xfd_tx_ring *tx_ring = priv->tx;
        struct mcp251xfd_tx_obj *tx_obj;
-       unsigned int frame_len;
        u8 tx_head;
        int err;
 
@@ -2462,9 +2451,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
        if (mcp251xfd_get_tx_free(tx_ring) == 0)
                netif_stop_queue(ndev);
 
-       frame_len = can_skb_get_frame_len(skb);
-       can_put_echo_skb(skb, ndev, tx_head, frame_len);
-       netdev_sent_queue(priv->ndev, frame_len);
+       can_put_echo_skb(skb, ndev, tx_head, 0);
 
        err = mcp251xfd_tx_obj_write(priv, tx_obj);
        if (err)
index 5ee8103b8e9c7eb16d4cce068182a883429687dd..f277df922fcded6db853d155399e8354287ea299 100644 (file)
@@ -406,7 +406,7 @@ static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
        /* The watchdog reset does not work on 7278, we need to hit the
         * "external" reset line through the reset controller.
         */
-       if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev)) {
+       if (priv->type == BCM7278_DEVICE_ID) {
                ret = reset_control_assert(priv->rcdev);
                if (ret)
                        return ret;
@@ -1265,7 +1265,7 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
 
        priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
                                                                "switch");
-       if (PTR_ERR(priv->rcdev) == -EPROBE_DEFER)
+       if (IS_ERR(priv->rcdev))
                return PTR_ERR(priv->rcdev);
 
        /* Auto-detection using standard registers will not work, so
@@ -1426,7 +1426,7 @@ static int bcm_sf2_sw_remove(struct platform_device *pdev)
        bcm_sf2_mdio_unregister(priv);
        clk_disable_unprepare(priv->clk_mdiv);
        clk_disable_unprepare(priv->clk);
-       if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev))
+       if (priv->type == BCM7278_DEVICE_ID)
                reset_control_assert(priv->rcdev);
 
        return 0;
index c17de2bcf2fef7233efc3f047ffb54c3ac71815d..f06f5fa2f898c115c4999cc793c8c91634f2acd0 100644 (file)
@@ -1624,6 +1624,7 @@ mtk_get_tag_protocol(struct dsa_switch *ds, int port,
        }
 }
 
+#ifdef CONFIG_GPIOLIB
 static inline u32
 mt7530_gpio_to_bit(unsigned int offset)
 {
@@ -1726,6 +1727,7 @@ mt7530_setup_gpio(struct mt7530_priv *priv)
 
        return devm_gpiochip_add_data(dev, gc, priv);
 }
+#endif /* CONFIG_GPIOLIB */
 
 static int
 mt7530_setup(struct dsa_switch *ds)
@@ -1868,11 +1870,13 @@ mt7530_setup(struct dsa_switch *ds)
                }
        }
 
+#ifdef CONFIG_GPIOLIB
        if (of_property_read_bool(priv->dev->of_node, "gpio-controller")) {
                ret = mt7530_setup_gpio(priv);
                if (ret)
                        return ret;
        }
+#endif /* CONFIG_GPIOLIB */
 
        mt7530_setup_port5(ds, interface);
 
index 7692338730df525cf7673192ac9bac4d0f40177e..51ea104c63bbbed55c160200fe29100013c20eaf 100644 (file)
@@ -1922,7 +1922,7 @@ out_unlock_ptp:
                                speed = SPEED_1000;
                        else if (bmcr & BMCR_SPEED100)
                                speed = SPEED_100;
-                       else if (bmcr & BMCR_SPEED10)
+                       else
                                speed = SPEED_10;
 
                        sja1105_sgmii_pcs_force_speed(priv, speed);
@@ -3369,14 +3369,14 @@ static int sja1105_port_ucast_bcast_flood(struct sja1105_private *priv, int to,
                if (flags.val & BR_FLOOD)
                        priv->ucast_egress_floods |= BIT(to);
                else
-                       priv->ucast_egress_floods |= BIT(to);
+                       priv->ucast_egress_floods &= ~BIT(to);
        }
 
        if (flags.mask & BR_BCAST_FLOOD) {
                if (flags.val & BR_BCAST_FLOOD)
                        priv->bcast_egress_floods |= BIT(to);
                else
-                       priv->bcast_egress_floods |= BIT(to);
+                       priv->bcast_egress_floods &= ~BIT(to);
        }
 
        return sja1105_manage_flood_domains(priv);
index f025f968f96da298772cc5716541900646c81c36..fde6e99274b60a43a7b9475d039fc3fdfdfe9e24 100644 (file)
@@ -528,7 +528,10 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port,
                return -EOPNOTSUPP;
 
        dsa_hsr_foreach_port(dp, ds, hsr) {
-               partner = dp;
+               if (dp->index != port) {
+                       partner = dp;
+                       break;
+               }
        }
 
        /* We can't enable redundancy on the switch until both
@@ -582,7 +585,10 @@ static int xrs700x_hsr_leave(struct dsa_switch *ds, int port,
        unsigned int val;
 
        dsa_hsr_foreach_port(dp, ds, hsr) {
-               partner = dp;
+               if (dp->index != port) {
+                       partner = dp;
+                       break;
+               }
        }
 
        if (!partner)
index 9b7f1af5f574708caf5475f62212c72d12fe942e..9e02f886459312ce022d10ce7dabd110917588d1 100644 (file)
@@ -1894,13 +1894,16 @@ static int alx_resume(struct device *dev)
 
        if (!netif_running(alx->dev))
                return 0;
-       netif_device_attach(alx->dev);
 
        rtnl_lock();
        err = __alx_open(alx, true);
        rtnl_unlock();
+       if (err)
+               return err;
 
-       return err;
+       netif_device_attach(alx->dev);
+
+       return 0;
 }
 
 static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
index 0b70e9e0ddad559d5d3c127682f1381ab94bf503..98cf82dea3e4a1cf67d6639d7a098f6a2f3ba16e 100644 (file)
@@ -592,6 +592,9 @@ static int bcm4908_enet_poll(struct napi_struct *napi, int weight)
                bcm4908_enet_intrs_on(enet);
        }
 
+       /* Hardware could disable ring if it run out of descriptors */
+       bcm4908_enet_dma_rx_ring_enable(enet, &enet->rx_ring);
+
        return handled;
 }
 
index a680fd9c68ea909c8e4a0618123010a615014907..b53a0d87371a204d43d037ab1a3e92bb89eb14cd 100644 (file)
@@ -8556,10 +8556,18 @@ static void bnxt_setup_inta(struct bnxt *bp)
        bp->irq_tbl[0].handler = bnxt_inta;
 }
 
+static int bnxt_init_int_mode(struct bnxt *bp);
+
 static int bnxt_setup_int_mode(struct bnxt *bp)
 {
        int rc;
 
+       if (!bp->irq_tbl) {
+               rc = bnxt_init_int_mode(bp);
+               if (rc || !bp->irq_tbl)
+                       return rc ?: -ENODEV;
+       }
+
        if (bp->flags & BNXT_FLAG_USING_MSIX)
                bnxt_setup_msix(bp);
        else
@@ -8744,7 +8752,7 @@ static int bnxt_init_inta(struct bnxt *bp)
 
 static int bnxt_init_int_mode(struct bnxt *bp)
 {
-       int rc = 0;
+       int rc = -ENODEV;
 
        if (bp->flags & BNXT_FLAG_MSIX_CAP)
                rc = bnxt_init_msix(bp);
@@ -9514,7 +9522,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
 {
        struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr;
        struct hwrm_func_drv_if_change_input req = {0};
-       bool resc_reinit = false, fw_reset = false;
+       bool fw_reset = !bp->irq_tbl;
+       bool resc_reinit = false;
        int rc, retry = 0;
        u32 flags = 0;
 
@@ -9557,6 +9566,7 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
 
        if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) {
                netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n");
+               set_bit(BNXT_STATE_ABORT_ERR, &bp->state);
                return -ENODEV;
        }
        if (resc_reinit || fw_reset) {
@@ -9890,6 +9900,9 @@ static int bnxt_reinit_after_abort(struct bnxt *bp)
        if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
                return -EBUSY;
 
+       if (bp->dev->reg_state == NETREG_UNREGISTERED)
+               return -ENODEV;
+
        rc = bnxt_fw_init_one(bp);
        if (!rc) {
                bnxt_clear_int_mode(bp);
index 472bf8f220bc6234e0cbf480b143acf33fd3cc04..15362d016a87e1862b756b7f10e8506795029462 100644 (file)
@@ -3954,6 +3954,13 @@ static int macb_init(struct platform_device *pdev)
        return 0;
 }
 
+static const struct macb_usrio_config macb_default_usrio = {
+       .mii = MACB_BIT(MII),
+       .rmii = MACB_BIT(RMII),
+       .rgmii = GEM_BIT(RGMII),
+       .refclk = MACB_BIT(CLKEN),
+};
+
 #if defined(CONFIG_OF)
 /* 1518 rounded up */
 #define AT91ETHER_MAX_RBUFF_SZ 0x600
@@ -4439,13 +4446,6 @@ static int fu540_c000_init(struct platform_device *pdev)
        return macb_init(pdev);
 }
 
-static const struct macb_usrio_config macb_default_usrio = {
-       .mii = MACB_BIT(MII),
-       .rmii = MACB_BIT(RMII),
-       .rgmii = GEM_BIT(RGMII),
-       .refclk = MACB_BIT(CLKEN),
-};
-
 static const struct macb_usrio_config sama7g5_usrio = {
        .mii = 0,
        .rmii = 1,
@@ -4594,6 +4594,7 @@ static const struct macb_config default_gem_config = {
        .dma_burst_length = 16,
        .clk_init = macb_clk_init,
        .init = macb_init,
+       .usrio = &macb_default_usrio,
        .jumbo_max_len = 10240,
 };
 
index 46a809f2aeca22e09ac1fea3948720a9bfb554a5..169e10c913780659bcd6e3128815a996a3896e3f 100644 (file)
@@ -672,7 +672,7 @@ static int chcr_ktls_cpl_act_open_rpl(struct adapter *adap,
        if (tx_info->pending_close) {
                spin_unlock(&tx_info->lock);
                if (!status) {
-                       /* it's a late success, tcb status is establised,
+                       /* it's a late success, tcb status is established,
                         * mark it close.
                         */
                        chcr_ktls_mark_tcb_close(tx_info);
@@ -930,7 +930,7 @@ chcr_ktls_get_tx_flits(u32 nr_frags, unsigned int key_ctx_len)
 }
 
 /*
- * chcr_ktls_check_tcp_options: To check if there is any TCP option availbale
+ * chcr_ktls_check_tcp_options: To check if there is any TCP option available
  * other than timestamp.
  * @skb - skb contains partial record..
  * return: 1 / 0
@@ -1115,7 +1115,7 @@ static int chcr_ktls_xmit_wr_complete(struct sk_buff *skb,
        }
 
        if (unlikely(credits < ETHTXQ_STOP_THRES)) {
-               /* Credits are below the threshold vaues, stop the queue after
+               /* Credits are below the threshold values, stop the queue after
                 * injecting the Work Request for this packet.
                 */
                chcr_eth_txq_stop(q);
@@ -2006,7 +2006,7 @@ static int chcr_ktls_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* TCP segments can be in received either complete or partial.
         * chcr_end_part_handler will handle cases if complete record or end
-        * part of the record is received. Incase of partial end part of record,
+        * part of the record is received. In case of partial end part of record,
         * we will send the complete record again.
         */
 
index 3fdc70dab5c141a74b536e88ecff8d9730d276c4..252adfa5d837ba1002498f3c6a83efd5f62187d1 100644 (file)
@@ -133,6 +133,8 @@ struct board_info {
        u32             wake_state;
 
        int             ip_summed;
+
+       struct regulator *power_supply;
 };
 
 /* debug code */
@@ -1449,7 +1451,7 @@ dm9000_probe(struct platform_device *pdev)
                if (ret) {
                        dev_err(dev, "failed to request reset gpio %d: %d\n",
                                reset_gpios, ret);
-                       return -ENODEV;
+                       goto out_regulator_disable;
                }
 
                /* According to manual PWRST# Low Period Min 1ms */
@@ -1461,8 +1463,10 @@ dm9000_probe(struct platform_device *pdev)
 
        if (!pdata) {
                pdata = dm9000_parse_dt(&pdev->dev);
-               if (IS_ERR(pdata))
-                       return PTR_ERR(pdata);
+               if (IS_ERR(pdata)) {
+                       ret = PTR_ERR(pdata);
+                       goto out_regulator_disable;
+               }
        }
 
        /* Init network device */
@@ -1479,6 +1483,8 @@ dm9000_probe(struct platform_device *pdev)
 
        db->dev = &pdev->dev;
        db->ndev = ndev;
+       if (!IS_ERR(power))
+               db->power_supply = power;
 
        spin_lock_init(&db->lock);
        mutex_init(&db->addr_lock);
@@ -1501,7 +1507,7 @@ dm9000_probe(struct platform_device *pdev)
                goto out;
        }
 
-       db->irq_wake = platform_get_irq(pdev, 1);
+       db->irq_wake = platform_get_irq_optional(pdev, 1);
        if (db->irq_wake >= 0) {
                dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);
 
@@ -1703,6 +1709,10 @@ out:
        dm9000_release_board(pdev, db);
        free_netdev(ndev);
 
+out_regulator_disable:
+       if (!IS_ERR(power))
+               regulator_disable(power);
+
        return ret;
 }
 
@@ -1760,10 +1770,13 @@ static int
 dm9000_drv_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
+       struct board_info *dm = to_dm9000_board(ndev);
 
        unregister_netdev(ndev);
-       dm9000_release_board(pdev, netdev_priv(ndev));
+       dm9000_release_board(pdev, dm);
        free_netdev(ndev);              /* free device structure */
+       if (dm->power_supply)
+               regulator_disable(dm->power_supply);
 
        dev_dbg(&pdev->dev, "released and freed device\n");
        return 0;
index c78d12229730ba27cb2206f7c1609894059ccec2..09471329f3a36ebaee687b105556f33ba22c1b5c 100644 (file)
@@ -281,6 +281,8 @@ static int enetc_poll(struct napi_struct *napi, int budget)
        int work_done;
        int i;
 
+       enetc_lock_mdio();
+
        for (i = 0; i < v->count_tx_rings; i++)
                if (!enetc_clean_tx_ring(&v->tx_ring[i], budget))
                        complete = false;
@@ -291,8 +293,10 @@ static int enetc_poll(struct napi_struct *napi, int budget)
        if (work_done)
                v->rx_napi_work = true;
 
-       if (!complete)
+       if (!complete) {
+               enetc_unlock_mdio();
                return budget;
+       }
 
        napi_complete_done(napi, work_done);
 
@@ -301,8 +305,6 @@ static int enetc_poll(struct napi_struct *napi, int budget)
 
        v->rx_napi_work = false;
 
-       enetc_lock_mdio();
-
        /* enable interrupts */
        enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE);
 
@@ -327,8 +329,8 @@ static void enetc_get_tx_tstamp(struct enetc_hw *hw, union enetc_tx_bd *txbd,
 {
        u32 lo, hi, tstamp_lo;
 
-       lo = enetc_rd(hw, ENETC_SICTR0);
-       hi = enetc_rd(hw, ENETC_SICTR1);
+       lo = enetc_rd_hot(hw, ENETC_SICTR0);
+       hi = enetc_rd_hot(hw, ENETC_SICTR1);
        tstamp_lo = le32_to_cpu(txbd->wb.tstamp);
        if (lo <= tstamp_lo)
                hi -= 1;
@@ -342,6 +344,12 @@ static void enetc_tstamp_tx(struct sk_buff *skb, u64 tstamp)
        if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) {
                memset(&shhwtstamps, 0, sizeof(shhwtstamps));
                shhwtstamps.hwtstamp = ns_to_ktime(tstamp);
+               /* Ensure skb_mstamp_ns, which might have been populated with
+                * the txtime, is not mistaken for a software timestamp,
+                * because this will prevent the dispatch of our hardware
+                * timestamp to the socket.
+                */
+               skb->tstamp = ktime_set(0, 0);
                skb_tstamp_tx(skb, &shhwtstamps);
        }
 }
@@ -358,9 +366,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
        i = tx_ring->next_to_clean;
        tx_swbd = &tx_ring->tx_swbd[i];
 
-       enetc_lock_mdio();
        bds_to_clean = enetc_bd_ready_count(tx_ring, i);
-       enetc_unlock_mdio();
 
        do_tstamp = false;
 
@@ -403,8 +409,6 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
                        tx_swbd = tx_ring->tx_swbd;
                }
 
-               enetc_lock_mdio();
-
                /* BD iteration loop end */
                if (is_eof) {
                        tx_frm_cnt++;
@@ -415,8 +419,6 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
 
                if (unlikely(!bds_to_clean))
                        bds_to_clean = enetc_bd_ready_count(tx_ring, i);
-
-               enetc_unlock_mdio();
        }
 
        tx_ring->next_to_clean = i;
@@ -527,9 +529,8 @@ static void enetc_get_rx_tstamp(struct net_device *ndev,
 static void enetc_get_offloads(struct enetc_bdr *rx_ring,
                               union enetc_rx_bd *rxbd, struct sk_buff *skb)
 {
-#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
        struct enetc_ndev_priv *priv = netdev_priv(rx_ring->ndev);
-#endif
+
        /* TODO: hashing */
        if (rx_ring->ndev->features & NETIF_F_RXCSUM) {
                u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum);
@@ -538,12 +539,31 @@ static void enetc_get_offloads(struct enetc_bdr *rx_ring,
                skb->ip_summed = CHECKSUM_COMPLETE;
        }
 
-       /* copy VLAN to skb, if one is extracted, for now we assume it's a
-        * standard TPID, but HW also supports custom values
-        */
-       if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN)
-               __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-                                      le16_to_cpu(rxbd->r.vlan_opt));
+       if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) {
+               __be16 tpid = 0;
+
+               switch (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TPID) {
+               case 0:
+                       tpid = htons(ETH_P_8021Q);
+                       break;
+               case 1:
+                       tpid = htons(ETH_P_8021AD);
+                       break;
+               case 2:
+                       tpid = htons(enetc_port_rd(&priv->si->hw,
+                                                  ENETC_PCVLANR1));
+                       break;
+               case 3:
+                       tpid = htons(enetc_port_rd(&priv->si->hw,
+                                                  ENETC_PCVLANR2));
+                       break;
+               default:
+                       break;
+               }
+
+               __vlan_hwaccel_put_tag(skb, tpid, le16_to_cpu(rxbd->r.vlan_opt));
+       }
+
 #ifdef CONFIG_FSL_ENETC_PTP_CLOCK
        if (priv->active_offloads & ENETC_F_RX_TSTAMP)
                enetc_get_rx_tstamp(rx_ring->ndev, rxbd, skb);
@@ -660,8 +680,6 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
                u32 bd_status;
                u16 size;
 
-               enetc_lock_mdio();
-
                if (cleaned_cnt >= ENETC_RXBD_BUNDLE) {
                        int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
 
@@ -672,19 +690,15 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
 
                rxbd = enetc_rxbd(rx_ring, i);
                bd_status = le32_to_cpu(rxbd->r.lstatus);
-               if (!bd_status) {
-                       enetc_unlock_mdio();
+               if (!bd_status)
                        break;
-               }
 
                enetc_wr_reg_hot(rx_ring->idr, BIT(rx_ring->index));
                dma_rmb(); /* for reading other rxbd fields */
                size = le16_to_cpu(rxbd->r.buf_len);
                skb = enetc_map_rx_buff_to_skb(rx_ring, i, size);
-               if (!skb) {
-                       enetc_unlock_mdio();
+               if (!skb)
                        break;
-               }
 
                enetc_get_offloads(rx_ring, rxbd, skb);
 
@@ -696,7 +710,6 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
 
                if (unlikely(bd_status &
                             ENETC_RXBD_LSTATUS(ENETC_RXBD_ERR_MASK))) {
-                       enetc_unlock_mdio();
                        dev_kfree_skb(skb);
                        while (!(bd_status & ENETC_RXBD_LSTATUS_F)) {
                                dma_rmb();
@@ -736,8 +749,6 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
 
                enetc_process_skb(rx_ring, skb);
 
-               enetc_unlock_mdio();
-
                napi_gro_receive(napi, skb);
 
                rx_frm_cnt++;
@@ -984,7 +995,7 @@ static void enetc_free_rxtx_rings(struct enetc_ndev_priv *priv)
                enetc_free_tx_ring(priv->tx_ring[i]);
 }
 
-static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
+int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
 {
        int size = cbdr->bd_count * sizeof(struct enetc_cbd);
 
@@ -1005,7 +1016,7 @@ static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
        return 0;
 }
 
-static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
+void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
 {
        int size = cbdr->bd_count * sizeof(struct enetc_cbd);
 
@@ -1013,7 +1024,7 @@ static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
        cbdr->bd_base = NULL;
 }
 
-static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr)
+void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr)
 {
        /* set CBDR cache attributes */
        enetc_wr(hw, ENETC_SICAR2,
@@ -1033,7 +1044,7 @@ static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr)
        cbdr->cir = hw->reg + ENETC_SICBDRCIR;
 }
 
-static void enetc_clear_cbdr(struct enetc_hw *hw)
+void enetc_clear_cbdr(struct enetc_hw *hw)
 {
        enetc_wr(hw, ENETC_SICBDRMR, 0);
 }
@@ -1058,13 +1069,12 @@ static int enetc_setup_default_rss_table(struct enetc_si *si, int num_groups)
        return 0;
 }
 
-static int enetc_configure_si(struct enetc_ndev_priv *priv)
+int enetc_configure_si(struct enetc_ndev_priv *priv)
 {
        struct enetc_si *si = priv->si;
        struct enetc_hw *hw = &si->hw;
        int err;
 
-       enetc_setup_cbdr(hw, &si->cbd_ring);
        /* set SI cache attributes */
        enetc_wr(hw, ENETC_SICAR0,
                 ENETC_SICAR_RD_COHERENT | ENETC_SICAR_WR_COHERENT);
@@ -1112,6 +1122,8 @@ int enetc_alloc_si_resources(struct enetc_ndev_priv *priv)
        if (err)
                return err;
 
+       enetc_setup_cbdr(&si->hw, &si->cbd_ring);
+
        priv->cls_rules = kcalloc(si->num_fs_entries, sizeof(*priv->cls_rules),
                                  GFP_KERNEL);
        if (!priv->cls_rules) {
@@ -1119,14 +1131,8 @@ int enetc_alloc_si_resources(struct enetc_ndev_priv *priv)
                goto err_alloc_cls;
        }
 
-       err = enetc_configure_si(priv);
-       if (err)
-               goto err_config_si;
-
        return 0;
 
-err_config_si:
-       kfree(priv->cls_rules);
 err_alloc_cls:
        enetc_clear_cbdr(&si->hw);
        enetc_free_cbdr(priv->dev, &si->cbd_ring);
@@ -1212,7 +1218,8 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
        rx_ring->idr = hw->reg + ENETC_SIRXIDR;
 
        enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring));
-       enetc_wr(hw, ENETC_SIRXIDR, rx_ring->next_to_use);
+       /* update ENETC's consumer index */
+       enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use);
 
        /* enable ring */
        enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr);
index 8532d23b54f5f14c57dec2eb47855b6fcd35c4cb..8b380fc13314a3fd43c9ba0ddf71bb6284264fb0 100644 (file)
@@ -292,6 +292,7 @@ void enetc_get_si_caps(struct enetc_si *si);
 void enetc_init_si_rings_params(struct enetc_ndev_priv *priv);
 int enetc_alloc_si_resources(struct enetc_ndev_priv *priv);
 void enetc_free_si_resources(struct enetc_ndev_priv *priv);
+int enetc_configure_si(struct enetc_ndev_priv *priv);
 
 int enetc_open(struct net_device *ndev);
 int enetc_close(struct net_device *ndev);
@@ -309,6 +310,10 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 void enetc_set_ethtool_ops(struct net_device *ndev);
 
 /* control buffer descriptor ring (CBDR) */
+int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr);
+void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr);
+void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr);
+void enetc_clear_cbdr(struct enetc_hw *hw);
 int enetc_set_mac_flt_entry(struct enetc_si *si, int index,
                            char *mac_addr, int si_map);
 int enetc_clear_mac_flt_entry(struct enetc_si *si, int index);
index c71fe8d751d50342a9ad2d764a4afe01ba1aaf18..00938f7960a43aae09bc10c44fc5cea0db313d4b 100644 (file)
@@ -172,6 +172,8 @@ enum enetc_bdr_type {TX, RX};
 #define ENETC_PSIPMAR0(n)      (0x0100 + (n) * 0x8) /* n = SI index */
 #define ENETC_PSIPMAR1(n)      (0x0104 + (n) * 0x8)
 #define ENETC_PVCLCTR          0x0208
+#define ENETC_PCVLANR1         0x0210
+#define ENETC_PCVLANR2         0x0214
 #define ENETC_VLAN_TYPE_C      BIT(0)
 #define ENETC_VLAN_TYPE_S      BIT(1)
 #define ENETC_PVCLCTR_OVTPIDL(bmp)     ((bmp) & 0xff) /* VLAN_TYPE */
@@ -232,14 +234,23 @@ enum enetc_bdr_type {TX, RX};
 #define ENETC_PM0_MAXFRM       0x8014
 #define ENETC_SET_TX_MTU(val)  ((val) << 16)
 #define ENETC_SET_MAXFRM(val)  ((val) & 0xffff)
+#define ENETC_PM0_RX_FIFO      0x801c
+#define ENETC_PM0_RX_FIFO_VAL  1
 
 #define ENETC_PM_IMDIO_BASE    0x8030
 
 #define ENETC_PM0_IF_MODE      0x8300
-#define ENETC_PMO_IFM_RG       BIT(2)
+#define ENETC_PM0_IFM_RG       BIT(2)
 #define ENETC_PM0_IFM_RLP      (BIT(5) | BIT(11))
-#define ENETC_PM0_IFM_RGAUTO   (BIT(15) | ENETC_PMO_IFM_RG | BIT(1))
-#define ENETC_PM0_IFM_XGMII    BIT(12)
+#define ENETC_PM0_IFM_EN_AUTO  BIT(15)
+#define ENETC_PM0_IFM_SSP_MASK GENMASK(14, 13)
+#define ENETC_PM0_IFM_SSP_1000 (2 << 13)
+#define ENETC_PM0_IFM_SSP_100  (0 << 13)
+#define ENETC_PM0_IFM_SSP_10   (1 << 13)
+#define ENETC_PM0_IFM_FULL_DPX BIT(12)
+#define ENETC_PM0_IFM_IFMODE_MASK GENMASK(1, 0)
+#define ENETC_PM0_IFM_IFMODE_XGMII 0
+#define ENETC_PM0_IFM_IFMODE_GMII 2
 #define ENETC_PSIDCAPR         0x1b08
 #define ENETC_PSIDCAPR_MSK     GENMASK(15, 0)
 #define ENETC_PSFCAPR          0x1b18
@@ -453,6 +464,8 @@ static inline u64 _enetc_rd_reg64_wa(void __iomem *reg)
 #define enetc_wr_reg(reg, val)         _enetc_wr_reg_wa((reg), (val))
 #define enetc_rd(hw, off)              enetc_rd_reg((hw)->reg + (off))
 #define enetc_wr(hw, off, val)         enetc_wr_reg((hw)->reg + (off), val)
+#define enetc_rd_hot(hw, off)          enetc_rd_reg_hot((hw)->reg + (off))
+#define enetc_wr_hot(hw, off, val)     enetc_wr_reg_hot((hw)->reg + (off), val)
 #define enetc_rd64(hw, off)            _enetc_rd_reg64_wa((hw)->reg + (off))
 /* port register accessors - PF only */
 #define enetc_port_rd(hw, off)         enetc_rd_reg((hw)->port + (off))
@@ -568,6 +581,7 @@ union enetc_rx_bd {
 #define ENETC_RXBD_LSTATUS(flags)      ((flags) << 16)
 #define ENETC_RXBD_FLAG_VLAN   BIT(9)
 #define ENETC_RXBD_FLAG_TSTMP  BIT(10)
+#define ENETC_RXBD_FLAG_TPID   GENMASK(1, 0)
 
 #define ENETC_MAC_ADDR_FILT_CNT        8 /* # of supported entries per port */
 #define EMETC_MAC_ADDR_FILT_RES        3 /* # of reserved entries at the beginning */
index 515c5b29d7aabe4553c3e547c08beebaae86cb87..224fc37a6757cd5d8a87532d3ac0360433e5957c 100644 (file)
@@ -190,7 +190,6 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
        struct enetc_pf *pf = enetc_si_priv(priv->si);
-       char vlan_promisc_simap = pf->vlan_promisc_simap;
        struct enetc_hw *hw = &priv->si->hw;
        bool uprom = false, mprom = false;
        struct enetc_mac_filter *filter;
@@ -203,16 +202,12 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
                psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0);
                uprom = true;
                mprom = true;
-               /* Enable VLAN promiscuous mode for SI0 (PF) */
-               vlan_promisc_simap |= BIT(0);
        } else if (ndev->flags & IFF_ALLMULTI) {
                /* enable multi cast promisc mode for SI0 (PF) */
                psipmr = ENETC_PSIPMR_SET_MP(0);
                mprom = true;
        }
 
-       enetc_set_vlan_promisc(&pf->si->hw, vlan_promisc_simap);
-
        /* first 2 filter entries belong to PF */
        if (!uprom) {
                /* Update unicast filters */
@@ -320,7 +315,7 @@ static void enetc_set_loopback(struct net_device *ndev, bool en)
        u32 reg;
 
        reg = enetc_port_rd(hw, ENETC_PM0_IF_MODE);
-       if (reg & ENETC_PMO_IFM_RG) {
+       if (reg & ENETC_PM0_IFM_RG) {
                /* RGMII mode */
                reg = (reg & ~ENETC_PM0_IFM_RLP) |
                      (en ? ENETC_PM0_IFM_RLP : 0);
@@ -495,17 +490,30 @@ static void enetc_configure_port_mac(struct enetc_hw *hw)
 
        enetc_port_wr(hw, ENETC_PM1_CMD_CFG, ENETC_PM0_CMD_PHY_TX_EN |
                      ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC);
+
+       /* On LS1028A, the MAC RX FIFO defaults to 2, which is too high
+        * and may lead to RX lock-up under traffic. Set it to 1 instead,
+        * as recommended by the hardware team.
+        */
+       enetc_port_wr(hw, ENETC_PM0_RX_FIFO, ENETC_PM0_RX_FIFO_VAL);
 }
 
 static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode)
 {
-       /* set auto-speed for RGMII */
-       if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG ||
-           phy_interface_mode_is_rgmii(phy_mode))
-               enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO);
+       u32 val;
+
+       if (phy_interface_mode_is_rgmii(phy_mode)) {
+               val = enetc_port_rd(hw, ENETC_PM0_IF_MODE);
+               val &= ~ENETC_PM0_IFM_EN_AUTO;
+               val &= ENETC_PM0_IFM_IFMODE_MASK;
+               val |= ENETC_PM0_IFM_IFMODE_GMII | ENETC_PM0_IFM_RG;
+               enetc_port_wr(hw, ENETC_PM0_IF_MODE, val);
+       }
 
-       if (phy_mode == PHY_INTERFACE_MODE_USXGMII)
-               enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII);
+       if (phy_mode == PHY_INTERFACE_MODE_USXGMII) {
+               val = ENETC_PM0_IFM_FULL_DPX | ENETC_PM0_IFM_IFMODE_XGMII;
+               enetc_port_wr(hw, ENETC_PM0_IF_MODE, val);
+       }
 }
 
 static void enetc_mac_enable(struct enetc_hw *hw, bool en)
@@ -937,6 +945,34 @@ static void enetc_pl_mac_config(struct phylink_config *config,
                phylink_set_pcs(priv->phylink, &pf->pcs->pcs);
 }
 
+static void enetc_force_rgmii_mac(struct enetc_hw *hw, int speed, int duplex)
+{
+       u32 old_val, val;
+
+       old_val = val = enetc_port_rd(hw, ENETC_PM0_IF_MODE);
+
+       if (speed == SPEED_1000) {
+               val &= ~ENETC_PM0_IFM_SSP_MASK;
+               val |= ENETC_PM0_IFM_SSP_1000;
+       } else if (speed == SPEED_100) {
+               val &= ~ENETC_PM0_IFM_SSP_MASK;
+               val |= ENETC_PM0_IFM_SSP_100;
+       } else if (speed == SPEED_10) {
+               val &= ~ENETC_PM0_IFM_SSP_MASK;
+               val |= ENETC_PM0_IFM_SSP_10;
+       }
+
+       if (duplex == DUPLEX_FULL)
+               val |= ENETC_PM0_IFM_FULL_DPX;
+       else
+               val &= ~ENETC_PM0_IFM_FULL_DPX;
+
+       if (val == old_val)
+               return;
+
+       enetc_port_wr(hw, ENETC_PM0_IF_MODE, val);
+}
+
 static void enetc_pl_mac_link_up(struct phylink_config *config,
                                 struct phy_device *phy, unsigned int mode,
                                 phy_interface_t interface, int speed,
@@ -949,6 +985,10 @@ static void enetc_pl_mac_link_up(struct phylink_config *config,
        if (priv->active_offloads & ENETC_F_QBV)
                enetc_sched_speed_set(priv, speed);
 
+       if (!phylink_autoneg_inband(mode) &&
+           phy_interface_mode_is_rgmii(interface))
+               enetc_force_rgmii_mac(&pf->si->hw, speed, duplex);
+
        enetc_mac_enable(&pf->si->hw, true);
 }
 
@@ -1041,6 +1081,26 @@ static int enetc_init_port_rss_memory(struct enetc_si *si)
        return err;
 }
 
+static void enetc_init_unused_port(struct enetc_si *si)
+{
+       struct device *dev = &si->pdev->dev;
+       struct enetc_hw *hw = &si->hw;
+       int err;
+
+       si->cbd_ring.bd_count = ENETC_CBDR_DEFAULT_SIZE;
+       err = enetc_alloc_cbdr(dev, &si->cbd_ring);
+       if (err)
+               return;
+
+       enetc_setup_cbdr(hw, &si->cbd_ring);
+
+       enetc_init_port_rfs_memory(si);
+       enetc_init_port_rss_memory(si);
+
+       enetc_clear_cbdr(hw);
+       enetc_free_cbdr(dev, &si->cbd_ring);
+}
+
 static int enetc_pf_probe(struct pci_dev *pdev,
                          const struct pci_device_id *ent)
 {
@@ -1051,11 +1111,6 @@ static int enetc_pf_probe(struct pci_dev *pdev,
        struct enetc_pf *pf;
        int err;
 
-       if (node && !of_device_is_available(node)) {
-               dev_info(&pdev->dev, "device is disabled, skipping\n");
-               return -ENODEV;
-       }
-
        err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf));
        if (err) {
                dev_err(&pdev->dev, "PCI probing failed\n");
@@ -1069,6 +1124,13 @@ static int enetc_pf_probe(struct pci_dev *pdev,
                goto err_map_pf_space;
        }
 
+       if (node && !of_device_is_available(node)) {
+               enetc_init_unused_port(si);
+               dev_info(&pdev->dev, "device is disabled, skipping\n");
+               err = -ENODEV;
+               goto err_device_disabled;
+       }
+
        pf = enetc_si_priv(si);
        pf->si = si;
        pf->total_vfs = pci_sriov_get_totalvfs(pdev);
@@ -1108,6 +1170,12 @@ static int enetc_pf_probe(struct pci_dev *pdev,
                goto err_init_port_rss;
        }
 
+       err = enetc_configure_si(priv);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to configure SI\n");
+               goto err_config_si;
+       }
+
        err = enetc_alloc_msix(priv);
        if (err) {
                dev_err(&pdev->dev, "MSIX alloc failed\n");
@@ -1136,6 +1204,7 @@ err_phylink_create:
        enetc_mdiobus_destroy(pf);
 err_mdiobus_create:
        enetc_free_msix(priv);
+err_config_si:
 err_init_port_rss:
 err_init_port_rfs:
 err_alloc_msix:
@@ -1144,6 +1213,7 @@ err_alloc_si_res:
        si->ndev = NULL;
        free_netdev(ndev);
 err_alloc_netdev:
+err_device_disabled:
 err_map_pf_space:
        enetc_pci_remove(pdev);
 
index 39c1a09e69a95d8ccb1fa0981a0b992c2ec07eae..9b755a84c2d6276a25893aaaa9530a3b11d62379 100644 (file)
@@ -171,6 +171,12 @@ static int enetc_vf_probe(struct pci_dev *pdev,
                goto err_alloc_si_res;
        }
 
+       err = enetc_configure_si(priv);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to configure SI\n");
+               goto err_config_si;
+       }
+
        err = enetc_alloc_msix(priv);
        if (err) {
                dev_err(&pdev->dev, "MSIX alloc failed\n");
@@ -187,6 +193,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
 
 err_reg_netdev:
        enetc_free_msix(priv);
+err_config_si:
 err_alloc_msix:
        enetc_free_si_resources(priv);
 err_alloc_si_res:
index 2e344aada4c6027a2a235d1f618be321e5001f0d..1753807cbf97e2bff83a218a8ba33f662fe593b7 100644 (file)
@@ -377,9 +377,16 @@ static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
        u64 ns;
        unsigned long flags;
 
+       mutex_lock(&adapter->ptp_clk_mutex);
+       /* Check the ptp clock */
+       if (!adapter->ptp_clk_on) {
+               mutex_unlock(&adapter->ptp_clk_mutex);
+               return -EINVAL;
+       }
        spin_lock_irqsave(&adapter->tmreg_lock, flags);
        ns = timecounter_read(&adapter->tc);
        spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+       mutex_unlock(&adapter->ptp_clk_mutex);
 
        *ts = ns_to_timespec64(ns);
 
index 541de32ea6622e355130ad5d284ae6414e278a5a..1cf8ef717453dd46bbde2c98e1525618f789b8e8 100644 (file)
@@ -2390,6 +2390,10 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
                if (lstatus & BD_LFLAG(RXBD_LAST))
                        size -= skb->len;
 
+               WARN(size < 0, "gianfar: rx fragment size underflow");
+               if (size < 0)
+                       return false;
+
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
                                rxb->page_offset + RXBUF_ALIGNMENT,
                                size, GFAR_RXB_TRUESIZE);
@@ -2552,6 +2556,17 @@ static int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue,
                if (lstatus & BD_LFLAG(RXBD_EMPTY))
                        break;
 
+               /* lost RXBD_LAST descriptor due to overrun */
+               if (skb &&
+                   (lstatus & BD_LFLAG(RXBD_FIRST))) {
+                       /* discard faulty buffer */
+                       dev_kfree_skb(skb);
+                       skb = NULL;
+                       rx_queue->stats.rx_dropped++;
+
+                       /* can continue normally */
+               }
+
                /* order rx buffer descriptor reads */
                rmb();
 
index 5d7824d2b4d475fb2e07f912afd197e980afdf61..c66a7a51198ee4431f4edaacb742f2135027cb9d 100644 (file)
@@ -1663,8 +1663,10 @@ static int hns_nic_clear_all_rx_fetch(struct net_device *ndev)
                        for (j = 0; j < fetch_num; j++) {
                                /* alloc one skb and init */
                                skb = hns_assemble_skb(ndev);
-                               if (!skb)
+                               if (!skb) {
+                                       ret = -ENOMEM;
                                        goto out;
+                               }
                                rd = &tx_ring_data(priv, skb->queue_mapping);
                                hns_nic_net_xmit_hw(ndev, skb, rd);
 
index ff52a65b4cffbc9555687f78d8e01fb361dfc416..057dda735492478fcf38de0229312e90b4bf22a9 100644 (file)
@@ -1053,16 +1053,16 @@ struct hclge_fd_tcam_config_3_cmd {
 #define HCLGE_FD_AD_DROP_B             0
 #define HCLGE_FD_AD_DIRECT_QID_B       1
 #define HCLGE_FD_AD_QID_S              2
-#define HCLGE_FD_AD_QID_M              GENMASK(12, 2)
+#define HCLGE_FD_AD_QID_M              GENMASK(11, 2)
 #define HCLGE_FD_AD_USE_COUNTER_B      12
 #define HCLGE_FD_AD_COUNTER_NUM_S      13
 #define HCLGE_FD_AD_COUNTER_NUM_M      GENMASK(20, 13)
 #define HCLGE_FD_AD_NXT_STEP_B         20
 #define HCLGE_FD_AD_NXT_KEY_S          21
-#define HCLGE_FD_AD_NXT_KEY_M          GENMASK(26, 21)
+#define HCLGE_FD_AD_NXT_KEY_M          GENMASK(25, 21)
 #define HCLGE_FD_AD_WR_RULE_ID_B       0
 #define HCLGE_FD_AD_RULE_ID_S          1
-#define HCLGE_FD_AD_RULE_ID_M          GENMASK(13, 1)
+#define HCLGE_FD_AD_RULE_ID_M          GENMASK(12, 1)
 #define HCLGE_FD_AD_TC_OVRD_B          16
 #define HCLGE_FD_AD_TC_SIZE_S          17
 #define HCLGE_FD_AD_TC_SIZE_M          GENMASK(20, 17)
index 34b744df67096ba826b68b688da81ca8856f8407..e3f81c7e0ce74fa185773d3fc5f1284abf88d0e4 100644 (file)
@@ -5245,9 +5245,9 @@ static bool hclge_fd_convert_tuple(u32 tuple_bit, u8 *key_x, u8 *key_y,
        case BIT(INNER_SRC_MAC):
                for (i = 0; i < ETH_ALEN; i++) {
                        calc_x(key_x[ETH_ALEN - 1 - i], rule->tuples.src_mac[i],
-                              rule->tuples.src_mac[i]);
+                              rule->tuples_mask.src_mac[i]);
                        calc_y(key_y[ETH_ALEN - 1 - i], rule->tuples.src_mac[i],
-                              rule->tuples.src_mac[i]);
+                              rule->tuples_mask.src_mac[i]);
                }
 
                return true;
@@ -6330,8 +6330,7 @@ static void hclge_fd_get_ext_info(struct ethtool_rx_flow_spec *fs,
                fs->h_ext.vlan_tci = cpu_to_be16(rule->tuples.vlan_tag1);
                fs->m_ext.vlan_tci =
                                rule->unused_tuple & BIT(INNER_VLAN_TAG_FST) ?
-                               cpu_to_be16(VLAN_VID_MASK) :
-                               cpu_to_be16(rule->tuples_mask.vlan_tag1);
+                               0 : cpu_to_be16(rule->tuples_mask.vlan_tag1);
        }
 
        if (fs->flow_type & FLOW_MAC_EXT) {
index c3ec9ceed833ed4e6d128c86bbf09aa476de91b5..7fea9ae60f130b8d8e9b974be2d9d92544a18df0 100644 (file)
@@ -1758,7 +1758,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
        return 0;
 }
 
-static int ibmveth_remove(struct vio_dev *dev)
+static void ibmveth_remove(struct vio_dev *dev)
 {
        struct net_device *netdev = dev_get_drvdata(&dev->dev);
        struct ibmveth_adapter *adapter = netdev_priv(netdev);
@@ -1771,8 +1771,6 @@ static int ibmveth_remove(struct vio_dev *dev)
 
        free_netdev(netdev);
        dev_set_drvdata(&dev->dev, NULL);
-
-       return 0;
 }
 
 static struct attribute veth_active_attr;
index 118a4bd3f8779031f68cf925a7937c51dbea646f..9c6438d3b3a5be52fe3cd02f97481964b6bcedf7 100644 (file)
@@ -78,7 +78,6 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
 
 static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
-static int ibmvnic_remove(struct vio_dev *);
 static void release_sub_crqs(struct ibmvnic_adapter *, bool);
 static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
 static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
@@ -1906,10 +1905,9 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
-       if (adapter->state != VNIC_PROBED) {
-               ether_addr_copy(adapter->mac_addr, addr->sa_data);
+       ether_addr_copy(adapter->mac_addr, addr->sa_data);
+       if (adapter->state != VNIC_PROBED)
                rc = __ibmvnic_set_mac(netdev, addr->sa_data);
-       }
 
        return rc;
 }
@@ -5219,16 +5217,14 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
 {
        struct device *dev = &adapter->vdev->dev;
        unsigned long timeout = msecs_to_jiffies(20000);
-       u64 old_num_rx_queues, old_num_tx_queues;
+       u64 old_num_rx_queues = adapter->req_rx_queues;
+       u64 old_num_tx_queues = adapter->req_tx_queues;
        int rc;
 
        adapter->from_passive_init = false;
 
-       if (reset) {
-               old_num_rx_queues = adapter->req_rx_queues;
-               old_num_tx_queues = adapter->req_tx_queues;
+       if (reset)
                reinit_completion(&adapter->init_done);
-       }
 
        adapter->init_done_rc = 0;
        rc = ibmvnic_send_crq_init(adapter);
@@ -5396,7 +5392,7 @@ ibmvnic_init_fail:
        return rc;
 }
 
-static int ibmvnic_remove(struct vio_dev *dev)
+static void ibmvnic_remove(struct vio_dev *dev)
 {
        struct net_device *netdev = dev_get_drvdata(&dev->dev);
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -5411,9 +5407,9 @@ static int ibmvnic_remove(struct vio_dev *dev)
         * after setting state, so __ibmvnic_reset() which is called
         * from the flush_work() below, can make progress.
         */
-       spin_lock_irqsave(&adapter->rwi_lock, flags);
+       spin_lock(&adapter->rwi_lock);
        adapter->state = VNIC_REMOVING;
-       spin_unlock_irqrestore(&adapter->rwi_lock, flags);
+       spin_unlock(&adapter->rwi_lock);
 
        spin_unlock_irqrestore(&adapter->state_lock, flags);
 
@@ -5437,8 +5433,6 @@ static int ibmvnic_remove(struct vio_dev *dev)
        device_remove_file(&dev->dev, &dev_attr_failover);
        free_netdev(netdev);
        dev_set_drvdata(&dev->dev, NULL);
-
-       return 0;
 }
 
 static ssize_t failover_store(struct device *dev, struct device_attribute *attr,
index 0a867d64d46753ae4f065ce479b4f4a139f38067..dc5b3c06d1e01451917d75e5bedf83bdf8bec8da 100644 (file)
@@ -1776,7 +1776,8 @@ static int iavf_init_get_resources(struct iavf_adapter *adapter)
                goto err_alloc;
        }
 
-       if (iavf_process_config(adapter))
+       err = iavf_process_config(adapter);
+       if (err)
                goto err_alloc;
        adapter->current_op = VIRTCHNL_OP_UNKNOWN;
 
index eca73526ac86bc609d560023596b9d2391caead0..54d47265a7ac1038e3e5ab8938f6aab3238ce8c9 100644 (file)
@@ -575,6 +575,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
                return -EINVAL;
        }
 
+       if (xs->props.mode != XFRM_MODE_TRANSPORT) {
+               netdev_err(dev, "Unsupported mode for ipsec offload\n");
+               return -EINVAL;
+       }
+
        if (ixgbe_ipsec_check_mgmt_ip(xs)) {
                netdev_err(dev, "IPsec IP addr clash with mgmt filters\n");
                return -EINVAL;
index fae84202d870c9c2206904349e790f0cc1125362..9f3f12e2ccf231a7e9002d89096ab86e4e74d050 100644 (file)
@@ -9565,8 +9565,10 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
        ixgbe_atr_compute_perfect_hash_82599(&input->filter, mask);
        err = ixgbe_fdir_write_perfect_filter_82599(hw, &input->filter,
                                                    input->sw_idx, queue);
-       if (!err)
-               ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx);
+       if (err)
+               goto err_out_w_lock;
+
+       ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx);
        spin_unlock(&adapter->fdir_perfect_lock);
 
        if ((uhtid != 0x800) && (adapter->jump_tables[uhtid]))
index 5170dd9d8705b0b6467151b9154e5f7b2ea8d78a..caaea2c920a6e48d08abc13501996960755dbdea 100644 (file)
@@ -272,6 +272,11 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
                return -EINVAL;
        }
 
+       if (xs->props.mode != XFRM_MODE_TRANSPORT) {
+               netdev_err(dev, "Unsupported mode for ipsec offload\n");
+               return -EINVAL;
+       }
+
        if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
                struct rx_sa rsa;
 
index 9caa375d01b15dec793e26209b8ea8cc97bda720..68deae529bc94a4ddb32503ce6424d8122495c6b 100644 (file)
@@ -56,7 +56,9 @@ static bool is_dev_rpm(void *cgxd)
 
 bool is_lmac_valid(struct cgx *cgx, int lmac_id)
 {
-       return cgx && test_bit(lmac_id, &cgx->lmac_bmap);
+       if (!cgx || lmac_id < 0 || lmac_id >= MAX_LMAC_PER_CGX)
+               return false;
+       return test_bit(lmac_id, &cgx->lmac_bmap);
 }
 
 struct mac_ops *get_mac_ops(void *cgxd)
index a8641a407c06a817faed34e537420ffc25e1e924..96d2891f1675ab80c4b0a1d04fc78b7e5ce115f9 100644 (file)
@@ -1225,8 +1225,6 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
                goto push_new_skb;
        }
 
-       desc_data.dma_addr = new_dma_addr;
-
        /* We can't fail anymore at this point: it's safe to unmap the skb. */
        mtk_star_dma_unmap_rx(priv, &desc_data);
 
@@ -1236,6 +1234,9 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
        desc_data.skb->dev = ndev;
        netif_receive_skb(desc_data.skb);
 
+       /* update dma_addr for new skb */
+       desc_data.dma_addr = new_dma_addr;
+
 push_new_skb:
        desc_data.len = skb_tailroom(new_skb);
        desc_data.skb = new_skb;
index 23849f2b9c2527f4ab85815b7ada6260722d5742..1434df66fcf2ee0910d086e44694dfd35d7f1039 100644 (file)
@@ -47,7 +47,7 @@
 #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff)
 #define EN_ETHTOOL_WORD_MASK  cpu_to_be32(0xffffffff)
 
-static int mlx4_en_moderation_update(struct mlx4_en_priv *priv)
+int mlx4_en_moderation_update(struct mlx4_en_priv *priv)
 {
        int i, t;
        int err = 0;
index 51b9700fce83630ac2e7dabfb54c252875f83e18..5d0c9c62382dc5b5832743ebe94a862ccf5a798a 100644 (file)
@@ -3554,6 +3554,8 @@ int mlx4_en_reset_config(struct net_device *dev,
                        en_err(priv, "Failed starting port\n");
        }
 
+       if (!err)
+               err = mlx4_en_moderation_update(priv);
 out:
        mutex_unlock(&mdev->state_lock);
        kfree(tmp);
index e8ed23190de01b1b4c7e961387bb53a22d783c23..f3d1a20201ef34f860ef865143de5abc3349f04e 100644 (file)
@@ -775,6 +775,7 @@ void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev);
 #define DEV_FEATURE_CHANGED(dev, new_features, feature) \
        ((dev->features & feature) ^ (new_features & feature))
 
+int mlx4_en_moderation_update(struct mlx4_en_priv *priv);
 int mlx4_en_reset_config(struct net_device *dev,
                         struct hwtstamp_config ts_config,
                         netdev_features_t new_features);
index 16e2df6ef2f48edead0736aded2a2a32abb336cb..c4adc7f740d3e6b8a6c2f50b399846cbd2ecacbd 100644 (file)
@@ -4430,6 +4430,7 @@ MLXSW_ITEM32(reg, ptys, ext_eth_proto_cap, 0x08, 0, 32);
 #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4          BIT(20)
 #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4          BIT(21)
 #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4          BIT(22)
+#define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4      BIT(23)
 #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR            BIT(27)
 #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR            BIT(28)
 #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR            BIT(29)
index bd7f873f6290b3e74fcf49c747fee4280e99d0cf..0bd64169bf8121c6c39f19be9ba8add48bf3374f 100644 (file)
@@ -1169,6 +1169,11 @@ static const struct mlxsw_sp1_port_link_mode mlxsw_sp1_port_link_mode[] = {
                .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
                .speed          = SPEED_100000,
        },
+       {
+               .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
+               .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+               .speed          = SPEED_100000,
+       },
 };
 
 #define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode)
index 9ce90841f92d8117cf4be234cb9e3183bbb99216..eda99d82766a7b40e420df70feefcf4acd311de5 100644 (file)
@@ -5951,6 +5951,10 @@ mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
        if (mlxsw_sp->router->aborted)
                return 0;
 
+       if (fen_info->fi->nh &&
+           !mlxsw_sp_nexthop_obj_group_lookup(mlxsw_sp, fen_info->fi->nh->id))
+               return 0;
+
        fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, fen_info->tb_id,
                                         &fen_info->dst, sizeof(fen_info->dst),
                                         fen_info->dst_len,
@@ -6601,6 +6605,9 @@ static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
        if (mlxsw_sp_fib6_rt_should_ignore(rt))
                return 0;
 
+       if (rt->nh && !mlxsw_sp_nexthop_obj_group_lookup(mlxsw_sp, rt->nh->id))
+               return 0;
+
        fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, rt->fib6_table->tb6_id,
                                         &rt->fib6_dst.addr,
                                         sizeof(rt->fib6_dst.addr),
index 40e2e79d451798eb7009a1de733fd4372893f223..131b2a53d261d64b5ff2d19cbe68741eead7d469 100644 (file)
@@ -613,7 +613,8 @@ static const struct mlxsw_sx_port_link_mode mlxsw_sx_port_link_mode[] = {
        {
                .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 |
                                  MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
-                                 MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4,
+                                 MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
+                                 MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
                .speed          = 100000,
        },
 };
index dbdfabff3b0034e64db879b117e5749c6dd6281e..1c3e204d727cf8b242e6befc3a8f79791b96306f 100644 (file)
@@ -2040,7 +2040,7 @@ lan743x_rx_trim_skb(struct sk_buff *skb, int frame_length)
                dev_kfree_skb_irq(skb);
                return NULL;
        }
-       frame_length = max_t(int, 0, frame_length - RX_HEAD_PADDING - 2);
+       frame_length = max_t(int, 0, frame_length - RX_HEAD_PADDING - 4);
        if (skb->len > frame_length) {
                skb->tail -= skb->len - frame_length;
                skb->len = frame_length;
index c0ede0ca7115e26be088631dfda175f803209308..05cb040c26775657c851867371daada609d90fe9 100644 (file)
@@ -13,6 +13,7 @@ if NET_VENDOR_MICROSEMI
 
 # Users should depend on NET_SWITCHDEV, HAS_IOMEM
 config MSCC_OCELOT_SWITCH_LIB
+       select NET_DEVLINK
        select REGMAP_MMIO
        select PACKING
        select PHYLIB
index c3ac026f6aea2bc270e32d77789ff7481e367a63..a41b458b1b3ef09fdb6933384a19ed917f104746 100644 (file)
@@ -540,13 +540,14 @@ ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress,
                        return -EOPNOTSUPP;
                }
 
+               flow_rule_match_ipv4_addrs(rule, &match);
+
                if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) {
                        NL_SET_ERR_MSG_MOD(extack,
                                           "Key type S1_NORMAL cannot match on destination IP");
                        return -EOPNOTSUPP;
                }
 
-               flow_rule_match_ipv4_addrs(rule, &match);
                tmp = &filter->key.ipv4.sip.value.addr[0];
                memcpy(tmp, &match.key->src, 4);
 
index f704da3f214c04d3f43c344a98806f0a1b25a966..7aad0ba53372cb5cd5765d5819d5f61935a2a2da 100644 (file)
@@ -767,7 +767,7 @@ static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int typ
        if (type == ERIAR_OOB &&
            (tp->mac_version == RTL_GIGA_MAC_VER_52 ||
             tp->mac_version == RTL_GIGA_MAC_VER_53))
-               *cmd |= 0x7f0 << 18;
+               *cmd |= 0xf70 << 18;
 }
 
 DECLARE_RTL_COND(rtl_eriar_cond)
index 590b088bc4c7f3e2f0d6d79443fcff6a6f4da077..f029c7c03804f916e9ff134475f14ecd8a0d0058 100644 (file)
@@ -560,6 +560,8 @@ static struct sh_eth_cpu_data r7s72100_data = {
                          EESR_TDE,
        .fdr_value      = 0x0000070f,
 
+       .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5,
+
        .no_psr         = 1,
        .apr            = 1,
        .mpr            = 1,
@@ -780,6 +782,8 @@ static struct sh_eth_cpu_data r7s9210_data = {
 
        .fdr_value      = 0x0000070f,
 
+       .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5,
+
        .apr            = 1,
        .mpr            = 1,
        .tpauser        = 1,
@@ -1089,6 +1093,9 @@ static struct sh_eth_cpu_data sh771x_data = {
                          EESIPR_CEEFIP | EESIPR_CELFIP |
                          EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP |
                          EESIPR_PREIP | EESIPR_CERFIP,
+
+       .trscer_err_mask = DESC_I_RINT8,
+
        .tsu            = 1,
        .dual_port      = 1,
 };
index 751dfdeec41c04949430884f98d286238490ac1b..0b64f7710d174836e540fef7473ef6a80e010bda 100644 (file)
@@ -233,6 +233,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat)
 static int intel_mgbe_common_data(struct pci_dev *pdev,
                                  struct plat_stmmacenet_data *plat)
 {
+       char clk_name[20];
        int ret;
        int i;
 
@@ -301,8 +302,10 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
        plat->eee_usecs_rate = plat->clk_ptp_rate;
 
        /* Set system clock */
+       sprintf(clk_name, "%s-%s", "stmmac", pci_name(pdev));
+
        plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev,
-                                                  "stmmac-clk", NULL, 0,
+                                                  clk_name, NULL, 0,
                                                   plat->clk_ptp_rate);
 
        if (IS_ERR(plat->stmmac_clk)) {
@@ -446,8 +449,8 @@ static int tgl_common_data(struct pci_dev *pdev,
        return intel_mgbe_common_data(pdev, plat);
 }
 
-static int tgl_sgmii_data(struct pci_dev *pdev,
-                         struct plat_stmmacenet_data *plat)
+static int tgl_sgmii_phy0_data(struct pci_dev *pdev,
+                              struct plat_stmmacenet_data *plat)
 {
        plat->bus_id = 1;
        plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
@@ -456,12 +459,26 @@ static int tgl_sgmii_data(struct pci_dev *pdev,
        return tgl_common_data(pdev, plat);
 }
 
-static struct stmmac_pci_info tgl_sgmii1g_info = {
-       .setup = tgl_sgmii_data,
+static struct stmmac_pci_info tgl_sgmii1g_phy0_info = {
+       .setup = tgl_sgmii_phy0_data,
 };
 
-static int adls_sgmii_data(struct pci_dev *pdev,
-                          struct plat_stmmacenet_data *plat)
+static int tgl_sgmii_phy1_data(struct pci_dev *pdev,
+                              struct plat_stmmacenet_data *plat)
+{
+       plat->bus_id = 2;
+       plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+       plat->serdes_powerup = intel_serdes_powerup;
+       plat->serdes_powerdown = intel_serdes_powerdown;
+       return tgl_common_data(pdev, plat);
+}
+
+static struct stmmac_pci_info tgl_sgmii1g_phy1_info = {
+       .setup = tgl_sgmii_phy1_data,
+};
+
+static int adls_sgmii_phy0_data(struct pci_dev *pdev,
+                               struct plat_stmmacenet_data *plat)
 {
        plat->bus_id = 1;
        plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
@@ -471,10 +488,24 @@ static int adls_sgmii_data(struct pci_dev *pdev,
        return tgl_common_data(pdev, plat);
 }
 
-static struct stmmac_pci_info adls_sgmii1g_info = {
-       .setup = adls_sgmii_data,
+static struct stmmac_pci_info adls_sgmii1g_phy0_info = {
+       .setup = adls_sgmii_phy0_data,
 };
 
+static int adls_sgmii_phy1_data(struct pci_dev *pdev,
+                               struct plat_stmmacenet_data *plat)
+{
+       plat->bus_id = 2;
+       plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+
+       /* SerDes power up and power down are done in BIOS for ADL */
+
+       return tgl_common_data(pdev, plat);
+}
+
+static struct stmmac_pci_info adls_sgmii1g_phy1_info = {
+       .setup = adls_sgmii_phy1_data,
+};
 static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
        {
                .func = 6,
@@ -756,11 +787,11 @@ static const struct pci_device_id intel_eth_pci_id_table[] = {
        { PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G_ID, &ehl_pse1_rgmii1g_info) },
        { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, &ehl_pse1_sgmii1g_info) },
        { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, &ehl_pse1_sgmii1g_info) },
-       { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_info) },
-       { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_0_ID, &tgl_sgmii1g_info) },
-       { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1_ID, &tgl_sgmii1g_info) },
-       { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_0_ID, &adls_sgmii1g_info) },
-       { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_1_ID, &adls_sgmii1g_info) },
+       { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_phy0_info) },
+       { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_0_ID, &tgl_sgmii1g_phy0_info) },
+       { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1_ID, &tgl_sgmii1g_phy1_info) },
+       { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_0_ID, &adls_sgmii1g_phy0_info) },
+       { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_1_ID, &adls_sgmii1g_phy1_info) },
        {}
 };
 MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table);
index c6540b003b430b05301756a67dc876741e7965dc..cbf4429fb1d232f15f3371b5e841399538af70dd 100644 (file)
@@ -402,19 +402,53 @@ static void dwmac4_rd_set_tx_ic(struct dma_desc *p)
        p->des2 |= cpu_to_le32(TDES2_INTERRUPT_ON_COMPLETION);
 }
 
-static void dwmac4_display_ring(void *head, unsigned int size, bool rx)
+static void dwmac4_display_ring(void *head, unsigned int size, bool rx,
+                               dma_addr_t dma_rx_phy, unsigned int desc_size)
 {
-       struct dma_desc *p = (struct dma_desc *)head;
+       dma_addr_t dma_addr;
        int i;
 
        pr_info("%s descriptor ring:\n", rx ? "RX" : "TX");
 
-       for (i = 0; i < size; i++) {
-               pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
-                       i, (unsigned int)virt_to_phys(p),
-                       le32_to_cpu(p->des0), le32_to_cpu(p->des1),
-                       le32_to_cpu(p->des2), le32_to_cpu(p->des3));
-               p++;
+       if (desc_size == sizeof(struct dma_desc)) {
+               struct dma_desc *p = (struct dma_desc *)head;
+
+               for (i = 0; i < size; i++) {
+                       dma_addr = dma_rx_phy + i * sizeof(*p);
+                       pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
+                               i, &dma_addr,
+                               le32_to_cpu(p->des0), le32_to_cpu(p->des1),
+                               le32_to_cpu(p->des2), le32_to_cpu(p->des3));
+                       p++;
+               }
+       } else if (desc_size == sizeof(struct dma_extended_desc)) {
+               struct dma_extended_desc *extp = (struct dma_extended_desc *)head;
+
+               for (i = 0; i < size; i++) {
+                       dma_addr = dma_rx_phy + i * sizeof(*extp);
+                       pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+                               i, &dma_addr,
+                               le32_to_cpu(extp->basic.des0), le32_to_cpu(extp->basic.des1),
+                               le32_to_cpu(extp->basic.des2), le32_to_cpu(extp->basic.des3),
+                               le32_to_cpu(extp->des4), le32_to_cpu(extp->des5),
+                               le32_to_cpu(extp->des6), le32_to_cpu(extp->des7));
+                       extp++;
+               }
+       } else if (desc_size == sizeof(struct dma_edesc)) {
+               struct dma_edesc *ep = (struct dma_edesc *)head;
+
+               for (i = 0; i < size; i++) {
+                       dma_addr = dma_rx_phy + i * sizeof(*ep);
+                       pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+                               i, &dma_addr,
+                               le32_to_cpu(ep->des4), le32_to_cpu(ep->des5),
+                               le32_to_cpu(ep->des6), le32_to_cpu(ep->des7),
+                               le32_to_cpu(ep->basic.des0), le32_to_cpu(ep->basic.des1),
+                               le32_to_cpu(ep->basic.des2), le32_to_cpu(ep->basic.des3));
+                       ep++;
+               }
+       } else {
+               pr_err("unsupported descriptor!");
        }
 }
 
@@ -499,10 +533,15 @@ static void dwmac4_get_rx_header_len(struct dma_desc *p, unsigned int *len)
        *len = le32_to_cpu(p->des2) & RDES2_HL;
 }
 
-static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
+static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool buf2_valid)
 {
        p->des2 = cpu_to_le32(lower_32_bits(addr));
-       p->des3 = cpu_to_le32(upper_32_bits(addr) | RDES3_BUFFER2_VALID_ADDR);
+       p->des3 = cpu_to_le32(upper_32_bits(addr));
+
+       if (buf2_valid)
+               p->des3 |= cpu_to_le32(RDES3_BUFFER2_VALID_ADDR);
+       else
+               p->des3 &= cpu_to_le32(~RDES3_BUFFER2_VALID_ADDR);
 }
 
 static void dwmac4_set_tbs(struct dma_edesc *p, u32 sec, u32 nsec)
index bb29bfcd62c347cda7a9a93fa932568c2828de7a..62aa0e95beb709a65faefba7cafae6e9b6105ddc 100644 (file)
@@ -124,6 +124,23 @@ static void dwmac4_dma_init_channel(void __iomem *ioaddr,
               ioaddr + DMA_CHAN_INTR_ENA(chan));
 }
 
+static void dwmac410_dma_init_channel(void __iomem *ioaddr,
+                                     struct stmmac_dma_cfg *dma_cfg, u32 chan)
+{
+       u32 value;
+
+       /* common channel control register config */
+       value = readl(ioaddr + DMA_CHAN_CONTROL(chan));
+       if (dma_cfg->pblx8)
+               value = value | DMA_BUS_MODE_PBL;
+
+       writel(value, ioaddr + DMA_CHAN_CONTROL(chan));
+
+       /* Mask interrupts by writing to CSR7 */
+       writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10,
+              ioaddr + DMA_CHAN_INTR_ENA(chan));
+}
+
 static void dwmac4_dma_init(void __iomem *ioaddr,
                            struct stmmac_dma_cfg *dma_cfg, int atds)
 {
@@ -523,7 +540,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
 const struct stmmac_dma_ops dwmac410_dma_ops = {
        .reset = dwmac4_dma_reset,
        .init = dwmac4_dma_init,
-       .init_chan = dwmac4_dma_init_channel,
+       .init_chan = dwmac410_dma_init_channel,
        .init_rx_chan = dwmac4_dma_init_rx_chan,
        .init_tx_chan = dwmac4_dma_init_tx_chan,
        .axi = dwmac4_dma_axi,
index 0b4ee2dbb691d3c0112e9f56e8ce294317bb45e6..71e50751ef2dc2c6ba3d1a133edb3663dc5a6968 100644 (file)
@@ -53,10 +53,6 @@ void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan)
 
        value &= ~DMA_CONTROL_ST;
        writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
-
-       value = readl(ioaddr + GMAC_CONFIG);
-       value &= ~GMAC_CONFIG_TE;
-       writel(value, ioaddr + GMAC_CONFIG);
 }
 
 void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan)
index 0aaf19ab56729555b15de680622d21deb38c2ecf..ccfb0102dde492657e70cc6958edc428158be8d4 100644 (file)
@@ -292,7 +292,7 @@ static void dwxgmac2_get_rx_header_len(struct dma_desc *p, unsigned int *len)
                *len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL;
 }
 
-static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
+static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool is_valid)
 {
        p->des2 = cpu_to_le32(lower_32_bits(addr));
        p->des3 = cpu_to_le32(upper_32_bits(addr));
index d02cec296f51e078a7da9838fba7d5afd0b0404f..6650edfab5bc488b041be84e261e7c2d8a20a37f 100644 (file)
@@ -417,19 +417,22 @@ static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc,
        }
 }
 
-static void enh_desc_display_ring(void *head, unsigned int size, bool rx)
+static void enh_desc_display_ring(void *head, unsigned int size, bool rx,
+                                 dma_addr_t dma_rx_phy, unsigned int desc_size)
 {
        struct dma_extended_desc *ep = (struct dma_extended_desc *)head;
+       dma_addr_t dma_addr;
        int i;
 
        pr_info("Extended %s descriptor ring:\n", rx ? "RX" : "TX");
 
        for (i = 0; i < size; i++) {
                u64 x;
+               dma_addr = dma_rx_phy + i * sizeof(*ep);
 
                x = *(u64 *)ep;
-               pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
-                       i, (unsigned int)virt_to_phys(ep),
+               pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
+                       i, &dma_addr,
                        (unsigned int)x, (unsigned int)(x >> 32),
                        ep->basic.des2, ep->basic.des3);
                ep++;
index b40b2e0667bbae44a50221762b9d6eb506b7fcb1..979ac9fca23c7bb1434a5c3f0717c035ee18f1c9 100644 (file)
@@ -78,7 +78,8 @@ struct stmmac_desc_ops {
        /* get rx timestamp status */
        int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats);
        /* Display ring */
-       void (*display_ring)(void *head, unsigned int size, bool rx);
+       void (*display_ring)(void *head, unsigned int size, bool rx,
+                            dma_addr_t dma_rx_phy, unsigned int desc_size);
        /* set MSS via context descriptor */
        void (*set_mss)(struct dma_desc *p, unsigned int mss);
        /* get descriptor skbuff address */
@@ -91,7 +92,7 @@ struct stmmac_desc_ops {
        int (*get_rx_hash)(struct dma_desc *p, u32 *hash,
                           enum pkt_hash_types *type);
        void (*get_rx_header_len)(struct dma_desc *p, unsigned int *len);
-       void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr);
+       void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr, bool buf2_valid);
        void (*set_sarc)(struct dma_desc *p, u32 sarc_type);
        void (*set_vlan_tag)(struct dma_desc *p, u16 tag, u16 inner_tag,
                             u32 inner_type);
index f083360e4ba67f126b3e719e81a5f21f9b3903cc..98ef43f35802adfa50aa5e55bf5ce0d5e407acae 100644 (file)
@@ -269,19 +269,22 @@ static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats)
                return 1;
 }
 
-static void ndesc_display_ring(void *head, unsigned int size, bool rx)
+static void ndesc_display_ring(void *head, unsigned int size, bool rx,
+                              dma_addr_t dma_rx_phy, unsigned int desc_size)
 {
        struct dma_desc *p = (struct dma_desc *)head;
+       dma_addr_t dma_addr;
        int i;
 
        pr_info("%s descriptor ring:\n", rx ? "RX" : "TX");
 
        for (i = 0; i < size; i++) {
                u64 x;
+               dma_addr = dma_rx_phy + i * sizeof(*p);
 
                x = *(u64 *)p;
-               pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x",
-                       i, (unsigned int)virt_to_phys(p),
+               pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x",
+                       i, &dma_addr,
                        (unsigned int)x, (unsigned int)(x >> 32),
                        p->des2, p->des3);
                p++;
index 26b971cd4da5abfb8407fe9b8bf3aa63c6f87c52..208cae344ffa26432885dea59be676fa1b6dca9e 100644 (file)
@@ -1133,6 +1133,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 static void stmmac_display_rx_rings(struct stmmac_priv *priv)
 {
        u32 rx_cnt = priv->plat->rx_queues_to_use;
+       unsigned int desc_size;
        void *head_rx;
        u32 queue;
 
@@ -1142,19 +1143,24 @@ static void stmmac_display_rx_rings(struct stmmac_priv *priv)
 
                pr_info("\tRX Queue %u rings\n", queue);
 
-               if (priv->extend_desc)
+               if (priv->extend_desc) {
                        head_rx = (void *)rx_q->dma_erx;
-               else
+                       desc_size = sizeof(struct dma_extended_desc);
+               } else {
                        head_rx = (void *)rx_q->dma_rx;
+                       desc_size = sizeof(struct dma_desc);
+               }
 
                /* Display RX ring */
-               stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true);
+               stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true,
+                                   rx_q->dma_rx_phy, desc_size);
        }
 }
 
 static void stmmac_display_tx_rings(struct stmmac_priv *priv)
 {
        u32 tx_cnt = priv->plat->tx_queues_to_use;
+       unsigned int desc_size;
        void *head_tx;
        u32 queue;
 
@@ -1164,14 +1170,19 @@ static void stmmac_display_tx_rings(struct stmmac_priv *priv)
 
                pr_info("\tTX Queue %d rings\n", queue);
 
-               if (priv->extend_desc)
+               if (priv->extend_desc) {
                        head_tx = (void *)tx_q->dma_etx;
-               else if (tx_q->tbs & STMMAC_TBS_AVAIL)
+                       desc_size = sizeof(struct dma_extended_desc);
+               } else if (tx_q->tbs & STMMAC_TBS_AVAIL) {
                        head_tx = (void *)tx_q->dma_entx;
-               else
+                       desc_size = sizeof(struct dma_edesc);
+               } else {
                        head_tx = (void *)tx_q->dma_tx;
+                       desc_size = sizeof(struct dma_desc);
+               }
 
-               stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false);
+               stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false,
+                                   tx_q->dma_tx_phy, desc_size);
        }
 }
 
@@ -1303,9 +1314,10 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
                        return -ENOMEM;
 
                buf->sec_addr = page_pool_get_dma_addr(buf->sec_page);
-               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr);
+               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true);
        } else {
                buf->sec_page = NULL;
+               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false);
        }
 
        buf->addr = page_pool_get_dma_addr(buf->page);
@@ -1367,6 +1379,88 @@ static void stmmac_free_tx_buffer(struct stmmac_priv *priv, u32 queue, int i)
        }
 }
 
+/**
+ * stmmac_reinit_rx_buffers - reinit the RX descriptor buffer.
+ * @priv: driver private structure
+ * Description: this function is called to re-allocate a receive buffer, perform
+ * the DMA mapping and init the descriptor.
+ */
+static void stmmac_reinit_rx_buffers(struct stmmac_priv *priv)
+{
+       u32 rx_count = priv->plat->rx_queues_to_use;
+       u32 queue;
+       int i;
+
+       for (queue = 0; queue < rx_count; queue++) {
+               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+
+               for (i = 0; i < priv->dma_rx_size; i++) {
+                       struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
+
+                       if (buf->page) {
+                               page_pool_recycle_direct(rx_q->page_pool, buf->page);
+                               buf->page = NULL;
+                       }
+
+                       if (priv->sph && buf->sec_page) {
+                               page_pool_recycle_direct(rx_q->page_pool, buf->sec_page);
+                               buf->sec_page = NULL;
+                       }
+               }
+       }
+
+       for (queue = 0; queue < rx_count; queue++) {
+               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+
+               for (i = 0; i < priv->dma_rx_size; i++) {
+                       struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
+                       struct dma_desc *p;
+
+                       if (priv->extend_desc)
+                               p = &((rx_q->dma_erx + i)->basic);
+                       else
+                               p = rx_q->dma_rx + i;
+
+                       if (!buf->page) {
+                               buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
+                               if (!buf->page)
+                                       goto err_reinit_rx_buffers;
+
+                               buf->addr = page_pool_get_dma_addr(buf->page);
+                       }
+
+                       if (priv->sph && !buf->sec_page) {
+                               buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
+                               if (!buf->sec_page)
+                                       goto err_reinit_rx_buffers;
+
+                               buf->sec_addr = page_pool_get_dma_addr(buf->sec_page);
+                       }
+
+                       stmmac_set_desc_addr(priv, p, buf->addr);
+                       if (priv->sph)
+                               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true);
+                       else
+                               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false);
+                       if (priv->dma_buf_sz == BUF_SIZE_16KiB)
+                               stmmac_init_desc3(priv, p);
+               }
+       }
+
+       return;
+
+err_reinit_rx_buffers:
+       do {
+               while (--i >= 0)
+                       stmmac_free_rx_buffer(priv, queue, i);
+
+               if (queue == 0)
+                       break;
+
+               i = priv->dma_rx_size;
+       } while (queue-- > 0);
+}
+
 /**
  * init_dma_rx_desc_rings - init the RX descriptor rings
  * @dev: net device structure
@@ -3648,7 +3742,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
                                           DMA_FROM_DEVICE);
 
                stmmac_set_desc_addr(priv, p, buf->addr);
-               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr);
+               if (priv->sph)
+                       stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true);
+               else
+                       stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false);
                stmmac_refill_desc3(priv, rx_q, p);
 
                rx_q->rx_count_frames++;
@@ -3736,18 +3833,23 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
        unsigned int count = 0, error = 0, len = 0;
        int status = 0, coe = priv->hw->rx_csum;
        unsigned int next_entry = rx_q->cur_rx;
+       unsigned int desc_size;
        struct sk_buff *skb = NULL;
 
        if (netif_msg_rx_status(priv)) {
                void *rx_head;
 
                netdev_dbg(priv->dev, "%s: descriptor ring:\n", __func__);
-               if (priv->extend_desc)
+               if (priv->extend_desc) {
                        rx_head = (void *)rx_q->dma_erx;
-               else
+                       desc_size = sizeof(struct dma_extended_desc);
+               } else {
                        rx_head = (void *)rx_q->dma_rx;
+                       desc_size = sizeof(struct dma_desc);
+               }
 
-               stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true);
+               stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true,
+                                   rx_q->dma_rx_phy, desc_size);
        }
        while (count < limit) {
                unsigned int buf1_len = 0, buf2_len = 0;
@@ -4315,24 +4417,27 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr)
 static struct dentry *stmmac_fs_dir;
 
 static void sysfs_display_ring(void *head, int size, int extend_desc,
-                              struct seq_file *seq)
+                              struct seq_file *seq, dma_addr_t dma_phy_addr)
 {
        int i;
        struct dma_extended_desc *ep = (struct dma_extended_desc *)head;
        struct dma_desc *p = (struct dma_desc *)head;
+       dma_addr_t dma_addr;
 
        for (i = 0; i < size; i++) {
                if (extend_desc) {
-                       seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
-                                  i, (unsigned int)virt_to_phys(ep),
+                       dma_addr = dma_phy_addr + i * sizeof(*ep);
+                       seq_printf(seq, "%d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
+                                  i, &dma_addr,
                                   le32_to_cpu(ep->basic.des0),
                                   le32_to_cpu(ep->basic.des1),
                                   le32_to_cpu(ep->basic.des2),
                                   le32_to_cpu(ep->basic.des3));
                        ep++;
                } else {
-                       seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
-                                  i, (unsigned int)virt_to_phys(p),
+                       dma_addr = dma_phy_addr + i * sizeof(*p);
+                       seq_printf(seq, "%d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
+                                  i, &dma_addr,
                                   le32_to_cpu(p->des0), le32_to_cpu(p->des1),
                                   le32_to_cpu(p->des2), le32_to_cpu(p->des3));
                        p++;
@@ -4360,11 +4465,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
                if (priv->extend_desc) {
                        seq_printf(seq, "Extended descriptor ring:\n");
                        sysfs_display_ring((void *)rx_q->dma_erx,
-                                          priv->dma_rx_size, 1, seq);
+                                          priv->dma_rx_size, 1, seq, rx_q->dma_rx_phy);
                } else {
                        seq_printf(seq, "Descriptor ring:\n");
                        sysfs_display_ring((void *)rx_q->dma_rx,
-                                          priv->dma_rx_size, 0, seq);
+                                          priv->dma_rx_size, 0, seq, rx_q->dma_rx_phy);
                }
        }
 
@@ -4376,11 +4481,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
                if (priv->extend_desc) {
                        seq_printf(seq, "Extended descriptor ring:\n");
                        sysfs_display_ring((void *)tx_q->dma_etx,
-                                          priv->dma_tx_size, 1, seq);
+                                          priv->dma_tx_size, 1, seq, tx_q->dma_tx_phy);
                } else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) {
                        seq_printf(seq, "Descriptor ring:\n");
                        sysfs_display_ring((void *)tx_q->dma_tx,
-                                          priv->dma_tx_size, 0, seq);
+                                          priv->dma_tx_size, 0, seq, tx_q->dma_tx_phy);
                }
        }
 
@@ -5144,13 +5249,16 @@ int stmmac_dvr_remove(struct device *dev)
        netdev_info(priv->dev, "%s: removing driver", __func__);
 
        stmmac_stop_all_dma(priv);
+       stmmac_mac_set(priv, priv->ioaddr, false);
+       netif_carrier_off(ndev);
+       unregister_netdev(ndev);
 
+       /* Serdes power down needs to happen after VLAN filter
+        * is deleted that is triggered by unregister_netdev().
+        */
        if (priv->plat->serdes_powerdown)
                priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
 
-       stmmac_mac_set(priv, priv->ioaddr, false);
-       netif_carrier_off(ndev);
-       unregister_netdev(ndev);
 #ifdef CONFIG_DEBUG_FS
        stmmac_exit_fs(ndev);
 #endif
@@ -5257,6 +5365,8 @@ static void stmmac_reset_queues_param(struct stmmac_priv *priv)
                tx_q->cur_tx = 0;
                tx_q->dirty_tx = 0;
                tx_q->mss = 0;
+
+               netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
        }
 }
 
@@ -5318,7 +5428,7 @@ int stmmac_resume(struct device *dev)
        mutex_lock(&priv->lock);
 
        stmmac_reset_queues_param(priv);
-
+       stmmac_reinit_rx_buffers(priv);
        stmmac_free_tx_skbufs(priv);
        stmmac_clear_descriptors(priv);
 
index 68695d4afacd542a7d8d51d18da7a07918f72575..707ccdd03b19eea1de7c818bd6ead715a2da7393 100644 (file)
@@ -3931,8 +3931,6 @@ static void niu_xmac_interrupt(struct niu *np)
                mp->rx_mcasts += RXMAC_MC_FRM_CNT_COUNT;
        if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP)
                mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT;
-       if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP)
-               mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT;
        if (val & XRXMAC_STATUS_RXHIST1_CNT_EXP)
                mp->rx_hist_cnt1 += RXMAC_HIST_CNT1_COUNT;
        if (val & XRXMAC_STATUS_RXHIST2_CNT_EXP)
index b8f4f419173f974fd6ff1f04a1ab660ba896ebfc..d054c6e83b1c92184fe4b12227aff2ea72d6ad2a 100644 (file)
@@ -2044,6 +2044,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                /*bdx_hw_reset(priv); */
                if (bdx_read_mac(priv)) {
                        pr_err("load MAC address failed\n");
+                       err = -EFAULT;
                        goto err_out_iomap;
                }
                SET_NETDEV_DEV(ndev, &pdev->dev);
index 71d6629e65c970e7e133cfa615aa01341a68d43f..9f5b5614a1503734e201d14e8524b74db6e8e884 100644 (file)
@@ -171,11 +171,6 @@ static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
                goto out_drop;
        }
 
-       if (len > sp->mtu) {    /* sp->mtu = AX25_MTU = max. PACLEN = 256 */
-               msg = "oversized transmit packet!";
-               goto out_drop;
-       }
-
        if (p[0] > 5) {
                msg = "invalid KISS command";
                goto out_drop;
index e1a497d3c9ba427fa8e9fea9262225cc34f5bb5c..59ac04a610adbf6670611a2db7b1d7cdeb2474b4 100644 (file)
@@ -229,7 +229,7 @@ int netvsc_send(struct net_device *net,
                bool xdp_tx);
 void netvsc_linkstatus_callback(struct net_device *net,
                                struct rndis_message *resp,
-                               void *data);
+                               void *data, u32 data_buflen);
 int netvsc_recv_callback(struct net_device *net,
                         struct netvsc_device *nvdev,
                         struct netvsc_channel *nvchan);
index 8176fa0c8b16868efb49573c53c7d6db9e7340fd..15f262b70489e3b6475d3a4af82273130467ddd0 100644 (file)
@@ -744,7 +744,7 @@ static netdev_tx_t netvsc_start_xmit(struct sk_buff *skb,
  */
 void netvsc_linkstatus_callback(struct net_device *net,
                                struct rndis_message *resp,
-                               void *data)
+                               void *data, u32 data_buflen)
 {
        struct rndis_indicate_status *indicate = &resp->msg.indicate_status;
        struct net_device_context *ndev_ctx = netdev_priv(net);
@@ -765,11 +765,16 @@ void netvsc_linkstatus_callback(struct net_device *net,
        if (indicate->status == RNDIS_STATUS_LINK_SPEED_CHANGE) {
                u32 speed;
 
-               /* Validate status_buf_offset */
+               /* Validate status_buf_offset and status_buflen.
+                *
+                * Certain (pre-Fe) implementations of Hyper-V's vSwitch didn't account
+                * for the status buffer field in resp->msg_len; perform the validation
+                * using data_buflen (>= resp->msg_len).
+                */
                if (indicate->status_buflen < sizeof(speed) ||
                    indicate->status_buf_offset < sizeof(*indicate) ||
-                   resp->msg_len - RNDIS_HEADER_SIZE < indicate->status_buf_offset ||
-                   resp->msg_len - RNDIS_HEADER_SIZE - indicate->status_buf_offset
+                   data_buflen - RNDIS_HEADER_SIZE < indicate->status_buf_offset ||
+                   data_buflen - RNDIS_HEADER_SIZE - indicate->status_buf_offset
                                < indicate->status_buflen) {
                        netdev_err(net, "invalid rndis_indicate_status packet\n");
                        return;
index 123cc9d25f5ed52fa66698348aab827a263b4975..c0e89e107d575256573c70bde95f308a25c99c28 100644 (file)
@@ -620,7 +620,7 @@ int rndis_filter_receive(struct net_device *ndev,
 
        case RNDIS_MSG_INDICATE:
                /* notification msgs */
-               netvsc_linkstatus_callback(ndev, rndis_msg, data);
+               netvsc_linkstatus_callback(ndev, rndis_msg, data, buflen);
                break;
        default:
                netdev_err(ndev,
index aec92440eef16dc7b8b29a1649e1ea2a21e0aff0..659d3dceb687f368c2e6dd1c8c1e90016c91823d 100644 (file)
@@ -294,6 +294,7 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
        dev_net_set(dev, nsim_dev_net(nsim_dev));
        ns = netdev_priv(dev);
        ns->netdev = dev;
+       u64_stats_init(&ns->syncp);
        ns->nsim_dev = nsim_dev;
        ns->nsim_dev_port = nsim_dev_port;
        ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
index be1224b4447b40af8f608439c83930d689805ddc..f7a2ec150e542af3ff5ed1cd62a9fdae020868dd 100644 (file)
@@ -290,6 +290,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
 
 static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
 {
+       bool trigger_machine = false;
        int irq_status;
 
        /* The MISR1 and MISR2 registers are holding the interrupt status in
@@ -305,7 +306,7 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
        if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-               goto trigger_machine;
+               trigger_machine = true;
 
        irq_status = phy_read(phydev, MII_DP83822_MISR2);
        if (irq_status < 0) {
@@ -313,11 +314,11 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
        if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-               goto trigger_machine;
+               trigger_machine = true;
 
-       return IRQ_NONE;
+       if (!trigger_machine)
+               return IRQ_NONE;
 
-trigger_machine:
        phy_trigger_machine(phydev);
 
        return IRQ_HANDLED;
index 688fadffb249daf35720cea2836e6f8d4f980252..7ea32fb77190c47544355d17edaffd8f9d9c7c23 100644 (file)
@@ -264,6 +264,7 @@ static int dp83811_config_intr(struct phy_device *phydev)
 
 static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
 {
+       bool trigger_machine = false;
        int irq_status;
 
        /* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
@@ -279,7 +280,7 @@ static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
        if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-               goto trigger_machine;
+               trigger_machine = true;
 
        irq_status = phy_read(phydev, MII_DP83811_INT_STAT2);
        if (irq_status < 0) {
@@ -287,7 +288,7 @@ static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
        if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-               goto trigger_machine;
+               trigger_machine = true;
 
        irq_status = phy_read(phydev, MII_DP83811_INT_STAT3);
        if (irq_status < 0) {
@@ -295,11 +296,11 @@ static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
        if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-               goto trigger_machine;
+               trigger_machine = true;
 
-       return IRQ_NONE;
+       if (!trigger_machine)
+               return IRQ_NONE;
 
-trigger_machine:
        phy_trigger_machine(phydev);
 
        return IRQ_HANDLED;
index 1be07e45d314e5354bb1bfe31f4ea75431d991fd..fc2e7cb5b2e584030ee030311f3e365b02153646 100644 (file)
@@ -276,14 +276,16 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
 
        phydev->autoneg = autoneg;
 
-       phydev->speed = speed;
+       if (autoneg == AUTONEG_DISABLE) {
+               phydev->speed = speed;
+               phydev->duplex = duplex;
+       }
 
        linkmode_copy(phydev->advertising, advertising);
 
        linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
                         phydev->advertising, autoneg == AUTONEG_ENABLE);
 
-       phydev->duplex = duplex;
        phydev->master_slave_set = cmd->base.master_slave_cfg;
        phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
 
index ce495473cd5dc80a0a85764fa998258b0067fbe4..cc38e326405a6585a7b602628ba61c51daa7912a 100644 (file)
@@ -230,7 +230,6 @@ static struct phy_driver genphy_driver;
 static LIST_HEAD(phy_fixup_list);
 static DEFINE_MUTEX(phy_fixup_lock);
 
-#ifdef CONFIG_PM
 static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
 {
        struct device_driver *drv = phydev->mdio.dev.driver;
@@ -270,7 +269,7 @@ out:
        return !phydev->suspended;
 }
 
-static int mdio_bus_phy_suspend(struct device *dev)
+static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
 {
        struct phy_device *phydev = to_phy_device(dev);
 
@@ -290,7 +289,7 @@ static int mdio_bus_phy_suspend(struct device *dev)
        return phy_suspend(phydev);
 }
 
-static int mdio_bus_phy_resume(struct device *dev)
+static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
 {
        struct phy_device *phydev = to_phy_device(dev);
        int ret;
@@ -316,7 +315,6 @@ no_resume:
 
 static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend,
                         mdio_bus_phy_resume);
-#endif /* CONFIG_PM */
 
 /**
  * phy_register_fixup - creates a new phy_fixup and adds it to the list
index 4087c9e337819b3bfe1679495a3215386f84c027..8acf3011542820114edc728d65cbd404ad9434f0 100644 (file)
@@ -851,17 +851,17 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
 
        /* check if we got everything */
        if (!ctx->data) {
-               dev_dbg(&intf->dev, "CDC Union missing and no IAD found\n");
+               dev_err(&intf->dev, "CDC Union missing and no IAD found\n");
                goto error;
        }
        if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) {
                if (!ctx->mbim_desc) {
-                       dev_dbg(&intf->dev, "MBIM functional descriptor missing\n");
+                       dev_err(&intf->dev, "MBIM functional descriptor missing\n");
                        goto error;
                }
        } else {
                if (!ctx->ether_desc || !ctx->func_desc) {
-                       dev_dbg(&intf->dev, "NCM or ECM functional descriptors missing\n");
+                       dev_err(&intf->dev, "NCM or ECM functional descriptors missing\n");
                        goto error;
                }
        }
@@ -870,7 +870,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
        if (ctx->data != ctx->control) {
                temp = usb_driver_claim_interface(driver, ctx->data, dev);
                if (temp) {
-                       dev_dbg(&intf->dev, "failed to claim data intf\n");
+                       dev_err(&intf->dev, "failed to claim data intf\n");
                        goto error;
                }
        }
@@ -926,7 +926,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
        if (ctx->ether_desc) {
                temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress);
                if (temp) {
-                       dev_dbg(&intf->dev, "failed to get mac address\n");
+                       dev_err(&intf->dev, "failed to get mac address\n");
                        goto error2;
                }
                dev_info(&intf->dev, "MAC-Address: %pM\n", dev->net->dev_addr);
index 17a050521b866b44c6877c5ff78be5d79534b846..6700f1970b240bb53c372727efdb92f72854c7a5 100644 (file)
@@ -429,13 +429,6 @@ static ssize_t add_mux_store(struct device *d,  struct device_attribute *attr, c
                goto err;
        }
 
-       /* we don't want to modify a running netdev */
-       if (netif_running(dev->net)) {
-               netdev_err(dev->net, "Cannot change a running device\n");
-               ret = -EBUSY;
-               goto err;
-       }
-
        ret = qmimux_register_device(dev->net, mux_id);
        if (!ret) {
                info->flags |= QMI_WWAN_FLAG_MUX;
@@ -465,13 +458,6 @@ static ssize_t del_mux_store(struct device *d,  struct device_attribute *attr, c
        if (!rtnl_trylock())
                return restart_syscall();
 
-       /* we don't want to modify a running netdev */
-       if (netif_running(dev->net)) {
-               netdev_err(dev->net, "Cannot change a running device\n");
-               ret = -EBUSY;
-               goto err;
-       }
-
        del_dev = qmimux_find_dev(dev, mux_id);
        if (!del_dev) {
                netdev_err(dev->net, "mux_id not present\n");
index b246817f340574e684ee96f83132b15df7f1f742..90f1c020004257871d8a21ab88cc40dc37caf974 100644 (file)
@@ -3021,29 +3021,6 @@ static void __rtl_set_wol(struct r8152 *tp, u32 wolopts)
                device_set_wakeup_enable(&tp->udev->dev, false);
 }
 
-static void r8153_mac_clk_spd(struct r8152 *tp, bool enable)
-{
-       /* MAC clock speed down */
-       if (enable) {
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL,
-                              ALDPS_SPDWN_RATIO);
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2,
-                              EEE_SPDWN_RATIO);
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3,
-                              PKT_AVAIL_SPDWN_EN | SUSPEND_SPDWN_EN |
-                              U1U2_SPDWN_EN | L1_SPDWN_EN);
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4,
-                              PWRSAVE_SPDWN_EN | RXDV_SPDWN_EN | TX10MIDLE_EN |
-                              TP100_SPDWN_EN | TP500_SPDWN_EN | EEE_SPDWN_EN |
-                              TP1000_SPDWN_EN);
-       } else {
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0);
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0);
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0);
-               ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0);
-       }
-}
-
 static void r8153_u1u2en(struct r8152 *tp, bool enable)
 {
        u8 u1u2[8];
@@ -3338,11 +3315,9 @@ static void rtl8153_runtime_enable(struct r8152 *tp, bool enable)
        if (enable) {
                r8153_u1u2en(tp, false);
                r8153_u2p3en(tp, false);
-               r8153_mac_clk_spd(tp, true);
                rtl_runtime_suspend_enable(tp, true);
        } else {
                rtl_runtime_suspend_enable(tp, false);
-               r8153_mac_clk_spd(tp, false);
 
                switch (tp->version) {
                case RTL_VER_03:
@@ -4718,7 +4693,6 @@ static void r8153_first_init(struct r8152 *tp)
 {
        u32 ocp_data;
 
-       r8153_mac_clk_spd(tp, false);
        rxdy_gated_en(tp, true);
        r8153_teredo_off(tp);
 
@@ -4769,8 +4743,6 @@ static void r8153_enter_oob(struct r8152 *tp)
 {
        u32 ocp_data;
 
-       r8153_mac_clk_spd(tp, true);
-
        ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
        ocp_data &= ~NOW_IS_OOB;
        ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
@@ -5496,10 +5468,15 @@ static void r8153_init(struct r8152 *tp)
 
        ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001);
 
+       /* MAC clock speed down */
+       ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0);
+       ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0);
+       ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0);
+       ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0);
+
        r8153_power_cut_en(tp, false);
        rtl_runtime_suspend_enable(tp, false);
        r8153_u1u2en(tp, true);
-       r8153_mac_clk_spd(tp, false);
        usb_enable_lpm(tp->udev);
 
        ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6);
index b4c8080e6f87ae8e0e17c2fc587bd5de7b32db9b..f4f37ecfed58743d8bbfa41abcef244e7bbe8bb7 100644 (file)
@@ -887,7 +887,7 @@ int usbnet_open (struct net_device *net)
 
        // insist peer be connected
        if (info->check_connect && (retval = info->check_connect (dev)) < 0) {
-               netif_dbg(dev, ifup, dev->net, "can't open; %d\n", retval);
+               netif_err(dev, ifup, dev->net, "can't open; %d\n", retval);
                goto done;
        }
 
index dca97cd7c4e75c4ec4f069d5816d969fbf710c25..7eac6a3e1cdee1e90de74fa17ce75e899a4bda1c 100644 (file)
@@ -204,14 +204,18 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
        priv->rx_skbuff = kcalloc(priv->rx_ring_size,
                                  sizeof(*priv->rx_skbuff),
                                  GFP_KERNEL);
-       if (!priv->rx_skbuff)
+       if (!priv->rx_skbuff) {
+               ret = -ENOMEM;
                goto free_ucc_pram;
+       }
 
        priv->tx_skbuff = kcalloc(priv->tx_ring_size,
                                  sizeof(*priv->tx_skbuff),
                                  GFP_KERNEL);
-       if (!priv->tx_skbuff)
+       if (!priv->tx_skbuff) {
+               ret = -ENOMEM;
                goto free_rx_skbuff;
+       }
 
        priv->skb_curtx = 0;
        priv->skb_dirtytx = 0;
index 605fe555e157d59e2e76d7b58cf8abd39110b183..c3372498f4f154dc483bb4beda7ce4a83aa52b36 100644 (file)
@@ -292,7 +292,6 @@ static int lapbeth_open(struct net_device *dev)
                return -ENODEV;
        }
 
-       netif_start_queue(dev);
        return 0;
 }
 
@@ -300,8 +299,6 @@ static int lapbeth_close(struct net_device *dev)
 {
        int err;
 
-       netif_stop_queue(dev);
-
        if ((err = lapb_unregister(dev)) != LAPB_OK)
                pr_err("lapb_unregister error: %d\n", err);
 
index b391169576e27c613931dc8f8f90575506657a60..faa2e678e63eff9b1c605ad0c32a30127b2b171e 100644 (file)
@@ -5450,8 +5450,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
        }
 
        if (ab->hw_params.vdev_start_delay &&
-           (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
-           arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) {
+           arvif->vdev_type != WMI_VDEV_TYPE_AP &&
+           arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) {
                param.vdev_id = arvif->vdev_id;
                param.peer_type = WMI_PEER_TYPE_DEFAULT;
                param.peer_addr = ar->mac_addr;
index 1aca841cd147cfee6dedb59b6e08b38201257dfb..7968fe4eda22a839d80e4ed5b2220d857598d4ca 100644 (file)
@@ -1687,8 +1687,8 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
                        req->mem_seg[i].size = ab->qmi.target_mem[i].size;
                        req->mem_seg[i].type = ab->qmi.target_mem[i].type;
                        ath11k_dbg(ab, ATH11K_DBG_QMI,
-                                  "qmi req mem_seg[%d] 0x%llx %u %u\n", i,
-                                   ab->qmi.target_mem[i].paddr,
+                                  "qmi req mem_seg[%d] %pad %u %u\n", i,
+                                   &ab->qmi.target_mem[i].paddr,
                                    ab->qmi.target_mem[i].size,
                                    ab->qmi.target_mem[i].type);
                }
index 13b4f5f50f8aac5af114bc1941570d6100960a74..ef6f5ea06c1f53d2bd3b118f43e7444cf0090dec 100644 (file)
@@ -177,7 +177,8 @@ struct ath_frame_info {
        s8 txq;
        u8 keyix;
        u8 rtscts_rate;
-       u8 retries : 7;
+       u8 retries : 6;
+       u8 dyn_smps : 1;
        u8 baw_tracked : 1;
        u8 tx_power;
        enum ath9k_key_type keytype:2;
index e60d4737fc6e4e42bc49c9486b6ea90263d43838..5691bd6eb82c2fc5d251f37855cb1ea0b694ba2e 100644 (file)
@@ -1271,6 +1271,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
                                 is_40, is_sgi, is_sp);
                        if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
                                info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC;
+                       if (rix >= 8 && fi->dyn_smps) {
+                               info->rates[i].RateFlags |=
+                                       ATH9K_RATESERIES_RTS_CTS;
+                               info->flags |= ATH9K_TXDESC_CTSENA;
+                       }
 
                        info->txpower[i] = ath_get_rate_txpower(sc, bf, rix,
                                                                is_40, false);
@@ -2114,6 +2119,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
                fi->keyix = an->ps_key;
        else
                fi->keyix = ATH9K_TXKEYIX_INVALID;
+       fi->dyn_smps = sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC;
        fi->keytype = keytype;
        fi->framelen = framelen;
        fi->tx_power = txpower;
index fd070ca5e517ffa4139e5d66f89e5fd1fd4cce3e..40f2109a097f3eb8a9c9cab9826385a3895b1c07 100644 (file)
@@ -271,12 +271,12 @@ static int iwl_pnvm_get_from_efi(struct iwl_trans *trans,
        err = efivar_entry_get(pnvm_efivar, NULL, &package_size, package);
        if (err) {
                IWL_DEBUG_FW(trans,
-                            "PNVM UEFI variable not found %d (len %zd)\n",
+                            "PNVM UEFI variable not found %d (len %lu)\n",
                             err, package_size);
                goto out;
        }
 
-       IWL_DEBUG_FW(trans, "Read PNVM fro UEFI with size %zd\n", package_size);
+       IWL_DEBUG_FW(trans, "Read PNVM fro UEFI with size %lu\n", package_size);
 
        *data = kmemdup(package->data, *len, GFP_KERNEL);
        if (!*data)
index 868da7e79a45507ba2a8851267cb56b402569591..e6d2e09943170af6fb48334d34182f74dc8f7ad5 100644 (file)
@@ -205,6 +205,8 @@ static inline void iwl_op_mode_time_point(struct iwl_op_mode *op_mode,
                                          enum iwl_fw_ini_time_point tp_id,
                                          union iwl_dbg_tlv_tp_data *tp_data)
 {
+       if (!op_mode || !op_mode->ops || !op_mode->ops->time_point)
+               return;
        op_mode->ops->time_point(op_mode, tp_id, tp_data);
 }
 
index 15e2773ce7e700e85a58957dd88c0acf40f730ae..5ee64f7f3c85fcffd9ede8d7247062d2aba9ab62 100644 (file)
@@ -1083,6 +1083,7 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek COMPUTER INC."),
                },
        },
+       {}
 };
 
 static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
index 314fec4a89ad12b7b2171d1d6ddc7978478cc52a..ffaf973dae948bfc5616d4a025ea150bc0dfddb1 100644 (file)
@@ -1106,6 +1106,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                }
        }
 
+#if IS_ENABLED(CONFIG_IWLMVM)
+
        /*
         * Workaround for problematic SnJ device: sometimes when
         * certain RF modules are connected to SnJ, the device ID
@@ -1116,7 +1118,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_SNJ)
                iwl_trans->trans_cfg = &iwl_so_trans_cfg;
 
-#if IS_ENABLED(CONFIG_IWLMVM)
        /*
         * special-case 7265D, it has the same PCI IDs.
         *
index 42426e25cac605aabe41ab134a4233e0e1028fbb..2bec971331194245a6cae0bba64d9ff199d33b74 100644 (file)
@@ -1129,6 +1129,8 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
 
                iwl_pcie_rx_init_rxb_lists(rxq);
 
+               spin_unlock_bh(&rxq->lock);
+
                if (!rxq->napi.poll) {
                        int (*poll)(struct napi_struct *, int) = iwl_pcie_napi_poll;
 
@@ -1149,7 +1151,6 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
                        napi_enable(&rxq->napi);
                }
 
-               spin_unlock_bh(&rxq->lock);
        }
 
        /* move the pool to the default queue and allocator ownerships */
index 19098b852d0a8bb69f9d539a41e64b5c640be1af..2f27c43ad76df3f354f6196fb49e3df911a45ad4 100644 (file)
@@ -345,7 +345,6 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
        };
        struct ieee80211_hw *hw;
        int len, n = 0, ret = -ENOMEM;
-       struct mt76_queue_entry e;
        struct mt76_txwi_cache *t;
        struct sk_buff *iter;
        dma_addr_t addr;
@@ -387,6 +386,11 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
        }
        tx_info.nbuf = n;
 
+       if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) {
+               ret = -ENOMEM;
+               goto unmap;
+       }
+
        dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
                                DMA_TO_DEVICE);
        ret = dev->drv->tx_prepare_skb(dev, txwi, q->qid, wcid, sta, &tx_info);
@@ -395,11 +399,6 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
        if (ret < 0)
                goto unmap;
 
-       if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) {
-               ret = -ENOMEM;
-               goto unmap;
-       }
-
        return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
                                tx_info.info, tx_info.skb, t);
 
@@ -419,9 +418,7 @@ free:
        }
 #endif
 
-       e.skb = tx_info.skb;
-       e.txwi = t;
-       dev->drv->tx_complete_skb(dev, &e);
+       dev_kfree_skb(tx_info.skb);
        mt76_put_txwi(dev, t);
        return ret;
 }
@@ -515,13 +512,13 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
 {
        struct sk_buff *skb = q->rx_head;
        struct skb_shared_info *shinfo = skb_shinfo(skb);
+       int nr_frags = shinfo->nr_frags;
 
-       if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) {
+       if (nr_frags < ARRAY_SIZE(shinfo->frags)) {
                struct page *page = virt_to_head_page(data);
                int offset = data - page_address(page) + q->buf_offset;
 
-               skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len,
-                               q->buf_size);
+               skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
        } else {
                skb_free_frag(data);
        }
@@ -530,7 +527,10 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
                return;
 
        q->rx_head = NULL;
-       dev->drv->rx_skb(dev, q - dev->q_rx, skb);
+       if (nr_frags < ARRAY_SIZE(shinfo->frags))
+               dev->drv->rx_skb(dev, q - dev->q_rx, skb);
+       else
+               dev_kfree_skb(skb);
 }
 
 static int
index eb889f8d6feaaa8ad82dc9f839ae859fb3eb2452..e5a258958ac919a8407d43564571a9f0750714c1 100644 (file)
@@ -967,11 +967,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
        }
        txp->nbuf = nbuf;
 
-       /* pass partial skb header to fw */
-       tx_info->buf[1].len = MT_CT_PARSE_LEN;
-       tx_info->buf[1].skip_unmap = true;
-       tx_info->nbuf = MT_CT_DMA_BUF_NUM;
-
        txp->flags = cpu_to_le16(MT_CT_INFO_APPLY_TXD | MT_CT_INFO_FROM_HOST);
 
        if (!key)
@@ -1009,6 +1004,11 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
                txp->rept_wds_wcid = cpu_to_le16(0x3ff);
        tx_info->skb = DMA_DUMMY_DATA;
 
+       /* pass partial skb header to fw */
+       tx_info->buf[1].len = MT_CT_PARSE_LEN;
+       tx_info->buf[1].skip_unmap = true;
+       tx_info->nbuf = MT_CT_DMA_BUF_NUM;
+
        return 0;
 }
 
index 7fb2170a9561210cbb3f7f18b5ef5ba93e750f3c..bd798df748ba5ea107ae38b95fd762670c21b85e 100644 (file)
@@ -543,7 +543,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
                tx_cont->bw = CMD_CBW_20MHZ;
                break;
        default:
-               break;
+               return -EINVAL;
        }
 
        if (!en) {
@@ -591,7 +591,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
                mode = MT_PHY_TYPE_HE_MU;
                break;
        default:
-               break;
+               return -EINVAL;
        }
 
        rateval =  mode << 6 | rate_idx;
index db125cd22b91a6558c58e1aaef9fea5fbb0d2926..b5cc72e7e81c3681d9bd111f603785090c532aaa 100644 (file)
@@ -405,10 +405,8 @@ mt7921_mcu_tx_rate_report(struct mt7921_dev *dev, struct sk_buff *skb,
        if (wlan_idx >= MT76_N_WCIDS)
                return;
        wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-       if (!wcid) {
-               stats->tx_rate = rate;
+       if (!wcid)
                return;
-       }
 
        msta = container_of(wcid, struct mt7921_sta, wcid);
        stats = &msta->stats;
index 6afb5ca999c2c993e045bc8e3325206852327069..39a01c2a3058d6a8628d9dc47a7520b5f969cabe 100644 (file)
@@ -557,8 +557,8 @@ check_frags:
        }
 
        if (skb_has_frag_list(skb) && !first_shinfo) {
-               first_shinfo = skb_shinfo(skb);
-               shinfo = skb_shinfo(skb_shinfo(skb)->frag_list);
+               first_shinfo = shinfo;
+               shinfo = skb_shinfo(shinfo->frag_list);
                nr_frags = shinfo->nr_frags;
 
                goto check_frags;
index c2689386a90688a47020b9b2e38d0571aaca92b5..1556998425d5bc752c35970be104b1fbcf09e972 100644 (file)
@@ -1492,7 +1492,11 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table,
 
        mutex_lock(&opp_table->lock);
        list_for_each_entry(temp, &opp_table->opp_list, node) {
-               if (dynamic == temp->dynamic) {
+               /*
+                * Refcount must be dropped only once for each OPP by OPP core,
+                * do that with help of "removed" flag.
+                */
+               if (!temp->removed && dynamic == temp->dynamic) {
                        opp = temp;
                        break;
                }
@@ -1502,10 +1506,27 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table,
        return opp;
 }
 
-bool _opp_remove_all_static(struct opp_table *opp_table)
+/*
+ * Can't call dev_pm_opp_put() from under the lock as debugfs removal needs to
+ * happen lock less to avoid circular dependency issues. This routine must be
+ * called without the opp_table->lock held.
+ */
+static void _opp_remove_all(struct opp_table *opp_table, bool dynamic)
 {
        struct dev_pm_opp *opp;
 
+       while ((opp = _opp_get_next(opp_table, dynamic))) {
+               opp->removed = true;
+               dev_pm_opp_put(opp);
+
+               /* Drop the references taken by dev_pm_opp_add() */
+               if (dynamic)
+                       dev_pm_opp_put_opp_table(opp_table);
+       }
+}
+
+bool _opp_remove_all_static(struct opp_table *opp_table)
+{
        mutex_lock(&opp_table->lock);
 
        if (!opp_table->parsed_static_opps) {
@@ -1520,13 +1541,7 @@ bool _opp_remove_all_static(struct opp_table *opp_table)
 
        mutex_unlock(&opp_table->lock);
 
-       /*
-        * Can't remove the OPP from under the lock, debugfs removal needs to
-        * happen lock less to avoid circular dependency issues.
-        */
-       while ((opp = _opp_get_next(opp_table, false)))
-               dev_pm_opp_put(opp);
-
+       _opp_remove_all(opp_table, false);
        return true;
 }
 
@@ -1539,25 +1554,12 @@ bool _opp_remove_all_static(struct opp_table *opp_table)
 void dev_pm_opp_remove_all_dynamic(struct device *dev)
 {
        struct opp_table *opp_table;
-       struct dev_pm_opp *opp;
-       int count = 0;
 
        opp_table = _find_opp_table(dev);
        if (IS_ERR(opp_table))
                return;
 
-       /*
-        * Can't remove the OPP from under the lock, debugfs removal needs to
-        * happen lock less to avoid circular dependency issues.
-        */
-       while ((opp = _opp_get_next(opp_table, true))) {
-               dev_pm_opp_put(opp);
-               count++;
-       }
-
-       /* Drop the references taken by dev_pm_opp_add() */
-       while (count--)
-               dev_pm_opp_put_opp_table(opp_table);
+       _opp_remove_all(opp_table, true);
 
        /* Drop the reference taken by _find_opp_table() */
        dev_pm_opp_put_opp_table(opp_table);
index 50fb9dced3c528018e8a467c286c8efb1226c161..407c3bfe51d9685344ffcc643f7835b273e57aea 100644 (file)
@@ -56,6 +56,7 @@ extern struct list_head opp_tables, lazy_opp_tables;
  * @dynamic:   not-created from static DT entries.
  * @turbo:     true if turbo (boost) OPP
  * @suspend:   true if suspend OPP
+ * @removed:   flag indicating that OPP's reference is dropped by OPP core.
  * @pstate: Device's power domain's performance state.
  * @rate:      Frequency in hertz
  * @level:     Performance level
@@ -78,6 +79,7 @@ struct dev_pm_opp {
        bool dynamic;
        bool turbo;
        bool suspend;
+       bool removed;
        unsigned int pstate;
        unsigned long rate;
        unsigned int level;
index c6fe0cfec0f681f19cabecc0826627e5d6018f2f..2d75026482197de191e13b73f39f3f4ba09ce79f 100644 (file)
@@ -26,7 +26,7 @@
 #include <xen/platform_pci.h>
 
 #include <asm/xen/swiotlb-xen.h>
-#define INVALID_GRANT_REF (0)
+
 #define INVALID_EVTCHN    (-1)
 
 struct pci_bus_entry {
@@ -42,7 +42,7 @@ struct pcifront_device {
        struct list_head root_buses;
 
        int evtchn;
-       int gnt_ref;
+       grant_ref_t gnt_ref;
 
        int irq;
 
index 66ad5b3ece1974b6b2fd296408b69d87fd0f8682..f2a85500258d0bca8bfb57f01bd0d1b4f545d456 100644 (file)
@@ -681,6 +681,7 @@ static int dmc620_pmu_device_probe(struct platform_device *pdev)
        if (!name) {
                dev_err(&pdev->dev,
                          "Create name failed, PMU @%pa\n", &res->start);
+               ret = -ENOMEM;
                goto out_teardown_dev;
        }
 
index d49a1534d8e91c5b34ae93f639fb0257b10636a5..9edc34981ee0a21c7adcec13e801f5b5890c1bc1 100644 (file)
@@ -41,7 +41,7 @@ struct mt6315_chip {
                .type = REGULATOR_VOLTAGE,                      \
                .id = _bid,                                     \
                .owner = THIS_MODULE,                           \
-               .n_voltages = 0xbf,                             \
+               .n_voltages = 0xc0,                             \
                .linear_ranges = mt_volt_range1,                \
                .n_linear_ranges = ARRAY_SIZE(mt_volt_range1),  \
                .vsel_reg = _vsel,                              \
@@ -69,7 +69,7 @@ static unsigned int mt6315_map_mode(u32 mode)
        case MT6315_BUCK_MODE_LP:
                return REGULATOR_MODE_IDLE;
        default:
-               return -EINVAL;
+               return REGULATOR_MODE_INVALID;
        }
 }
 
index 833d398c6aa21f3f5cdd777ca0c3ec6120d1045b..2f7ee212cb8c9d2b3b70e8900bff8c3bf461be04 100644 (file)
@@ -797,6 +797,14 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
+       /* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
+       ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
+                               BUCK123_PRESET_EN);
+       if (ret) {
+               dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
+               return ret;
+       }
+
        /* Set reset behavior on assertion of WDOG_B signal */
        ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
                                WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12);
@@ -814,7 +822,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
 
        if (IS_ERR(pca9450->sd_vsel_gpio)) {
                dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
-               return ret;
+               return PTR_ERR(pca9450->sd_vsel_gpio);
        }
 
        dev_info(&i2c->dev, "%s probed.\n",
index 79a554f1029dcd8722ea249155304686f3758e4d..65a108c9121f55590133f05f05314372556e9531 100644 (file)
@@ -726,8 +726,8 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
 static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
        .regulator_type = VRM,
        .ops = &rpmh_regulator_vrm_ops,
-       .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 16000),
-       .n_voltages = 5,
+       .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000),
+       .n_voltages = 236,
        .pmic_mode_map = pmic_mode_map_pmic5_smps,
        .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
 };
@@ -901,7 +901,7 @@ static const struct rpmh_vreg_init_data pm8350_vreg_data[] = {
 };
 
 static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = {
-       RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps510, "vdd-s1"),
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps515, "vdd-s1"),
        RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
        RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
        RPMH_VREG("smps4",  "smp%s4",  &pmic5_ftsmps510, "vdd-s4"),
index 3d4695ded6293de5edb60290273b3d28e2251db8..e3aaac90d238faf4697222e2e6de9cc85a4a50c5 100644 (file)
@@ -153,9 +153,9 @@ static int rt4831_regulator_probe(struct platform_device *pdev)
        int i, ret;
 
        regmap = dev_get_regmap(pdev->dev.parent, NULL);
-       if (IS_ERR(regmap)) {
+       if (!regmap) {
                dev_err(&pdev->dev, "Failed to init regmap\n");
-               return PTR_ERR(regmap);
+               return -ENODEV;
        }
 
        /* Configure DSV mode to normal by default */
index 15692449a1c3fc6032e739efb926ef071a6bdaeb..307a80f85c07de434274d0b8338c591040553c17 100644 (file)
@@ -424,8 +424,10 @@ tty3270_update(struct timer_list *t)
                         * last output position matches the start address
                         * of this line.
                         */
-                       if (s->string[1] == sba[0] && s->string[2] == sba[1])
-                               str += 3, len -= 3;
+                       if (s->string[1] == sba[0] && s->string[2] == sba[1]) {
+                               str += 3;
+                               len -= 3;
+                       }
                        if (raw3270_request_add_data(wrq, str, len) != 0)
                                break;
                        list_del_init(&s->update);
index 1515fdc3c1abd53c6fc73c57ecaebeafbc605eff..bd3c724bf695f12866a53b02faaa28c2628d602d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/debugfs.h>
+#include <linux/reboot.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/ipl.h>
@@ -238,6 +239,28 @@ static int __init zcore_reipl_init(void)
        return 0;
 }
 
+static int zcore_reboot_and_on_panic_handler(struct notifier_block *self,
+                                            unsigned long         event,
+                                            void                  *data)
+{
+       if (hsa_available)
+               release_hsa();
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block zcore_reboot_notifier = {
+       .notifier_call  = zcore_reboot_and_on_panic_handler,
+       /* we need to be notified before reipl and kdump */
+       .priority       = INT_MAX,
+};
+
+static struct notifier_block zcore_on_panic_notifier = {
+       .notifier_call  = zcore_reboot_and_on_panic_handler,
+       /* we need to be notified before reipl and kdump */
+       .priority       = INT_MAX,
+};
+
 static int __init zcore_init(void)
 {
        unsigned char arch;
@@ -293,28 +316,15 @@ static int __init zcore_init(void)
                goto fail;
 
        zcore_dir = debugfs_create_dir("zcore" , NULL);
-       if (!zcore_dir) {
-               rc = -ENOMEM;
-               goto fail;
-       }
        zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
                                                NULL, &zcore_reipl_fops);
-       if (!zcore_reipl_file) {
-               rc = -ENOMEM;
-               goto fail_dir;
-       }
        zcore_hsa_file = debugfs_create_file("hsa", S_IRUSR|S_IWUSR, zcore_dir,
                                             NULL, &zcore_hsa_fops);
-       if (!zcore_hsa_file) {
-               rc = -ENOMEM;
-               goto fail_reipl_file;
-       }
-       return 0;
 
-fail_reipl_file:
-       debugfs_remove(zcore_reipl_file);
-fail_dir:
-       debugfs_remove(zcore_dir);
+       register_reboot_notifier(&zcore_reboot_notifier);
+       atomic_notifier_chain_register(&panic_notifier_list, &zcore_on_panic_notifier);
+
+       return 0;
 fail:
        diag308(DIAG308_REL_HSA, NULL);
        return rc;
index 6420b197bb050724f0d6ed8127a4e1674526f171..05e136cfb8be7226381570392d282d83aafad375 100644 (file)
@@ -47,7 +47,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
        orb = &private->orb;
        cc = stsch(sch->schid, &schib);
 
-       printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
+       printk(KERN_WARNING "cio: ccw device timeout occurred at %lx, "
               "device information:\n", get_tod_clock());
        printk(KERN_WARNING "cio: orb:\n");
        print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
index 68106be4ba7a19b5fb182e820cf92cc132eb328e..767ac41686fe2f123a23e8c099aad17a23fc9836 100644 (file)
@@ -543,7 +543,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
                if (ret)
                        return ret;
 
-               return copy_to_user((void __user *)arg, &info, minsz);
+               return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
        }
        case VFIO_DEVICE_GET_REGION_INFO:
        {
@@ -561,7 +561,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
                if (ret)
                        return ret;
 
-               return copy_to_user((void __user *)arg, &info, minsz);
+               return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
        }
        case VFIO_DEVICE_GET_IRQ_INFO:
        {
@@ -582,7 +582,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
                if (info.count == -1)
                        return -EINVAL;
 
-               return copy_to_user((void __user *)arg, &info, minsz);
+               return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
        }
        case VFIO_DEVICE_SET_IRQS:
        {
index 41fc2e4135fe18714aba0a9e39748fe826886067..1ffdd411201cd62333d0efdd988d33a3ba116c85 100644 (file)
@@ -1286,7 +1286,7 @@ static int vfio_ap_mdev_get_device_info(unsigned long arg)
        info.num_regions = 0;
        info.num_irqs = 0;
 
-       return copy_to_user((void __user *)arg, &info, minsz);
+       return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
 }
 
 static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
index a1da83b0b0ef329f2684408a10647412bb16efd2..91acff493612aaa7082f391a4bfd99d086889a1e 100644 (file)
@@ -436,7 +436,7 @@ struct qeth_qdio_out_buffer {
        int is_header[QDIO_MAX_ELEMENTS_PER_BUFFER];
 
        struct qeth_qdio_out_q *q;
-       struct qeth_qdio_out_buffer *next_pending;
+       struct list_head list_entry;
 };
 
 struct qeth_card;
@@ -500,6 +500,7 @@ struct qeth_qdio_out_q {
        struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
        struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q];
        struct qdio_outbuf_state *bufstates; /* convenience pointer */
+       struct list_head pending_bufs;
        struct qeth_out_q_stats stats;
        spinlock_t lock;
        unsigned int priority;
index b71b8902d1c49a66fae6072f84336d3afbbdaeaf..a814698387bc37d397e64ee3546a2b67b5ac1bee 100644 (file)
@@ -73,8 +73,6 @@ static void qeth_free_qdio_queues(struct qeth_card *card);
 static void qeth_notify_skbs(struct qeth_qdio_out_q *queue,
                struct qeth_qdio_out_buffer *buf,
                enum iucv_tx_notify notification);
-static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error,
-                                int budget);
 
 static void qeth_close_dev_handler(struct work_struct *work)
 {
@@ -465,41 +463,6 @@ static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
        return n;
 }
 
-static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx,
-                                        int forced_cleanup)
-{
-       if (q->card->options.cq != QETH_CQ_ENABLED)
-               return;
-
-       if (q->bufs[bidx]->next_pending != NULL) {
-               struct qeth_qdio_out_buffer *head = q->bufs[bidx];
-               struct qeth_qdio_out_buffer *c = q->bufs[bidx]->next_pending;
-
-               while (c) {
-                       if (forced_cleanup ||
-                           atomic_read(&c->state) == QETH_QDIO_BUF_EMPTY) {
-                               struct qeth_qdio_out_buffer *f = c;
-
-                               QETH_CARD_TEXT(f->q->card, 5, "fp");
-                               QETH_CARD_TEXT_(f->q->card, 5, "%lx", (long) f);
-                               /* release here to avoid interleaving between
-                                  outbound tasklet and inbound tasklet
-                                  regarding notifications and lifecycle */
-                               qeth_tx_complete_buf(c, forced_cleanup, 0);
-
-                               c = f->next_pending;
-                               WARN_ON_ONCE(head->next_pending != f);
-                               head->next_pending = c;
-                               kmem_cache_free(qeth_qdio_outbuf_cache, f);
-                       } else {
-                               head = c;
-                               c = c->next_pending;
-                       }
-
-               }
-       }
-}
-
 static void qeth_qdio_handle_aob(struct qeth_card *card,
                                 unsigned long phys_aob_addr)
 {
@@ -507,6 +470,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
        struct qaob *aob;
        struct qeth_qdio_out_buffer *buffer;
        enum iucv_tx_notify notification;
+       struct qeth_qdio_out_q *queue;
        unsigned int i;
 
        aob = (struct qaob *) phys_to_virt(phys_aob_addr);
@@ -537,7 +501,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
                qeth_notify_skbs(buffer->q, buffer, notification);
 
                /* Free dangling allocations. The attached skbs are handled by
-                * qeth_cleanup_handled_pending().
+                * qeth_tx_complete_pending_bufs().
                 */
                for (i = 0;
                     i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
@@ -549,7 +513,9 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
                        buffer->is_header[i] = 0;
                }
 
+               queue = buffer->q;
                atomic_set(&buffer->state, QETH_QDIO_BUF_EMPTY);
+               napi_schedule(&queue->napi);
                break;
        default:
                WARN_ON_ONCE(1);
@@ -1424,9 +1390,6 @@ static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error,
        struct qeth_qdio_out_q *queue = buf->q;
        struct sk_buff *skb;
 
-       if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING)
-               qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR);
-
        /* Empty buffer? */
        if (buf->next_element_to_fill == 0)
                return;
@@ -1488,14 +1451,38 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
        atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
 
+static void qeth_tx_complete_pending_bufs(struct qeth_card *card,
+                                         struct qeth_qdio_out_q *queue,
+                                         bool drain)
+{
+       struct qeth_qdio_out_buffer *buf, *tmp;
+
+       list_for_each_entry_safe(buf, tmp, &queue->pending_bufs, list_entry) {
+               if (drain || atomic_read(&buf->state) == QETH_QDIO_BUF_EMPTY) {
+                       QETH_CARD_TEXT(card, 5, "fp");
+                       QETH_CARD_TEXT_(card, 5, "%lx", (long) buf);
+
+                       if (drain)
+                               qeth_notify_skbs(queue, buf,
+                                                TX_NOTIFY_GENERALERROR);
+                       qeth_tx_complete_buf(buf, drain, 0);
+
+                       list_del(&buf->list_entry);
+                       kmem_cache_free(qeth_qdio_outbuf_cache, buf);
+               }
+       }
+}
+
 static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free)
 {
        int j;
 
+       qeth_tx_complete_pending_bufs(q->card, q, true);
+
        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
                if (!q->bufs[j])
                        continue;
-               qeth_cleanup_handled_pending(q, j, 1);
+
                qeth_clear_output_buffer(q, q->bufs[j], true, 0);
                if (free) {
                        kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]);
@@ -2615,7 +2602,6 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx)
        skb_queue_head_init(&newbuf->skb_list);
        lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key);
        newbuf->q = q;
-       newbuf->next_pending = q->bufs[bidx];
        atomic_set(&newbuf->state, QETH_QDIO_BUF_EMPTY);
        q->bufs[bidx] = newbuf;
        return 0;
@@ -2634,15 +2620,28 @@ static void qeth_free_output_queue(struct qeth_qdio_out_q *q)
 static struct qeth_qdio_out_q *qeth_alloc_output_queue(void)
 {
        struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL);
+       unsigned int i;
 
        if (!q)
                return NULL;
 
-       if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) {
-               kfree(q);
-               return NULL;
+       if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q))
+               goto err_qdio_bufs;
+
+       for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
+               if (qeth_init_qdio_out_buf(q, i))
+                       goto err_out_bufs;
        }
+
        return q;
+
+err_out_bufs:
+       while (i > 0)
+               kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[--i]);
+       qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
+err_qdio_bufs:
+       kfree(q);
+       return NULL;
 }
 
 static void qeth_tx_completion_timer(struct timer_list *timer)
@@ -2655,7 +2654,7 @@ static void qeth_tx_completion_timer(struct timer_list *timer)
 
 static int qeth_alloc_qdio_queues(struct qeth_card *card)
 {
-       int i, j;
+       unsigned int i;
 
        QETH_CARD_TEXT(card, 2, "allcqdbf");
 
@@ -2684,18 +2683,12 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card)
                card->qdio.out_qs[i] = queue;
                queue->card = card;
                queue->queue_no = i;
+               INIT_LIST_HEAD(&queue->pending_bufs);
                spin_lock_init(&queue->lock);
                timer_setup(&queue->timer, qeth_tx_completion_timer, 0);
                queue->coalesce_usecs = QETH_TX_COALESCE_USECS;
                queue->max_coalesced_frames = QETH_TX_MAX_COALESCED_FRAMES;
                queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT;
-
-               /* give outbound qeth_qdio_buffers their qdio_buffers */
-               for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
-                       WARN_ON(queue->bufs[j]);
-                       if (qeth_init_qdio_out_buf(queue, j))
-                               goto out_freeoutqbufs;
-               }
        }
 
        /* completion */
@@ -2704,13 +2697,6 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card)
 
        return 0;
 
-out_freeoutqbufs:
-       while (j > 0) {
-               --j;
-               kmem_cache_free(qeth_qdio_outbuf_cache,
-                               card->qdio.out_qs[i]->bufs[j]);
-               card->qdio.out_qs[i]->bufs[j] = NULL;
-       }
 out_freeoutq:
        while (i > 0) {
                qeth_free_output_queue(card->qdio.out_qs[--i]);
@@ -6107,6 +6093,8 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
                                        qeth_schedule_recovery(card);
                                }
 
+                               list_add(&buffer->list_entry,
+                                        &queue->pending_bufs);
                                /* Skip clearing the buffer: */
                                return;
                        case QETH_QDIO_BUF_QAOB_OK:
@@ -6162,6 +6150,8 @@ static int qeth_tx_poll(struct napi_struct *napi, int budget)
                unsigned int bytes = 0;
                int completed;
 
+               qeth_tx_complete_pending_bufs(card, queue, false);
+
                if (qeth_out_queue_is_empty(queue)) {
                        napi_complete(napi);
                        return 0;
@@ -6194,7 +6184,6 @@ static int qeth_tx_poll(struct napi_struct *napi, int budget)
 
                        qeth_handle_send_error(card, buffer, error);
                        qeth_iqd_tx_complete(queue, bidx, error, budget);
-                       qeth_cleanup_handled_pending(queue, bidx, false);
                }
 
                netdev_tx_completed_queue(txq, packets, bytes);
@@ -7249,9 +7238,7 @@ int qeth_open(struct net_device *dev)
        card->data.state = CH_STATE_UP;
        netif_tx_start_all_queues(dev);
 
-       napi_enable(&card->napi);
        local_bh_disable();
-       napi_schedule(&card->napi);
        if (IS_IQD(card)) {
                struct qeth_qdio_out_q *queue;
                unsigned int i;
@@ -7263,8 +7250,12 @@ int qeth_open(struct net_device *dev)
                        napi_schedule(&queue->napi);
                }
        }
+
+       napi_enable(&card->napi);
+       napi_schedule(&card->napi);
        /* kick-start the NAPI softirq: */
        local_bh_enable();
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(qeth_open);
@@ -7274,6 +7265,11 @@ int qeth_stop(struct net_device *dev)
        struct qeth_card *card = dev->ml_priv;
 
        QETH_CARD_TEXT(card, 4, "qethstop");
+
+       napi_disable(&card->napi);
+       cancel_delayed_work_sync(&card->buffer_reclaim_work);
+       qdio_stop_irq(CARD_DDEV(card));
+
        if (IS_IQD(card)) {
                struct qeth_qdio_out_q *queue;
                unsigned int i;
@@ -7294,10 +7290,6 @@ int qeth_stop(struct net_device *dev)
                netif_tx_disable(dev);
        }
 
-       napi_disable(&card->napi);
-       cancel_delayed_work_sync(&card->buffer_reclaim_work);
-       qdio_stop_irq(CARD_DDEV(card));
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(qeth_stop);
index 755313b766b914aed345a124b0052c1e969b1740..e663085a894468284c3f713016ea39525483b6ab 100644 (file)
@@ -6038,7 +6038,7 @@ out:
  * Return value:
  *     0
  **/
-static int ibmvfc_remove(struct vio_dev *vdev)
+static void ibmvfc_remove(struct vio_dev *vdev)
 {
        struct ibmvfc_host *vhost = dev_get_drvdata(&vdev->dev);
        LIST_HEAD(purge);
@@ -6070,7 +6070,6 @@ static int ibmvfc_remove(struct vio_dev *vdev)
        spin_unlock(&ibmvfc_driver_lock);
        scsi_host_put(vhost->host);
        LEAVE;
-       return 0;
 }
 
 /**
index 29fcc44be2d57f800363a8f8a5cfe98585c89a20..77fafb1bc173a1dc2fd1bdf6e037f501cf5d20d0 100644 (file)
@@ -2335,7 +2335,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        return -1;
 }
 
-static int ibmvscsi_remove(struct vio_dev *vdev)
+static void ibmvscsi_remove(struct vio_dev *vdev)
 {
        struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev);
 
@@ -2356,8 +2356,6 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
        spin_unlock(&ibmvscsi_driver_lock);
 
        scsi_host_put(hostdata->host);
-
-       return 0;
 }
 
 /**
index cc3908c2d2f943173e0bc6cffe7770032d1eb2a8..9abd9e253af60e88b79b6821757d8499517a3733 100644 (file)
@@ -3595,7 +3595,7 @@ free_adapter:
        return rc;
 }
 
-static int ibmvscsis_remove(struct vio_dev *vdev)
+static void ibmvscsis_remove(struct vio_dev *vdev)
 {
        struct scsi_info *vscsi = dev_get_drvdata(&vdev->dev);
 
@@ -3622,8 +3622,6 @@ static int ibmvscsis_remove(struct vio_dev *vdev)
        list_del(&vscsi->list);
        spin_unlock_bh(&ibmvscsis_dev_lock);
        kfree(vscsi);
-
-       return 0;
 }
 
 static ssize_t system_id_show(struct device *dev,
index c908489196442d9a1a7792a470c2469905e3a09d..9afa1dcef2c2f247fceb509a3153f59808078d5f 100644 (file)
@@ -317,7 +317,6 @@ static void hvcs_hangup(struct tty_struct * tty);
 
 static int hvcs_probe(struct vio_dev *dev,
                const struct vio_device_id *id);
-static int hvcs_remove(struct vio_dev *dev);
 static int __init hvcs_module_init(void);
 static void __exit hvcs_module_exit(void);
 static int hvcs_initialize(void);
@@ -819,7 +818,7 @@ static int hvcs_probe(
        return 0;
 }
 
-static int hvcs_remove(struct vio_dev *dev)
+static void hvcs_remove(struct vio_dev *dev)
 {
        struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
        unsigned long flags;
@@ -849,7 +848,6 @@ static int hvcs_remove(struct vio_dev *dev)
 
        printk(KERN_INFO "HVCS: vty-server@%X removed from the"
                        " vio bus.\n", dev->unit_address);
-       return 0;
 };
 
 static struct vio_driver hvcs_vio_driver = {
index 8f07b051610096d3957702c255d44b8183103ef2..a566bb494e246b852578130522539d577f06d256 100644 (file)
@@ -748,6 +748,38 @@ void usb_put_intf(struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usb_put_intf);
 
+/**
+ * usb_intf_get_dma_device - acquire a reference on the usb interface's DMA endpoint
+ * @intf: the usb interface
+ *
+ * While a USB device cannot perform DMA operations by itself, many USB
+ * controllers can. A call to usb_intf_get_dma_device() returns the DMA endpoint
+ * for the given USB interface, if any. The returned device structure must be
+ * released with put_device().
+ *
+ * See also usb_get_dma_device().
+ *
+ * Returns: A reference to the usb interface's DMA endpoint; or NULL if none
+ *          exists.
+ */
+struct device *usb_intf_get_dma_device(struct usb_interface *intf)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct device *dmadev;
+
+       if (!udev->bus)
+               return NULL;
+
+       dmadev = get_device(udev->bus->sysdev);
+       if (!dmadev || !dmadev->dma_mask) {
+               put_device(dmadev);
+               return NULL;
+       }
+
+       return dmadev;
+}
+EXPORT_SYMBOL_GPL(usb_intf_get_dma_device);
+
 /*                     USB device locking
  *
  * USB devices and interfaces are locked using the semaphore in their
index 551372f9b9aa283f8c2abcb49375b32dac274a85..465f55beb97f94182594e74dd33237c6f458ebc7 100644 (file)
@@ -287,11 +287,8 @@ static inline void aty_st_8(int regindex, u8 val, const struct atyfb_par *par)
 #endif
 }
 
-#if defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) || \
-defined (CONFIG_FB_ATY_BACKLIGHT)
 extern void aty_st_lcd(int index, u32 val, const struct atyfb_par *par);
 extern u32 aty_ld_lcd(int index, const struct atyfb_par *par);
-#endif
 
     /*
      *  DAC operations
index e946903a86c2d8ed042221534f8c916b93039291..1aef3d6ebd8809f5134381ab2d5b9878141a4c0d 100644 (file)
 #define PRINTKE(fmt, args...)  printk(KERN_ERR "atyfb: " fmt, ## args)
 
 #if defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_GENERIC_LCD) || \
-defined(CONFIG_FB_ATY_BACKLIGHT)
+defined(CONFIG_FB_ATY_BACKLIGHT) || defined (CONFIG_PPC_PMAC)
 static const u32 lt_lcd_regs[] = {
        CNFG_PANEL_LG,
        LCD_GEN_CNTL_LG,
@@ -175,8 +175,8 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par)
                return aty_ld_le32(LCD_DATA, par);
        }
 }
-#else /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) \
-        defined(CONFIG_FB_ATY_GENERIC_LCD) */
+#else /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) ||
+        defined(CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_PPC_PMAC) */
 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
 { }
 
@@ -184,7 +184,8 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par)
 {
        return 0;
 }
-#endif /* defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
+#endif /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) ||
+         defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_PPC_PMAC) */
 
 #ifdef CONFIG_FB_ATY_GENERIC_LCD
 /*
index da87f3a1e351b0bb2794b11aa900dc540d09351b..b8f2f971c2f0fc6ef6ef3b3e8ab88147b4dc39c3 100644 (file)
@@ -47,6 +47,11 @@ static unsigned evtchn_2l_max_channels(void)
        return EVTCHN_2L_NR_CHANNELS;
 }
 
+static void evtchn_2l_remove(evtchn_port_t evtchn, unsigned int cpu)
+{
+       clear_bit(evtchn, BM(per_cpu(cpu_evtchn_mask, cpu)));
+}
+
 static void evtchn_2l_bind_to_cpu(evtchn_port_t evtchn, unsigned int cpu,
                                  unsigned int old_cpu)
 {
@@ -72,12 +77,6 @@ static bool evtchn_2l_is_pending(evtchn_port_t port)
        return sync_test_bit(port, BM(&s->evtchn_pending[0]));
 }
 
-static bool evtchn_2l_test_and_set_mask(evtchn_port_t port)
-{
-       struct shared_info *s = HYPERVISOR_shared_info;
-       return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0]));
-}
-
 static void evtchn_2l_mask(evtchn_port_t port)
 {
        struct shared_info *s = HYPERVISOR_shared_info;
@@ -355,18 +354,27 @@ static void evtchn_2l_resume(void)
                                EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD);
 }
 
+static int evtchn_2l_percpu_deinit(unsigned int cpu)
+{
+       memset(per_cpu(cpu_evtchn_mask, cpu), 0, sizeof(xen_ulong_t) *
+                       EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD);
+
+       return 0;
+}
+
 static const struct evtchn_ops evtchn_ops_2l = {
        .max_channels      = evtchn_2l_max_channels,
        .nr_channels       = evtchn_2l_max_channels,
+       .remove            = evtchn_2l_remove,
        .bind_to_cpu       = evtchn_2l_bind_to_cpu,
        .clear_pending     = evtchn_2l_clear_pending,
        .set_pending       = evtchn_2l_set_pending,
        .is_pending        = evtchn_2l_is_pending,
-       .test_and_set_mask = evtchn_2l_test_and_set_mask,
        .mask              = evtchn_2l_mask,
        .unmask            = evtchn_2l_unmask,
        .handle_events     = evtchn_2l_handle_events,
        .resume            = evtchn_2l_resume,
+       .percpu_deinit     = evtchn_2l_percpu_deinit,
 };
 
 void __init xen_evtchn_2l_init(void)
index adb7260e94b232d6ffe334cb2b5f6c023092c432..8236e2364eeb4e4415d2ab53348dc2306ce60126 100644 (file)
@@ -98,13 +98,19 @@ struct irq_info {
        short refcnt;
        u8 spurious_cnt;
        u8 is_accounted;
-       enum xen_irq_type type; /* type */
+       short type;             /* type: IRQT_* */
+       u8 mask_reason;         /* Why is event channel masked */
+#define EVT_MASK_REASON_EXPLICIT       0x01
+#define EVT_MASK_REASON_TEMPORARY      0x02
+#define EVT_MASK_REASON_EOI_PENDING    0x04
+       u8 is_active;           /* Is event just being handled? */
        unsigned irq;
        evtchn_port_t evtchn;   /* event channel */
        unsigned short cpu;     /* cpu bound */
        unsigned short eoi_cpu; /* EOI must happen on this cpu-1 */
        unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */
        u64 eoi_time;           /* Time in jiffies when to EOI. */
+       spinlock_t lock;
 
        union {
                unsigned short virq;
@@ -154,6 +160,7 @@ static DEFINE_RWLOCK(evtchn_rwlock);
  *   evtchn_rwlock
  *     IRQ-desc lock
  *       percpu eoi_list_lock
+ *         irq_info->lock
  */
 
 static LIST_HEAD(xen_irq_list_head);
@@ -304,6 +311,8 @@ static int xen_irq_info_common_setup(struct irq_info *info,
        info->irq = irq;
        info->evtchn = evtchn;
        info->cpu = cpu;
+       info->mask_reason = EVT_MASK_REASON_EXPLICIT;
+       spin_lock_init(&info->lock);
 
        ret = set_evtchn_to_irq(evtchn, irq);
        if (ret < 0)
@@ -377,6 +386,7 @@ static int xen_irq_info_pirq_setup(unsigned irq,
 static void xen_irq_info_cleanup(struct irq_info *info)
 {
        set_evtchn_to_irq(info->evtchn, -1);
+       xen_evtchn_port_remove(info->evtchn, info->cpu);
        info->evtchn = 0;
        channels_on_cpu_dec(info);
 }
@@ -458,6 +468,34 @@ unsigned int cpu_from_evtchn(evtchn_port_t evtchn)
        return ret;
 }
 
+static void do_mask(struct irq_info *info, u8 reason)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&info->lock, flags);
+
+       if (!info->mask_reason)
+               mask_evtchn(info->evtchn);
+
+       info->mask_reason |= reason;
+
+       spin_unlock_irqrestore(&info->lock, flags);
+}
+
+static void do_unmask(struct irq_info *info, u8 reason)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&info->lock, flags);
+
+       info->mask_reason &= ~reason;
+
+       if (!info->mask_reason)
+               unmask_evtchn(info->evtchn);
+
+       spin_unlock_irqrestore(&info->lock, flags);
+}
+
 #ifdef CONFIG_X86
 static bool pirq_check_eoi_map(unsigned irq)
 {
@@ -604,7 +642,7 @@ static void xen_irq_lateeoi_locked(struct irq_info *info, bool spurious)
        }
 
        info->eoi_time = 0;
-       unmask_evtchn(evtchn);
+       do_unmask(info, EVT_MASK_REASON_EOI_PENDING);
 }
 
 static void xen_irq_lateeoi_worker(struct work_struct *work)
@@ -773,6 +811,12 @@ static void xen_evtchn_close(evtchn_port_t port)
                BUG();
 }
 
+static void event_handler_exit(struct irq_info *info)
+{
+       smp_store_release(&info->is_active, 0);
+       clear_evtchn(info->evtchn);
+}
+
 static void pirq_query_unmask(int irq)
 {
        struct physdev_irq_status_query irq_status;
@@ -791,14 +835,15 @@ static void pirq_query_unmask(int irq)
 
 static void eoi_pirq(struct irq_data *data)
 {
-       evtchn_port_t evtchn = evtchn_from_irq(data->irq);
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
        struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) };
        int rc = 0;
 
        if (!VALID_EVTCHN(evtchn))
                return;
 
-       clear_evtchn(evtchn);
+       event_handler_exit(info);
 
        if (pirq_needs_eoi(data->irq)) {
                rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
@@ -849,7 +894,8 @@ static unsigned int __startup_pirq(unsigned int irq)
                goto err;
 
 out:
-       unmask_evtchn(evtchn);
+       do_unmask(info, EVT_MASK_REASON_EXPLICIT);
+
        eoi_pirq(irq_get_irq_data(irq));
 
        return 0;
@@ -876,7 +922,7 @@ static void shutdown_pirq(struct irq_data *data)
        if (!VALID_EVTCHN(evtchn))
                return;
 
-       mask_evtchn(evtchn);
+       do_mask(info, EVT_MASK_REASON_EXPLICIT);
        xen_evtchn_close(evtchn);
        xen_irq_info_cleanup(info);
 }
@@ -1628,6 +1674,8 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl)
        }
 
        info = info_for_irq(irq);
+       if (xchg_acquire(&info->is_active, 1))
+               return;
 
        dev = (info->type == IRQT_EVTCHN) ? info->u.interdomain : NULL;
        if (dev)
@@ -1720,10 +1768,10 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
 }
 
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
-static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu)
+static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu)
 {
        struct evtchn_bind_vcpu bind_vcpu;
-       int masked;
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
 
        if (!VALID_EVTCHN(evtchn))
                return -1;
@@ -1739,7 +1787,7 @@ static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu)
         * Mask the event while changing the VCPU binding to prevent
         * it being delivered on an unexpected VCPU.
         */
-       masked = test_and_set_mask(evtchn);
+       do_mask(info, EVT_MASK_REASON_TEMPORARY);
 
        /*
         * If this fails, it usually just indicates that we're dealing with a
@@ -1749,8 +1797,7 @@ static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu)
        if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
                bind_evtchn_to_cpu(evtchn, tcpu, false);
 
-       if (!masked)
-               unmask_evtchn(evtchn);
+       do_unmask(info, EVT_MASK_REASON_TEMPORARY);
 
        return 0;
 }
@@ -1789,7 +1836,7 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
        unsigned int tcpu = select_target_cpu(dest);
        int ret;
 
-       ret = xen_rebind_evtchn_to_cpu(evtchn_from_irq(data->irq), tcpu);
+       ret = xen_rebind_evtchn_to_cpu(info_for_irq(data->irq), tcpu);
        if (!ret)
                irq_data_update_effective_affinity(data, cpumask_of(tcpu));
 
@@ -1798,28 +1845,29 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
 
 static void enable_dynirq(struct irq_data *data)
 {
-       evtchn_port_t evtchn = evtchn_from_irq(data->irq);
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
 
        if (VALID_EVTCHN(evtchn))
-               unmask_evtchn(evtchn);
+               do_unmask(info, EVT_MASK_REASON_EXPLICIT);
 }
 
 static void disable_dynirq(struct irq_data *data)
 {
-       evtchn_port_t evtchn = evtchn_from_irq(data->irq);
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
 
        if (VALID_EVTCHN(evtchn))
-               mask_evtchn(evtchn);
+               do_mask(info, EVT_MASK_REASON_EXPLICIT);
 }
 
 static void ack_dynirq(struct irq_data *data)
 {
-       evtchn_port_t evtchn = evtchn_from_irq(data->irq);
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
 
-       if (!VALID_EVTCHN(evtchn))
-               return;
-
-       clear_evtchn(evtchn);
+       if (VALID_EVTCHN(evtchn))
+               event_handler_exit(info);
 }
 
 static void mask_ack_dynirq(struct irq_data *data)
@@ -1828,18 +1876,39 @@ static void mask_ack_dynirq(struct irq_data *data)
        ack_dynirq(data);
 }
 
+static void lateeoi_ack_dynirq(struct irq_data *data)
+{
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
+
+       if (VALID_EVTCHN(evtchn)) {
+               do_mask(info, EVT_MASK_REASON_EOI_PENDING);
+               event_handler_exit(info);
+       }
+}
+
+static void lateeoi_mask_ack_dynirq(struct irq_data *data)
+{
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
+
+       if (VALID_EVTCHN(evtchn)) {
+               do_mask(info, EVT_MASK_REASON_EXPLICIT);
+               event_handler_exit(info);
+       }
+}
+
 static int retrigger_dynirq(struct irq_data *data)
 {
-       evtchn_port_t evtchn = evtchn_from_irq(data->irq);
-       int masked;
+       struct irq_info *info = info_for_irq(data->irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
 
        if (!VALID_EVTCHN(evtchn))
                return 0;
 
-       masked = test_and_set_mask(evtchn);
+       do_mask(info, EVT_MASK_REASON_TEMPORARY);
        set_evtchn(evtchn);
-       if (!masked)
-               unmask_evtchn(evtchn);
+       do_unmask(info, EVT_MASK_REASON_TEMPORARY);
 
        return 1;
 }
@@ -1938,10 +2007,11 @@ static void restore_cpu_ipis(unsigned int cpu)
 /* Clear an irq's pending state, in preparation for polling on it */
 void xen_clear_irq_pending(int irq)
 {
-       evtchn_port_t evtchn = evtchn_from_irq(irq);
+       struct irq_info *info = info_for_irq(irq);
+       evtchn_port_t evtchn = info ? info->evtchn : 0;
 
        if (VALID_EVTCHN(evtchn))
-               clear_evtchn(evtchn);
+               event_handler_exit(info);
 }
 EXPORT_SYMBOL(xen_clear_irq_pending);
 void xen_set_irq_pending(int irq)
@@ -2053,8 +2123,8 @@ static struct irq_chip xen_lateeoi_chip __read_mostly = {
        .irq_mask               = disable_dynirq,
        .irq_unmask             = enable_dynirq,
 
-       .irq_ack                = mask_ack_dynirq,
-       .irq_mask_ack           = mask_ack_dynirq,
+       .irq_ack                = lateeoi_ack_dynirq,
+       .irq_mask_ack           = lateeoi_mask_ack_dynirq,
 
        .irq_set_affinity       = set_affinity_irq,
        .irq_retrigger          = retrigger_dynirq,
index b234f1766810c61db949c4a17b3cf19cdf4d3306..ad9fe51d3fb33275ec711a81b1f09d50ee46e963 100644 (file)
@@ -209,12 +209,6 @@ static bool evtchn_fifo_is_pending(evtchn_port_t port)
        return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word));
 }
 
-static bool evtchn_fifo_test_and_set_mask(evtchn_port_t port)
-{
-       event_word_t *word = event_word_from_port(port);
-       return sync_test_and_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word));
-}
-
 static void evtchn_fifo_mask(evtchn_port_t port)
 {
        event_word_t *word = event_word_from_port(port);
@@ -423,7 +417,6 @@ static const struct evtchn_ops evtchn_ops_fifo = {
        .clear_pending     = evtchn_fifo_clear_pending,
        .set_pending       = evtchn_fifo_set_pending,
        .is_pending        = evtchn_fifo_is_pending,
-       .test_and_set_mask = evtchn_fifo_test_and_set_mask,
        .mask              = evtchn_fifo_mask,
        .unmask            = evtchn_fifo_unmask,
        .handle_events     = evtchn_fifo_handle_events,
index 0a97c0549db761fdf3f4ffdec0ff22401df427be..4d3398eff9cdf1567a5f64dcb63561680dda405e 100644 (file)
@@ -14,13 +14,13 @@ struct evtchn_ops {
        unsigned (*nr_channels)(void);
 
        int (*setup)(evtchn_port_t port);
+       void (*remove)(evtchn_port_t port, unsigned int cpu);
        void (*bind_to_cpu)(evtchn_port_t evtchn, unsigned int cpu,
                            unsigned int old_cpu);
 
        void (*clear_pending)(evtchn_port_t port);
        void (*set_pending)(evtchn_port_t port);
        bool (*is_pending)(evtchn_port_t port);
-       bool (*test_and_set_mask)(evtchn_port_t port);
        void (*mask)(evtchn_port_t port);
        void (*unmask)(evtchn_port_t port);
 
@@ -54,6 +54,13 @@ static inline int xen_evtchn_port_setup(evtchn_port_t evtchn)
        return 0;
 }
 
+static inline void xen_evtchn_port_remove(evtchn_port_t evtchn,
+                                         unsigned int cpu)
+{
+       if (evtchn_ops->remove)
+               evtchn_ops->remove(evtchn, cpu);
+}
+
 static inline void xen_evtchn_port_bind_to_cpu(evtchn_port_t evtchn,
                                               unsigned int cpu,
                                               unsigned int old_cpu)
@@ -76,11 +83,6 @@ static inline bool test_evtchn(evtchn_port_t port)
        return evtchn_ops->is_pending(port);
 }
 
-static inline bool test_and_set_mask(evtchn_port_t port)
-{
-       return evtchn_ops->test_and_set_mask(port);
-}
-
 static inline void mask_evtchn(evtchn_port_t port)
 {
        return evtchn_ops->mask(port);
index 5447c5156b2e62ea50f8190609a85db42904b4ed..f01d58c7a042ed747ce2c9227af0c5429a78546e 100644 (file)
@@ -133,20 +133,26 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count,
        if (NULL == add)
                return NULL;
 
-       add->grants    = kvcalloc(count, sizeof(add->grants[0]), GFP_KERNEL);
-       add->map_ops   = kvcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
-       add->unmap_ops = kvcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
-       add->kmap_ops  = kvcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
-       add->kunmap_ops = kvcalloc(count,
-                                  sizeof(add->kunmap_ops[0]), GFP_KERNEL);
+       add->grants    = kvmalloc_array(count, sizeof(add->grants[0]),
+                                       GFP_KERNEL);
+       add->map_ops   = kvmalloc_array(count, sizeof(add->map_ops[0]),
+                                       GFP_KERNEL);
+       add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]),
+                                       GFP_KERNEL);
        add->pages     = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
        if (NULL == add->grants    ||
            NULL == add->map_ops   ||
            NULL == add->unmap_ops ||
-           NULL == add->kmap_ops  ||
-           NULL == add->kunmap_ops ||
            NULL == add->pages)
                goto err;
+       if (use_ptemod) {
+               add->kmap_ops   = kvmalloc_array(count, sizeof(add->kmap_ops[0]),
+                                                GFP_KERNEL);
+               add->kunmap_ops = kvmalloc_array(count, sizeof(add->kunmap_ops[0]),
+                                                GFP_KERNEL);
+               if (NULL == add->kmap_ops || NULL == add->kunmap_ops)
+                       goto err;
+       }
 
 #ifdef CONFIG_XEN_GRANT_DMA_ALLOC
        add->dma_flags = dma_flags;
@@ -183,10 +189,14 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count,
                goto err;
 
        for (i = 0; i < count; i++) {
-               add->map_ops[i].handle = -1;
-               add->unmap_ops[i].handle = -1;
-               add->kmap_ops[i].handle = -1;
-               add->kunmap_ops[i].handle = -1;
+               add->grants[i].domid = DOMID_INVALID;
+               add->grants[i].ref = INVALID_GRANT_REF;
+               add->map_ops[i].handle = INVALID_GRANT_HANDLE;
+               add->unmap_ops[i].handle = INVALID_GRANT_HANDLE;
+               if (use_ptemod) {
+                       add->kmap_ops[i].handle = INVALID_GRANT_HANDLE;
+                       add->kunmap_ops[i].handle = INVALID_GRANT_HANDLE;
+               }
        }
 
        add->index = 0;
@@ -274,7 +284,7 @@ static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data)
                          map->grants[pgnr].ref,
                          map->grants[pgnr].domid);
        gnttab_set_unmap_op(&map->unmap_ops[pgnr], pte_maddr, flags,
-                           -1 /* handle */);
+                           INVALID_GRANT_HANDLE);
        return 0;
 }
 
@@ -292,7 +302,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
 
        if (!use_ptemod) {
                /* Note: it could already be mapped */
-               if (map->map_ops[0].handle != -1)
+               if (map->map_ops[0].handle != INVALID_GRANT_HANDLE)
                        return 0;
                for (i = 0; i < map->count; i++) {
                        unsigned long addr = (unsigned long)
@@ -301,7 +311,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
                                map->grants[i].ref,
                                map->grants[i].domid);
                        gnttab_set_unmap_op(&map->unmap_ops[i], addr,
-                               map->flags, -1 /* handle */);
+                               map->flags, INVALID_GRANT_HANDLE);
                }
        } else {
                /*
@@ -327,13 +337,13 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
                                map->grants[i].ref,
                                map->grants[i].domid);
                        gnttab_set_unmap_op(&map->kunmap_ops[i], address,
-                               flags, -1);
+                               flags, INVALID_GRANT_HANDLE);
                }
        }
 
        pr_debug("map %d+%d\n", map->index, map->count);
-       err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL,
-                       map->pages, map->count);
+       err = gnttab_map_refs(map->map_ops, map->kmap_ops, map->pages,
+                       map->count);
 
        for (i = 0; i < map->count; i++) {
                if (map->map_ops[i].status == GNTST_okay)
@@ -385,7 +395,7 @@ static int __unmap_grant_pages(struct gntdev_grant_map *map, int offset,
                pr_debug("unmap handle=%d st=%d\n",
                        map->unmap_ops[offset+i].handle,
                        map->unmap_ops[offset+i].status);
-               map->unmap_ops[offset+i].handle = -1;
+               map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE;
        }
        return err;
 }
@@ -401,13 +411,15 @@ static int unmap_grant_pages(struct gntdev_grant_map *map, int offset,
         * already unmapped some of the grants. Only unmap valid ranges.
         */
        while (pages && !err) {
-               while (pages && map->unmap_ops[offset].handle == -1) {
+               while (pages &&
+                      map->unmap_ops[offset].handle == INVALID_GRANT_HANDLE) {
                        offset++;
                        pages--;
                }
                range = 0;
                while (range < pages) {
-                       if (map->unmap_ops[offset+range].handle == -1)
+                       if (map->unmap_ops[offset + range].handle ==
+                           INVALID_GRANT_HANDLE)
                                break;
                        range++;
                }
index 462253ae483a34af11456e347cf0fb94e2da10ad..a55bda4233bbea9edd12555f03dac8289ea16232 100644 (file)
@@ -203,7 +203,7 @@ config TMPFS_XATTR
 
 config TMPFS_INODE64
        bool "Use 64-bit ino_t by default in tmpfs"
-       depends on TMPFS && 64BIT && !(S390 || ALPHA)
+       depends on TMPFS && 64BIT
        default n
        help
          tmpfs has historically used only inode numbers as wide as an unsigned
index 3aedc484e4401e7234cec63726c14c84c4afa59f..88a7958170ee0f7612e94f576f7da965e3c235ba 100644 (file)
@@ -207,7 +207,7 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
                                                from_kuid(&init_user_ns, cfile->uid),
                                                cfile->dentry);
 #ifdef CONFIG_CIFS_DEBUG2
-                                       seq_printf(m, " 0x%llx\n", cfile->fid.mid);
+                                       seq_printf(m, " %llu\n", cfile->fid.mid);
 #else
                                        seq_printf(m, "\n");
 #endif /* CIFS_DEBUG2 */
index d43e935d2df4365371200276509d4c72bab13289..099ad9f3660bb28db1b6a9aea9538282b41c6455 100644 (file)
@@ -290,7 +290,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
                rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
 
        free_xid(xid);
-       return 0;
+       return rc;
 }
 
 static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
index 3de3c5908a72d7f88b59ef566b30e4c8ffa9617c..31fc8695abd6d76c76b15fb67c772677946049e5 100644 (file)
@@ -257,7 +257,7 @@ struct smb_version_operations {
        /* verify the message */
        int (*check_message)(char *, unsigned int, struct TCP_Server_Info *);
        bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
-       int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *);
+       int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *);
        void (*downgrade_oplock)(struct TCP_Server_Info *server,
                                 struct cifsInodeInfo *cinode, __u32 oplock,
                                 unsigned int epoch, bool *purge_cache);
@@ -1705,16 +1705,17 @@ static inline bool is_retryable_error(int error)
 #define   CIFS_NO_RSP_BUF   0x040    /* no response buffer required */
 
 /* Type of request operation */
-#define   CIFS_ECHO_OP      0x080    /* echo request */
-#define   CIFS_OBREAK_OP   0x0100    /* oplock break request */
-#define   CIFS_NEG_OP      0x0200    /* negotiate request */
+#define   CIFS_ECHO_OP            0x080  /* echo request */
+#define   CIFS_OBREAK_OP          0x0100 /* oplock break request */
+#define   CIFS_NEG_OP             0x0200 /* negotiate request */
+#define   CIFS_CP_CREATE_CLOSE_OP 0x0400 /* compound create+close request */
 /* Lower bitmask values are reserved by others below. */
-#define   CIFS_SESS_OP     0x2000    /* session setup request */
-#define   CIFS_OP_MASK     0x2380    /* mask request type */
+#define   CIFS_SESS_OP            0x2000 /* session setup request */
+#define   CIFS_OP_MASK            0x2780 /* mask request type */
 
-#define   CIFS_HAS_CREDITS 0x0400    /* already has credits */
-#define   CIFS_TRANSFORM_REQ 0x0800    /* transform request before sending */
-#define   CIFS_NO_SRV_RSP    0x1000    /* there is no server response */
+#define   CIFS_HAS_CREDITS        0x0400 /* already has credits */
+#define   CIFS_TRANSFORM_REQ      0x0800 /* transform request before sending */
+#define   CIFS_NO_SRV_RSP         0x1000 /* there is no server response */
 
 /* Security Flags: indicate type of session setup needed */
 #define   CIFSSEC_MAY_SIGN     0x00001
index 112692300fb60a15a374c8729050cd87d6330146..eec8a2052da226bdda1cd4e61a68b367d0201d7a 100644 (file)
@@ -741,7 +741,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
                spin_lock(&GlobalMid_Lock);
                list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
                        mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-                       cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid);
+                       cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid);
                        kref_get(&mid_entry->refcount);
                        mid_entry->mid_state = MID_SHUTDOWN;
                        list_move(&mid_entry->qhead, &dispose_list);
@@ -752,7 +752,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
                /* now walk dispose list and issue callbacks */
                list_for_each_safe(tmp, tmp2, &dispose_list) {
                        mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-                       cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid);
+                       cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid);
                        list_del_init(&mid_entry->qhead);
                        mid_entry->callback(mid_entry);
                        cifs_mid_q_entry_release(mid_entry);
@@ -1429,6 +1429,11 @@ smbd_connected:
        tcp_ses->min_offload = ctx->min_offload;
        tcp_ses->tcpStatus = CifsNeedNegotiate;
 
+       if ((ctx->max_credits < 20) || (ctx->max_credits > 60000))
+               tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
+       else
+               tcp_ses->max_credits = ctx->max_credits;
+
        tcp_ses->nr_targets = 1;
        tcp_ses->ignore_signature = ctx->ignore_signature;
        /* thread spawned, put it on the list */
@@ -2832,11 +2837,6 @@ static int mount_get_conns(struct smb3_fs_context *ctx, struct cifs_sb_info *cif
 
        *nserver = server;
 
-       if ((ctx->max_credits < 20) || (ctx->max_credits > 60000))
-               server->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
-       else
-               server->max_credits = ctx->max_credits;
-
        /* get a reference to a SMB session */
        ses = cifs_get_smb_ses(server, ctx);
        if (IS_ERR(ses)) {
index 183a3a868d7b90946a9cc9f9b1a2fcac05ae3d45..63d517b9f2ffefddcc5cb01cf07f1c2b2df68826 100644 (file)
@@ -230,6 +230,7 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
        ctx.noautotune = ses->server->noautotune;
        ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
        ctx.echo_interval = ses->server->echo_interval / HZ;
+       ctx.max_credits = ses->server->max_credits;
 
        /*
         * This will be used for encoding/decoding user/domain/pw
index 1f900b81c34ae62516c26fd48e6e2d17629f3be3..a718dc77e604edfe0c91933a435c18a7cd816316 100644 (file)
@@ -358,6 +358,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
        if (cfile)
                goto after_close;
        /* Close */
+       flags |= CIFS_CP_CREATE_CLOSE_OP;
        rqst[num_rqst].rq_iov = &vars->close_iov[0];
        rqst[num_rqst].rq_nvec = 1;
        rc = SMB2_close_init(tcon, server,
index 60d4bd1eae2b3aaff52ddb9a783ad97e22284914..b50164e2c88dc65df34cfca7e5b2411fdf3d818e 100644 (file)
@@ -767,7 +767,7 @@ smb2_cancelled_close_fid(struct work_struct *work)
        int rc;
 
        if (cancelled->mid)
-               cifs_tcon_dbg(VFS, "Close unmatched open for MID:%llx\n",
+               cifs_tcon_dbg(VFS, "Close unmatched open for MID:%llu\n",
                              cancelled->mid);
        else
                cifs_tcon_dbg(VFS, "Close interrupted close\n");
@@ -844,14 +844,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
 }
 
 int
-smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
+smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server)
 {
-       struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer;
-       struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
+       struct smb2_sync_hdr *sync_hdr = mid->resp_buf;
+       struct smb2_create_rsp *rsp = mid->resp_buf;
        struct cifs_tcon *tcon;
        int rc;
 
-       if (sync_hdr->Command != SMB2_CREATE ||
+       if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE ||
            sync_hdr->Status != STATUS_SUCCESS)
                return 0;
 
index f5087295424c65dfa1c9444f02890f8fcec8fc41..9bae7e8deb09e07bc28332f8c41767a239858ccd 100644 (file)
@@ -1195,7 +1195,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
        struct TCP_Server_Info *server = cifs_pick_channel(ses);
        __le16 *utf16_path = NULL;
        int ea_name_len = strlen(ea_name);
-       int flags = 0;
+       int flags = CIFS_CP_CREATE_CLOSE_OP;
        int len;
        struct smb_rqst rqst[3];
        int resp_buftype[3];
@@ -1573,7 +1573,7 @@ smb2_ioctl_query_info(const unsigned int xid,
        struct smb_query_info qi;
        struct smb_query_info __user *pqi;
        int rc = 0;
-       int flags = 0;
+       int flags = CIFS_CP_CREATE_CLOSE_OP;
        struct smb2_query_info_rsp *qi_rsp = NULL;
        struct smb2_ioctl_rsp *io_rsp = NULL;
        void *buffer = NULL;
@@ -2577,7 +2577,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 {
        struct cifs_ses *ses = tcon->ses;
        struct TCP_Server_Info *server = cifs_pick_channel(ses);
-       int flags = 0;
+       int flags = CIFS_CP_CREATE_CLOSE_OP;
        struct smb_rqst rqst[3];
        int resp_buftype[3];
        struct kvec rsp_iov[3];
@@ -2975,7 +2975,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        unsigned int sub_offset;
        unsigned int print_len;
        unsigned int print_offset;
-       int flags = 0;
+       int flags = CIFS_CP_CREATE_CLOSE_OP;
        struct smb_rqst rqst[3];
        int resp_buftype[3];
        struct kvec rsp_iov[3];
@@ -3157,7 +3157,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
        struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
-       int flags = 0;
+       int flags = CIFS_CP_CREATE_CLOSE_OP;
        struct smb_rqst rqst[3];
        int resp_buftype[3];
        struct kvec rsp_iov[3];
index 4bbb6126b14d6e9a3703129a5616dff47611e11f..2199a9bfae8f79b60b35f53e9ea3dc696beb4665 100644 (file)
@@ -4041,8 +4041,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
        if (rdata->credits.value > 0) {
                shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
                                                SMB2_MAX_BUFFER_SIZE));
-               shdr->CreditRequest =
-                       cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
+               shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
 
                rc = adjust_credits(server, &rdata->credits, rdata->bytes);
                if (rc)
@@ -4348,8 +4347,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
        if (wdata->credits.value > 0) {
                shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
                                                    SMB2_MAX_BUFFER_SIZE));
-               shdr->CreditRequest =
-                       cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
+               shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
 
                rc = adjust_credits(server, &wdata->credits, wdata->bytes);
                if (rc)
index 9565e27681a541447c74ee0d5a2f745277f935f5..a2eb34a8d9c910b2aa616ba3cc6c5d145cb54566 100644 (file)
@@ -246,8 +246,7 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
 extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon,
                                       __u64 persistent_fid,
                                       __u64 volatile_fid);
-extern int smb2_handle_cancelled_mid(char *buffer,
-                                       struct TCP_Server_Info *server);
+extern int smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server);
 void smb2_cancelled_close_fid(struct work_struct *work);
 extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
                         u64 persistent_file_id, u64 volatile_file_id,
index e90a1d1380b0697f2cf1aea53c50265ca068c42e..007d99437c77154aa7709fba5a76f93991a1d792 100644 (file)
@@ -101,7 +101,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount)
        if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) &&
            midEntry->mid_state == MID_RESPONSE_RECEIVED &&
            server->ops->handle_cancelled_mid)
-               server->ops->handle_cancelled_mid(midEntry->resp_buf, server);
+               server->ops->handle_cancelled_mid(midEntry, server);
 
        midEntry->mid_state = MID_FREE;
        atomic_dec(&midCount);
@@ -1207,7 +1207,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
        }
        if (rc != 0) {
                for (; i < num_rqst; i++) {
-                       cifs_server_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n",
+                       cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",
                                 midQ[i]->mid, le16_to_cpu(midQ[i]->command));
                        send_cancel(server, &rqst[i], midQ[i]);
                        spin_lock(&GlobalMid_Lock);
index 1f0270229d7b7e099765e1658bab5a0c6bc596a1..da8351d1e455209150954bf6cc002e5643d97870 100644 (file)
@@ -378,7 +378,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
 
        attr = to_attr(dentry);
        if (!attr)
-               goto out_put_item;
+               goto out_free_buffer;
 
        if (type & CONFIGFS_ITEM_BIN_ATTR) {
                buffer->bin_attr = to_bin_attr(dentry);
@@ -391,7 +391,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
        /* Grab the module reference for this attribute if we have one */
        error = -ENODEV;
        if (!try_module_get(buffer->owner))
-               goto out_put_item;
+               goto out_free_buffer;
 
        error = -EACCES;
        if (!buffer->item->ci_type)
@@ -435,8 +435,6 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
 
 out_put_module:
        module_put(buffer->owner);
-out_put_item:
-       config_item_put(buffer->item);
 out_free_buffer:
        up_read(&frag->frag_sem);
        kfree(buffer);
index 16937ebb2a3e3463cdf176f90c877982abf93f5e..6410281546f924942dd6a3f734a357e8eadd300a 100644 (file)
@@ -998,12 +998,16 @@ static void trans_drain(struct gfs2_trans *tr)
        while (!list_empty(head)) {
                bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
                list_del_init(&bd->bd_list);
+               if (!list_empty(&bd->bd_ail_st_list))
+                       gfs2_remove_from_ail(bd);
                kmem_cache_free(gfs2_bufdata_cachep, bd);
        }
        head = &tr->tr_databuf;
        while (!list_empty(head)) {
                bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
                list_del_init(&bd->bd_list);
+               if (!list_empty(&bd->bd_ail_st_list))
+                       gfs2_remove_from_ail(bd);
                kmem_cache_free(gfs2_bufdata_cachep, bd);
        }
 }
@@ -1032,7 +1036,7 @@ repeat:
         * Do this check while holding the log_flush_lock to prevent new
         * buffers from being added to the ail via gfs2_pin()
         */
-       if (gfs2_withdrawn(sdp))
+       if (gfs2_withdrawn(sdp) || !test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
                goto out;
 
        /* Log might have been flushed while we waited for the flush lock */
index 74c7d01723b95667a5e42fb659d37e7de944d479..aa4136055a83c220c02cdab111f779141dc93d7b 100644 (file)
@@ -1539,9 +1539,7 @@ static int gfs2_reconfigure(struct fs_context *fc)
                        return -EINVAL;
 
                if (fc->sb_flags & SB_RDONLY) {
-                       error = gfs2_make_fs_ro(sdp);
-                       if (error)
-                               errorfc(fc, "unable to remount read-only");
+                       gfs2_make_fs_ro(sdp);
                } else {
                        error = gfs2_make_fs_rw(sdp);
                        if (error)
index 861ed5fe02a59dc786d781265183bc3ec9cf2051..97076d3f562f90dfec3a40f06abb5fdb165a2fee 100644 (file)
@@ -587,9 +587,8 @@ out:
  * Returns: errno
  */
 
-int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
+void gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 {
-       int error = 0;
        int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
 
        gfs2_flush_delete_work(sdp);
@@ -624,8 +623,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 
        if (!log_write_allowed)
                sdp->sd_vfs->s_flags |= SB_RDONLY;
-
-       return error;
 }
 
 /**
@@ -637,7 +634,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 static void gfs2_put_super(struct super_block *sb)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
-       int error;
        struct gfs2_jdesc *jd;
 
        /* No more recovery requests */
@@ -658,9 +654,7 @@ restart:
        spin_unlock(&sdp->sd_jindex_spin);
 
        if (!sb_rdonly(sb)) {
-               error = gfs2_make_fs_ro(sdp);
-               if (error)
-                       gfs2_io_error(sdp);
+               gfs2_make_fs_ro(sdp);
        }
        WARN_ON(gfs2_withdrawing(sdp));
 
index 08e502dec7ecb01ca2587f475e58ab077c483ee1..ec4affb33ed53f84c7fc622cd669da3bb80b2d66 100644 (file)
@@ -34,7 +34,7 @@ extern int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename,
                                     struct gfs2_inode **ipp);
 
 extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp);
-extern int gfs2_make_fs_ro(struct gfs2_sbd *sdp);
+extern void gfs2_make_fs_ro(struct gfs2_sbd *sdp);
 extern void gfs2_online_uevent(struct gfs2_sbd *sdp);
 extern int gfs2_statfs_init(struct gfs2_sbd *sdp);
 extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
index ab96cf0bf26bea1c9b10136e54a207baafaaa0d3..63fec11ef2ce3fe8c37ff0f76a923444ee0df7d6 100644 (file)
@@ -169,6 +169,8 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl,
        bd->bd_bh = bh;
        bd->bd_gl = gl;
        INIT_LIST_HEAD(&bd->bd_list);
+       INIT_LIST_HEAD(&bd->bd_ail_st_list);
+       INIT_LIST_HEAD(&bd->bd_ail_gl_list);
        bh->b_private = bd;
        return bd;
 }
index 8d3c670c990fd99580a1c39eb13929eed2de1375..4f034b87b427609103357b4694d831a08b18e3bc 100644 (file)
@@ -119,17 +119,22 @@ void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh)
 static void signal_our_withdraw(struct gfs2_sbd *sdp)
 {
        struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl;
-       struct inode *inode = sdp->sd_jdesc->jd_inode;
-       struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_glock *i_gl = ip->i_gl;
-       u64 no_formal_ino = ip->i_no_formal_ino;
+       struct inode *inode;
+       struct gfs2_inode *ip;
+       struct gfs2_glock *i_gl;
+       u64 no_formal_ino;
        int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
        int ret = 0;
        int tries;
 
-       if (test_bit(SDF_NORECOVERY, &sdp->sd_flags))
+       if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc)
                return;
 
+       inode = sdp->sd_jdesc->jd_inode;
+       ip = GFS2_I(inode);
+       i_gl = ip->i_gl;
+       no_formal_ino = ip->i_no_formal_ino;
+
        /* Prevent any glock dq until withdraw recovery is complete */
        set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
        /*
@@ -156,7 +161,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
                                ret = 0;
                }
                if (!ret)
-                       ret = gfs2_make_fs_ro(sdp);
+                       gfs2_make_fs_ro(sdp);
                gfs2_freeze_unlock(&freeze_gh);
        }
 
index 26f74e092bd98123b0bd45175491d81b80bb35c5..988f1aa9b02aeaac191f6743ac88b5b6f2877ac7 100644 (file)
@@ -12,7 +12,7 @@
 
 #define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED)
 #define IS_MNT_SLAVE(m) ((m)->mnt_master)
-#define IS_MNT_NEW(m)  (!(m)->mnt_ns)
+#define IS_MNT_NEW(m)  (!(m)->mnt_ns || is_anon_ns((m)->mnt_ns))
 #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED)
 #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE)
 #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED)
index 9f432411e9883296c880f345323a344e26ea654d..fcdaab72391672f077de07d3ad49d1f3dc7d6eeb 100644 (file)
@@ -1079,19 +1079,25 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
 #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
 bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
                                struct acpi_resource_gpio **agpio);
-int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index);
+int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
 #else
 static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
                                              struct acpi_resource_gpio **agpio)
 {
        return false;
 }
-static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
+static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
+                                          const char *name, int index)
 {
        return -ENXIO;
 }
 #endif
 
+static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
+{
+       return acpi_dev_gpio_irq_get_by(adev, NULL, index);
+}
+
 /* Device properties */
 
 #ifdef CONFIG_ACPI
index 60cd25c0461b873c959c49523b5563e2685d3205..9b02961d65ee6666bea094095d5efe9e35ba735f 100644 (file)
@@ -151,7 +151,7 @@ struct atm_dev {
        const char      *type;          /* device type name */
        int             number;         /* device index */
        void            *dev_data;      /* per-device data */
-       void            *phy_data;      /* private PHY date */
+       void            *phy_data;      /* private PHY data */
        unsigned long   flags;          /* device flags (ATM_DF_*) */
        struct list_head local;         /* local ATM addresses */
        struct list_head lecs;          /* LECS ATM addresses learned via ILMI */
index 685f34cfba20741d372d340fe7df1084767b2850..d438eb058069b1c420473cb2cedee5d0b78eed4a 100644 (file)
@@ -65,8 +65,12 @@ static inline void can_skb_reserve(struct sk_buff *skb)
 
 static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
 {
-       if (sk) {
-               sock_hold(sk);
+       /* If the socket has already been closed by user space, the
+        * refcount may already be 0 (and the socket will be freed
+        * after the last TX skb has been freed). So only increase
+        * socket refcount if the refcount is > 0.
+        */
+       if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) {
                skb->destructor = sock_efree;
                skb->sk = sk;
        }
index ef49307611d219881c8ce9da694807a3a2b4d227..c73b25bc92134bee2fb9b19822ef42ac293ae4cd 100644 (file)
@@ -674,6 +674,8 @@ struct acpi_gpio_mapping {
  * get GpioIo type explicitly, this quirk may be used.
  */
 #define ACPI_GPIO_QUIRK_ONLY_GPIOIO            BIT(1)
+/* Use given pin as an absolute GPIO number in the system */
+#define ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER                BIT(2)
 
        unsigned int quirks;
 };
index f06fbee8638e84d42a4b8cb98bd2f2dcc33a0374..5b67ea89d5f26d72257ba03a1d669999cb570f92 100644 (file)
@@ -3959,8 +3959,6 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
 int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
 u32 dev_xdp_prog_id(struct net_device *dev, enum bpf_xdp_mode mode);
 
-int xdp_umem_query(struct net_device *dev, u16 queue_id);
-
 int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 int dev_forward_skb_nomtu(struct net_device *dev, struct sk_buff *skb);
index cdfc4e9f253e4e7004b08b5f275387dedb408d7d..5e772392a379560d2cc7dffc02227fcc0c604559 100644 (file)
@@ -904,6 +904,10 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma,
 #define pgprot_device pgprot_noncached
 #endif
 
+#ifndef pgprot_mhp
+#define pgprot_mhp(prot)       (prot)
+#endif
+
 #ifdef CONFIG_MMU
 #ifndef pgprot_modify
 #define pgprot_modify pgprot_modify
index ccdb5320a2406a400a3c111c4a3cd5557c6b5fce..71902f41c91999d21cc037e9c9d1731a71844f0f 100644 (file)
@@ -147,6 +147,9 @@ enum {
 #define BUCK6_FPWM                     0x04
 #define BUCK6_ENMODE_MASK              0x03
 
+/* PCA9450_REG_BUCK123_PRESET_EN bit */
+#define BUCK123_PRESET_EN              0x80
+
 /* PCA9450_BUCK1OUT_DVS0 bits */
 #define BUCK1OUT_DVS0_MASK             0x7F
 #define BUCK1OUT_DVS0_DEFAULT          0x14
index 13770cfe33ad8f7a5d084c1774ac170f6c7a8229..6673e4d4ac2e1b1348f6e94ad070f63921cc4cff 100644 (file)
@@ -23,7 +23,7 @@ struct ts_config;
 struct ts_state
 {
        unsigned int            offset;
-       char                    cb[40];
+       char                    cb[48];
 };
 
 /**
index 7d72c4e0713c1068d11a01256de7a37bc44b809b..d6a41841b93e4f92647e938d0bff02712b795f12 100644 (file)
@@ -746,6 +746,8 @@ extern int usb_lock_device_for_reset(struct usb_device *udev,
 extern int usb_reset_device(struct usb_device *dev);
 extern void usb_queue_reset_device(struct usb_interface *dev);
 
+extern struct device *usb_intf_get_dma_device(struct usb_interface *intf);
+
 #ifdef CONFIG_ACPI
 extern int usb_acpi_set_power_state(struct usb_device *hdev, int index,
        bool enable);
index e8a924eeea3d01c86c40766445c5661c395bce6c..6b5fcfa1e5553576b0e853ae31a2df655c04204b 100644 (file)
@@ -79,8 +79,13 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
                if (gso_type && skb->network_header) {
                        struct flow_keys_basic keys;
 
-                       if (!skb->protocol)
+                       if (!skb->protocol) {
+                               __be16 protocol = dev_parse_header_protocol(skb);
+
                                virtio_net_hdr_set_proto(skb, hdr);
+                               if (protocol && protocol != skb->protocol)
+                                       return -EINVAL;
+                       }
 retry:
                        if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
                                                              NULL, 0, 0, 0,
index 999b750bc6b88163a85e64f323ebfe6c0e33d9f1..30f138ebab6f0fdbc067708c9a12274ee846da79 100644 (file)
@@ -175,6 +175,13 @@ struct rc_map_list {
        struct rc_map map;
 };
 
+#ifdef CONFIG_MEDIA_CEC_RC
+/*
+ * rc_map_list from rc-cec.c
+ */
+extern struct rc_map_list cec_map;
+#endif
+
 /* Routines from rc-map.c */
 
 /**
index 4c24daa43bacc601cd3fc5ca8eeda3614bb45344..79c893310492b33689352b9dff5f53a42dd9d72b 100644 (file)
@@ -3850,7 +3850,6 @@ union bpf_attr {
  *
  * long bpf_check_mtu(void *ctx, u32 ifindex, u32 *mtu_len, s32 len_diff, u64 flags)
  *     Description
-
  *             Check ctx packet size against exceeding MTU of net device (based
  *             on *ifindex*).  This helper will likely be used in combination
  *             with helpers that adjust/change the packet size.
index 30c80d5ba4bfcba26a2bdd14045cfe0b936fdbfb..bab8c9708611139357eb888c9ad367935f380844 100644 (file)
@@ -145,6 +145,7 @@ enum {
        L2TP_ATTR_RX_ERRORS,            /* u64 */
        L2TP_ATTR_STATS_PAD,
        L2TP_ATTR_RX_COOKIE_DISCARDS,   /* u64 */
+       L2TP_ATTR_RX_INVALID,           /* u64 */
        __L2TP_ATTR_STATS_MAX,
 };
 
index a13137afc42994b75b9730e843d3e3ec59967fbc..70af02092d16efb30d3dac74a1fd3f2b35d618e5 100644 (file)
@@ -5,7 +5,7 @@
 #define NFCT_HELPER_STATUS_DISABLED    0
 #define NFCT_HELPER_STATUS_ENABLED     1
 
-enum nfnl_acct_msg_types {
+enum nfnl_cthelper_msg_types {
        NFNL_MSG_CTHELPER_NEW,
        NFNL_MSG_CTHELPER_GET,
        NFNL_MSG_CTHELPER_DEL,
index 0b1182a3cf4128b4502b7e3db59adeb8522daea5..cb854df031ce0715b9158fa71c7f02ad2c2dc732 100644 (file)
 #include <linux/page-flags.h>
 #include <linux/kernel.h>
 
+/*
+ * Technically there's no reliably invalid grant reference or grant handle,
+ * so pick the value that is the most unlikely one to be observed valid.
+ */
+#define INVALID_GRANT_REF          ((grant_ref_t)-1)
+#define INVALID_GRANT_HANDLE       ((grant_handle_t)-1)
+
 #define GNTTAB_RESERVED_XENSTORE 1
 
 /* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
index 0b1386073d49bf48d40909954d6043e15a27638d..b94074c827721b8ebdee18a5199ba3657cfcccfd 100644 (file)
@@ -51,7 +51,6 @@
 
 #define XENBUS_MAX_RING_GRANT_ORDER 4
 #define XENBUS_MAX_RING_GRANTS      (1U << XENBUS_MAX_RING_GRANT_ORDER)
-#define INVALID_GRANT_HANDLE       (~0U)
 
 /* Register callback to watch this node. */
 struct xenbus_watch
index 2efeb5f4b3433a35570544600e72e08f4855db3e..b1a76fe046cbafed9f36ae3d76950ce05fd9200a 100644 (file)
@@ -4321,8 +4321,6 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf,
                 * is not supported yet.
                 * BPF_PROG_TYPE_RAW_TRACEPOINT is fine.
                 */
-               if (log->level & BPF_LOG_LEVEL)
-                       bpf_log(log, "arg#%d type is not a struct\n", arg);
                return NULL;
        }
        tname = btf_name_by_offset(btf, t->name_off);
index 0ae015ad1e05672c4baf60e81f68fd39e043b1f5..3a283bf97f2f674927d17da17efec2f5906c6580 100644 (file)
@@ -1118,6 +1118,8 @@ static void bpf_prog_clone_free(struct bpf_prog *fp)
         * clone is guaranteed to not be locked.
         */
        fp->aux = NULL;
+       fp->stats = NULL;
+       fp->active = NULL;
        __bpf_prog_free(fp);
 }
 
@@ -2342,6 +2344,10 @@ bool __weak bpf_helper_changes_pkt_data(void *func)
 /* Return TRUE if the JIT backend wants verifier to enable sub-register usage
  * analysis code and wants explicit zero extension inserted by verifier.
  * Otherwise, return FALSE.
+ *
+ * The verifier inserts an explicit zero extension after BPF_CMPXCHGs even if
+ * you don't override this. JITs that don't want these extra insns can detect
+ * them using insn_is_zext.
  */
 bool __weak bpf_jit_needs_zext(void)
 {
index 1dda9d81f12c5e8ef3bbc7327ebe51f305b6e67a..c56e3fcb5f1a07d2e0df00d82f01c4e6a1b12ff9 100644 (file)
@@ -504,6 +504,13 @@ static bool is_ptr_cast_function(enum bpf_func_id func_id)
                func_id == BPF_FUNC_skc_to_tcp_request_sock;
 }
 
+static bool is_cmpxchg_insn(const struct bpf_insn *insn)
+{
+       return BPF_CLASS(insn->code) == BPF_STX &&
+              BPF_MODE(insn->code) == BPF_ATOMIC &&
+              insn->imm == BPF_CMPXCHG;
+}
+
 /* string representation of 'enum bpf_reg_type' */
 static const char * const reg_type_str[] = {
        [NOT_INIT]              = "?",
@@ -1120,7 +1127,7 @@ static void mark_ptr_not_null_reg(struct bpf_reg_state *reg)
                reg->type = PTR_TO_RDWR_BUF;
                break;
        default:
-               WARN_ON("unknown nullable register type");
+               WARN_ONCE(1, "unknown nullable register type");
        }
 }
 
@@ -1703,7 +1710,11 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
        }
 
        if (class == BPF_STX) {
-               if (reg->type != SCALAR_VALUE)
+               /* BPF_STX (including atomic variants) has multiple source
+                * operands, one of which is a ptr. Check whether the caller is
+                * asking about it.
+                */
+               if (t == SRC_OP && reg->type != SCALAR_VALUE)
                        return true;
                return BPF_SIZE(code) == BPF_DW;
        }
@@ -1735,22 +1746,38 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
        return true;
 }
 
-/* Return TRUE if INSN doesn't have explicit value define. */
-static bool insn_no_def(struct bpf_insn *insn)
+/* Return the regno defined by the insn, or -1. */
+static int insn_def_regno(const struct bpf_insn *insn)
 {
-       u8 class = BPF_CLASS(insn->code);
-
-       return (class == BPF_JMP || class == BPF_JMP32 ||
-               class == BPF_STX || class == BPF_ST);
+       switch (BPF_CLASS(insn->code)) {
+       case BPF_JMP:
+       case BPF_JMP32:
+       case BPF_ST:
+               return -1;
+       case BPF_STX:
+               if (BPF_MODE(insn->code) == BPF_ATOMIC &&
+                   (insn->imm & BPF_FETCH)) {
+                       if (insn->imm == BPF_CMPXCHG)
+                               return BPF_REG_0;
+                       else
+                               return insn->src_reg;
+               } else {
+                       return -1;
+               }
+       default:
+               return insn->dst_reg;
+       }
 }
 
 /* Return TRUE if INSN has defined any 32-bit value explicitly. */
 static bool insn_has_def32(struct bpf_verifier_env *env, struct bpf_insn *insn)
 {
-       if (insn_no_def(insn))
+       int dst_reg = insn_def_regno(insn);
+
+       if (dst_reg == -1)
                return false;
 
-       return !is_reg64(env, insn, insn->dst_reg, NULL, DST_OP);
+       return !is_reg64(env, insn, dst_reg, NULL, DST_OP);
 }
 
 static void mark_insn_zext(struct bpf_verifier_env *env,
@@ -11006,9 +11033,10 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
        for (i = 0; i < len; i++) {
                int adj_idx = i + delta;
                struct bpf_insn insn;
-               u8 load_reg;
+               int load_reg;
 
                insn = insns[adj_idx];
+               load_reg = insn_def_regno(&insn);
                if (!aux[adj_idx].zext_dst) {
                        u8 code, class;
                        u32 imm_rnd;
@@ -11018,14 +11046,14 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
 
                        code = insn.code;
                        class = BPF_CLASS(code);
-                       if (insn_no_def(&insn))
+                       if (load_reg == -1)
                                continue;
 
                        /* NOTE: arg "reg" (the fourth one) is only used for
-                        *       BPF_STX which has been ruled out in above
-                        *       check, it is safe to pass NULL here.
+                        *       BPF_STX + SRC_OP, so it is safe to pass NULL
+                        *       here.
                         */
-                       if (is_reg64(env, &insn, insn.dst_reg, NULL, DST_OP)) {
+                       if (is_reg64(env, &insn, load_reg, NULL, DST_OP)) {
                                if (class == BPF_LD &&
                                    BPF_MODE(code) == BPF_IMM)
                                        i++;
@@ -11040,31 +11068,28 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
                        imm_rnd = get_random_int();
                        rnd_hi32_patch[0] = insn;
                        rnd_hi32_patch[1].imm = imm_rnd;
-                       rnd_hi32_patch[3].dst_reg = insn.dst_reg;
+                       rnd_hi32_patch[3].dst_reg = load_reg;
                        patch = rnd_hi32_patch;
                        patch_len = 4;
                        goto apply_patch_buffer;
                }
 
-               if (!bpf_jit_needs_zext())
+               /* Add in an zero-extend instruction if a) the JIT has requested
+                * it or b) it's a CMPXCHG.
+                *
+                * The latter is because: BPF_CMPXCHG always loads a value into
+                * R0, therefore always zero-extends. However some archs'
+                * equivalent instruction only does this load when the
+                * comparison is successful. This detail of CMPXCHG is
+                * orthogonal to the general zero-extension behaviour of the
+                * CPU, so it's treated independently of bpf_jit_needs_zext.
+                */
+               if (!bpf_jit_needs_zext() && !is_cmpxchg_insn(&insn))
                        continue;
 
-               /* zext_dst means that we want to zero-extend whatever register
-                * the insn defines, which is dst_reg most of the time, with
-                * the notable exception of BPF_STX + BPF_ATOMIC + BPF_FETCH.
-                */
-               if (BPF_CLASS(insn.code) == BPF_STX &&
-                   BPF_MODE(insn.code) == BPF_ATOMIC) {
-                       /* BPF_STX + BPF_ATOMIC insns without BPF_FETCH do not
-                        * define any registers, therefore zext_dst cannot be
-                        * set.
-                        */
-                       if (WARN_ON(!(insn.imm & BPF_FETCH)))
-                               return -EINVAL;
-                       load_reg = insn.imm == BPF_CMPXCHG ? BPF_REG_0
-                                                          : insn.src_reg;
-               } else {
-                       load_reg = insn.dst_reg;
+               if (WARN_ON(load_reg == -1)) {
+                       verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n");
+                       return -EFAULT;
                }
 
                zext_patch[0] = insn;
index c3e59caf7ffa1004c2bbd1d3d04fefc17eece90e..9c9f40bd2b3d9b04e5ecc76825cdc1004f2dbc2a 100644 (file)
@@ -21,7 +21,6 @@ static inline unsigned long ex_to_insn(const struct exception_table_entry *x)
 }
 #endif
 
-#ifndef ARCH_HAS_SORT_EXTABLE
 #ifndef ARCH_HAS_RELATIVE_EXTABLE
 #define swap_ex                NULL
 #else
@@ -88,9 +87,6 @@ void trim_init_extable(struct module *m)
                m->num_exentries--;
 }
 #endif /* CONFIG_MODULES */
-#endif /* !ARCH_HAS_SORT_EXTABLE */
-
-#ifndef ARCH_HAS_SEARCH_EXTABLE
 
 static int cmp_ex_search(const void *key, const void *elt)
 {
@@ -120,4 +116,3 @@ search_extable(const struct exception_table_entry *base,
        return bsearch(&value, base, num,
                       sizeof(struct exception_table_entry), cmp_ex_search);
 }
-#endif
index 5ba51a8bdaeb208c51eea97f95738c16d3b7e3bf..0cdbbfbc57572e4e12f71b660af93e29bb9022fe 100644 (file)
@@ -1072,7 +1072,7 @@ static int online_memory_block(struct memory_block *mem, void *arg)
  */
 int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags)
 {
-       struct mhp_params params = { .pgprot = PAGE_KERNEL };
+       struct mhp_params params = { .pgprot = pgprot_mhp(PAGE_KERNEL) };
        u64 start, size;
        bool new_node = false;
        int ret;
index e26c274b4657f2a164643ffca3c7607f496b13d5..3021ce9bf1b3d704f6ade2300827a3178a2ae205 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1993,7 +1993,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
 
                t = acquire_slab(s, n, page, object == NULL, &objects);
                if (!t)
-                       continue; /* cmpxchg raced */
+                       break;
 
                available += objects;
                if (!object) {
index 4f62f299da0cfdbd99fa9a08b60c4aec891eccdf..0a9019da18f3956106d024ce1920d1ea27117500 100644 (file)
@@ -1623,10 +1623,6 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
        }
 
        p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
-       if (!count) {
-               p9_tag_remove(clnt, req);
-               return 0;
-       }
 
        if (non_zc) {
                int n = copy_to_iter(dataptr, count, to);
index 0edc0b2baaa433938883bee99ae90c9fca9663bd..1bdcb33fb561994472a7dde6b9a3c992a300bb87 100644 (file)
@@ -2147,7 +2147,7 @@ out:
 out_err:
        cb->args[1] = idx;
        cb->args[0] = h;
-       cb->seq = net->dev_base_seq;
+       cb->seq = tgt_net->dev_base_seq;
        nl_dump_check_consistent(cb, nlmsg_hdr(skb));
        if (netnsid >= 0)
                put_net(tgt_net);
index 545a472273a50387b0701d372d5f29db16385b0e..c421c8f809256f7b13a8b5a1331108449353ee2d 100644 (file)
@@ -3659,6 +3659,8 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
        struct ts_state state;
        unsigned int ret;
 
+       BUILD_BUG_ON(sizeof(struct skb_seq_state) > sizeof(state.cb));
+
        config->get_next_block = skb_ts_get_next_block;
        config->finish = skb_ts_finish;
 
index 3589224c8da9699fd474cc820fd9db8355be339a..58b8fc82cd3c4b833f9a3badf4e22b256f909fe1 100644 (file)
@@ -118,6 +118,8 @@ config NET_DSA_TAG_OCELOT
 
 config NET_DSA_TAG_OCELOT_8021Q
        tristate "Tag driver for Ocelot family of switches, using VLAN"
+       depends on MSCC_OCELOT_SWITCH_LIB || \
+                 (MSCC_OCELOT_SWITCH_LIB=n && COMPILE_TEST)
        select NET_DSA_TAG_8021Q
        help
          Say Y or M if you want to enable support for tagging frames with a
index 2eeaa42f2e083aa1287cd34ba2fbd582e0cb6d88..9d4b0e9b1aa1e3e720ee51670b7558d7ab79122c 100644 (file)
@@ -230,8 +230,8 @@ int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
 void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr);
 extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
 
-static inline bool dsa_port_offloads_netdev(struct dsa_port *dp,
-                                           struct net_device *dev)
+static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
+                                                struct net_device *dev)
 {
        /* Switchdev offloading can be configured on: */
 
@@ -241,12 +241,6 @@ static inline bool dsa_port_offloads_netdev(struct dsa_port *dp,
                 */
                return true;
 
-       if (dp->bridge_dev == dev)
-               /* DSA ports connected to a bridge, and event was emitted
-                * for the bridge.
-                */
-               return true;
-
        if (dp->lag_dev == dev)
                /* DSA ports connected to a bridge via a LAG */
                return true;
@@ -254,14 +248,23 @@ static inline bool dsa_port_offloads_netdev(struct dsa_port *dp,
        return false;
 }
 
+static inline bool dsa_port_offloads_bridge(struct dsa_port *dp,
+                                           struct net_device *bridge_dev)
+{
+       /* DSA ports connected to a bridge, and event was emitted
+        * for the bridge.
+        */
+       return dp->bridge_dev == bridge_dev;
+}
+
 /* Returns true if any port of this tree offloads the given net_device */
-static inline bool dsa_tree_offloads_netdev(struct dsa_switch_tree *dst,
-                                           struct net_device *dev)
+static inline bool dsa_tree_offloads_bridge_port(struct dsa_switch_tree *dst,
+                                                struct net_device *dev)
 {
        struct dsa_port *dp;
 
        list_for_each_entry(dp, &dst->ports, list)
-               if (dsa_port_offloads_netdev(dp, dev))
+               if (dsa_port_offloads_bridge_port(dp, dev))
                        return true;
 
        return false;
index 491e3761b5f4a443ec76e077a6fcff97ee6e9c49..992fcab4b55293e6629ea079d48766fa246b733c 100644 (file)
@@ -278,28 +278,43 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
        struct dsa_port *dp = dsa_slave_to_port(dev);
        int ret;
 
-       if (!dsa_port_offloads_netdev(dp, attr->orig_dev))
-               return -EOPNOTSUPP;
-
        switch (attr->id) {
        case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+               if (!dsa_port_offloads_bridge_port(dp, attr->orig_dev))
+                       return -EOPNOTSUPP;
+
                ret = dsa_port_set_state(dp, attr->u.stp_state);
                break;
        case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
+               if (!dsa_port_offloads_bridge(dp, attr->orig_dev))
+                       return -EOPNOTSUPP;
+
                ret = dsa_port_vlan_filtering(dp, attr->u.vlan_filtering,
                                              extack);
                break;
        case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
+               if (!dsa_port_offloads_bridge(dp, attr->orig_dev))
+                       return -EOPNOTSUPP;
+
                ret = dsa_port_ageing_time(dp, attr->u.ageing_time);
                break;
        case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
+               if (!dsa_port_offloads_bridge_port(dp, attr->orig_dev))
+                       return -EOPNOTSUPP;
+
                ret = dsa_port_pre_bridge_flags(dp, attr->u.brport_flags,
                                                extack);
                break;
        case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+               if (!dsa_port_offloads_bridge_port(dp, attr->orig_dev))
+                       return -EOPNOTSUPP;
+
                ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, extack);
                break;
        case SWITCHDEV_ATTR_ID_BRIDGE_MROUTER:
+               if (!dsa_port_offloads_bridge(dp, attr->orig_dev))
+                       return -EOPNOTSUPP;
+
                ret = dsa_port_mrouter(dp->cpu_dp, attr->u.mrouter, extack);
                break;
        default:
@@ -341,9 +356,6 @@ static int dsa_slave_vlan_add(struct net_device *dev,
        struct switchdev_obj_port_vlan vlan;
        int err;
 
-       if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
-               return -EOPNOTSUPP;
-
        if (dsa_port_skip_vlan_configuration(dp)) {
                NL_SET_ERR_MSG_MOD(extack, "skipping configuration of VLAN");
                return 0;
@@ -391,27 +403,36 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
 
        switch (obj->id) {
        case SWITCHDEV_OBJ_ID_PORT_MDB:
-               if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+               if (!dsa_port_offloads_bridge_port(dp, obj->orig_dev))
                        return -EOPNOTSUPP;
+
                err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
                break;
        case SWITCHDEV_OBJ_ID_HOST_MDB:
+               if (!dsa_port_offloads_bridge(dp, obj->orig_dev))
+                       return -EOPNOTSUPP;
+
                /* DSA can directly translate this to a normal MDB add,
                 * but on the CPU port.
                 */
                err = dsa_port_mdb_add(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj));
                break;
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
+               if (!dsa_port_offloads_bridge_port(dp, obj->orig_dev))
+                       return -EOPNOTSUPP;
+
                err = dsa_slave_vlan_add(dev, obj, extack);
                break;
        case SWITCHDEV_OBJ_ID_MRP:
-               if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+               if (!dsa_port_offloads_bridge(dp, obj->orig_dev))
                        return -EOPNOTSUPP;
+
                err = dsa_port_mrp_add(dp, SWITCHDEV_OBJ_MRP(obj));
                break;
        case SWITCHDEV_OBJ_ID_RING_ROLE_MRP:
-               if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+               if (!dsa_port_offloads_bridge(dp, obj->orig_dev))
                        return -EOPNOTSUPP;
+
                err = dsa_port_mrp_add_ring_role(dp,
                                                 SWITCHDEV_OBJ_RING_ROLE_MRP(obj));
                break;
@@ -431,9 +452,6 @@ static int dsa_slave_vlan_del(struct net_device *dev,
        struct switchdev_obj_port_vlan *vlan;
        int err;
 
-       if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
-               return -EOPNOTSUPP;
-
        if (dsa_port_skip_vlan_configuration(dp))
                return 0;
 
@@ -459,27 +477,36 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
 
        switch (obj->id) {
        case SWITCHDEV_OBJ_ID_PORT_MDB:
-               if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+               if (!dsa_port_offloads_bridge_port(dp, obj->orig_dev))
                        return -EOPNOTSUPP;
+
                err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
                break;
        case SWITCHDEV_OBJ_ID_HOST_MDB:
+               if (!dsa_port_offloads_bridge(dp, obj->orig_dev))
+                       return -EOPNOTSUPP;
+
                /* DSA can directly translate this to a normal MDB add,
                 * but on the CPU port.
                 */
                err = dsa_port_mdb_del(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj));
                break;
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
+               if (!dsa_port_offloads_bridge_port(dp, obj->orig_dev))
+                       return -EOPNOTSUPP;
+
                err = dsa_slave_vlan_del(dev, obj);
                break;
        case SWITCHDEV_OBJ_ID_MRP:
-               if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+               if (!dsa_port_offloads_bridge(dp, obj->orig_dev))
                        return -EOPNOTSUPP;
+
                err = dsa_port_mrp_del(dp, SWITCHDEV_OBJ_MRP(obj));
                break;
        case SWITCHDEV_OBJ_ID_RING_ROLE_MRP:
-               if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+               if (!dsa_port_offloads_bridge(dp, obj->orig_dev))
                        return -EOPNOTSUPP;
+
                err = dsa_port_mrp_del_ring_role(dp,
                                                 SWITCHDEV_OBJ_RING_ROLE_MRP(obj));
                break;
@@ -2298,7 +2325,7 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
                         * other ports bridged with the LAG should be able to
                         * autonomously forward towards it.
                         */
-                       if (dsa_tree_offloads_netdev(dp->ds->dst, dev))
+                       if (dsa_tree_offloads_bridge_port(dp->ds->dst, dev))
                                return NOTIFY_DONE;
                }
 
index 38dcdded74c0524ab984468d64a16469dc91ed06..59748487664fe8e118b8c181b9caf9bc7ace65a9 100644 (file)
@@ -13,6 +13,7 @@
 #define MTK_HDR_LEN            4
 #define MTK_HDR_XMIT_UNTAGGED          0
 #define MTK_HDR_XMIT_TAGGED_TPID_8100  1
+#define MTK_HDR_XMIT_TAGGED_TPID_88A8  2
 #define MTK_HDR_RECV_SOURCE_PORT_MASK  GENMASK(2, 0)
 #define MTK_HDR_XMIT_DP_BIT_MASK       GENMASK(5, 0)
 #define MTK_HDR_XMIT_SA_DIS            BIT(6)
@@ -21,8 +22,8 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
                                    struct net_device *dev)
 {
        struct dsa_port *dp = dsa_slave_to_port(dev);
+       u8 xmit_tpid;
        u8 *mtk_tag;
-       bool is_vlan_skb = true;
        unsigned char *dest = eth_hdr(skb)->h_dest;
        bool is_multicast_skb = is_multicast_ether_addr(dest) &&
                                !is_broadcast_ether_addr(dest);
@@ -33,10 +34,17 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
         * the both special and VLAN tag at the same time and then look up VLAN
         * table with VID.
         */
-       if (!skb_vlan_tagged(skb)) {
+       switch (skb->protocol) {
+       case htons(ETH_P_8021Q):
+               xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100;
+               break;
+       case htons(ETH_P_8021AD):
+               xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8;
+               break;
+       default:
+               xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
                skb_push(skb, MTK_HDR_LEN);
                memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN);
-               is_vlan_skb = false;
        }
 
        mtk_tag = skb->data + 2 * ETH_ALEN;
@@ -44,8 +52,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
        /* Mark tag attribute on special tag insertion to notify hardware
         * whether that's a combined special tag with 802.1Q header.
         */
-       mtk_tag[0] = is_vlan_skb ? MTK_HDR_XMIT_TAGGED_TPID_8100 :
-                    MTK_HDR_XMIT_UNTAGGED;
+       mtk_tag[0] = xmit_tpid;
        mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
 
        /* Disable SA learning for multicast frames */
@@ -53,7 +60,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
                mtk_tag[1] |= MTK_HDR_XMIT_SA_DIS;
 
        /* Tag control information is kept for 802.1Q */
-       if (!is_vlan_skb) {
+       if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) {
                mtk_tag[2] = 0;
                mtk_tag[3] = 0;
        }
index c17d39b4a1a04826fc9d631679d41ec62e4fb979..e9176475bac89541cd49581403881009d3b6dd4b 100644 (file)
@@ -35,14 +35,12 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
                                      struct net_device *dev)
 {
        struct dsa_port *dp = dsa_slave_to_port(dev);
+       __be16 *p;
        u8 *tag;
-       u16 *p;
        u16 out;
 
        /* Pad out to at least 60 bytes */
-       if (unlikely(eth_skb_pad(skb)))
-               return NULL;
-       if (skb_cow_head(skb, RTL4_A_HDR_LEN) < 0)
+       if (unlikely(__skb_put_padto(skb, ETH_ZLEN, false)))
                return NULL;
 
        netdev_dbg(dev, "add realtek tag to package to port %d\n",
@@ -53,13 +51,13 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
        tag = skb->data + 2 * ETH_ALEN;
 
        /* Set Ethertype */
-       p = (u16 *)tag;
+       p = (__be16 *)tag;
        *p = htons(RTL4_A_ETHERTYPE);
 
        out = (RTL4_A_PROTOCOL_RTL8366RB << 12) | (2 << 8);
-       /* The lower bits is the port numer */
+       /* The lower bits is the port number */
        out |= (u8)dp->index;
-       p = (u16 *)(tag + 2);
+       p = (__be16 *)(tag + 2);
        *p = htons(out);
 
        return skb;
index 25a9e566ef5cdd45c3e1c460fb6bf1c3404b6b5c..6a070dc8e4b0dba90656d92f742320200c6bdfe3 100644 (file)
@@ -116,10 +116,9 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info)
        struct ethtool_channels channels = {};
        struct ethnl_req_info req_info = {};
        struct nlattr **tb = info->attrs;
-       const struct nlattr *err_attr;
+       u32 err_attr, max_rx_in_use = 0;
        const struct ethtool_ops *ops;
        struct net_device *dev;
-       u32 max_rx_in_use = 0;
        int ret;
 
        ret = ethnl_parse_header_dev_get(&req_info,
@@ -157,34 +156,35 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info)
 
        /* ensure new channel counts are within limits */
        if (channels.rx_count > channels.max_rx)
-               err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT];
+               err_attr = ETHTOOL_A_CHANNELS_RX_COUNT;
        else if (channels.tx_count > channels.max_tx)
-               err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT];
+               err_attr = ETHTOOL_A_CHANNELS_TX_COUNT;
        else if (channels.other_count > channels.max_other)
-               err_attr = tb[ETHTOOL_A_CHANNELS_OTHER_COUNT];
+               err_attr = ETHTOOL_A_CHANNELS_OTHER_COUNT;
        else if (channels.combined_count > channels.max_combined)
-               err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT];
+               err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT;
        else
-               err_attr = NULL;
+               err_attr = 0;
        if (err_attr) {
                ret = -EINVAL;
-               NL_SET_ERR_MSG_ATTR(info->extack, err_attr,
+               NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr],
                                    "requested channel count exceeds maximum");
                goto out_ops;
        }
 
        /* ensure there is at least one RX and one TX channel */
        if (!channels.combined_count && !channels.rx_count)
-               err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT];
+               err_attr = ETHTOOL_A_CHANNELS_RX_COUNT;
        else if (!channels.combined_count && !channels.tx_count)
-               err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT];
+               err_attr = ETHTOOL_A_CHANNELS_TX_COUNT;
        else
-               err_attr = NULL;
+               err_attr = 0;
        if (err_attr) {
                if (mod_combined)
-                       err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT];
+                       err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT;
                ret = -EINVAL;
-               NL_SET_ERR_MSG_ATTR(info->extack, err_attr, "requested channel counts would result in no RX or TX channel being configured");
+               NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr],
+                                   "requested channel counts would result in no RX or TX channel being configured");
                goto out_ops;
        }
 
index 471d33a0d095fc32b8a8303124bc6718acdb207d..bfaf327e9d1214af9d1952ca68dde9c30a878199 100644 (file)
@@ -519,16 +519,10 @@ int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
                ret_val = -ENOENT;
                goto doi_remove_return;
        }
-       if (!refcount_dec_and_test(&doi_def->refcount)) {
-               spin_unlock(&cipso_v4_doi_list_lock);
-               ret_val = -EBUSY;
-               goto doi_remove_return;
-       }
        list_del_rcu(&doi_def->list);
        spin_unlock(&cipso_v4_doi_list_lock);
 
-       cipso_v4_cache_invalidate();
-       call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
+       cipso_v4_doi_putdef(doi_def);
        ret_val = 0;
 
 doi_remove_return:
@@ -585,9 +579,6 @@ void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def)
 
        if (!refcount_dec_and_test(&doi_def->refcount))
                return;
-       spin_lock(&cipso_v4_doi_list_lock);
-       list_del_rcu(&doi_def->list);
-       spin_unlock(&cipso_v4_doi_list_lock);
 
        cipso_v4_cache_invalidate();
        call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
@@ -1162,7 +1153,7 @@ static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
 {
        buf[0] = IPOPT_CIPSO;
        buf[1] = CIPSO_V4_HDR_LEN + len;
-       *(__be32 *)&buf[2] = htonl(doi_def->doi);
+       put_unaligned_be32(doi_def->doi, &buf[2]);
 }
 
 /**
index ff327a62c9ce9b1794104c3c924f5f2b9820ac8b..da21dfce24d7390bdc51899e03a0c7b3efbc3cec 100644 (file)
@@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(inet_peer_base_init);
 #define PEER_MAX_GC 32
 
 /* Exported for sysctl_net_ipv4.  */
-int inet_peer_threshold __read_mostly = 65536 + 128;   /* start to throw entries more
+int inet_peer_threshold __read_mostly; /* start to throw entries more
                                         * aggressively at this stage */
 int inet_peer_minttl __read_mostly = 120 * HZ; /* TTL under high load: 120 sec */
 int inet_peer_maxttl __read_mostly = 10 * 60 * HZ;     /* usual time to live: 10 min */
@@ -73,20 +73,13 @@ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ;  /* usual time to live: 10 min
 /* Called from ip_output.c:ip_init  */
 void __init inet_initpeers(void)
 {
-       struct sysinfo si;
+       u64 nr_entries;
 
-       /* Use the straight interface to information about memory. */
-       si_meminfo(&si);
-       /* The values below were suggested by Alexey Kuznetsov
-        * <kuznet@ms2.inr.ac.ru>.  I don't have any opinion about the values
-        * myself.  --SAW
-        */
-       if (si.totalram <= (32768*1024)/PAGE_SIZE)
-               inet_peer_threshold >>= 1; /* max pool size about 1MB on IA32 */
-       if (si.totalram <= (16384*1024)/PAGE_SIZE)
-               inet_peer_threshold >>= 1; /* about 512KB */
-       if (si.totalram <= (8192*1024)/PAGE_SIZE)
-               inet_peer_threshold >>= 2; /* about 128KB */
+        /* 1% of physical memory */
+       nr_entries = div64_ul((u64)totalram_pages() << PAGE_SHIFT,
+                             100 * L1_CACHE_ALIGN(sizeof(struct inet_peer)));
+
+       inet_peer_threshold = clamp_val(nr_entries, 4096, 65536 + 128);
 
        peer_cachep = kmem_cache_create("inet_peer_cache",
                        sizeof(struct inet_peer),
index 76a420c76f16e701d36e0ffe235fc19e0ccd8235..f6cc26de5ed304e0d70bce9444bb4201b6172c11 100644 (file)
@@ -502,8 +502,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
                if (!skb_is_gso(skb) &&
                    (inner_iph->frag_off & htons(IP_DF)) &&
                    mtu < pkt_size) {
-                       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
-                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
+                       icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
                        return -E2BIG;
                }
        }
@@ -527,7 +526,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
 
                if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
                                        mtu < pkt_size) {
-                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                        return -E2BIG;
                }
        }
index abc171e79d3e4f755182be054a6f948e20903c2d..eb207089ece0b29bbb96dd66544be79133be2ecc 100644 (file)
@@ -238,13 +238,13 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
        if (skb->len > mtu) {
                skb_dst_update_pmtu_no_confirm(skb, mtu);
                if (skb->protocol == htons(ETH_P_IP)) {
-                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
-                                 htonl(mtu));
+                       icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+                                     htonl(mtu));
                } else {
                        if (mtu < IPV6_MIN_MTU)
                                mtu = IPV6_MIN_MTU;
 
-                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                }
 
                dst_release(dst);
index f1c6cbdb9e43648dc1664ecb65cb9f05eeb1e673..743777bce179481ce46536e6b7ca866a2d7f7fbf 100644 (file)
@@ -1399,7 +1399,7 @@ out:
 
 /* rtnl */
 /* remove all nexthops tied to a device being deleted */
-static void nexthop_flush_dev(struct net_device *dev)
+static void nexthop_flush_dev(struct net_device *dev, unsigned long event)
 {
        unsigned int hash = nh_dev_hashfn(dev->ifindex);
        struct net *net = dev_net(dev);
@@ -1411,6 +1411,10 @@ static void nexthop_flush_dev(struct net_device *dev)
                if (nhi->fib_nhc.nhc_dev != dev)
                        continue;
 
+               if (nhi->reject_nh &&
+                   (event == NETDEV_DOWN || event == NETDEV_CHANGE))
+                       continue;
+
                remove_nexthop(net, nhi->nh_parent, NULL);
        }
 }
@@ -2189,11 +2193,11 @@ static int nh_netdev_event(struct notifier_block *this,
        switch (event) {
        case NETDEV_DOWN:
        case NETDEV_UNREGISTER:
-               nexthop_flush_dev(dev);
+               nexthop_flush_dev(dev, event);
                break;
        case NETDEV_CHANGE:
                if (!(dev_get_flags(dev) & (IFF_RUNNING | IFF_LOWER_UP)))
-                       nexthop_flush_dev(dev);
+                       nexthop_flush_dev(dev, event);
                break;
        case NETDEV_CHANGEMTU:
                info_ext = ptr;
index a3422e42784edfedeecd7e9cfe6ed68990c90957..de7cc8445ac035ff2f7d17b93acabd7342144da8 100644 (file)
@@ -3469,16 +3469,23 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
                break;
 
        case TCP_QUEUE_SEQ:
-               if (sk->sk_state != TCP_CLOSE)
+               if (sk->sk_state != TCP_CLOSE) {
                        err = -EPERM;
-               else if (tp->repair_queue == TCP_SEND_QUEUE)
-                       WRITE_ONCE(tp->write_seq, val);
-               else if (tp->repair_queue == TCP_RECV_QUEUE) {
-                       WRITE_ONCE(tp->rcv_nxt, val);
-                       WRITE_ONCE(tp->copied_seq, val);
-               }
-               else
+               } else if (tp->repair_queue == TCP_SEND_QUEUE) {
+                       if (!tcp_rtx_queue_empty(sk))
+                               err = -EPERM;
+                       else
+                               WRITE_ONCE(tp->write_seq, val);
+               } else if (tp->repair_queue == TCP_RECV_QUEUE) {
+                       if (tp->rcv_nxt != tp->copied_seq) {
+                               err = -EPERM;
+                       } else {
+                               WRITE_ONCE(tp->rcv_nxt, val);
+                               WRITE_ONCE(tp->copied_seq, val);
+                       }
+               } else {
                        err = -EINVAL;
+               }
                break;
 
        case TCP_REPAIR_OPTIONS:
@@ -4143,7 +4150,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
 
                if (get_user(len, optlen))
                        return -EFAULT;
-               if (len < offsetofend(struct tcp_zerocopy_receive, length))
+               if (len < 0 ||
+                   len < offsetofend(struct tcp_zerocopy_receive, length))
                        return -EINVAL;
                if (unlikely(len > sizeof(zc))) {
                        err = check_zeroed_user(optval + sizeof(zc),
index b76c48efd37ee5f7de8a15ad5ea791b2f3fee625..c5b4b586570feab5bea5303ab55097727d69dd90 100644 (file)
@@ -526,7 +526,7 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
        }
 
        if (!sk || NAPI_GRO_CB(skb)->encap_mark ||
-           (skb->ip_summed != CHECKSUM_PARTIAL &&
+           (uh->check && skb->ip_summed != CHECKSUM_PARTIAL &&
             NAPI_GRO_CB(skb)->csum_cnt == 0 &&
             !NAPI_GRO_CB(skb)->csum_valid) ||
            !udp_sk(sk)->gro_receive)
index 51184a70ac7e545c1c1d440a717c0b220ed420b7..1578ed9e97d892eab85514a21ceff9a4aa79b22d 100644 (file)
@@ -83,6 +83,9 @@ struct calipso_map_cache_entry {
 
 static struct calipso_map_cache_bkt *calipso_cache;
 
+static void calipso_cache_invalidate(void);
+static void calipso_doi_putdef(struct calipso_doi *doi_def);
+
 /* Label Mapping Cache Functions
  */
 
@@ -444,15 +447,10 @@ static int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info)
                ret_val = -ENOENT;
                goto doi_remove_return;
        }
-       if (!refcount_dec_and_test(&doi_def->refcount)) {
-               spin_unlock(&calipso_doi_list_lock);
-               ret_val = -EBUSY;
-               goto doi_remove_return;
-       }
        list_del_rcu(&doi_def->list);
        spin_unlock(&calipso_doi_list_lock);
 
-       call_rcu(&doi_def->rcu, calipso_doi_free_rcu);
+       calipso_doi_putdef(doi_def);
        ret_val = 0;
 
 doi_remove_return:
@@ -508,10 +506,8 @@ static void calipso_doi_putdef(struct calipso_doi *doi_def)
 
        if (!refcount_dec_and_test(&doi_def->refcount))
                return;
-       spin_lock(&calipso_doi_list_lock);
-       list_del_rcu(&doi_def->list);
-       spin_unlock(&calipso_doi_list_lock);
 
+       calipso_cache_invalidate();
        call_rcu(&doi_def->rcu, calipso_doi_free_rcu);
 }
 
index c3bc89b6b1a1afeb449fa29984450bbac2c81412..1baf43aacb2e4be20c7b2d7367b048bbb4c39c82 100644 (file)
@@ -678,8 +678,8 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *skb,
 
                tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
                if (tel->encap_limit == 0) {
-                       icmpv6_send(skb, ICMPV6_PARAMPROB,
-                                   ICMPV6_HDR_FIELD, offset + 2);
+                       icmpv6_ndo_send(skb, ICMPV6_PARAMPROB,
+                                       ICMPV6_HDR_FIELD, offset + 2);
                        return -1;
                }
                *encap_limit = tel->encap_limit - 1;
@@ -805,8 +805,8 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
        if (err != 0) {
                /* XXX: send ICMP error even if DF is not set. */
                if (err == -EMSGSIZE)
-                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
-                                 htonl(mtu));
+                       icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+                                     htonl(mtu));
                return -1;
        }
 
@@ -837,7 +837,7 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
                          &mtu, skb->protocol);
        if (err != 0) {
                if (err == -EMSGSIZE)
-                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                return -1;
        }
 
@@ -1063,10 +1063,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
                /* XXX: send ICMP error even if DF is not set. */
                if (err == -EMSGSIZE) {
                        if (skb->protocol == htons(ETH_P_IP))
-                               icmp_send(skb, ICMP_DEST_UNREACH,
-                                         ICMP_FRAG_NEEDED, htonl(mtu));
+                               icmp_ndo_send(skb, ICMP_DEST_UNREACH,
+                                             ICMP_FRAG_NEEDED, htonl(mtu));
                        else
-                               icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                               icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                }
 
                goto tx_err;
index a7950baa05e511a4dabec54757a3057f1e4a25c7..3fa0eca5a06f8af1afef3a497f9411e98007b149 100644 (file)
@@ -1332,8 +1332,8 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev,
 
                                tel = (void *)&skb_network_header(skb)[offset];
                                if (tel->encap_limit == 0) {
-                                       icmpv6_send(skb, ICMPV6_PARAMPROB,
-                                               ICMPV6_HDR_FIELD, offset + 2);
+                                       icmpv6_ndo_send(skb, ICMPV6_PARAMPROB,
+                                                       ICMPV6_HDR_FIELD, offset + 2);
                                        return -1;
                                }
                                encap_limit = tel->encap_limit - 1;
@@ -1385,11 +1385,11 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev,
                if (err == -EMSGSIZE)
                        switch (protocol) {
                        case IPPROTO_IPIP:
-                               icmp_send(skb, ICMP_DEST_UNREACH,
-                                         ICMP_FRAG_NEEDED, htonl(mtu));
+                               icmp_ndo_send(skb, ICMP_DEST_UNREACH,
+                                             ICMP_FRAG_NEEDED, htonl(mtu));
                                break;
                        case IPPROTO_IPV6:
-                               icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                               icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                                break;
                        default:
                                break;
index 0225fd6941925ad2f1da6533801ab66cbd327b87..f10e7a72ea6248e5ec1fbdb8b4e1c4e0e874cb96 100644 (file)
@@ -521,10 +521,10 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
                        if (mtu < IPV6_MIN_MTU)
                                mtu = IPV6_MIN_MTU;
 
-                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                } else {
-                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
-                                 htonl(mtu));
+                       icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+                                     htonl(mtu));
                }
 
                err = -EMSGSIZE;
index 93636867aee28dac0d166a4919ee26c77cb692a3..63ccd9f2dcccf972eebefa8f293fb47090feb8e1 100644 (file)
@@ -987,7 +987,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
                        skb_dst_update_pmtu_no_confirm(skb, mtu);
 
                if (skb->len > mtu && !skb_is_gso(skb)) {
-                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                        ip_rt_put(rt);
                        goto tx_error;
                }
index 7be5103ff2a84e19f1dfd4e4dfbbb04e4667e150..203890e378cb0b8acb42a2781b3cce80f9511fd3 100644 (file)
@@ -649,9 +649,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
        /* Parse and check optional cookie */
        if (session->peer_cookie_len > 0) {
                if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) {
-                       pr_warn_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
-                                           tunnel->name, tunnel->tunnel_id,
-                                           session->session_id);
+                       pr_debug_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
+                                            tunnel->name, tunnel->tunnel_id,
+                                            session->session_id);
                        atomic_long_inc(&session->stats.rx_cookie_discards);
                        goto discard;
                }
@@ -702,8 +702,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                 * If user has configured mandatory sequence numbers, discard.
                 */
                if (session->recv_seq) {
-                       pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
-                                           session->name);
+                       pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
+                                            session->name);
                        atomic_long_inc(&session->stats.rx_seq_discards);
                        goto discard;
                }
@@ -718,8 +718,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                        session->send_seq = 0;
                        l2tp_session_set_header_len(session, tunnel->version);
                } else if (session->send_seq) {
-                       pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
-                                           session->name);
+                       pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
+                                            session->name);
                        atomic_long_inc(&session->stats.rx_seq_discards);
                        goto discard;
                }
@@ -809,9 +809,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
 
        /* Short packet? */
        if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) {
-               pr_warn_ratelimited("%s: recv short packet (len=%d)\n",
-                                   tunnel->name, skb->len);
-               goto error;
+               pr_debug_ratelimited("%s: recv short packet (len=%d)\n",
+                                    tunnel->name, skb->len);
+               goto invalid;
        }
 
        /* Point to L2TP header */
@@ -824,9 +824,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
        /* Check protocol version */
        version = hdrflags & L2TP_HDR_VER_MASK;
        if (version != tunnel->version) {
-               pr_warn_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
-                                   tunnel->name, version, tunnel->version);
-               goto error;
+               pr_debug_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
+                                    tunnel->name, version, tunnel->version);
+               goto invalid;
        }
 
        /* Get length of L2TP packet */
@@ -834,7 +834,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
 
        /* If type is control packet, it is handled by userspace. */
        if (hdrflags & L2TP_HDRFLAG_T)
-               goto error;
+               goto pass;
 
        /* Skip flags */
        ptr += 2;
@@ -863,21 +863,24 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
                        l2tp_session_dec_refcount(session);
 
                /* Not found? Pass to userspace to deal with */
-               pr_warn_ratelimited("%s: no session found (%u/%u). Passing up.\n",
-                                   tunnel->name, tunnel_id, session_id);
-               goto error;
+               pr_debug_ratelimited("%s: no session found (%u/%u). Passing up.\n",
+                                    tunnel->name, tunnel_id, session_id);
+               goto pass;
        }
 
        if (tunnel->version == L2TP_HDR_VER_3 &&
            l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
-               goto error;
+               goto invalid;
 
        l2tp_recv_common(session, skb, ptr, optr, hdrflags, length);
        l2tp_session_dec_refcount(session);
 
        return 0;
 
-error:
+invalid:
+       atomic_long_inc(&tunnel->stats.rx_invalid);
+
+pass:
        /* Put UDP header back */
        __skb_push(skb, sizeof(struct udphdr));
 
index cb21d906343e8a569307be62bd951db473d0e572..98ea98eb9567bc7bd3e96c48acc4fefecb05b58f 100644 (file)
@@ -39,6 +39,7 @@ struct l2tp_stats {
        atomic_long_t           rx_oos_packets;
        atomic_long_t           rx_errors;
        atomic_long_t           rx_cookie_discards;
+       atomic_long_t           rx_invalid;
 };
 
 struct l2tp_tunnel;
index 83956c9ee1fcc7b17ed33239d6c8df53ba4598fd..96eb91be9238ba13413e7948df07f1084389fd83 100644 (file)
@@ -428,6 +428,9 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
                              L2TP_ATTR_STATS_PAD) ||
            nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS,
                              atomic_long_read(&tunnel->stats.rx_errors),
+                             L2TP_ATTR_STATS_PAD) ||
+           nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID,
+                             atomic_long_read(&tunnel->stats.rx_invalid),
                              L2TP_ATTR_STATS_PAD))
                goto nla_put_failure;
        nla_nest_end(skb, nest);
@@ -771,6 +774,9 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
                              L2TP_ATTR_STATS_PAD) ||
            nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS,
                              atomic_long_read(&session->stats.rx_errors),
+                             L2TP_ATTR_STATS_PAD) ||
+           nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID,
+                             atomic_long_read(&session->stats.rx_invalid),
                              L2TP_ATTR_STATS_PAD))
                goto nla_put_failure;
        nla_nest_end(skb, nest);
index b1690149b6fa08147b4bb582379ba2a9535f52ef..1482259de9b5d7a5e791f0deb34cedcb1f26bf21 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/netdev_features.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <net/mpls.h>
 
 static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
                                       netdev_features_t features)
@@ -27,6 +28,8 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
 
        skb_reset_network_header(skb);
        mpls_hlen = skb_inner_network_header(skb) - skb_network_header(skb);
+       if (unlikely(!mpls_hlen || mpls_hlen % MPLS_HLEN))
+               goto out;
        if (unlikely(!pskb_may_pull(skb, mpls_hlen)))
                goto out;
 
index c5d5e68940ea2b6f88dccc0f8359fb961afc1f68..76958570ae7f258a0276e423bb7ddbbd0a200224 100644 (file)
@@ -1061,6 +1061,12 @@ out:
        }
 }
 
+static void __mptcp_clean_una_wakeup(struct sock *sk)
+{
+       __mptcp_clean_una(sk);
+       mptcp_write_space(sk);
+}
+
 static void mptcp_enter_memory_pressure(struct sock *sk)
 {
        struct mptcp_subflow_context *subflow;
@@ -1189,6 +1195,7 @@ static bool mptcp_tx_cache_refill(struct sock *sk, int size,
                         */
                        while (skbs->qlen > 1) {
                                skb = __skb_dequeue_tail(skbs);
+                               *total_ts -= skb->truesize;
                                __kfree_skb(skb);
                        }
                        return skbs->qlen > 0;
@@ -1444,7 +1451,7 @@ static void mptcp_push_release(struct sock *sk, struct sock *ssk,
        release_sock(ssk);
 }
 
-static void mptcp_push_pending(struct sock *sk, unsigned int flags)
+static void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 {
        struct sock *prev_ssk = NULL, *ssk = NULL;
        struct mptcp_sock *msk = mptcp_sk(sk);
@@ -1696,14 +1703,14 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
 wait_for_memory:
                mptcp_set_nospace(sk);
-               mptcp_push_pending(sk, msg->msg_flags);
+               __mptcp_push_pending(sk, msg->msg_flags);
                ret = sk_stream_wait_memory(sk, &timeo);
                if (ret)
                        goto out;
        }
 
        if (copied)
-               mptcp_push_pending(sk, msg->msg_flags);
+               __mptcp_push_pending(sk, msg->msg_flags);
 
 out:
        release_sock(sk);
@@ -2115,6 +2122,14 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk)
        return backup;
 }
 
+static void mptcp_dispose_initial_subflow(struct mptcp_sock *msk)
+{
+       if (msk->subflow) {
+               iput(SOCK_INODE(msk->subflow));
+               msk->subflow = NULL;
+       }
+}
+
 /* subflow sockets can be either outgoing (connect) or incoming
  * (accept).
  *
@@ -2126,6 +2141,8 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk)
 static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                              struct mptcp_subflow_context *subflow)
 {
+       struct mptcp_sock *msk = mptcp_sk(sk);
+
        list_del(&subflow->node);
 
        lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
@@ -2154,6 +2171,18 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
        release_sock(ssk);
 
        sock_put(ssk);
+
+       if (ssk == msk->last_snd)
+               msk->last_snd = NULL;
+
+       if (ssk == msk->ack_hint)
+               msk->ack_hint = NULL;
+
+       if (ssk == msk->first)
+               msk->first = NULL;
+
+       if (msk->subflow && ssk == msk->subflow->sk)
+               mptcp_dispose_initial_subflow(msk);
 }
 
 void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
@@ -2238,14 +2267,58 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
        mptcp_close_wake_up(sk);
 }
 
-static void mptcp_worker(struct work_struct *work)
+static void __mptcp_retrans(struct sock *sk)
 {
-       struct mptcp_sock *msk = container_of(work, struct mptcp_sock, work);
-       struct sock *ssk, *sk = &msk->sk.icsk_inet.sk;
+       struct mptcp_sock *msk = mptcp_sk(sk);
        struct mptcp_sendmsg_info info = {};
        struct mptcp_data_frag *dfrag;
        size_t copied = 0;
-       int state, ret;
+       struct sock *ssk;
+       int ret;
+
+       __mptcp_clean_una_wakeup(sk);
+       dfrag = mptcp_rtx_head(sk);
+       if (!dfrag)
+               return;
+
+       ssk = mptcp_subflow_get_retrans(msk);
+       if (!ssk)
+               goto reset_timer;
+
+       lock_sock(ssk);
+
+       /* limit retransmission to the bytes already sent on some subflows */
+       info.sent = 0;
+       info.limit = dfrag->already_sent;
+       while (info.sent < dfrag->already_sent) {
+               if (!mptcp_alloc_tx_skb(sk, ssk))
+                       break;
+
+               ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info);
+               if (ret <= 0)
+                       break;
+
+               MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RETRANSSEGS);
+               copied += ret;
+               info.sent += ret;
+       }
+       if (copied)
+               tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
+                        info.size_goal);
+
+       mptcp_set_timeout(sk, ssk);
+       release_sock(ssk);
+
+reset_timer:
+       if (!mptcp_timer_pending(sk))
+               mptcp_reset_timer(sk);
+}
+
+static void mptcp_worker(struct work_struct *work)
+{
+       struct mptcp_sock *msk = container_of(work, struct mptcp_sock, work);
+       struct sock *sk = &msk->sk.icsk_inet.sk;
+       int state;
 
        lock_sock(sk);
        state = sk->sk_state;
@@ -2280,45 +2353,8 @@ static void mptcp_worker(struct work_struct *work)
        if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
                __mptcp_close_subflow(msk);
 
-       if (!test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
-               goto unlock;
-
-       __mptcp_clean_una(sk);
-       dfrag = mptcp_rtx_head(sk);
-       if (!dfrag)
-               goto unlock;
-
-       ssk = mptcp_subflow_get_retrans(msk);
-       if (!ssk)
-               goto reset_unlock;
-
-       lock_sock(ssk);
-
-       /* limit retransmission to the bytes already sent on some subflows */
-       info.sent = 0;
-       info.limit = dfrag->already_sent;
-       while (info.sent < dfrag->already_sent) {
-               if (!mptcp_alloc_tx_skb(sk, ssk))
-                       break;
-
-               ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info);
-               if (ret <= 0)
-                       break;
-
-               MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RETRANSSEGS);
-               copied += ret;
-               info.sent += ret;
-       }
-       if (copied)
-               tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
-                        info.size_goal);
-
-       mptcp_set_timeout(sk, ssk);
-       release_sock(ssk);
-
-reset_unlock:
-       if (!mptcp_timer_pending(sk))
-               mptcp_reset_timer(sk);
+       if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
+               __mptcp_retrans(sk);
 
 unlock:
        release_sock(sk);
@@ -2523,12 +2559,6 @@ static void __mptcp_destroy_sock(struct sock *sk)
 
        might_sleep();
 
-       /* dispose the ancillatory tcp socket, if any */
-       if (msk->subflow) {
-               iput(SOCK_INODE(msk->subflow));
-               msk->subflow = NULL;
-       }
-
        /* be sure to always acquire the join list lock, to sync vs
         * mptcp_finish_join().
         */
@@ -2553,6 +2583,7 @@ static void __mptcp_destroy_sock(struct sock *sk)
        sk_stream_kill_queues(sk);
        xfrm_sk_free_policy(sk);
        sk_refcnt_debug_release(sk);
+       mptcp_dispose_initial_subflow(msk);
        sock_put(sk);
 }
 
@@ -2934,13 +2965,14 @@ static void mptcp_release_cb(struct sock *sk)
 {
        unsigned long flags, nflags;
 
-       /* push_pending may touch wmem_reserved, do it before the later
-        * cleanup
-        */
-       if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags))
-               __mptcp_clean_una(sk);
-       if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags)) {
-               /* mptcp_push_pending() acquires the subflow socket lock
+       for (;;) {
+               flags = 0;
+               if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags))
+                       flags |= MPTCP_PUSH_PENDING;
+               if (!flags)
+                       break;
+
+               /* the following actions acquire the subflow socket lock
                 *
                 * 1) can't be invoked in atomic scope
                 * 2) must avoid ABBA deadlock with msk socket spinlock: the RX
@@ -2949,13 +2981,21 @@ static void mptcp_release_cb(struct sock *sk)
                 */
 
                spin_unlock_bh(&sk->sk_lock.slock);
-               mptcp_push_pending(sk, 0);
+               if (flags & MPTCP_PUSH_PENDING)
+                       __mptcp_push_pending(sk, 0);
+
+               cond_resched();
                spin_lock_bh(&sk->sk_lock.slock);
        }
+
+       if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags))
+               __mptcp_clean_una_wakeup(sk);
        if (test_and_clear_bit(MPTCP_ERROR_REPORT, &mptcp_sk(sk)->flags))
                __mptcp_error_report(sk);
 
-       /* clear any wmem reservation and errors */
+       /* push_pending may touch wmem_reserved, ensure we do the cleanup
+        * later
+        */
        __mptcp_update_wmem(sk);
        __mptcp_update_rmem(sk);
 
@@ -3285,6 +3325,9 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
                /* PM/worker can now acquire the first subflow socket
                 * lock without racing with listener queue cleanup,
                 * we can notify it, if needed.
+                *
+                * Even if remote has reset the initial subflow by now
+                * the refcnt is still at least one.
                 */
                subflow = mptcp_subflow_ctx(msk->first);
                list_add(&subflow->node, &msk->conn_list);
index 91827d94976691b490d2f1854b50f5a785904ee0..e21a5bc36cf08e425ace584cabca77f823f2811b 100644 (file)
 #define TCPOLEN_MPTCP_DSS_MAP64                14
 #define TCPOLEN_MPTCP_DSS_CHECKSUM     2
 #define TCPOLEN_MPTCP_ADD_ADDR         16
-#define TCPOLEN_MPTCP_ADD_ADDR_PORT    20
+#define TCPOLEN_MPTCP_ADD_ADDR_PORT    18
 #define TCPOLEN_MPTCP_ADD_ADDR_BASE    8
-#define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT       12
+#define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT       10
 #define TCPOLEN_MPTCP_ADD_ADDR6                28
-#define TCPOLEN_MPTCP_ADD_ADDR6_PORT   32
+#define TCPOLEN_MPTCP_ADD_ADDR6_PORT   30
 #define TCPOLEN_MPTCP_ADD_ADDR6_BASE   20
-#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT      24
-#define TCPOLEN_MPTCP_PORT_LEN         4
+#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT      22
+#define TCPOLEN_MPTCP_PORT_LEN         2
+#define TCPOLEN_MPTCP_PORT_ALIGN       2
 #define TCPOLEN_MPTCP_RM_ADDR_BASE     4
 #define TCPOLEN_MPTCP_PRIO             3
 #define TCPOLEN_MPTCP_PRIO_ALIGN       4
@@ -701,8 +702,9 @@ static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
                len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
        if (!echo)
                len += MPTCPOPT_THMAC_LEN;
+       /* account for 2 trailing 'nop' options */
        if (port)
-               len += TCPOLEN_MPTCP_PORT_LEN;
+               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
 
        return len;
 }
index e1fbcab257e6dd044227b005bc4ec3a79422c2ea..3d47d670e66546f2f4cd4be7588cead55687be06 100644 (file)
@@ -687,11 +687,6 @@ create_child:
                        /* move the msk reference ownership to the subflow */
                        subflow_req->msk = NULL;
                        ctx->conn = (struct sock *)owner;
-                       if (!mptcp_finish_join(child))
-                               goto dispose_child;
-
-                       SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKRX);
-                       tcp_rsk(req)->drop_req = true;
 
                        if (subflow_use_different_sport(owner, sk)) {
                                pr_debug("ack inet_sport=%d %d",
@@ -699,10 +694,16 @@ create_child:
                                         ntohs(inet_sk((struct sock *)owner)->inet_sport));
                                if (!mptcp_pm_sport_in_anno_list(owner, sk)) {
                                        SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MISMATCHPORTACKRX);
-                                       goto out;
+                                       goto dispose_child;
                                }
                                SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINPORTACKRX);
                        }
+
+                       if (!mptcp_finish_join(child))
+                               goto dispose_child;
+
+                       SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKRX);
+                       tcp_rsk(req)->drop_req = true;
                }
        }
 
@@ -1297,6 +1298,7 @@ failed_unlink:
        spin_lock_bh(&msk->join_list_lock);
        list_del(&subflow->node);
        spin_unlock_bh(&msk->join_list_lock);
+       sock_put(mptcp_subflow_tcp_sock(subflow));
 
 failed:
        subflow->disposable = 1;
index 118f415928aefe26d7771379b98a2156e6b6b227..b055187235f87c0def9fef5f72d583b1ac2cf13a 100644 (file)
@@ -219,7 +219,7 @@ nf_ct_lookup_helper(struct nf_conn *ct, struct net *net)
                        return NULL;
                pr_info("nf_conntrack: default automatic helper assignment "
                        "has been turned off for security reasons and CT-based "
-                       " firewall rule not found. Use the iptables CT target "
+                       "firewall rule not found. Use the iptables CT target "
                        "to attach helpers instead.\n");
                net->ct.auto_assign_helper_warned = 1;
                return NULL;
@@ -228,7 +228,6 @@ nf_ct_lookup_helper(struct nf_conn *ct, struct net *net)
        return __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 }
 
-
 int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
                              gfp_t flags)
 {
index 1d7e1c5955463545edf96ba2b8a106f9db9f4121..ec23330687a5ed92f608c5836b47ebd8f6fa211e 100644 (file)
@@ -982,8 +982,10 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
                                        IP_CT_EXP_CHALLENGE_ACK;
                }
                spin_unlock_bh(&ct->lock);
-               nf_ct_l4proto_log_invalid(skb, ct, "invalid packet ignored in "
-                                         "state %s ", tcp_conntrack_names[old_state]);
+               nf_ct_l4proto_log_invalid(skb, ct,
+                                         "packet (index %d) in dir %d ignored, state %s",
+                                         index, dir,
+                                         tcp_conntrack_names[old_state]);
                return NF_ACCEPT;
        case TCP_CONNTRACK_MAX:
                /* Special case for SYN proxy: when the SYN to the server or
index e87b6bd6b3cdb6b79b2d229df4ce3d74f8e374d8..4731d21fc3ad83022d59a43d0fea0c0945f333f6 100644 (file)
@@ -646,8 +646,8 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
 }
 
 static unsigned int
-nf_nat_ipv4_in(void *priv, struct sk_buff *skb,
-              const struct nf_hook_state *state)
+nf_nat_ipv4_pre_routing(void *priv, struct sk_buff *skb,
+                       const struct nf_hook_state *state)
 {
        unsigned int ret;
        __be32 daddr = ip_hdr(skb)->daddr;
@@ -659,6 +659,23 @@ nf_nat_ipv4_in(void *priv, struct sk_buff *skb,
        return ret;
 }
 
+static unsigned int
+nf_nat_ipv4_local_in(void *priv, struct sk_buff *skb,
+                    const struct nf_hook_state *state)
+{
+       __be32 saddr = ip_hdr(skb)->saddr;
+       struct sock *sk = skb->sk;
+       unsigned int ret;
+
+       ret = nf_nat_ipv4_fn(priv, skb, state);
+
+       if (ret == NF_ACCEPT && sk && saddr != ip_hdr(skb)->saddr &&
+           !inet_sk_transparent(sk))
+               skb_orphan(skb); /* TCP edemux obtained wrong socket */
+
+       return ret;
+}
+
 static unsigned int
 nf_nat_ipv4_out(void *priv, struct sk_buff *skb,
                const struct nf_hook_state *state)
@@ -736,7 +753,7 @@ nf_nat_ipv4_local_fn(void *priv, struct sk_buff *skb,
 static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
        /* Before packet filtering, change destination */
        {
-               .hook           = nf_nat_ipv4_in,
+               .hook           = nf_nat_ipv4_pre_routing,
                .pf             = NFPROTO_IPV4,
                .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP_PRI_NAT_DST,
@@ -757,7 +774,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
        },
        /* After packet filtering, change source */
        {
-               .hook           = nf_nat_ipv4_fn,
+               .hook           = nf_nat_ipv4_local_in,
                .pf             = NFPROTO_IPV4,
                .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_NAT_SRC,
index c1eb5cdb30330f5fdb1b3d58e10f87db6bf83ac7..224c8e537cb3357200da964ac29e336cf10798a4 100644 (file)
@@ -916,6 +916,12 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
        if (flags == ctx->table->flags)
                return 0;
 
+       if ((nft_table_has_owner(ctx->table) &&
+            !(flags & NFT_TABLE_F_OWNER)) ||
+           (!nft_table_has_owner(ctx->table) &&
+            flags & NFT_TABLE_F_OWNER))
+               return -EOPNOTSUPP;
+
        trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
                                sizeof(struct nft_trans_table));
        if (trans == NULL)
@@ -9022,8 +9028,12 @@ static void __nft_release_hooks(struct net *net)
 {
        struct nft_table *table;
 
-       list_for_each_entry(table, &net->nft.tables, list)
+       list_for_each_entry(table, &net->nft.tables, list) {
+               if (nft_table_has_owner(table))
+                       continue;
+
                __nft_release_hook(net, table);
+       }
 }
 
 static void __nft_release_table(struct net *net, struct nft_table *table)
@@ -9073,13 +9083,12 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
        nf_tables_table_destroy(&ctx);
 }
 
-static void __nft_release_tables(struct net *net, u32 nlpid)
+static void __nft_release_tables(struct net *net)
 {
        struct nft_table *table, *nt;
 
        list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
-               if (nft_table_has_owner(table) &&
-                   nlpid != table->nlpid)
+               if (nft_table_has_owner(table))
                        continue;
 
                __nft_release_table(net, table);
@@ -9145,7 +9154,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
        mutex_lock(&net->nft.commit_mutex);
        if (!list_empty(&net->nft.commit_list))
                __nf_tables_abort(net, NFNL_ABORT_NONE);
-       __nft_release_tables(net, 0);
+       __nft_release_tables(net);
        mutex_unlock(&net->nft.commit_mutex);
        WARN_ON_ONCE(!list_empty(&net->nft.tables));
        WARN_ON_ONCE(!list_empty(&net->nft.module_list));
index acce622582e3d769ecaa0bf09b588c07769ba53b..bce6ca203d46242aaa993ae5e485af1556e824de 100644 (file)
@@ -330,6 +330,7 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp)
        const struct xt_match *m;
        int have_rev = 0;
 
+       mutex_lock(&xt[af].mutex);
        list_for_each_entry(m, &xt[af].match, list) {
                if (strcmp(m->name, name) == 0) {
                        if (m->revision > *bestp)
@@ -338,6 +339,7 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp)
                                have_rev = 1;
                }
        }
+       mutex_unlock(&xt[af].mutex);
 
        if (af != NFPROTO_UNSPEC && !have_rev)
                return match_revfn(NFPROTO_UNSPEC, name, revision, bestp);
@@ -350,6 +352,7 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp)
        const struct xt_target *t;
        int have_rev = 0;
 
+       mutex_lock(&xt[af].mutex);
        list_for_each_entry(t, &xt[af].target, list) {
                if (strcmp(t->name, name) == 0) {
                        if (t->revision > *bestp)
@@ -358,6 +361,7 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp)
                                have_rev = 1;
                }
        }
+       mutex_unlock(&xt[af].mutex);
 
        if (af != NFPROTO_UNSPEC && !have_rev)
                return target_revfn(NFPROTO_UNSPEC, name, revision, bestp);
@@ -371,12 +375,10 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
 {
        int have_rev, best = -1;
 
-       mutex_lock(&xt[af].mutex);
        if (target == 1)
                have_rev = target_revfn(af, name, revision, &best);
        else
                have_rev = match_revfn(af, name, revision, &best);
-       mutex_unlock(&xt[af].mutex);
 
        /* Nothing at all?  Return 0 to try loading module. */
        if (best == -1) {
index 726dda95934c660b051fdbd618825080320e3775..4f50a64315cf0f8663d6f70116e5d0eb7e3d9264 100644 (file)
@@ -575,6 +575,7 @@ list_start:
 
                break;
        }
+       cipso_v4_doi_putdef(doi_def);
        rcu_read_unlock();
 
        genlmsg_end(ans_skb, data);
@@ -583,12 +584,14 @@ list_start:
 list_retry:
        /* XXX - this limit is a guesstimate */
        if (nlsze_mult < 4) {
+               cipso_v4_doi_putdef(doi_def);
                rcu_read_unlock();
                kfree_skb(ans_skb);
                nlsze_mult *= 2;
                goto list_start;
        }
 list_failure_lock:
+       cipso_v4_doi_putdef(doi_def);
        rcu_read_unlock();
 list_failure:
        kfree_skb(ans_skb);
index b34358282f3798157206e3836517bba937daa5b9..edb6ac17cecabd94fe392eb4f589dbbbf7bfa2c0 100644 (file)
@@ -439,7 +439,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
        if (len == 0 || len & 3)
                return -EINVAL;
 
-       skb = netdev_alloc_skb(NULL, len);
+       skb = __netdev_alloc_skb(NULL, len, GFP_ATOMIC | __GFP_NOWARN);
        if (!skb)
                return -ENOMEM;
 
@@ -958,8 +958,10 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
        plen = (len + 3) & ~3;
        skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_MAX_SIZE,
                                  msg->msg_flags & MSG_DONTWAIT, &rc);
-       if (!skb)
+       if (!skb) {
+               rc = -ENOMEM;
                goto out_node;
+       }
 
        skb_reserve(skb, QRTR_HDR_MAX_SIZE);
 
index e2e4353db8a70d5fe3d0f41d93b446c7b5ff628f..f87d07736a1404edcfd17a792321758cd4bdd173 100644 (file)
@@ -2168,7 +2168,7 @@ static int tc_dump_tclass_qdisc(struct Qdisc *q, struct sk_buff *skb,
 
 static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
                               struct tcmsg *tcm, struct netlink_callback *cb,
-                              int *t_p, int s_t)
+                              int *t_p, int s_t, bool recur)
 {
        struct Qdisc *q;
        int b;
@@ -2179,7 +2179,7 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
        if (tc_dump_tclass_qdisc(root, skb, tcm, cb, t_p, s_t) < 0)
                return -1;
 
-       if (!qdisc_dev(root))
+       if (!qdisc_dev(root) || !recur)
                return 0;
 
        if (tcm->tcm_parent) {
@@ -2214,13 +2214,13 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
        s_t = cb->args[0];
        t = 0;
 
-       if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0)
+       if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t, true) < 0)
                goto done;
 
        dev_queue = dev_ingress_queue(dev);
        if (dev_queue &&
            tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb,
-                               &t, s_t) < 0)
+                               &t, s_t, false) < 0)
                goto done;
 
 done:
index a9c6af5795d81bb1a368a91b76ffbfd50e428d6d..5ba456727f631887113b8b9a3f3ace8ff1c92eff 100644 (file)
@@ -75,7 +75,7 @@ int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn)
                return 1;
 
        /* Verify that we can hold this TSN and that it will not
-        * overlfow our map
+        * overflow our map
         */
        if (!TSN_lt(tsn, map->base_tsn + SCTP_TSN_MAP_SIZE))
                return -1;
index db0cb73513a58bdb8e2f346b4ef028aeb975e422..1e2a1105d0e67aba88a2bd4a3ab4998b549acdcb 100644 (file)
@@ -1699,5 +1699,7 @@ int main(int argc, char **argv)
 
        xdpsock_cleanup();
 
+       munmap(bufs, NUM_FRAMES * opt_xsk_frame_size);
+
        return 0;
 }
index d053beccfaec3e0f789b928f2a20b14fc4b00a47..e2237239d922a7c778148a160560340e97a95660 100644 (file)
@@ -39,6 +39,11 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
        if (!nhlt)
                return 0;
 
+       if (nhlt->header.length <= sizeof(struct acpi_table_header)) {
+               dev_warn(dev, "Invalid DMIC description table\n");
+               return 0;
+       }
+
        for (j = 0, epnt = nhlt->desc; j < nhlt->endpoint_count; j++,
             epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length)) {
 
index 6a85645663759d097e2615444ae72618fb915526..17a25e453f60cc31cfdf5fca04d1369c400e235c 100644 (file)
@@ -47,6 +47,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
        if (codec->bus->shutdown)
                return;
 
+       /* ignore unsol events during system suspend/resume */
+       if (codec->core.dev.power.power_state.event != PM_EVENT_ON)
+               return;
+
        if (codec->patch_ops.unsol_event)
                codec->patch_ops.unsol_event(codec, ev);
 }
index 9087981cd1f709f8b9a785d8fce079e28f46920a..ca2f2ecd14888115ad4e712b4d68b093f03ded1e 100644 (file)
@@ -609,13 +609,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
                                     20,
                                     178000000);
 
-       /* by some reason, the playback stream stalls on PulseAudio with
-        * tsched=1 when a capture stream triggers.  Until we figure out the
-        * real cause, disable tsched mode by telling the PCM info flag.
-        */
-       if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND)
-               runtime->hw.info |= SNDRV_PCM_INFO_BATCH;
-
        if (chip->align_buffer_size)
                /* constrain buffer sizes to be multiple of 128
                   bytes. This is more efficient in terms of memory
index 5b492c3f816c1841a505fbea44af20178ab0d744..5eea130dcf0a593d4c2373df25305fc90e33f811 100644 (file)
@@ -1026,6 +1026,8 @@ static int azx_prepare(struct device *dev)
        chip = card->private_data;
        chip->pm_prepared = 1;
 
+       flush_work(&azx_bus(chip)->unsol_work);
+
        /* HDA controller always requires different WAKEEN for runtime suspend
         * and system suspend, so don't use direct-complete here.
         */
index c966f49fa942a1ac6d3e7148b2294d163bee6a60..b2b620f6c832094efd4a70bb0dfea6fec21901ed 100644 (file)
@@ -1309,6 +1309,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
        SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
        SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
        SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
+       SND_PCI_QUIRK(0x1102, 0x0191, "Sound Blaster AE-5 Plus", QUIRK_AE5),
        SND_PCI_QUIRK(0x1102, 0x0081, "Sound Blaster AE-7", QUIRK_AE7),
        {}
 };
index f2aa226d1373d1c680ae99662f8047729dc0d71b..c20dad46a7c90314ad879cd9d9e291ca730756eb 100644 (file)
@@ -149,6 +149,21 @@ static int cx_auto_vmaster_mute_led(struct led_classdev *led_cdev,
        return 0;
 }
 
+static void cxt_init_gpio_led(struct hda_codec *codec)
+{
+       struct conexant_spec *spec = codec->spec;
+       unsigned int mask = spec->gpio_mute_led_mask | spec->gpio_mic_led_mask;
+
+       if (mask) {
+               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
+                                   mask);
+               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
+                                   mask);
+               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+                                   spec->gpio_led);
+       }
+}
+
 static int cx_auto_init(struct hda_codec *codec)
 {
        struct conexant_spec *spec = codec->spec;
@@ -156,6 +171,7 @@ static int cx_auto_init(struct hda_codec *codec)
        if (!spec->dynamic_eapd)
                cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
 
+       cxt_init_gpio_led(codec);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
 
        return 0;
@@ -215,6 +231,7 @@ enum {
        CXT_FIXUP_HP_SPECTRE,
        CXT_FIXUP_HP_GATE_MIC,
        CXT_FIXUP_MUTE_LED_GPIO,
+       CXT_FIXUP_HP_ZBOOK_MUTE_LED,
        CXT_FIXUP_HEADSET_MIC,
        CXT_FIXUP_HP_MIC_NO_PRESENCE,
 };
@@ -654,31 +671,36 @@ static int cxt_gpio_micmute_update(struct led_classdev *led_cdev,
        return 0;
 }
 
-
-static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
-                               const struct hda_fixup *fix, int action)
+static void cxt_setup_mute_led(struct hda_codec *codec,
+                              unsigned int mute, unsigned int mic_mute)
 {
        struct conexant_spec *spec = codec->spec;
-       static const struct hda_verb gpio_init[] = {
-               { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 },
-               { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 },
-               {}
-       };
 
-       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+       spec->gpio_led = 0;
+       spec->mute_led_polarity = 0;
+       if (mute) {
                snd_hda_gen_add_mute_led_cdev(codec, cxt_gpio_mute_update);
-               spec->gpio_led = 0;
-               spec->mute_led_polarity = 0;
-               spec->gpio_mute_led_mask = 0x01;
-               spec->gpio_mic_led_mask = 0x02;
+               spec->gpio_mute_led_mask = mute;
+       }
+       if (mic_mute) {
                snd_hda_gen_add_micmute_led_cdev(codec, cxt_gpio_micmute_update);
+               spec->gpio_mic_led_mask = mic_mute;
        }
-       snd_hda_add_verbs(codec, gpio_init);
-       if (spec->gpio_led)
-               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
-                                   spec->gpio_led);
 }
 
+static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
+                               const struct hda_fixup *fix, int action)
+{
+       if (action == HDA_FIXUP_ACT_PRE_PROBE)
+               cxt_setup_mute_led(codec, 0x01, 0x02);
+}
+
+static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec,
+                                       const struct hda_fixup *fix, int action)
+{
+       if (action == HDA_FIXUP_ACT_PRE_PROBE)
+               cxt_setup_mute_led(codec, 0x10, 0x20);
+}
 
 /* ThinkPad X200 & co with cxt5051 */
 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
@@ -839,6 +861,10 @@ static const struct hda_fixup cxt_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cxt_fixup_mute_led_gpio,
        },
+       [CXT_FIXUP_HP_ZBOOK_MUTE_LED] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cxt_fixup_hp_zbook_mute_led,
+       },
        [CXT_FIXUP_HEADSET_MIC] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cxt_fixup_headset_mic,
@@ -917,6 +943,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
+       SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
        SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x8456, "HP Z2 G4 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE),
@@ -956,6 +983,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
        { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" },
        { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" },
        { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" },
+       { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" },
        { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" },
        {}
 };
index e6d0843ee9df2aab82ae35372549c6d0452a3402..45ae845e82df6859ed880a88005824ce646d5664 100644 (file)
@@ -2480,6 +2480,18 @@ static void generic_hdmi_free(struct hda_codec *codec)
 }
 
 #ifdef CONFIG_PM
+static int generic_hdmi_suspend(struct hda_codec *codec)
+{
+       struct hdmi_spec *spec = codec->spec;
+       int pin_idx;
+
+       for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+               struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+               cancel_delayed_work_sync(&per_pin->work);
+       }
+       return 0;
+}
+
 static int generic_hdmi_resume(struct hda_codec *codec)
 {
        struct hdmi_spec *spec = codec->spec;
@@ -2503,6 +2515,7 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
        .build_controls         = generic_hdmi_build_controls,
        .unsol_event            = hdmi_unsol_event,
 #ifdef CONFIG_PM
+       .suspend                = generic_hdmi_suspend,
        .resume                 = generic_hdmi_resume,
 #endif
 };
index 85ed8507e41a21d10008dd72dc7c6a957f84e68e..b6f4c0848e6618584d8bd567ff93f740aa657517 100644 (file)
@@ -830,6 +830,9 @@ static int usb_audio_probe(struct usb_interface *intf,
                snd_media_device_create(chip, intf);
        }
 
+       if (quirk)
+               chip->quirk_type = quirk->type;
+
        usb_chip[chip->index] = chip;
        chip->intf[chip->num_interfaces] = intf;
        chip->num_interfaces++;
@@ -904,6 +907,9 @@ static void usb_audio_disconnect(struct usb_interface *intf)
                }
        }
 
+       if (chip->quirk_type & QUIRK_SETUP_DISABLE_AUTOSUSPEND)
+               usb_enable_autosuspend(interface_to_usbdev(intf));
+
        chip->num_interfaces--;
        if (chip->num_interfaces <= 0) {
                usb_chip[chip->index] = NULL;
index 737b2729c0d3790be07206c505a2e13a7b3f9da0..d3001fb18141fe02317a3056dd35e9b9b541db91 100644 (file)
@@ -547,7 +547,7 @@ static int setup_disable_autosuspend(struct snd_usb_audio *chip,
                                       struct usb_driver *driver,
                                       const struct snd_usb_audio_quirk *quirk)
 {
-       driver->supports_autosuspend = 0;
+       usb_disable_autosuspend(interface_to_usbdev(iface));
        return 1;       /* Continue with creating streams and mixer */
 }
 
@@ -1520,6 +1520,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
        case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
        case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
        case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */
+       case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */
                return true;
        }
 
@@ -1670,6 +1671,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
            && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
                msleep(20);
 
+       /*
+        * Plantronics headsets (C320, C320-M, etc) need a delay to avoid
+        * random microhpone failures.
+        */
+       if (USB_ID_VENDOR(chip->usb_id) == 0x047f &&
+           (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+               msleep(20);
+
        /* Zoom R16/24, many Logitech(at least H650e/H570e/BCC950),
         * Jabra 550a, Kingston HyperX needs a tiny delay here,
         * otherwise requests like get/set frequency return
index 215c1771dd570725671ceab9913ca2cdadc33126..60b9dd7df6bb76e5c3e8e7dbaadfe43f16ce5b0f 100644 (file)
@@ -27,6 +27,7 @@ struct snd_usb_audio {
        struct snd_card *card;
        struct usb_interface *intf[MAX_CARD_INTERFACES];
        u32 usb_id;
+       uint16_t quirk_type;
        struct mutex mutex;
        unsigned int system_suspend;
        atomic_t active;
index 543dd70e12c81d59a9987c437f1895a216c2525b..ad64d673b5e6bb6372bf4e9ec0694c47d469c90b 100644 (file)
 #define ACR_SIZE       4
 
 
-#define PTRACE_OLDSETOPTIONS        21
-
+#define PTRACE_OLDSETOPTIONS           21
+#define PTRACE_SYSEMU                  31
+#define PTRACE_SYSEMU_SINGLESTEP       32
 #ifndef __ASSEMBLY__
 #include <linux/stddef.h>
 #include <linux/types.h>
index 84b887825f126b75727809dcb37cd6c8b5739ff4..cc96e26d69f7ae9fa04ccdbc35d1f72f93d735a2 100644 (file)
@@ -13,7 +13,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS                       19         /* N 32-bit words worth of info */
+#define NCAPINTS                       20         /* N 32-bit words worth of info */
 #define NBUGINTS                       1          /* N 32-bit bug flags */
 
 /*
@@ -96,7 +96,7 @@
 #define X86_FEATURE_SYSCALL32          ( 3*32+14) /* "" syscall in IA32 userspace */
 #define X86_FEATURE_SYSENTER32         ( 3*32+15) /* "" sysenter in IA32 userspace */
 #define X86_FEATURE_REP_GOOD           ( 3*32+16) /* REP microcode works well */
-#define X86_FEATURE_SME_COHERENT       ( 3*32+17) /* "" AMD hardware-enforced cache coherency */
+/* FREE!                                ( 3*32+17) */
 #define X86_FEATURE_LFENCE_RDTSC       ( 3*32+18) /* "" LFENCE synchronizes RDTSC */
 #define X86_FEATURE_ACC_POWER          ( 3*32+19) /* AMD Accumulated Power Mechanism */
 #define X86_FEATURE_NOPL               ( 3*32+20) /* The NOPL (0F 1F) instructions */
 #define X86_FEATURE_INVPCID_SINGLE     ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */
 #define X86_FEATURE_HW_PSTATE          ( 7*32+ 8) /* AMD HW-PState */
 #define X86_FEATURE_PROC_FEEDBACK      ( 7*32+ 9) /* AMD ProcFeedbackInterface */
-#define X86_FEATURE_SME                        ( 7*32+10) /* AMD Secure Memory Encryption */
+/* FREE!                                ( 7*32+10) */
 #define X86_FEATURE_PTI                        ( 7*32+11) /* Kernel Page Table Isolation enabled */
 #define X86_FEATURE_RETPOLINE          ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
 #define X86_FEATURE_RETPOLINE_AMD      ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
 #define X86_FEATURE_SSBD               ( 7*32+17) /* Speculative Store Bypass Disable */
 #define X86_FEATURE_MBA                        ( 7*32+18) /* Memory Bandwidth Allocation */
 #define X86_FEATURE_RSB_CTXSW          ( 7*32+19) /* "" Fill RSB on context switches */
-#define X86_FEATURE_SEV                        ( 7*32+20) /* AMD Secure Encrypted Virtualization */
+/* FREE!                                ( 7*32+20) */
 #define X86_FEATURE_USE_IBPB           ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
 #define X86_FEATURE_USE_IBRS_FW                ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
 #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE  ( 7*32+23) /* "" Disable Speculative Store Bypass. */
 #define X86_FEATURE_EPT_AD             ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
 #define X86_FEATURE_VMCALL             ( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */
 #define X86_FEATURE_VMW_VMMCALL                ( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */
-#define X86_FEATURE_SEV_ES             ( 8*32+20) /* AMD Secure Encrypted Virtualization - Encrypted State */
-#define X86_FEATURE_VM_PAGE_FLUSH      ( 8*32+21) /* "" VM Page Flush MSR is supported */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE           ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
 #define X86_FEATURE_PER_THREAD_MBA     (11*32+ 7) /* "" Per-thread Memory Bandwidth Allocation */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+#define X86_FEATURE_AVX_VNNI           (12*32+ 4) /* AVX VNNI instructions */
 #define X86_FEATURE_AVX512_BF16                (12*32+ 5) /* AVX512 BFLOAT16 instructions */
 
 /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
 #define X86_FEATURE_AVIC               (15*32+13) /* Virtual Interrupt Controller */
 #define X86_FEATURE_V_VMSAVE_VMLOAD    (15*32+15) /* Virtual VMSAVE VMLOAD */
 #define X86_FEATURE_VGIF               (15*32+16) /* Virtual GIF */
+#define X86_FEATURE_SVME_ADDR_CHK      (15*32+28) /* "" SVME addr check */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ECX), word 16 */
 #define X86_FEATURE_AVX512VBMI         (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
 #define X86_FEATURE_CORE_CAPABILITIES  (18*32+30) /* "" IA32_CORE_CAPABILITIES MSR */
 #define X86_FEATURE_SPEC_CTRL_SSBD     (18*32+31) /* "" Speculative Store Bypass Disable */
 
+/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
+#define X86_FEATURE_SME                        (19*32+ 0) /* AMD Secure Memory Encryption */
+#define X86_FEATURE_SEV                        (19*32+ 1) /* AMD Secure Encrypted Virtualization */
+#define X86_FEATURE_VM_PAGE_FLUSH      (19*32+ 2) /* "" VM Page Flush MSR is supported */
+#define X86_FEATURE_SEV_ES             (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */
+#define X86_FEATURE_SME_COHERENT       (19*32+10) /* "" AMD hardware-enforced cache coherency */
+
 /*
  * BUG word(s)
  */
index 8e76d3701db3f2432c91c9bd32623202547593b1..5a3022c8af82b8af1b88e5ed9d8b9af8afc5c9dd 100644 (file)
@@ -112,6 +112,7 @@ struct kvm_ioapic_state {
 #define KVM_NR_IRQCHIPS          3
 
 #define KVM_RUN_X86_SMM                 (1 << 0)
+#define KVM_RUN_X86_BUS_LOCK     (1 << 1)
 
 /* for KVM_GET_REGS and KVM_SET_REGS */
 struct kvm_regs {
index ada955c5ebb6055d7d71d12e20f578dfe6d1ab91..b8e650a985e358f9ef91c140d910a781f93edd7b 100644 (file)
@@ -89,6 +89,7 @@
 #define EXIT_REASON_XRSTORS             64
 #define EXIT_REASON_UMWAIT              67
 #define EXIT_REASON_TPAUSE              68
+#define EXIT_REASON_BUS_LOCK            74
 
 #define VMX_EXIT_REASONS \
        { EXIT_REASON_EXCEPTION_NMI,         "EXCEPTION_NMI" }, \
        { EXIT_REASON_XSAVES,                "XSAVES" }, \
        { EXIT_REASON_XRSTORS,               "XRSTORS" }, \
        { EXIT_REASON_UMWAIT,                "UMWAIT" }, \
-       { EXIT_REASON_TPAUSE,                "TPAUSE" }
+       { EXIT_REASON_TPAUSE,                "TPAUSE" }, \
+       { EXIT_REASON_BUS_LOCK,              "BUS_LOCK" }
 
 #define VMX_EXIT_REASON_FLAGS \
        { VMX_EXIT_REASONS_FAILED_VMENTRY,      "FAILED_VMENTRY" }
index 7409d7860aa6c3167b6a9e282f4e046b06e6b91f..80d966cfcaa1461e2fb6199f8806dd578b0cf2bb 100644 (file)
@@ -260,6 +260,11 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
        return btf_id__add(root, id, false);
 }
 
+/* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */
+#ifndef SHF_COMPRESSED
+#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
+#endif
+
 /*
  * The data of compressed section should be aligned to 4
  * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
index bae48e6fa9952accdb6b61596020d74371e2f42c..5ed41b96fcdedabac4de5127da70322f5b8de961 100644 (file)
@@ -30,12 +30,18 @@ build     := -f $(srctree)/tools/build/Makefile.build dir=. obj
 
 all: $(OUTPUT)fixdep
 
+# Make sure there's anything to clean,
+# feature contains check for existing OUTPUT
+TMP_O := $(if $(OUTPUT),$(OUTPUT)/feature,./)
+
 clean:
        $(call QUIET_CLEAN, fixdep)
        $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
        $(Q)rm -f $(OUTPUT)fixdep
        $(call QUIET_CLEAN, feature-detect)
-       $(Q)$(MAKE) -C feature/ clean >/dev/null
+ifneq ($(wildcard $(TMP_O)),)
+       $(Q)$(MAKE) -C feature OUTPUT=$(TMP_O) clean >/dev/null
+endif
 
 $(OUTPUT)fixdep-in.o: FORCE
        $(Q)$(MAKE) $(build)=fixdep
index b0e35eec6499bf4367da462c1f180c77821336e2..4ac5c081af93d729757bffaaad40bdb7076d05a4 100644 (file)
 #define CORESIGHT_ETM_PMU_NAME "cs_etm"
 #define CORESIGHT_ETM_PMU_SEED  0x10
 
-/* ETMv3.5/PTM's ETMCR config bit */
-#define ETM_OPT_CYCACC  12
-#define ETM_OPT_CTXTID 14
-#define ETM_OPT_TS      28
-#define ETM_OPT_RETSTK 29
+/*
+ * Below are the definition of bit offsets for perf option, and works as
+ * arbitrary values for all ETM versions.
+ *
+ * Most of them are orignally from ETMv3.5/PTM's ETMCR config, therefore,
+ * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
+ * directly use below macros as config bits.
+ */
+#define ETM_OPT_CYCACC         12
+#define ETM_OPT_CTXTID         14
+#define ETM_OPT_CTXTID2                15
+#define ETM_OPT_TS             28
+#define ETM_OPT_RETSTK         29
 
 /* ETMv4 CONFIGR programming bits for the ETM OPTs */
 #define ETM4_CFG_BIT_CYCACC    4
 #define ETM4_CFG_BIT_CTXTID    6
+#define ETM4_CFG_BIT_VMID      7
 #define ETM4_CFG_BIT_TS                11
 #define ETM4_CFG_BIT_RETSTK    12
+#define ETM4_CFG_BIT_VMID_OPT  15
 
 static inline int coresight_get_trace_id(int cpu)
 {
index 808b48a93330bad83759a3cd81331f812296a12a..0827037c54847898c6771146c5ac285d57849ede 100644 (file)
@@ -1,11 +1,10 @@
-/**
- * \file drm.h
+/*
  * Header for the Direct Rendering Manager
  *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * Author: Rickard E. (Rik) Faith <faith@valinux.com>
  *
- * \par Acknowledgments:
- * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
+ * Acknowledgments:
+ * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
  */
 
 /*
@@ -85,7 +84,7 @@ typedef unsigned int drm_context_t;
 typedef unsigned int drm_drawable_t;
 typedef unsigned int drm_magic_t;
 
-/**
+/*
  * Cliprect.
  *
  * \warning: If you change this structure, make sure you change
@@ -101,7 +100,7 @@ struct drm_clip_rect {
        unsigned short y2;
 };
 
-/**
+/*
  * Drawable information.
  */
 struct drm_drawable_info {
@@ -109,7 +108,7 @@ struct drm_drawable_info {
        struct drm_clip_rect *rects;
 };
 
-/**
+/*
  * Texture region,
  */
 struct drm_tex_region {
@@ -120,7 +119,7 @@ struct drm_tex_region {
        unsigned int age;
 };
 
-/**
+/*
  * Hardware lock.
  *
  * The lock structure is a simple cache-line aligned integer.  To avoid
@@ -132,7 +131,7 @@ struct drm_hw_lock {
        char padding[60];                       /**< Pad to cache line */
 };
 
-/**
+/*
  * DRM_IOCTL_VERSION ioctl argument type.
  *
  * \sa drmGetVersion().
@@ -149,7 +148,7 @@ struct drm_version {
        char __user *desc;        /**< User-space buffer to hold desc */
 };
 
-/**
+/*
  * DRM_IOCTL_GET_UNIQUE ioctl argument type.
  *
  * \sa drmGetBusid() and drmSetBusId().
@@ -168,7 +167,7 @@ struct drm_block {
        int unused;
 };
 
-/**
+/*
  * DRM_IOCTL_CONTROL ioctl argument type.
  *
  * \sa drmCtlInstHandler() and drmCtlUninstHandler().
@@ -183,7 +182,7 @@ struct drm_control {
        int irq;
 };
 
-/**
+/*
  * Type of memory to map.
  */
 enum drm_map_type {
@@ -195,7 +194,7 @@ enum drm_map_type {
        _DRM_CONSISTENT = 5       /**< Consistent memory for PCI DMA */
 };
 
-/**
+/*
  * Memory mapping flags.
  */
 enum drm_map_flags {
@@ -214,7 +213,7 @@ struct drm_ctx_priv_map {
        void *handle;            /**< Handle of map */
 };
 
-/**
+/*
  * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
  * argument type.
  *
@@ -231,7 +230,7 @@ struct drm_map {
        /*   Private data */
 };
 
-/**
+/*
  * DRM_IOCTL_GET_CLIENT ioctl argument type.
  */
 struct drm_client {
@@ -263,7 +262,7 @@ enum drm_stat_type {
            /* Add to the *END* of the list */
 };
 
-/**
+/*
  * DRM_IOCTL_GET_STATS ioctl argument type.
  */
 struct drm_stats {
@@ -274,7 +273,7 @@ struct drm_stats {
        } data[15];
 };
 
-/**
+/*
  * Hardware locking flags.
  */
 enum drm_lock_flags {
@@ -289,7 +288,7 @@ enum drm_lock_flags {
        _DRM_HALT_CUR_QUEUES = 0x20  /**< Halt all current queues */
 };
 
-/**
+/*
  * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
  *
  * \sa drmGetLock() and drmUnlock().
@@ -299,7 +298,7 @@ struct drm_lock {
        enum drm_lock_flags flags;
 };
 
-/**
+/*
  * DMA flags
  *
  * \warning
@@ -328,7 +327,7 @@ enum drm_dma_flags {
        _DRM_DMA_LARGER_OK = 0x40     /**< Larger-than-requested buffers OK */
 };
 
-/**
+/*
  * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
  *
  * \sa drmAddBufs().
@@ -351,7 +350,7 @@ struct drm_buf_desc {
                                  */
 };
 
-/**
+/*
  * DRM_IOCTL_INFO_BUFS ioctl argument type.
  */
 struct drm_buf_info {
@@ -359,7 +358,7 @@ struct drm_buf_info {
        struct drm_buf_desc __user *list;
 };
 
-/**
+/*
  * DRM_IOCTL_FREE_BUFS ioctl argument type.
  */
 struct drm_buf_free {
@@ -367,7 +366,7 @@ struct drm_buf_free {
        int __user *list;
 };
 
-/**
+/*
  * Buffer information
  *
  * \sa drm_buf_map.
@@ -379,7 +378,7 @@ struct drm_buf_pub {
        void __user *address;          /**< Address of buffer */
 };
 
-/**
+/*
  * DRM_IOCTL_MAP_BUFS ioctl argument type.
  */
 struct drm_buf_map {
@@ -392,7 +391,7 @@ struct drm_buf_map {
        struct drm_buf_pub __user *list;        /**< Buffer information */
 };
 
-/**
+/*
  * DRM_IOCTL_DMA ioctl argument type.
  *
  * Indices here refer to the offset into the buffer list in drm_buf_get.
@@ -417,7 +416,7 @@ enum drm_ctx_flags {
        _DRM_CONTEXT_2DONLY = 0x02
 };
 
-/**
+/*
  * DRM_IOCTL_ADD_CTX ioctl argument type.
  *
  * \sa drmCreateContext() and drmDestroyContext().
@@ -427,7 +426,7 @@ struct drm_ctx {
        enum drm_ctx_flags flags;
 };
 
-/**
+/*
  * DRM_IOCTL_RES_CTX ioctl argument type.
  */
 struct drm_ctx_res {
@@ -435,14 +434,14 @@ struct drm_ctx_res {
        struct drm_ctx __user *contexts;
 };
 
-/**
+/*
  * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
  */
 struct drm_draw {
        drm_drawable_t handle;
 };
 
-/**
+/*
  * DRM_IOCTL_UPDATE_DRAW ioctl argument type.
  */
 typedef enum {
@@ -456,14 +455,14 @@ struct drm_update_draw {
        unsigned long long data;
 };
 
-/**
+/*
  * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
  */
 struct drm_auth {
        drm_magic_t magic;
 };
 
-/**
+/*
  * DRM_IOCTL_IRQ_BUSID ioctl argument type.
  *
  * \sa drmGetInterruptFromBusID().
@@ -505,7 +504,7 @@ struct drm_wait_vblank_reply {
        long tval_usec;
 };
 
-/**
+/*
  * DRM_IOCTL_WAIT_VBLANK ioctl argument type.
  *
  * \sa drmWaitVBlank().
@@ -518,7 +517,7 @@ union drm_wait_vblank {
 #define _DRM_PRE_MODESET 1
 #define _DRM_POST_MODESET 2
 
-/**
+/*
  * DRM_IOCTL_MODESET_CTL ioctl argument type
  *
  * \sa drmModesetCtl().
@@ -528,7 +527,7 @@ struct drm_modeset_ctl {
        __u32 cmd;
 };
 
-/**
+/*
  * DRM_IOCTL_AGP_ENABLE ioctl argument type.
  *
  * \sa drmAgpEnable().
@@ -537,7 +536,7 @@ struct drm_agp_mode {
        unsigned long mode;     /**< AGP mode */
 };
 
-/**
+/*
  * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
  *
  * \sa drmAgpAlloc() and drmAgpFree().
@@ -549,7 +548,7 @@ struct drm_agp_buffer {
        unsigned long physical; /**< Physical used by i810 */
 };
 
-/**
+/*
  * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
  *
  * \sa drmAgpBind() and drmAgpUnbind().
@@ -559,7 +558,7 @@ struct drm_agp_binding {
        unsigned long offset;   /**< In bytes -- will round to page boundary */
 };
 
-/**
+/*
  * DRM_IOCTL_AGP_INFO ioctl argument type.
  *
  * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
@@ -580,7 +579,7 @@ struct drm_agp_info {
        unsigned short id_device;
 };
 
-/**
+/*
  * DRM_IOCTL_SG_ALLOC ioctl argument type.
  */
 struct drm_scatter_gather {
@@ -588,7 +587,7 @@ struct drm_scatter_gather {
        unsigned long handle;   /**< Used for mapping / unmapping */
 };
 
-/**
+/*
  * DRM_IOCTL_SET_VERSION ioctl argument type.
  */
 struct drm_set_version {
@@ -598,14 +597,14 @@ struct drm_set_version {
        int drm_dd_minor;
 };
 
-/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
+/* DRM_IOCTL_GEM_CLOSE ioctl argument type */
 struct drm_gem_close {
        /** Handle of the object to be closed. */
        __u32 handle;
        __u32 pad;
 };
 
-/** DRM_IOCTL_GEM_FLINK ioctl argument type */
+/* DRM_IOCTL_GEM_FLINK ioctl argument type */
 struct drm_gem_flink {
        /** Handle for the object being named */
        __u32 handle;
@@ -614,7 +613,7 @@ struct drm_gem_flink {
        __u32 name;
 };
 
-/** DRM_IOCTL_GEM_OPEN ioctl argument type */
+/* DRM_IOCTL_GEM_OPEN ioctl argument type */
 struct drm_gem_open {
        /** Name of object being opened */
        __u32 name;
@@ -652,7 +651,7 @@ struct drm_gem_open {
 #define DRM_CAP_SYNCOBJ                0x13
 #define DRM_CAP_SYNCOBJ_TIMELINE       0x14
 
-/** DRM_IOCTL_GET_CAP ioctl argument type */
+/* DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
        __u64 capability;
        __u64 value;
@@ -678,7 +677,9 @@ struct drm_get_cap {
 /**
  * DRM_CLIENT_CAP_ATOMIC
  *
- * If set to 1, the DRM core will expose atomic properties to userspace
+ * If set to 1, the DRM core will expose atomic properties to userspace. This
+ * implicitly enables &DRM_CLIENT_CAP_UNIVERSAL_PLANES and
+ * &DRM_CLIENT_CAP_ASPECT_RATIO.
  */
 #define DRM_CLIENT_CAP_ATOMIC  3
 
@@ -698,7 +699,7 @@ struct drm_get_cap {
  */
 #define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS    5
 
-/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
+/* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
 struct drm_set_client_cap {
        __u64 capability;
        __u64 value;
@@ -950,7 +951,7 @@ extern "C" {
 
 #define DRM_IOCTL_MODE_GETFB2          DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
 
-/**
+/*
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
  * Generic IOCTLS restart at 0xA0.
@@ -961,7 +962,7 @@ extern "C" {
 #define DRM_COMMAND_BASE                0x40
 #define DRM_COMMAND_END                        0xA0
 
-/**
+/*
  * Header for events written back to userspace on the drm fd.  The
  * type defines the type of event, the length specifies the total
  * length of the event (including the header), and user_data is
index fa1f3d62f9a6cebb300c63bf82955af91ab2a6ed..1987e2ea79a3b86263529b5d3207ac89c767e6fd 100644 (file)
@@ -177,8 +177,9 @@ enum drm_i915_pmu_engine_sample {
 #define I915_PMU_REQUESTED_FREQUENCY   __I915_PMU_OTHER(1)
 #define I915_PMU_INTERRUPTS            __I915_PMU_OTHER(2)
 #define I915_PMU_RC6_RESIDENCY         __I915_PMU_OTHER(3)
+#define I915_PMU_SOFTWARE_GT_AWAKE_TIME        __I915_PMU_OTHER(4)
 
-#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
+#define I915_PMU_LAST /* Deprecated - do not use */ I915_PMU_RC6_RESIDENCY
 
 /* Each region is a minimum of 16k, and there are at most 255 of them.
  */
index 4c24daa43bacc601cd3fc5ca8eeda3614bb45344..79c893310492b33689352b9dff5f53a42dd9d72b 100644 (file)
@@ -3850,7 +3850,6 @@ union bpf_attr {
  *
  * long bpf_check_mtu(void *ctx, u32 ifindex, u32 *mtu_len, s32 len_diff, u64 flags)
  *     Description
-
  *             Check ctx packet size against exceeding MTU of net device (based
  *             on *ifindex*).  This helper will likely be used in combination
  *             with helpers that adjust/change the packet size.
index abb89bbe563544034496af2271d77622aca86381..8b281f722e5bd8f098a384dd9f00c5115ad497d7 100644 (file)
@@ -216,6 +216,20 @@ struct kvm_hyperv_exit {
        } u;
 };
 
+struct kvm_xen_exit {
+#define KVM_EXIT_XEN_HCALL          1
+       __u32 type;
+       union {
+               struct {
+                       __u32 longmode;
+                       __u32 cpl;
+                       __u64 input;
+                       __u64 result;
+                       __u64 params[6];
+               } hcall;
+       } u;
+};
+
 #define KVM_S390_GET_SKEYS_NONE   1
 #define KVM_S390_SKEYS_MAX        1048576
 
@@ -252,6 +266,8 @@ struct kvm_hyperv_exit {
 #define KVM_EXIT_X86_WRMSR        30
 #define KVM_EXIT_DIRTY_RING_FULL  31
 #define KVM_EXIT_AP_RESET_HOLD    32
+#define KVM_EXIT_X86_BUS_LOCK     33
+#define KVM_EXIT_XEN              34
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -428,6 +444,8 @@ struct kvm_run {
                        __u32 index; /* kernel -> user */
                        __u64 data; /* kernel <-> user */
                } msr;
+               /* KVM_EXIT_XEN */
+               struct kvm_xen_exit xen;
                /* Fix the size of the union. */
                char padding[256];
        };
@@ -1058,6 +1076,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ENFORCE_PV_FEATURE_CPUID 190
 #define KVM_CAP_SYS_HYPERV_CPUID 191
 #define KVM_CAP_DIRTY_LOG_RING 192
+#define KVM_CAP_X86_BUS_LOCK_EXIT 193
 #define KVM_CAP_PPC_DAWR1 194
 
 #ifdef KVM_CAP_IRQ_ROUTING
@@ -1132,6 +1151,10 @@ struct kvm_x86_mce {
 #endif
 
 #ifdef KVM_CAP_XEN_HVM
+#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR       (1 << 0)
+#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL     (1 << 1)
+#define KVM_XEN_HVM_CONFIG_SHARED_INFO         (1 << 2)
+
 struct kvm_xen_hvm_config {
        __u32 flags;
        __u32 msr;
@@ -1566,6 +1589,45 @@ struct kvm_pv_cmd {
 /* Available with KVM_CAP_DIRTY_LOG_RING */
 #define KVM_RESET_DIRTY_RINGS          _IO(KVMIO, 0xc7)
 
+/* Per-VM Xen attributes */
+#define KVM_XEN_HVM_GET_ATTR   _IOWR(KVMIO, 0xc8, struct kvm_xen_hvm_attr)
+#define KVM_XEN_HVM_SET_ATTR   _IOW(KVMIO,  0xc9, struct kvm_xen_hvm_attr)
+
+struct kvm_xen_hvm_attr {
+       __u16 type;
+       __u16 pad[3];
+       union {
+               __u8 long_mode;
+               __u8 vector;
+               struct {
+                       __u64 gfn;
+               } shared_info;
+               __u64 pad[8];
+       } u;
+};
+
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
+#define KVM_XEN_ATTR_TYPE_LONG_MODE            0x0
+#define KVM_XEN_ATTR_TYPE_SHARED_INFO          0x1
+#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR                0x2
+
+/* Per-vCPU Xen attributes */
+#define KVM_XEN_VCPU_GET_ATTR  _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr)
+#define KVM_XEN_VCPU_SET_ATTR  _IOW(KVMIO,  0xcb, struct kvm_xen_vcpu_attr)
+
+struct kvm_xen_vcpu_attr {
+       __u16 type;
+       __u16 pad[3];
+       union {
+               __u64 gpa;
+               __u64 pad[8];
+       } u;
+};
+
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO       0x0
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO  0x1
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
        /* Guest initialization commands */
@@ -1594,6 +1656,8 @@ enum sev_cmd_id {
        KVM_SEV_DBG_ENCRYPT,
        /* Guest certificates commands */
        KVM_SEV_CERT_EXPORT,
+       /* Attestation report */
+       KVM_SEV_GET_ATTESTATION_REPORT,
 
        KVM_SEV_NR_MAX,
 };
@@ -1646,6 +1710,12 @@ struct kvm_sev_dbg {
        __u32 len;
 };
 
+struct kvm_sev_attestation_report {
+       __u8 mnonce[16];
+       __u64 uaddr;
+       __u32 len;
+};
+
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU    (1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3         (1 << 1)
 #define KVM_DEV_ASSIGN_MASK_INTX       (1 << 2)
@@ -1767,4 +1837,7 @@ struct kvm_dirty_gfn {
        __u64 offset;
 };
 
+#define KVM_BUS_LOCK_DETECTION_OFF             (1 << 0)
+#define KVM_BUS_LOCK_DETECTION_EXIT            (1 << 1)
+
 #endif /* __LINUX_KVM_H */
index dd8306ea336c19b695fa9a748c14f5ad92fe3e63..e6524ead2b7b9ead2cd5fa20435dd0ce2ecbe158 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _UAPI_LINUX_MOUNT_H
 #define _UAPI_LINUX_MOUNT_H
 
+#include <linux/types.h>
+
 /*
  * These are the fs-independent mount-flags: up to 32 flags are supported
  *
@@ -117,5 +119,19 @@ enum fsconfig_command {
 #define MOUNT_ATTR_NOATIME     0x00000010 /* - Do not update access times. */
 #define MOUNT_ATTR_STRICTATIME 0x00000020 /* - Always perform atime updates */
 #define MOUNT_ATTR_NODIRATIME  0x00000080 /* Do not update directory access times */
+#define MOUNT_ATTR_IDMAP       0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
+
+/*
+ * mount_setattr()
+ */
+struct mount_attr {
+       __u64 attr_set;
+       __u64 attr_clr;
+       __u64 propagation;
+       __u64 userns_fd;
+};
+
+/* List of all mount_attr versions. */
+#define MOUNT_ATTR_SIZE_VER0   32 /* sizeof first published struct */
 
 #endif /* _UAPI_LINUX_MOUNT_H */
index 58b1eb71136007727e8535eaeb19e2ea4a00fb9a..a5feb7604948791c7a34ec0876c24a97eb5a375b 100644 (file)
@@ -35,5 +35,9 @@ struct open_how {
 #define RESOLVE_IN_ROOT                0x10 /* Make all jumps to "/" and ".."
                                        be scoped inside the dirfd
                                        (similar to chroot(2)). */
+#define RESOLVE_CACHED         0x20 /* Only complete if resolution can be
+                                       completed through cached lookup. May
+                                       return -EAGAIN if that's not
+                                       possible. */
 
 #endif /* _UAPI_LINUX_OPENAT2_H */
index ffbb588724d8fc79bae9fd7ff8182b9eb649808f..526fc35c0b23318621ec9e70169192a776bcb499 100644 (file)
@@ -610,15 +610,16 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
                if (fd < 0)
                        continue;
 
+               memset(&map_info, 0, map_len);
                err = bpf_obj_get_info_by_fd(fd, &map_info, &map_len);
                if (err) {
                        close(fd);
                        continue;
                }
 
-               if (!strcmp(map_info.name, "xsks_map")) {
+               if (!strncmp(map_info.name, "xsks_map", sizeof(map_info.name))) {
                        ctx->xsks_map_fd = fd;
-                       continue;
+                       break;
                }
 
                close(fd);
index 17465d454a0e31d912f7d0782d3f0bc19b6bfcdd..a0aaf385cbb5855e48a46d37c49209a23c0c162e 100644 (file)
 
 void perf_evlist__init(struct perf_evlist *evlist)
 {
-       int i;
-
-       for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
-               INIT_HLIST_HEAD(&evlist->heads[i]);
        INIT_LIST_HEAD(&evlist->entries);
        evlist->nr_entries = 0;
        fdarray__init(&evlist->pollfd, 64);
+       perf_evlist__reset_id_hash(evlist);
 }
 
 static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
@@ -237,6 +234,14 @@ static void perf_evlist__id_hash(struct perf_evlist *evlist,
        hlist_add_head(&sid->node, &evlist->heads[hash]);
 }
 
+void perf_evlist__reset_id_hash(struct perf_evlist *evlist)
+{
+       int i;
+
+       for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
+               INIT_HLIST_HEAD(&evlist->heads[i]);
+}
+
 void perf_evlist__id_add(struct perf_evlist *evlist,
                         struct perf_evsel *evsel,
                         int cpu, int thread, u64 id)
index 2d0fa02b036f604646663ca5703bd13c12a00ae2..212c29063ad42ccc7891e5e17446ef6ab1827ef9 100644 (file)
@@ -124,4 +124,6 @@ int perf_evlist__id_add_fd(struct perf_evlist *evlist,
                           struct perf_evsel *evsel,
                           int cpu, int thread, int fd);
 
+void perf_evlist__reset_id_hash(struct perf_evlist *evlist);
+
 #endif /* __LIBPERF_INTERNAL_EVLIST_H */
index c0a66400a960d68cbf73690f608867f648d79797..9af8b8dfb7b60efb9491044ba8ded317a3f109eb 100644 (file)
@@ -29,7 +29,7 @@ OPTIONS
        Show just the sample frequency used for each event.
 
 -v::
---verbose=::
+--verbose::
        Show all fields.
 
 -g::
index 1e91121bac0f3815c3f3f9ba19e36ef8a5fca170..6e82b7cc0bf0f510d41168aed9b9eba16d6b3df2 100644 (file)
@@ -28,8 +28,8 @@ OPTIONS
        specified: function_graph or function.
 
 -v::
---verbose=::
-        Verbosity level.
+--verbose::
+        Increase the verbosity level.
 
 -F::
 --funcs::
index f3c620951f6eb945a211db4c7cb58156c9492c9c..c97527df8ecd26050a0db309870ef2e80bb398fc 100644 (file)
@@ -20,5 +20,5 @@ modules).
 OPTIONS
 -------
 -v::
---verbose=::
+--verbose::
        Increase verbosity level, showing details about symbol table loading, etc.
index abc9b5d833128c2bc803fd344308ff3059ea1a12..f0da8cf63e9a965a1ee162dc39559f8f172680e2 100644 (file)
@@ -97,8 +97,8 @@ filter out the startup phase of the program, which is often very different.
        Filter out events for these pids and for 'trace' itself (comma separated list).
 
 -v::
---verbose=::
-        Verbosity level.
+--verbose::
+        Increase the verbosity level.
 
 --no-inherit::
        Child tasks do not inherit counters.
index 5345ac70cd83250e4c2642ac9b44652e79c3b568..f6e609673de2b816850c6bff1f09ced894ac643e 100644 (file)
@@ -607,7 +607,7 @@ arch_errno_hdr_dir := $(srctree)/tools
 arch_errno_tbl := $(srctree)/tools/perf/trace/beauty/arch_errno_names.sh
 
 $(arch_errno_name_array): $(arch_errno_tbl)
-       $(Q)$(SHELL) '$(arch_errno_tbl)' $(firstword $(CC)) $(arch_errno_hdr_dir) > $@
+       $(Q)$(SHELL) '$(arch_errno_tbl)' '$(patsubst -%,,$(CC))' $(arch_errno_hdr_dir) > $@
 
 sync_file_range_arrays := $(beauty_outdir)/sync_file_range_arrays.c
 sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
@@ -1001,14 +1001,6 @@ $(INSTALL_DOC_TARGETS):
 
 ### Cleaning rules
 
-#
-# This is here, not in Makefile.config, because Makefile.config does
-# not get included for the clean target:
-#
-config-clean:
-       $(call QUIET_CLEAN, config)
-       $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
-
 python-clean:
        $(python-clean)
 
@@ -1048,7 +1040,7 @@ endif # BUILD_BPF_SKEL
 bpf-skel-clean:
        $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
 
-clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean config-clean fixdep-clean python-clean bpf-skel-clean
+clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
        $(call QUIET_CLEAN, core-objs)  $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
        $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
        $(Q)$(RM) $(OUTPUT).config-detected
index bd446aba64f7272daea834e7360fc071b888a7a5..c25c878fd06c97dde942b0311f231e997c05ea4e 100644 (file)
@@ -156,6 +156,10 @@ out:
        return err;
 }
 
+#define ETM_SET_OPT_CTXTID     (1 << 0)
+#define ETM_SET_OPT_TS         (1 << 1)
+#define ETM_SET_OPT_MASK       (ETM_SET_OPT_CTXTID | ETM_SET_OPT_TS)
+
 static int cs_etm_set_option(struct auxtrace_record *itr,
                             struct evsel *evsel, u32 option)
 {
@@ -169,17 +173,17 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
                    !cpu_map__has(online_cpus, i))
                        continue;
 
-               if (option & ETM_OPT_CTXTID) {
+               if (option & ETM_SET_OPT_CTXTID) {
                        err = cs_etm_set_context_id(itr, evsel, i);
                        if (err)
                                goto out;
                }
-               if (option & ETM_OPT_TS) {
+               if (option & ETM_SET_OPT_TS) {
                        err = cs_etm_set_timestamp(itr, evsel, i);
                        if (err)
                                goto out;
                }
-               if (option & ~(ETM_OPT_CTXTID | ETM_OPT_TS))
+               if (option & ~(ETM_SET_OPT_MASK))
                        /* Nothing else is currently supported */
                        goto out;
        }
@@ -406,7 +410,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
                evsel__set_sample_bit(cs_etm_evsel, CPU);
 
                err = cs_etm_set_option(itr, cs_etm_evsel,
-                                       ETM_OPT_CTXTID | ETM_OPT_TS);
+                                       ETM_SET_OPT_CTXTID | ETM_SET_OPT_TS);
                if (err)
                        goto out;
        }
index f744eb5cba887d398e150e9ef9fbb1293d5fe08f..0b2480cf3e4793bdedf18942696d8b2f118aa564 100644 (file)
@@ -9,9 +9,7 @@
 #
 0      nospu   restart_syscall                 sys_restart_syscall
 1      nospu   exit                            sys_exit
-2      32      fork                            ppc_fork                        sys_fork
-2      64      fork                            sys_fork
-2      spu     fork                            sys_ni_syscall
+2      nospu   fork                            sys_fork
 3      common  read                            sys_read
 4      common  write                           sys_write
 5      common  open                            sys_open                        compat_sys_open
 119    32      sigreturn                       sys_sigreturn                   compat_sys_sigreturn
 119    64      sigreturn                       sys_ni_syscall
 119    spu     sigreturn                       sys_ni_syscall
-120    32      clone                           ppc_clone                       sys_clone
-120    64      clone                           sys_clone
-120    spu     clone                           sys_ni_syscall
+120    nospu   clone                           sys_clone
 121    common  setdomainname                   sys_setdomainname
 122    common  uname                           sys_newuname
 123    common  modify_ldt                      sys_ni_syscall
 186    spu     sendfile                        sys_sendfile64
 187    common  getpmsg                         sys_ni_syscall
 188    common  putpmsg                         sys_ni_syscall
-189    32      vfork                           ppc_vfork                       sys_vfork
-189    64      vfork                           sys_vfork
-189    spu     vfork                           sys_ni_syscall
+189    nospu   vfork                           sys_vfork
 190    common  ugetrlimit                      sys_getrlimit                   compat_sys_getrlimit
 191    common  readahead                       sys_readahead                   compat_sys_readahead
 192    32      mmap2                           sys_mmap2                       compat_sys_mmap2
 248    32      clock_nanosleep                 sys_clock_nanosleep_time32
 248    64      clock_nanosleep                 sys_clock_nanosleep
 248    spu     clock_nanosleep                 sys_clock_nanosleep
-249    32      swapcontext                     ppc_swapcontext                 compat_sys_swapcontext
-249    64      swapcontext                     sys_swapcontext
-249    spu     swapcontext                     sys_ni_syscall
+249    nospu   swapcontext                     sys_swapcontext                 compat_sys_swapcontext
 250    common  tgkill                          sys_tgkill
 251    32      utimes                          sys_utimes_time32
 251    64      utimes                          sys_utimes
 432    common  fsmount                         sys_fsmount
 433    common  fspick                          sys_fspick
 434    common  pidfd_open                      sys_pidfd_open
-435    32      clone3                          ppc_clone3                      sys_clone3
-435    64      clone3                          sys_clone3
-435    spu     clone3                          sys_ni_syscall
+435    nospu   clone3                          sys_clone3
 436    common  close_range                     sys_close_range
 437    common  openat2                         sys_openat2
 438    common  pidfd_getfd                     sys_pidfd_getfd
 439    common  faccessat2                      sys_faccessat2
 440    common  process_madvise                 sys_process_madvise
 441    common  epoll_pwait2                    sys_epoll_pwait2                compat_sys_epoll_pwait2
+442    common  mount_setattr                   sys_mount_setattr
index d443423495e565e49a8e57527f00dfdd4ffbea17..3abef2144dac79b69b25852ce28ffb2e5b284afe 100644 (file)
 439  common    faccessat2              sys_faccessat2                  sys_faccessat2
 440  common    process_madvise         sys_process_madvise             sys_process_madvise
 441  common    epoll_pwait2            sys_epoll_pwait2                compat_sys_epoll_pwait2
+442  common    mount_setattr           sys_mount_setattr               sys_mount_setattr
index 8cc6642fce7a6699e3e3fd816ced37d7ae627f5a..5a9f9a7bf07d1750c4a868cd6e19f33632c30d6e 100644 (file)
@@ -10,10 +10,11 @@ PERF_HAVE_JITDUMP := 1
 # Syscall table generation
 #
 
-out    := $(OUTPUT)arch/x86/include/generated/asm
-header := $(out)/syscalls_64.c
-sys    := $(srctree)/tools/perf/arch/x86/entry/syscalls
-systbl := $(sys)/syscalltbl.sh
+generated := $(OUTPUT)arch/x86/include/generated
+out       := $(generated)/asm
+header    := $(out)/syscalls_64.c
+sys       := $(srctree)/tools/perf/arch/x86/entry/syscalls
+systbl    := $(sys)/syscalltbl.sh
 
 # Create output directory if not already present
 _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
@@ -22,6 +23,6 @@ $(header): $(sys)/syscall_64.tbl $(systbl)
        $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
 
 clean::
-       $(call QUIET_CLEAN, x86) $(RM) $(header)
+       $(call QUIET_CLEAN, x86) $(RM) -r $(header) $(generated)
 
 archheaders: $(header)
index 78672124d28be0da465300ee9a301bab59c1ac1d..7bf01cbe582f03bc26adb4092bb9023384ec217f 100644 (file)
 439    common  faccessat2              sys_faccessat2
 440    common  process_madvise         sys_process_madvise
 441    common  epoll_pwait2            sys_epoll_pwait2
+442    common  mount_setattr           sys_mount_setattr
 
 #
 # Due to a historical design error, certain syscalls are numbered differently
index 6a54b94f1c25b4c2798861e9662e0c957b4d5ce9..0e20f3dc69f3c847a1047f8a03f9852d1b3c0f6d 100644 (file)
@@ -10,6 +10,7 @@ int test__rdpmc(struct test *test __maybe_unused, int subtest);
 int test__insn_x86(struct test *test __maybe_unused, int subtest);
 int test__intel_pt_pkt_decoder(struct test *test, int subtest);
 int test__bp_modify(struct test *test, int subtest);
+int test__x86_sample_parsing(struct test *test, int subtest);
 
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
 struct thread;
index 36d4f248b51dbceda1364767b6949fe720cd6770..28d793390198f1416206c9013e0c1f445b8feb3b 100644 (file)
@@ -3,5 +3,6 @@ perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
 
 perf-y += arch-tests.o
 perf-y += rdpmc.o
+perf-y += sample-parsing.o
 perf-$(CONFIG_AUXTRACE) += insn-x86.o intel-pt-pkt-decoder-test.o
 perf-$(CONFIG_X86_64) += bp-modify.o
index bc25d727b4e9af4be2b2d360b928d9ab01fca7ae..71aa67367ad6bd352e7c16e0ca389fdc9d07c672 100644 (file)
@@ -30,6 +30,10 @@ struct test arch_tests[] = {
                .func = test__bp_modify,
        },
 #endif
+       {
+               .desc = "x86 Sample parsing",
+               .func = test__x86_sample_parsing,
+       },
        {
                .func = NULL,
        },
index f782ef8c5982fc6831e3a268454ad9e060cfe2ba..4f75ae9901403d34649da89dc7dedd3c38bbfe51 100644 (file)
@@ -1,11 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/types.h>
-#include "../../../../arch/x86/include/asm/insn.h"
 #include <string.h>
 
 #include "debug.h"
 #include "tests/tests.h"
 #include "arch-tests.h"
+#include "../../../../arch/x86/include/asm/insn.h"
 
 #include "intel-pt-decoder/intel-pt-insn-decoder.h"
 
diff --git a/tools/perf/arch/x86/tests/sample-parsing.c b/tools/perf/arch/x86/tests/sample-parsing.c
new file mode 100644 (file)
index 0000000..c92db87
--- /dev/null
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <stdbool.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "event.h"
+#include "evsel.h"
+#include "debug.h"
+#include "util/synthetic-events.h"
+
+#include "tests/tests.h"
+#include "arch-tests.h"
+
+#define COMP(m) do {                                   \
+       if (s1->m != s2->m) {                           \
+               pr_debug("Samples differ at '"#m"'\n"); \
+               return false;                           \
+       }                                               \
+} while (0)
+
+static bool samples_same(const struct perf_sample *s1,
+                        const struct perf_sample *s2,
+                        u64 type)
+{
+       if (type & PERF_SAMPLE_WEIGHT_STRUCT)
+               COMP(ins_lat);
+
+       return true;
+}
+
+static int do_test(u64 sample_type)
+{
+       struct evsel evsel = {
+               .needs_swap = false,
+               .core = {
+                       . attr = {
+                               .sample_type = sample_type,
+                               .read_format = 0,
+                       },
+               },
+       };
+       union perf_event *event;
+       struct perf_sample sample = {
+               .weight         = 101,
+               .ins_lat        = 102,
+       };
+       struct perf_sample sample_out;
+       size_t i, sz, bufsz;
+       int err, ret = -1;
+
+       sz = perf_event__sample_event_size(&sample, sample_type, 0);
+       bufsz = sz + 4096; /* Add a bit for overrun checking */
+       event = malloc(bufsz);
+       if (!event) {
+               pr_debug("malloc failed\n");
+               return -1;
+       }
+
+       memset(event, 0xff, bufsz);
+       event->header.type = PERF_RECORD_SAMPLE;
+       event->header.misc = 0;
+       event->header.size = sz;
+
+       err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
+       if (err) {
+               pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
+                        "perf_event__synthesize_sample", sample_type, err);
+               goto out_free;
+       }
+
+       /* The data does not contain 0xff so we use that to check the size */
+       for (i = bufsz; i > 0; i--) {
+               if (*(i - 1 + (u8 *)event) != 0xff)
+                       break;
+       }
+       if (i != sz) {
+               pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
+                        i, sz);
+               goto out_free;
+       }
+
+       evsel.sample_size = __evsel__sample_size(sample_type);
+
+       err = evsel__parse_sample(&evsel, event, &sample_out);
+       if (err) {
+               pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
+                        "evsel__parse_sample", sample_type, err);
+               goto out_free;
+       }
+
+       if (!samples_same(&sample, &sample_out, sample_type)) {
+               pr_debug("parsing failed for sample_type %#"PRIx64"\n",
+                        sample_type);
+               goto out_free;
+       }
+
+       ret = 0;
+out_free:
+       free(event);
+
+       return ret;
+}
+
+/**
+ * test__x86_sample_parsing - test X86 specific sample parsing
+ *
+ * This function implements a test that synthesizes a sample event, parses it
+ * and then checks that the parsed sample matches the original sample. If the
+ * test passes %0 is returned, otherwise %-1 is returned.
+ *
+ * For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type.
+ * The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type.
+ */
+int test__x86_sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused)
+{
+       return do_test(PERF_SAMPLE_WEIGHT_STRUCT);
+}
index 3e6791531ca5a1799f92f7db8c11c9b3b107439b..34d600c5104403c2eba909017f6751d3fffbfb50 100644 (file)
@@ -1,10 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0
-#include "../../../../arch/x86/include/asm/insn.h"
 #include "archinsn.h"
 #include "event.h"
 #include "machine.h"
 #include "thread.h"
 #include "symbol.h"
+#include "../../../../arch/x86/include/asm/insn.h"
 
 void arch_fetch_insn(struct perf_sample *sample,
                     struct thread *thread,
index 11726ec6285f3d3f05a92ced8c30978e4cfbf0c4..20b87e29c96f4b4c2832e8f3271b435575898168 100644 (file)
@@ -344,18 +344,22 @@ static void mempol_restore(void)
 
 static void bind_to_memnode(int node)
 {
-       unsigned long nodemask;
+       struct bitmask *node_mask;
        int ret;
 
        if (node == NUMA_NO_NODE)
                return;
 
-       BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8);
-       nodemask = 1L << node;
+       node_mask = numa_allocate_nodemask();
+       BUG_ON(!node_mask);
 
-       ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
-       dprintf("binding to node %d, mask: %016lx => %d\n", node, nodemask, ret);
+       numa_bitmask_clearall(node_mask);
+       numa_bitmask_setbit(node_mask, node);
 
+       ret = set_mempolicy(MPOL_BIND, node_mask->maskp, node_mask->size + 1);
+       dprintf("binding to node %d, mask: %016lx => %d\n", node, *node_mask->maskp, ret);
+
+       numa_bitmask_free(node_mask);
        BUG_ON(ret);
 }
 
@@ -876,8 +880,6 @@ static void update_curr_cpu(int task_nr, unsigned long bytes_worked)
        prctl(0, bytes_worked);
 }
 
-#define MAX_NR_NODES   64
-
 /*
  * Count the number of nodes a process's threads
  * are spread out on.
@@ -888,10 +890,15 @@ static void update_curr_cpu(int task_nr, unsigned long bytes_worked)
  */
 static int count_process_nodes(int process_nr)
 {
-       char node_present[MAX_NR_NODES] = { 0, };
+       char *node_present;
        int nodes;
        int n, t;
 
+       node_present = (char *)malloc(g->p.nr_nodes * sizeof(char));
+       BUG_ON(!node_present);
+       for (nodes = 0; nodes < g->p.nr_nodes; nodes++)
+               node_present[nodes] = 0;
+
        for (t = 0; t < g->p.nr_threads; t++) {
                struct thread_data *td;
                int task_nr;
@@ -901,17 +908,20 @@ static int count_process_nodes(int process_nr)
                td = g->threads + task_nr;
 
                node = numa_node_of_cpu(td->curr_cpu);
-               if (node < 0) /* curr_cpu was likely still -1 */
+               if (node < 0) /* curr_cpu was likely still -1 */ {
+                       free(node_present);
                        return 0;
+               }
 
                node_present[node] = 1;
        }
 
        nodes = 0;
 
-       for (n = 0; n < MAX_NR_NODES; n++)
+       for (n = 0; n < g->p.nr_nodes; n++)
                nodes += node_present[n];
 
+       free(node_present);
        return nodes;
 }
 
@@ -980,7 +990,7 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
 {
        unsigned int loops_done_min, loops_done_max;
        int process_groups;
-       int nodes[MAX_NR_NODES];
+       int *nodes;
        int distance;
        int nr_min;
        int nr_max;
@@ -994,6 +1004,8 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
        if (!g->p.show_convergence && !g->p.measure_convergence)
                return;
 
+       nodes = (int *)malloc(g->p.nr_nodes * sizeof(int));
+       BUG_ON(!nodes);
        for (node = 0; node < g->p.nr_nodes; node++)
                nodes[node] = 0;
 
@@ -1035,8 +1047,10 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
 
        BUG_ON(sum > g->p.nr_tasks);
 
-       if (0 && (sum < g->p.nr_tasks))
+       if (0 && (sum < g->p.nr_tasks)) {
+               free(nodes);
                return;
+       }
 
        /*
         * Count the number of distinct process groups present
@@ -1088,6 +1102,8 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
                }
                tprintf("\n");
        }
+
+       free(nodes);
 }
 
 static void show_summary(double runtime_ns_max, int l, double *convergence)
@@ -1413,7 +1429,7 @@ static int init(void)
        g->p.nr_nodes = numa_max_node() + 1;
 
        /* char array in count_process_nodes(): */
-       BUG_ON(g->p.nr_nodes > MAX_NR_NODES || g->p.nr_nodes < 0);
+       BUG_ON(g->p.nr_nodes < 0);
 
        if (g->p.show_quiet && !g->p.show_details)
                g->p.show_details = -1;
index cecce93ccc63600cb857e45c2bb02c6378843e4d..488f6e6ba1a55e8decd839c98a8d6a8ee838209b 100644 (file)
@@ -309,11 +309,11 @@ int bench_sched_messaging(int argc, const char **argv)
                       num_groups, num_groups * 2 * num_fds,
                       thread_mode ? "threads" : "processes");
                printf(" %14s: %lu.%03lu [sec]\n", "Total time",
-                      diff.tv_sec,
+                      (unsigned long) diff.tv_sec,
                       (unsigned long) (diff.tv_usec / USEC_PER_MSEC));
                break;
        case BENCH_FORMAT_SIMPLE:
-               printf("%lu.%03lu\n", diff.tv_sec,
+               printf("%lu.%03lu\n", (unsigned long) diff.tv_sec,
                       (unsigned long) (diff.tv_usec / USEC_PER_MSEC));
                break;
        default:
index 3c88d1f201f1cf81393edf432c90024f8bbe02d2..a960e7a93aecf1d6c0930be1ba0f28dc00103788 100644 (file)
@@ -156,7 +156,7 @@ int bench_sched_pipe(int argc, const char **argv)
                result_usec += diff.tv_usec;
 
                printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
-                      diff.tv_sec,
+                      (unsigned long) diff.tv_sec,
                       (unsigned long) (diff.tv_usec / USEC_PER_MSEC));
 
                printf(" %14lf usecs/op\n",
@@ -168,7 +168,7 @@ int bench_sched_pipe(int argc, const char **argv)
 
        case BENCH_FORMAT_SIMPLE:
                printf("%lu.%03lu\n",
-                      diff.tv_sec,
+                      (unsigned long) diff.tv_sec,
                       (unsigned long) (diff.tv_usec / USEC_PER_MSEC));
                break;
 
index 5fe621cff8e9330f1fb1dc46d4c4c6edbcac2e4f..9b751016f4b65560ad128153b9e6e1c05590e89f 100644 (file)
@@ -54,7 +54,7 @@ int bench_syscall_basic(int argc, const char **argv)
                result_usec += diff.tv_usec;
 
                printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
-                      diff.tv_sec,
+                      (unsigned long) diff.tv_sec,
                       (unsigned long) (diff.tv_usec/1000));
 
                printf(" %14lf usecs/op\n",
@@ -66,7 +66,7 @@ int bench_syscall_basic(int argc, const char **argv)
 
        case BENCH_FORMAT_SIMPLE:
                printf("%lu.%03lu\n",
-                      diff.tv_sec,
+                      (unsigned long) diff.tv_sec,
                       (unsigned long) (diff.tv_usec / 1000));
                break;
 
index 617feaf020f65db005da17732a00a1d8a2ae0832..ace8772a4f038d6b4f0730cd0d06d832f1d6c976 100644 (file)
@@ -161,7 +161,7 @@ static int session_config(struct daemon *daemon, const char *var, const char *va
        struct daemon_session *session;
        char name[100];
 
-       if (get_session_name(var, name, sizeof(name)))
+       if (get_session_name(var, name, sizeof(name) - 1))
                return -EINVAL;
 
        var = strchr(var, '.');
@@ -373,12 +373,12 @@ static int daemon_session__run(struct daemon_session *session,
        dup2(fd, 2);
        close(fd);
 
-       if (mkfifo(SESSION_CONTROL, O_RDWR) && errno != EEXIST) {
+       if (mkfifo(SESSION_CONTROL, 0600) && errno != EEXIST) {
                perror("failed: create control fifo");
                return -1;
        }
 
-       if (mkfifo(SESSION_ACK, O_RDWR) && errno != EEXIST) {
+       if (mkfifo(SESSION_ACK, 0600) && errno != EEXIST) {
                perror("failed: create ack fifo");
                return -1;
        }
index 8f6c784ce629c99efd3153f37c92fad7c32368f7..878e04b1fab746a234884a612080e53e5f6f8b5e 100644 (file)
@@ -1236,7 +1236,8 @@ static int __cmd_diff(void)
 
  out_delete:
        data__for_each_file(i, d) {
-               perf_session__delete(d->session);
+               if (!IS_ERR(d->session))
+                       perf_session__delete(d->session);
                data__free(d);
        }
 
index 85b6a46e85b686b99b2e7b99ba5e7a4de71b13d3..7ec18ff57fc4ae353eae76c8d53f26e68ea6b1c7 100644 (file)
@@ -3964,9 +3964,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 
        evlist__config(evlist, &trace->opts, &callchain_param);
 
-       signal(SIGCHLD, sig_handler);
-       signal(SIGINT, sig_handler);
-
        if (forks) {
                err = evlist__prepare_workload(evlist, &trace->opts.target, argv, false, NULL);
                if (err < 0) {
@@ -4827,6 +4824,8 @@ int cmd_trace(int argc, const char **argv)
 
        signal(SIGSEGV, sighandler_dump_stack);
        signal(SIGFPE, sighandler_dump_stack);
+       signal(SIGCHLD, sig_handler);
+       signal(SIGINT, sig_handler);
 
        trace.evlist = evlist__new();
        trace.sctbl = syscalltbl__new();
index 0cfb3e2cefef48bd630f0463469738f0c72692cc..133f0eddbcc4604e6731cd53aa62979398f36bd9 100644 (file)
@@ -20,9 +20,8 @@ else
 fi
 
 BUILDIDS=$(mktemp /tmp/perf-archive-buildids.XXXXXX)
-NOBUILDID=0000000000000000000000000000000000000000
 
-perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS
+perf buildid-list -i $PERF_DATA --with-hits | grep -v "^ " > $BUILDIDS
 if [ ! -s $BUILDIDS ] ; then
        echo "perf archive: no build-ids found"
        rm $BUILDIDS || true
index ec972e0892abe38d7cb9f112944b9f8b39d1177e..dd39ce9b027789ef1028eb76b0629ff08a8b6ab7 100644 (file)
@@ -182,14 +182,20 @@ int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused)
        struct stat st;
        char path_perf[PATH_MAX];
        char path_dir[PATH_MAX];
+       char *exec_path;
 
        /* First try development tree tests. */
        if (!lstat("./tests", &st))
                return run_dir("./tests", "./perf");
 
+       exec_path = get_argv_exec_path();
+       if (exec_path == NULL)
+               return -1;
+
        /* Then installed path. */
-       snprintf(path_dir,  PATH_MAX, "%s/tests", get_argv_exec_path());
+       snprintf(path_dir,  PATH_MAX, "%s/tests", exec_path);
        snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR);
+       free(exec_path);
 
        if (!lstat(path_dir, &st) &&
            !lstat(path_perf, &st))
index 280f0348a09c0ba01d164057e9b84bf36cd5658b..2fdc7b2f996ed5eefa6d1f186dc01edfa84a8755 100644 (file)
@@ -706,13 +706,9 @@ static int do_test_code_reading(bool try_kcore)
 out_put:
        thread__put(thread);
 out_err:
-
-       if (evlist) {
-               evlist__delete(evlist);
-       } else {
-               perf_cpu_map__put(cpus);
-               perf_thread_map__put(threads);
-       }
+       evlist__delete(evlist);
+       perf_cpu_map__put(cpus);
+       perf_thread_map__put(threads);
        machine__delete_threads(machine);
        machine__delete(machine);
 
index 29c793ac7d108baef49b2c2d1738f8272997adf9..0472b110fe651ffe1da7c0e7aec71bb6128f0439 100644 (file)
@@ -106,6 +106,8 @@ static int cpu_map_print(const char *str)
                return -1;
 
        cpu_map__snprint(map, buf, sizeof(buf));
+       perf_cpu_map__put(map);
+
        return !strcmp(buf, str);
 }
 
index e6f1b2a38e03222be1ef4836b26929b436b1d1a8..a0438b0f080526d4b6f4e8713aa14d35b987418d 100644 (file)
@@ -154,10 +154,9 @@ out_err:
        if (evlist) {
                evlist__disable(evlist);
                evlist__delete(evlist);
-       } else {
-               perf_cpu_map__put(cpus);
-               perf_thread_map__put(threads);
        }
+       perf_cpu_map__put(cpus);
+       perf_thread_map__put(threads);
 
        return err;
 }
index 57093aeacc6f4688a2cd90e04146e44a848254b3..73ae8f7aa0660eae32bfba5a0d81ac871a1b68aa 100644 (file)
@@ -158,8 +158,6 @@ out_init:
 
 out_delete_evlist:
        evlist__delete(evlist);
-       cpus    = NULL;
-       threads = NULL;
 out_free_cpus:
        perf_cpu_map__put(cpus);
 out_free_threads:
index 7cff02664d0e631196faf43bb9047b3640efe1a5..680c3cffb1286aa96c8a681bb340cc62980dd4f3 100644 (file)
@@ -167,6 +167,8 @@ next_event:
 
 out_err:
        evlist__delete(evlist);
+       perf_cpu_map__put(cpus);
+       perf_thread_map__put(threads);
        return err;
 }
 
index 0dbe3aa9985362d8ccc9c84d97c2922fba9f2e46..8fd8a4ef97da1521f3441ead3f367b328bc815c1 100644 (file)
@@ -129,9 +129,6 @@ static bool samples_same(const struct perf_sample *s1,
        if (type & PERF_SAMPLE_WEIGHT)
                COMP(weight);
 
-       if (type & PERF_SAMPLE_WEIGHT_STRUCT)
-               COMP(ins_lat);
-
        if (type & PERF_SAMPLE_DATA_SRC)
                COMP(data_src);
 
@@ -245,7 +242,6 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
                .cgroup         = 114,
                .data_page_size = 115,
                .code_page_size = 116,
-               .ins_lat        = 117,
                .aux_sample     = {
                        .size   = sizeof(aux_data),
                        .data   = (void *)aux_data,
index e5b824dd08d9d0d2d0506d98abe52c90801dcb03..5ad3ca8d681b7d8a8d8156942c39dfe61d10836a 100755 (executable)
@@ -140,10 +140,10 @@ test_list()
 base=BASE
 
 [session-size]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 
 [session-time]
-run = -e task-clock
+run = -e task-clock -m 1 sleep 10
 EOF
 
        sed -i -e "s|BASE|${base}|" ${config}
@@ -159,14 +159,14 @@ EOF
        # check 1st session
        # pid:size:-e cpu-clock:base/size:base/size/output:base/size/control:base/size/ack:0
        local line=`perf daemon --config ${config} -x: | head -2 | tail -1`
-       check_line_other "${line}" size "-e cpu-clock" ${base}/session-size \
+       check_line_other "${line}" size "-e cpu-clock -m 1 sleep 10" ${base}/session-size \
                         ${base}/session-size/output ${base}/session-size/control \
                         ${base}/session-size/ack "0"
 
        # check 2nd session
        # pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
        local line=`perf daemon --config ${config} -x: | head -3 | tail -1`
-       check_line_other "${line}" time "-e task-clock" ${base}/session-time \
+       check_line_other "${line}" time "-e task-clock -m 1 sleep 10" ${base}/session-time \
                         ${base}/session-time/output ${base}/session-time/control \
                         ${base}/session-time/ack "0"
 
@@ -190,10 +190,10 @@ test_reconfig()
 base=BASE
 
 [session-size]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 
 [session-time]
-run = -e task-clock
+run = -e task-clock -m 1 sleep 10
 EOF
 
        sed -i -e "s|BASE|${base}|" ${config}
@@ -204,7 +204,7 @@ EOF
        # check 2nd session
        # pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
        local line=`perf daemon --config ${config} -x: | head -3 | tail -1`
-       check_line_other "${line}" time "-e task-clock" ${base}/session-time \
+       check_line_other "${line}" time "-e task-clock -m 1 sleep 10" ${base}/session-time \
                         ${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0"
        local pid=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $1 }'`
 
@@ -215,10 +215,10 @@ EOF
 base=BASE
 
 [session-size]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 
 [session-time]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 EOF
 
        # TEST 1 - change config
@@ -238,7 +238,7 @@ EOF
        # check reconfigured 2nd session
        # pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
        local line=`perf daemon --config ${config} -x: | head -3 | tail -1`
-       check_line_other "${line}" time "-e cpu-clock" ${base}/session-time \
+       check_line_other "${line}" time "-e cpu-clock -m 1 sleep 10" ${base}/session-time \
                         ${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0"
 
        # TEST 2 - empty config
@@ -309,10 +309,10 @@ test_stop()
 base=BASE
 
 [session-size]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 
 [session-time]
-run = -e task-clock
+run = -e task-clock -m 1 sleep 10
 EOF
 
        sed -i -e "s|BASE|${base}|" ${config}
@@ -361,7 +361,7 @@ test_signal()
 base=BASE
 
 [session-test]
-run = -e cpu-clock --switch-output
+run = -e cpu-clock --switch-output -m 1 sleep 10
 EOF
 
        sed -i -e "s|BASE|${base}|" ${config}
@@ -400,10 +400,10 @@ test_ping()
 base=BASE
 
 [session-size]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 
 [session-time]
-run = -e task-clock
+run = -e task-clock -m 1 sleep 10
 EOF
 
        sed -i -e "s|BASE|${base}|" ${config}
@@ -439,7 +439,7 @@ test_lock()
 base=BASE
 
 [session-size]
-run = -e cpu-clock
+run = -e cpu-clock -m 1 sleep 10
 EOF
 
        sed -i -e "s|BASE|${base}|" ${config}
index a49c9e23053bd4bfe2e19ad7a1d1cfd3cb3d3da8..74988846be1da9ae2dae55873ae977376417c57f 100644 (file)
@@ -42,8 +42,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
                .disabled = 1,
                .freq = 1,
        };
-       struct perf_cpu_map *cpus;
-       struct perf_thread_map *threads;
+       struct perf_cpu_map *cpus = NULL;
+       struct perf_thread_map *threads = NULL;
        struct mmap *md;
 
        attr.sample_freq = 500;
@@ -66,14 +66,11 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
        if (!cpus || !threads) {
                err = -ENOMEM;
                pr_debug("Not enough memory to create thread/cpu maps\n");
-               goto out_free_maps;
+               goto out_delete_evlist;
        }
 
        perf_evlist__set_maps(&evlist->core, cpus, threads);
 
-       cpus    = NULL;
-       threads = NULL;
-
        if (evlist__open(evlist)) {
                const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
 
@@ -129,10 +126,9 @@ out_init:
                err = -1;
        }
 
-out_free_maps:
+out_delete_evlist:
        perf_cpu_map__put(cpus);
        perf_thread_map__put(threads);
-out_delete_evlist:
        evlist__delete(evlist);
        return err;
 }
index 15a2ab765d8901baa4fda4587652d920589aadbd..3ebaa758df77e18ebd1b6ea0d8d80c88d74539cc 100644 (file)
@@ -574,10 +574,9 @@ out:
        if (evlist) {
                evlist__disable(evlist);
                evlist__delete(evlist);
-       } else {
-               perf_cpu_map__put(cpus);
-               perf_thread_map__put(threads);
        }
+       perf_cpu_map__put(cpus);
+       perf_thread_map__put(threads);
 
        return err;
 
index bbf94e4aa1450b50a8f76e48e8955b27c25f36b9..4c2969db59b0777a7117d2e29647082e2d9c0bec 100644 (file)
@@ -75,14 +75,11 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
        if (!cpus || !threads) {
                err = -ENOMEM;
                pr_debug("Not enough memory to create thread/cpu maps\n");
-               goto out_free_maps;
+               goto out_delete_evlist;
        }
 
        perf_evlist__set_maps(&evlist->core, cpus, threads);
 
-       cpus    = NULL;
-       threads = NULL;
-
        err = evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal);
        if (err < 0) {
                pr_debug("Couldn't run the workload!\n");
@@ -137,7 +134,7 @@ out_init:
                if (retry_count++ > 1000) {
                        pr_debug("Failed after retrying 1000 times\n");
                        err = -1;
-                       goto out_free_maps;
+                       goto out_delete_evlist;
                }
 
                goto retry;
@@ -148,10 +145,9 @@ out_init:
                err = -1;
        }
 
-out_free_maps:
+out_delete_evlist:
        perf_cpu_map__put(cpus);
        perf_thread_map__put(threads);
-out_delete_evlist:
        evlist__delete(evlist);
        return err;
 }
index 28f51c4bd373c3d0de18e271c5266174594c0e0a..d1e208b4a571c939a0cf241b41dfa15eefddfcf0 100644 (file)
@@ -102,6 +102,7 @@ int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __
        TEST_ASSERT_VAL("failed to synthesize map",
                !perf_event__synthesize_thread_map2(NULL, threads, process_event, NULL));
 
+       perf_thread_map__put(threads);
        return 0;
 }
 
@@ -109,12 +110,12 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb
 {
        struct perf_thread_map *threads;
        char *str;
-       int i;
 
        TEST_ASSERT_VAL("failed to allocate map string",
                        asprintf(&str, "%d,%d", getpid(), getppid()) >= 0);
 
        threads = thread_map__new_str(str, NULL, 0, false);
+       free(str);
 
        TEST_ASSERT_VAL("failed to allocate thread_map",
                        threads);
@@ -141,9 +142,6 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb
        TEST_ASSERT_VAL("failed to not remove thread",
                        thread_map__remove(threads, 0));
 
-       for (i = 0; i < threads->nr; i++)
-               zfree(&threads->map[i].comm);
-
-       free(threads);
+       perf_thread_map__put(threads);
        return 0;
 }
index 5121b4db66fe5d58abc48aab2b2a025240a8eb51..882cd1f721d958aa607793d79c70ecdbe33955a2 100644 (file)
@@ -1306,6 +1306,7 @@ void evlist__close(struct evlist *evlist)
                perf_evsel__free_fd(&evsel->core);
                perf_evsel__free_id(&evsel->core);
        }
+       perf_evlist__reset_id_hash(&evlist->core);
 }
 
 static int evlist__create_syswide_maps(struct evlist *evlist)
index 1bf76864c4f26cc61036b5c0f57eda2fd42b5ede..7ecbc8e2fbfa8ec576c9366618881e286b2d7f64 100644 (file)
@@ -46,6 +46,7 @@
 #include "string2.h"
 #include "memswap.h"
 #include "util.h"
+#include "hashmap.h"
 #include "../perf-sys.h"
 #include "util/parse-branch-options.h"
 #include <internal/xyarray.h>
@@ -1390,7 +1391,9 @@ void evsel__exit(struct evsel *evsel)
        zfree(&evsel->group_name);
        zfree(&evsel->name);
        zfree(&evsel->pmu_name);
-       zfree(&evsel->per_pkg_mask);
+       evsel__zero_per_pkg(evsel);
+       hashmap__free(evsel->per_pkg_mask);
+       evsel->per_pkg_mask = NULL;
        zfree(&evsel->metric_events);
        perf_evsel__object.fini(evsel);
 }
@@ -2781,3 +2784,16 @@ int evsel__store_ids(struct evsel *evsel, struct evlist *evlist)
 
        return store_evsel_ids(evsel, evlist);
 }
+
+void evsel__zero_per_pkg(struct evsel *evsel)
+{
+       struct hashmap_entry *cur;
+       size_t bkt;
+
+       if (evsel->per_pkg_mask) {
+               hashmap__for_each_entry(evsel->per_pkg_mask, cur, bkt)
+                       free((char *)cur->key);
+
+               hashmap__clear(evsel->per_pkg_mask);
+       }
+}
index 4e8e49fb7e9de5f3a742e1ddf2743b95cd2ea0c7..6026487353dd834851061d74343ad2883873369b 100644 (file)
@@ -19,6 +19,7 @@ struct perf_stat_evsel;
 union perf_event;
 struct bpf_counter_ops;
 struct target;
+struct hashmap;
 
 typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
 
@@ -112,7 +113,7 @@ struct evsel {
        bool                    merged_stat;
        bool                    reset_group;
        bool                    errored;
-       unsigned long           *per_pkg_mask;
+       struct hashmap          *per_pkg_mask;
        struct evsel            *leader;
        struct list_head        config_terms;
        int                     err;
@@ -433,4 +434,5 @@ struct perf_env *evsel__env(struct evsel *evsel);
 
 int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
 
+void evsel__zero_per_pkg(struct evsel *evsel);
 #endif /* __PERF_EVSEL_H */
index 4fe9e2a54346e51fca8ad6b4f0b4396b6af966cf..20effdff76ceb6afc90ffb4f4796ccd7af97412a 100644 (file)
@@ -1618,8 +1618,8 @@ static void print_clock_data(struct feat_fd *ff, FILE *fp)
 
        fprintf(fp, "# clockid: %s (%u)\n", clockid_name(clockid), clockid);
        fprintf(fp, "# reference time: %s = %ld.%06d (TOD) = %ld.%09ld (%s)\n",
-                   tstr, tod_ns.tv_sec, (int) tod_ns.tv_usec,
-                   clockid_ns.tv_sec, clockid_ns.tv_nsec,
+                   tstr, (long) tod_ns.tv_sec, (int) tod_ns.tv_usec,
+                   (long) clockid_ns.tv_sec, clockid_ns.tv_nsec,
                    clockid_name(clockid));
 }
 
index 692e56dc832e78b0079b18e6bd5c1fd7b1753246..fbc40a2c17d4dca0658b9b0c129eb4253e64a2bc 100644 (file)
@@ -77,8 +77,7 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
        if (strstarts(filename, "/system/lib/")) {
                char *ndk, *app;
                const char *arch;
-               size_t ndk_length;
-               size_t app_length;
+               int ndk_length, app_length;
 
                ndk = getenv("NDK_ROOT");
                app = getenv("APP_PLATFORM");
@@ -106,8 +105,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
                if (new_length > PATH_MAX)
                        return false;
                snprintf(newfilename, new_length,
-                       "%s/platforms/%s/arch-%s/usr/lib/%s",
-                       ndk, app, arch, libname);
+                       "%.*s/platforms/%.*s/arch-%s/usr/lib/%s",
+                       ndk_length, ndk, app_length, app, arch, libname);
 
                return true;
        }
index d5b6aff82f21704d06c71def88677a27faa0dff3..d57ac86ce7ca2e3b04f8b4107e2709279cb07af9 100644 (file)
@@ -89,6 +89,7 @@ static void inc_group_count(struct list_head *list,
 %type <str> PE_EVENT_NAME
 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
 %type <str> PE_DRV_CFG_TERM
+%type <str> event_pmu_name
 %destructor { free ($$); } <str>
 %type <term> event_term
 %destructor { parse_events_term__delete ($$); } <term>
@@ -272,8 +273,11 @@ event_def: event_pmu |
           event_legacy_raw sep_dc |
           event_bpf_file
 
+event_pmu_name:
+PE_NAME | PE_PMU_EVENT_PRE
+
 event_pmu:
-PE_NAME opt_pmu_config
+event_pmu_name opt_pmu_config
 {
        struct parse_events_state *parse_state = _parse_state;
        struct parse_events_error *error = parse_state->error;
index 71b753523fac0f6791a0076d1311e6b91281960b..845dd46e3c6186a34ed6a0b4a2910cbbaba9d692 100644 (file)
@@ -36,3 +36,4 @@ util/symbol_fprintf.c
 util/units.c
 util/affinity.c
 util/rwsem.c
+util/hashmap.c
index 0d5ad42812b9d784cb6b67a17f632df9e76c9281..552b590485bf1008082193824579c72a92cbb981 100644 (file)
@@ -3140,7 +3140,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok)
                if (strncasecmp(tok, sd->name, strlen(tok)))
                        continue;
 
-               if (sort__mode != SORT_MODE__MEMORY)
+               if (sort__mode != SORT_MODE__BRANCH)
                        return -EINVAL;
 
                return __sort_dimension__add_output(list, sd);
@@ -3152,7 +3152,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok)
                if (strncasecmp(tok, sd->name, strlen(tok)))
                        continue;
 
-               if (sort__mode != SORT_MODE__BRANCH)
+               if (sort__mode != SORT_MODE__MEMORY)
                        return -EINVAL;
 
                return __sort_dimension__add_output(list, sd);
index cce7a76d6473c380dcbc544b120f57f48159c9ad..7f09cdaf5b6002350937f09c17dec329864514d0 100644 (file)
@@ -983,7 +983,7 @@ static void print_interval(struct perf_stat_config *config,
        if (config->interval_clear)
                puts(CONSOLE_CLEAR);
 
-       sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, config->csv_sep);
+       sprintf(prefix, "%6lu.%09lu%s", (unsigned long) ts->tv_sec, ts->tv_nsec, config->csv_sep);
 
        if ((num_print_interval == 0 && !config->csv_output) || config->interval_clear) {
                switch (config->aggr_mode) {
index 5d8af29447f44b959d75b06acd09a2e1aa62c796..c400f8dde017b0b9fc14dddce4fad25d8b787862 100644 (file)
@@ -13,6 +13,7 @@
 #include "evlist.h"
 #include "evsel.h"
 #include "thread_map.h"
+#include "hashmap.h"
 #include <linux/zalloc.h>
 
 void update_stats(struct stats *stats, u64 val)
@@ -277,18 +278,29 @@ void evlist__save_aggr_prev_raw_counts(struct evlist *evlist)
        }
 }
 
-static void zero_per_pkg(struct evsel *counter)
+static size_t pkg_id_hash(const void *__key, void *ctx __maybe_unused)
 {
-       if (counter->per_pkg_mask)
-               memset(counter->per_pkg_mask, 0, cpu__max_cpu());
+       uint64_t *key = (uint64_t *) __key;
+
+       return *key & 0xffffffff;
+}
+
+static bool pkg_id_equal(const void *__key1, const void *__key2,
+                        void *ctx __maybe_unused)
+{
+       uint64_t *key1 = (uint64_t *) __key1;
+       uint64_t *key2 = (uint64_t *) __key2;
+
+       return *key1 == *key2;
 }
 
 static int check_per_pkg(struct evsel *counter,
                         struct perf_counts_values *vals, int cpu, bool *skip)
 {
-       unsigned long *mask = counter->per_pkg_mask;
+       struct hashmap *mask = counter->per_pkg_mask;
        struct perf_cpu_map *cpus = evsel__cpus(counter);
-       int s;
+       int s, d, ret = 0;
+       uint64_t *key;
 
        *skip = false;
 
@@ -299,7 +311,7 @@ static int check_per_pkg(struct evsel *counter,
                return 0;
 
        if (!mask) {
-               mask = zalloc(cpu__max_cpu());
+               mask = hashmap__new(pkg_id_hash, pkg_id_equal, NULL);
                if (!mask)
                        return -ENOMEM;
 
@@ -321,8 +333,25 @@ static int check_per_pkg(struct evsel *counter,
        if (s < 0)
                return -1;
 
-       *skip = test_and_set_bit(s, mask) == 1;
-       return 0;
+       /*
+        * On multi-die system, die_id > 0. On no-die system, die_id = 0.
+        * We use hashmap(socket, die) to check the used socket+die pair.
+        */
+       d = cpu_map__get_die(cpus, cpu, NULL).die;
+       if (d < 0)
+               return -1;
+
+       key = malloc(sizeof(*key));
+       if (!key)
+               return -ENOMEM;
+
+       *key = (uint64_t)d << 32 | s;
+       if (hashmap__find(mask, (void *)key, NULL))
+               *skip = true;
+       else
+               ret = hashmap__add(mask, (void *)key, (void *)1);
+
+       return ret;
 }
 
 static int
@@ -422,7 +451,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,
        }
 
        if (counter->per_pkg)
-               zero_per_pkg(counter);
+               evsel__zero_per_pkg(counter);
 
        ret = process_counter_maps(config, counter);
        if (ret)
index f507dff713c9f8e55df4a233517ce531132a239f..8a01af783310a580d2c0f5e3fb11eee57850d993 100644 (file)
@@ -361,6 +361,7 @@ static int read_saved_cmdline(struct tep_handle *pevent)
                pr_debug("error reading saved cmdlines\n");
                goto out;
        }
+       buf[ret] = '\0';
 
        parse_saved_cmdline(pevent, buf, size);
        ret = 0;
index b2282be6f9384cb193e6ed9f54b75c3b6e5d1e75..612d3899614ac6be12c02696c204fe3a4252b96a 100644 (file)
@@ -332,5 +332,5 @@ int main(void)
 
        ksft_print_cnts();
 
-       return 0;
+       return ret;
 }
index 6b670039ea6799d7026ec3896b90a211a6405ffb..1d8918dfbd3ff541b5abaf51b4bb9e6106e924f2 100644 (file)
@@ -16,6 +16,13 @@ bool skip = false;
 #define STRSIZE                        2048
 #define EXPECTED_STRSIZE       256
 
+#if defined(bpf_target_s390)
+/* NULL points to a readable struct lowcore on s390, so take the last page */
+#define BADPTR                 ((void *)0xFFFFFFFFFFFFF000ULL)
+#else
+#define BADPTR                 0
+#endif
+
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x)  (sizeof(x) / sizeof((x)[0]))
 #endif
@@ -113,11 +120,11 @@ int BPF_PROG(trace_netif_receive_skb, struct sk_buff *skb)
        }
 
        /* Check invalid ptr value */
-       p.ptr = 0;
+       p.ptr = BADPTR;
        __ret = bpf_snprintf_btf(str, STRSIZE, &p, sizeof(p), 0);
        if (__ret >= 0) {
-               bpf_printk("printing NULL should generate error, got (%d)",
-                          __ret);
+               bpf_printk("printing %llx should generate error, got (%d)",
+                          (unsigned long long)BADPTR, __ret);
                ret = -ERANGE;
        }
 
index 28488047c84913fd992e781b6fbe05b2e724c26d..ef5277d982d92148a4b10d1819471fdd773f8587 100644 (file)
@@ -15,5 +15,5 @@ __noinline int foo(const struct S *s)
 SEC("cgroup_skb/ingress")
 int test_cls(struct __sk_buff *skb)
 {
-       return foo(skb);
+       return foo((const void *)skb);
 }
index a621b58ab079d57467da21da5947b9246847eba3..9afe947cfae95302937b36264791475acce22fc3 100644 (file)
@@ -446,10 +446,8 @@ int _geneve_get_tunnel(struct __sk_buff *skb)
        }
 
        ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
-       if (ret < 0) {
-               ERROR(ret);
-               return TC_ACT_SHOT;
-       }
+       if (ret < 0)
+               gopt.opt_class = 0;
 
        bpf_trace_printk(fmt, sizeof(fmt),
                        key.tunnel_id, key.remote_ipv4, gopt.opt_class);
index bed53b561e0443328c0a82015c38abc56015650a..1b138cd2b187d982428092dfd7217d9f32b2f385 100644 (file)
        BPF_MOV64_IMM(BPF_REG_5, 0),
        BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
                     BPF_FUNC_csum_diff),
+       BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
        BPF_EXIT_INSN(),
        },
        .prog_type = BPF_PROG_TYPE_SCHED_CLS,
        .fixup_map_array_ro = { 3 },
        .result = ACCEPT,
-       .retval = -29,
+       .retval = 65507,
 },
 {
        "invalid write map access into a read-only array 1",
index 1bdc8e6684f7c2d314d894dee82b3d0aaf1e2e5a..fe4bb70eb9c572f970c917e4e798244eebb20499 100644 (file)
        },
        .result = ACCEPT,
 },
+{
+       "BPF_ATOMIC_AND with fetch - r0 as source reg",
+       .insns = {
+               /* val = 0x110; */
+               BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0x110),
+               /* old = atomic_fetch_and(&val, 0x011); */
+               BPF_MOV64_IMM(BPF_REG_0, 0x011),
+               BPF_ATOMIC_OP(BPF_DW, BPF_AND | BPF_FETCH, BPF_REG_10, BPF_REG_0, -8),
+               /* if (old != 0x110) exit(3); */
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0x110, 2),
+               BPF_MOV64_IMM(BPF_REG_0, 3),
+               BPF_EXIT_INSN(),
+               /* if (val != 0x010) exit(2); */
+               BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -8),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x010, 2),
+               BPF_MOV64_IMM(BPF_REG_1, 2),
+               BPF_EXIT_INSN(),
+               /* exit(0); */
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+},
index 2efd8bcf57a1e4c514afa4aad30b5b95422da30b..6e52dfc644153f08af2587ed27eda74fa66bfa5c 100644 (file)
        .result = REJECT,
        .errstr = "invalid read from stack",
 },
+{
+       "BPF_W cmpxchg should zero top 32 bits",
+       .insns = {
+               /* r0 = U64_MAX; */
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 1),
+               /* u64 val = r0; */
+               BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+               /* r0 = (u32)atomic_cmpxchg((u32 *)&val, r0, 1); */
+               BPF_MOV32_IMM(BPF_REG_1, 1),
+               BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_1, -8),
+               /* r1 = 0x00000000FFFFFFFFull; */
+               BPF_MOV64_IMM(BPF_REG_1, 1),
+               BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
+               BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
+               /* if (r0 != r1) exit(1); */
+               BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_1, 2),
+               BPF_MOV32_IMM(BPF_REG_0, 1),
+               BPF_EXIT_INSN(),
+               /* exit(0); */
+               BPF_MOV32_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+},
index 70f982e1f9f05fc41c9da5f887d26f05df6e742b..9d0716ac508080a86db2109a96cbfd9ac2707055 100644 (file)
        },
        .result = ACCEPT,
 },
+{
+       "BPF_W atomic_fetch_or should zero top 32 bits",
+       .insns = {
+               /* r1 = U64_MAX; */
+               BPF_MOV64_IMM(BPF_REG_1, 0),
+               BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
+               /* u64 val = r1; */
+               BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
+               /* r1 = (u32)atomic_fetch_or((u32 *)&val, 2); */
+               BPF_MOV32_IMM(BPF_REG_1, 2),
+               BPF_ATOMIC_OP(BPF_W, BPF_OR | BPF_FETCH, BPF_REG_10, BPF_REG_1, -8),
+               /* r2 = 0x00000000FFFFFFFF; */
+               BPF_MOV64_IMM(BPF_REG_2, 1),
+               BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
+               BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 1),
+               /* if (r2 != r1) exit(1); */
+               BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_1, 2),
+               BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+               BPF_EXIT_INSN(),
+               /* exit(0); */
+               BPF_MOV32_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+},
index 4c69408f3e84004a5282349017463988fe92ae5b..a4969f7ee020d51f1f243808c3155667cbecf06d 100644 (file)
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-gpio-mockup-chardev
+gpio-mockup-cdev
index 4c7d33618437c658bf014afff57da52b1a7d36f9..d98fb85e201c810c3d6796ca6dfeca2485ce10b1 100755 (executable)
@@ -1524,6 +1524,14 @@ basic()
        run_cmd "$IP nexthop replace id 2 blackhole dev veth1"
        log_test $? 2 "Blackhole nexthop with other attributes"
 
+       # blackhole nexthop should not be affected by the state of the loopback
+       # device
+       run_cmd "$IP link set dev lo down"
+       check_nexthop "id 2" "id 2 blackhole"
+       log_test $? 0 "Blackhole nexthop with loopback device down"
+
+       run_cmd "$IP link set dev lo up"
+
        #
        # groups
        #
index 197e769c2ed16a65826c3bd67fb560725a28697b..f8cda822c1cec3291b01ad7c8f30e73090c216a9 100755 (executable)
@@ -86,11 +86,20 @@ test_ip6gretap()
 
 test_gretap_stp()
 {
+       # Sometimes after mirror installation, the neighbor's state is not valid.
+       # The reason is that there is no SW datapath activity related to the
+       # neighbor for the remote GRE address. Therefore whether the corresponding
+       # neighbor will be valid is a matter of luck, and the test is thus racy.
+       # Set the neighbor's state to permanent, so it would be always valid.
+       ip neigh replace 192.0.2.130 lladdr $(mac_get $h3) \
+               nud permanent dev br2
        full_test_span_gre_stp gt4 $swp3.555 "mirror to gretap"
 }
 
 test_ip6gretap_stp()
 {
+       ip neigh replace 2001:db8:2::2 lladdr $(mac_get $h3) \
+               nud permanent dev br2
        full_test_span_gre_stp gt6 $swp3.555 "mirror to ip6gretap"
 }
 
index 17ced7d6ce259c671e7ec63e7c9a4575a1db9bd4..f23438d512c58d3f3e1fbb5c0638f6d588cdf1f9 100644 (file)
@@ -1785,7 +1785,7 @@ static void grand_child_serv(unsigned int nr, int cmd_fd, void *buf,
                break;
        default:
                printk("got unknown msg type %d", msg->type);
-       };
+       }
 }
 
 static int grand_child_f(unsigned int nr, int cmd_fd, void *buf)
index 3006a8e5b41a1031af0231a7a17fa49f5f98edd3..3171069a6b461a7015acfc7fcef53dba257c46c3 100644 (file)
@@ -4,7 +4,7 @@
 TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh \
        conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh \
        nft_concat_range.sh nft_conntrack_helper.sh \
-       nft_queue.sh nft_meta.sh \
+       nft_queue.sh nft_meta.sh nf_nat_edemux.sh \
        ipip-conntrack-mtu.sh
 
 LDLIBS = -lmnl
diff --git a/tools/testing/selftests/netfilter/nf_nat_edemux.sh b/tools/testing/selftests/netfilter/nf_nat_edemux.sh
new file mode 100755 (executable)
index 0000000..cfee3b6
--- /dev/null
@@ -0,0 +1,99 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test NAT source port clash resolution
+#
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+ret=0
+
+sfx=$(mktemp -u "XXXXXXXX")
+ns1="ns1-$sfx"
+ns2="ns2-$sfx"
+
+cleanup()
+{
+       ip netns del $ns1
+       ip netns del $ns2
+}
+
+iperf3 -v > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without iperf3"
+       exit $ksft_skip
+fi
+
+iptables --version > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without iptables"
+       exit $ksft_skip
+fi
+
+ip -Version > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without ip tool"
+       exit $ksft_skip
+fi
+
+ip netns add "$ns1"
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not create net namespace $ns1"
+       exit $ksft_skip
+fi
+
+trap cleanup EXIT
+
+ip netns add $ns2
+
+# Connect the namespaces using a veth pair
+ip link add name veth2 type veth peer name veth1
+ip link set netns $ns1 dev veth1
+ip link set netns $ns2 dev veth2
+
+ip netns exec $ns1 ip link set up dev lo
+ip netns exec $ns1 ip link set up dev veth1
+ip netns exec $ns1 ip addr add 192.168.1.1/24 dev veth1
+
+ip netns exec $ns2 ip link set up dev lo
+ip netns exec $ns2 ip link set up dev veth2
+ip netns exec $ns2 ip addr add 192.168.1.2/24 dev veth2
+
+# Create a server in one namespace
+ip netns exec $ns1 iperf3 -s > /dev/null 2>&1 &
+iperfs=$!
+
+# Restrict source port to just one so we don't have to exhaust
+# all others.
+ip netns exec $ns2 sysctl -q net.ipv4.ip_local_port_range="10000 10000"
+
+# add a virtual IP using DNAT
+ip netns exec $ns2 iptables -t nat -A OUTPUT -d 10.96.0.1/32 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.1:5201
+
+# ... and route it to the other namespace
+ip netns exec $ns2 ip route add 10.96.0.1 via 192.168.1.1
+
+sleep 1
+
+# add a persistent connection from the other namespace
+ip netns exec $ns2 nc -q 10 -w 10 192.168.1.1 5201 > /dev/null &
+
+sleep 1
+
+# ip daddr:dport will be rewritten to 192.168.1.1 5201
+# NAT must reallocate source port 10000 because
+# 192.168.1.2:10000 -> 192.168.1.1:5201 is already in use
+echo test | ip netns exec $ns2 nc -w 3 -q 3 10.96.0.1 443 >/dev/null
+ret=$?
+
+kill $iperfs
+
+# Check nc can connect to 10.96.0.1:443 (aka 192.168.1.1:5201).
+if [ $ret -eq 0 ]; then
+       echo "PASS: nc can connect via NAT'd address"
+else
+       echo "FAIL: nc cannot connect via NAT'd address"
+       exit 1
+fi
+
+exit 0