Merge tag 'usb-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Dec 2021 21:16:43 +0000 (13:16 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Dec 2021 21:16:43 +0000 (13:16 -0800)
Pull USB fixes from Greg KH:
 "Here are a number of small USB driver fixes for reported problems.
  They include:

   - dwc2 driver fixes

   - xhci driver fixes

   - cdnsp driver fixes

   - typec driver fix

   - gadget u_ether driver fix

   - new quirk additions

   - usb gadget endpoint calculation fix

   - usb serial new device ids

   - revert of a xhci-dbg change that broke early debug booting

  All changes, except for the revert, have been in linux-next with no
  reported problems. The revert was from yesterday, and it was reported
  by the developers affected that it resolved their problem"

* tag 'usb-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  Revert "usb: early: convert to readl_poll_timeout_atomic()"
  usb: typec: tcpm: fix tcpm unregister port but leave a pending timer
  usb: cdnsp: Fix lack of spin_lock_irqsave/spin_lock_restore
  USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04)
  usb: xhci: Extend support for runtime power management for AMD's Yellow carp.
  usb: dwc2: fix STM ID/VBUS detection startup delay in dwc2_driver_probe
  USB: gadget: bRequestType is a bitfield, not a enum
  USB: serial: option: add Telit FN990 compositions
  USB: serial: cp210x: fix CP2105 GPIO registration
  usb: cdnsp: Fix incorrect status for control request
  usb: cdnsp: Fix issue in cdnsp_log_ep trace event
  usb: cdnsp: Fix incorrect calling of cdnsp_died function
  usb: xhci-mtk: fix list_del warning when enable list debug
  usb: gadget: u_ether: fix race in setting MAC address in setup phase

185 files changed:
Documentation/devicetree/bindings/i2c/apple,i2c.yaml
Documentation/networking/device_drivers/ethernet/intel/ixgbe.rst
MAINTAINERS
arch/arm/boot/dts/imx6qp-prtwd3.dts
arch/arm/boot/dts/imx6ull-pinfunc.h
arch/arm/boot/dts/ls1021a-tsn.dts
arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts
arch/arm/boot/dts/socfpga_arria5_socdk.dts
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
arch/arm/mach-rockchip/platsmp.c
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j100.dts
arch/arm64/boot/dts/apple/t8103-j274.dts
arch/arm64/boot/dts/apple/t8103.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts
arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts
arch/arm64/boot/dts/freescale/imx8mq.dtsi
arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts
arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
arch/arm64/kernel/machine_kexec_file.c
arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/kernel/ftrace.c
arch/s390/kernel/irq.c
arch/s390/kernel/machine_kexec_file.c
arch/x86/net/bpf_jit_comp.c
block/blk-core.c
block/blk-iocost.c
drivers/Makefile
drivers/ata/libata-scsi.c
drivers/clk/clk.c
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
drivers/dma/dw-edma/dw-edma-pcie.c
drivers/dma/idxd/irq.c
drivers/dma/idxd/submit.c
drivers/dma/st_fdma.c
drivers/dma/ti/k3-udma.c
drivers/firmware/scpi_pm_domain.c
drivers/firmware/tegra/bpmp-debugfs.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c
drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/i915/display/intel_dmc.c
drivers/gpu/drm/tiny/simpledrm.c
drivers/hv/Kconfig
drivers/md/bcache/super.c
drivers/md/dm-integrity.c
drivers/md/persistent-data/dm-btree-remove.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/port.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bcmsysport.h
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/ice/ice_ptp.c
drivers/net/ethernet/intel/ice/ice_ptp.h
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/igc/igc_i225.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/sfc/ef100_nic.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
drivers/net/ethernet/ti/am65-cpsw-nuss.c
drivers/net/netdevsim/bpf.c
drivers/net/netdevsim/ethtool.c
drivers/net/phy/mdio_bus.c
drivers/net/usb/lan78xx.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/wireless/broadcom/brcm80211/Kconfig
drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
drivers/net/wireless/intel/iwlegacy/Kconfig
drivers/net/wireless/intel/iwlwifi/Kconfig
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/mediatek/mt76/Makefile
drivers/pci/controller/Kconfig
drivers/reset/tegra/reset-bpmp.c
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/soc/imx/imx8m-blk-ctrl.c
drivers/soc/imx/soc-imx.c
drivers/soc/tegra/fuse/fuse-tegra.c
drivers/soc/tegra/fuse/fuse.h
drivers/tee/amdtee/core.c
drivers/vdpa/vdpa.c
drivers/vdpa/vdpa_user/vduse_dev.c
drivers/vhost/vdpa.c
drivers/virtio/virtio_ring.c
fs/afs/file.c
fs/afs/super.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-tree.c
fs/btrfs/ioctl.c
fs/btrfs/qgroup.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/ceph/caps.c
fs/ceph/file.c
fs/ceph/mds_client.c
fs/file.c
fs/io-wq.c
fs/zonefs/super.c
include/uapi/linux/mptcp.h
kernel/audit.c
kernel/bpf/verifier.c
net/core/skbuff.c
net/ipv4/inet_diag.c
net/ipv6/sit.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/driver-ops.h
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tx.c
net/mac80211/util.c
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/mptcp/sockopt.c
net/packet/af_packet.c
net/phonet/pep.c
net/rds/connection.c
net/sched/cls_api.c
net/sched/sch_cake.c
net/sched/sch_ets.c
net/smc/af_smc.c
net/vmw_vsock/virtio_transport_common.c
net/wireless/reg.c
net/xdp/xsk.c
scripts/recordmcount.pl
security/selinux/hooks.c
tools/perf/builtin-inject.c
tools/perf/util/expr.c
tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
tools/testing/selftests/bpf/prog_tests/btf_skc_cls_ingress.c
tools/testing/selftests/bpf/progs/test_module_attach.c
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c
tools/testing/selftests/bpf/verifier/atomic_fetch.c
tools/testing/selftests/bpf/verifier/search_pruning.c
tools/testing/selftests/bpf/verifier/spill_fill.c
tools/testing/selftests/bpf/verifier/value_ptr_arith.c
tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles_occ.sh
tools/testing/selftests/net/fcnal-test.sh
tools/testing/selftests/net/forwarding/forwarding.config.sample
tools/testing/selftests/net/icmp_redirect.sh
tools/testing/selftests/net/toeplitz.c

index 22fc8483256f1cdbca2438bbcbc0a313a78a1988..82b953181a5225a03d20e9d735fa6c3be38beb89 100644 (file)
@@ -20,9 +20,9 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - apple,t8103-i2c
-      - apple,i2c
+    items:
+      - const: apple,t8103-i2c
+      - const: apple,i2c
 
   reg:
     maxItems: 1
@@ -51,7 +51,7 @@ unevaluatedProperties: false
 examples:
   - |
     i2c@35010000 {
-      compatible = "apple,t8103-i2c";
+      compatible = "apple,t8103-i2c", "apple,i2c";
       reg = <0x35010000 0x4000>;
       interrupt-parent = <&aic>;
       interrupts = <0 627 4>;
index f1d5233e5e510929ba6d3f4f8cd049dc8767677c..0a233b17c664e202b245e65061cb28fd0f8621ea 100644 (file)
@@ -440,6 +440,22 @@ NOTE: For 82599-based network connections, if you are enabling jumbo frames in
 a virtual function (VF), jumbo frames must first be enabled in the physical
 function (PF). The VF MTU setting cannot be larger than the PF MTU.
 
+NBASE-T Support
+---------------
+The ixgbe driver supports NBASE-T on some devices. However, the advertisement
+of NBASE-T speeds is suppressed by default, to accommodate broken network
+switches which cannot cope with advertised NBASE-T speeds. Use the ethtool
+command to enable advertising NBASE-T speeds on devices which support it::
+
+  ethtool -s eth? advertise 0x1800000001028
+
+On Linux systems with INTERFACES(5), this can be specified as a pre-up command
+in /etc/network/interfaces so that the interface is always brought up with
+NBASE-T support, e.g.::
+
+  iface eth? inet dhcp
+       pre-up ethtool -s eth? advertise 0x1800000001028 || true
+
 Generic Receive Offload, aka GRO
 --------------------------------
 The driver supports the in-kernel software implementation of GRO. GRO has
index 13f9a84a617e309f0f7be5a682c5ccb1a5a824f1..8912b2c1260caab4caac9fc758cfcedb31bfe252 100644 (file)
@@ -3066,7 +3066,7 @@ F:        Documentation/devicetree/bindings/phy/phy-ath79-usb.txt
 F:     drivers/phy/qualcomm/phy-ath79-usb.c
 
 ATHEROS ATH GENERIC UTILITIES
-M:     Kalle Valo <kvalo@codeaurora.org>
+M:     Kalle Valo <kvalo@kernel.org>
 L:     linux-wireless@vger.kernel.org
 S:     Supported
 F:     drivers/net/wireless/ath/*
@@ -3081,7 +3081,7 @@ W:        https://wireless.wiki.kernel.org/en/users/Drivers/ath5k
 F:     drivers/net/wireless/ath/ath5k/
 
 ATHEROS ATH6KL WIRELESS DRIVER
-M:     Kalle Valo <kvalo@codeaurora.org>
+M:     Kalle Valo <kvalo@kernel.org>
 L:     linux-wireless@vger.kernel.org
 S:     Supported
 W:     https://wireless.wiki.kernel.org/en/users/Drivers/ath6kl
@@ -13248,7 +13248,7 @@ F:      include/uapi/linux/if_*
 F:     include/uapi/linux/netdevice.h
 
 NETWORKING DRIVERS (WIRELESS)
-M:     Kalle Valo <kvalo@codeaurora.org>
+M:     Kalle Valo <kvalo@kernel.org>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
 Q:     http://patchwork.kernel.org/project/linux-wireless/list/
@@ -15704,7 +15704,7 @@ T:      git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/qt1010*
 
 QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
-M:     Kalle Valo <kvalo@codeaurora.org>
+M:     Kalle Valo <kvalo@kernel.org>
 L:     ath10k@lists.infradead.org
 S:     Supported
 W:     https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
@@ -15712,7 +15712,7 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
 F:     drivers/net/wireless/ath/ath10k/
 
 QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
-M:     Kalle Valo <kvalo@codeaurora.org>
+M:     Kalle Valo <kvalo@kernel.org>
 L:     ath11k@lists.infradead.org
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
@@ -15885,7 +15885,7 @@ F:      Documentation/devicetree/bindings/media/*venus*
 F:     drivers/media/platform/qcom/venus/
 
 QUALCOMM WCN36XX WIRELESS DRIVER
-M:     Kalle Valo <kvalo@codeaurora.org>
+M:     Kalle Valo <kvalo@kernel.org>
 L:     wcn36xx@lists.infradead.org
 S:     Supported
 W:     https://wireless.wiki.kernel.org/en/users/Drivers/wcn36xx
@@ -21059,7 +21059,7 @@ S:      Maintained
 F:     arch/x86/kernel/cpu/zhaoxin.c
 
 ZONEFS FILESYSTEM
-M:     Damien Le Moal <damien.lemoal@wdc.com>
+M:     Damien Le Moal <damien.lemoal@opensource.wdc.com>
 M:     Naohiro Aota <naohiro.aota@wdc.com>
 R:     Johannes Thumshirn <jth@kernel.org>
 L:     linux-fsdevel@vger.kernel.org
index 7648e8a02000a3f37e1b14bb8b83f9683f94be38..cf6571cc4682e226773b5c996a44cb45b23e57ff 100644 (file)
                                label = "cpu";
                                ethernet = <&fec>;
                                phy-mode = "rgmii-id";
+                               rx-internal-delay-ps = <2000>;
+                               tx-internal-delay-ps = <2000>;
 
                                fixed-link {
                                        speed = <100>;
index eb025a9d4759255e57a3a3ba9b491167809278a2..7328d4ef8559f021aa087e5159f3275aef345452 100644 (file)
@@ -82,6 +82,6 @@
 #define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS                         0x01F4 0x0480 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK                        0x01F8 0x0484 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0                       0x01FC 0x0488 0x0000 0x9 0x0
-#define MX6ULL_PAD_CSI_DATA07__ESAI_T                           0x0200 0x048C 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA07__ESAI_TX0                           0x0200 0x048C 0x0000 0x9 0x0
 
 #endif /* __DTS_IMX6ULL_PINFUNC_H */
index ff0ffb22768b377aee7e594412989d75a84ae5cc..1ea32fff41201b7a787dd116eef675318861ad19 100644 (file)
@@ -91,6 +91,8 @@
                                /* Internal port connected to eth2 */
                                ethernet = <&enet2>;
                                phy-mode = "rgmii";
+                               rx-internal-delay-ps = <0>;
+                               tx-internal-delay-ps = <0>;
                                reg = <4>;
 
                                fixed-link {
index 2b645642b9352c13d2d0797d68a2053ec35df597..2a745522404d6b065ef71bbde83e648875d95014 100644 (file)
@@ -12,7 +12,7 @@
        flash0: n25q00@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q00aa";
+               compatible = "micron,mt25qu02g", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <100000000>;
 
index 90e676e7019f23377dd05bbf70b45f7af0d47ea5..1b02d46496a852786705a5875e5e5adc20d9540d 100644 (file)
        flash: flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q256a";
+               compatible = "micron,n25q256a", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <100000000>;
 
index 6f138b2b26163ada37d0c1cb0462ed70d44a4b4e..51bb436784e241470d7aba219b38323a37357007 100644 (file)
        flash0: n25q00@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q00";
+               compatible = "micron,mt25qu02g", "jedec,spi-nor";
                reg = <0>;      /* chip select */
                spi-max-frequency = <100000000>;
 
index c155ff02eb6e035a7c7e526635a80a5feda9b4d8..cae9ddd5ed38bbd57efe8371724e59aa49fb0ac2 100644 (file)
        flash: flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q00";
+               compatible = "micron,mt25qu02g", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <100000000>;
 
index 8d5d3996f6f27122412d68072767d621fa11ae8f..ca18b959e6559ebdd4515d71877211022559be19 100644 (file)
@@ -80,7 +80,7 @@
        flash: flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q256a";
+               compatible = "micron,n25q256a", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <100000000>;
                m25p,fast-read;
index 99a71757cdf46330418b65aeae3646668229c378..3f7aa7bf0863aa1150b64ad4a58e120a1bdf7fc1 100644 (file)
        flash0: n25q512a@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q512a";
+               compatible = "micron,n25q512a", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <100000000>;
 
index a060718758b6755a154c1842f95301d1a8c93806..25874e1b9c82987e090c7229cad34a07edb3c674 100644 (file)
        n25q128@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q128";
+               compatible = "micron,n25q128", "jedec,spi-nor";
                reg = <0>;              /* chip select */
                spi-max-frequency = <100000000>;
                m25p,fast-read;
        n25q00@1 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "n25q00";
+               compatible = "micron,mt25qu02g", "jedec,spi-nor";
                reg = <1>;              /* chip select */
                spi-max-frequency = <100000000>;
                m25p,fast-read;
index d60856898d97acaa51912e6097a5d968200b45bd..5ec58d004b7de85793fbbe9a01febf7dd0e399f6 100644 (file)
@@ -189,7 +189,7 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node)
        rockchip_boot_fn = __pa_symbol(secondary_startup);
 
        /* copy the trampoline to sram, that runs during startup of the core */
-       memcpy(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
+       memcpy_toio(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
        flush_cache_all();
        outer_clean_range(0, trampoline_sz);
 
index 1aa8b70732186e167f065b7175030529d2d1e293..54e3910e8b9bd4332e3ab689181de8c6ecbe9245 100644 (file)
@@ -161,7 +161,6 @@ config ARCH_MEDIATEK
 
 config ARCH_MESON
        bool "Amlogic Platforms"
-       select COMMON_CLK
        help
          This enables support for the arm64 based Amlogic SoCs
          such as the s905, S905X/D, S912, A113X/D or S905X/D2
index 52ebe371df2685ba89580883ce81149aa401398e..561eec21b4deb894ef206c43c8695cc0cb9655b2 100644 (file)
                                        type = "critical";
                                };
                        };
-               };
 
-               cpu_cooling_maps: cooling-maps {
-                       map0 {
-                               trip = <&cpu_passive>;
-                               cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                               <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                               <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                               <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
-                       };
+                       cpu_cooling_maps: cooling-maps {
+                               map0 {
+                                       trip = <&cpu_passive>;
+                                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
 
-                       map1 {
-                               trip = <&cpu_hot>;
-                               cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                               <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                               <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                               <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               map1 {
+                                       trip = <&cpu_hot>;
+                                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
                        };
                };
        };
index 33a80f9501dcaec0f986d1bdaa91ae7d0c6a7027..02c36301e985087d73ebed31f465f5c8b6d0a6f5 100644 (file)
@@ -60,7 +60,7 @@
 
 &port02 {
        bus-range = <3 3>;
-       ethernet0: pci@0,0 {
+       ethernet0: ethernet@0,0 {
                reg = <0x30000 0x0 0x0 0x0 0x0>;
                /* To be filled by the loader */
                local-mac-address = [00 10 18 00 00 00];
index e22c9433d5e0b908d64d0ceeb833b7b9313a9dec..8b61e7fd3e9c9844f8a02b747a3135474391c268 100644 (file)
                        apple,npins = <212>;
 
                        interrupt-controller;
+                       #interrupt-cells = <2>;
                        interrupt-parent = <&aic>;
                        interrupts = <AIC_IRQ 190 IRQ_TYPE_LEVEL_HIGH>,
                                     <AIC_IRQ 191 IRQ_TYPE_LEVEL_HIGH>,
                        apple,npins = <42>;
 
                        interrupt-controller;
+                       #interrupt-cells = <2>;
                        interrupt-parent = <&aic>;
                        interrupts = <AIC_IRQ 268 IRQ_TYPE_LEVEL_HIGH>,
                                     <AIC_IRQ 269 IRQ_TYPE_LEVEL_HIGH>,
                        apple,npins = <23>;
 
                        interrupt-controller;
+                       #interrupt-cells = <2>;
                        interrupt-parent = <&aic>;
                        interrupts = <AIC_IRQ 330 IRQ_TYPE_LEVEL_HIGH>,
                                     <AIC_IRQ 331 IRQ_TYPE_LEVEL_HIGH>,
                        apple,npins = <16>;
 
                        interrupt-controller;
+                       #interrupt-cells = <2>;
                        interrupt-parent = <&aic>;
                        interrupts = <AIC_IRQ 391 IRQ_TYPE_LEVEL_HIGH>,
                                     <AIC_IRQ 392 IRQ_TYPE_LEVEL_HIGH>,
index 3063851c2fb91e87248cc5c09b9148675b993b85..d3f03dcbb8c381c5a083bb0cc2f4e163ccb8e59e 100644 (file)
@@ -38,7 +38,6 @@
                powerdn {
                        label = "External Power Down";
                        gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
-                       interrupts = <&gpio1 17 IRQ_TYPE_EDGE_FALLING>;
                        linux,code = <KEY_POWER>;
                };
 
@@ -46,7 +45,6 @@
                admin {
                        label = "ADMIN button";
                        gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>;
-                       interrupts = <&gpio3 8 IRQ_TYPE_EDGE_RISING>;
                        linux,code = <KEY_WPS_BUTTON>;
                };
        };
index b21be03da0af117074f86700d15db6fef9d8d648..042c486bdda289333d953000b1d72d26cbc183da 100644 (file)
                                reg = <2>;
                                ethernet = <&dpmac17>;
                                phy-mode = "rgmii-id";
+                               rx-internal-delay-ps = <2000>;
+                               tx-internal-delay-ps = <2000>;
 
                                fixed-link {
                                        speed = <1000>;
                                reg = <2>;
                                ethernet = <&dpmac18>;
                                phy-mode = "rgmii-id";
+                               rx-internal-delay-ps = <2000>;
+                               tx-internal-delay-ps = <2000>;
 
                                fixed-link {
                                        speed = <1000>;
index 972766b67a15e2e6c40a9dbe4f2bbd03d52fe83d..71bf497f99c251fcc1723b172c5af47e1b23d3ff 100644 (file)
                                                  <&clk IMX8MQ_VIDEO_PLL1>,
                                                  <&clk IMX8MQ_VIDEO_PLL1_OUT>;
                                assigned-clock-rates = <0>, <0>, <0>, <594000000>;
-                               interconnects = <&noc IMX8MQ_ICM_LCDIF &noc IMX8MQ_ICS_DRAM>;
-                               interconnect-names = "dram";
                                status = "disabled";
 
                                port@0 {
index 665b2e69455dd1c8363602db9f9b63219f7d4063..ea6820902ede0401ccc7161025084ddbed6c8b34 100644 (file)
@@ -97,7 +97,7 @@
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
                regulator-boot-on;
-               vim-supply = <&vcc_io>;
+               vin-supply = <&vcc_io>;
        };
 
        vdd_core: vdd-core {
index d5c7648c841dc7d12ca42aae4d0ab85b774caa3f..f1fcc6b5b402c7e95f72bf2571587951bdedfe2e 100644 (file)
 &sdhci {
        bus-width = <8>;
        mmc-hs400-1_8v;
-       mmc-hs400-enhanced-strobe;
        non-removable;
        status = "okay";
 };
index 63c7681843daa60624ebf29e94f4aa335f440b63..b6ac00f6461370782a616643300746a9be011d4a 100644 (file)
                clock-output-names = "xin32k", "rk808-clkout2";
                pinctrl-names = "default";
                pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
                vcc1-supply = <&vcc5v0_sys>;
                vcc2-supply = <&vcc5v0_sys>;
                vcc3-supply = <&vcc5v0_sys>;
index 7c93f840bc64f9f2cca0f1bb7fae3eff9a452b23..e890166e7fd43701c0c5febe1d78acce77ccf354 100644 (file)
@@ -55,7 +55,7 @@
                regulator-boot-on;
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               vim-supply = <&vcc3v3_sys>;
+               vin-supply = <&vcc3v3_sys>;
        };
 
        vcc3v3_sys: vcc3v3-sys {
index 98136c88fa49792e8bff5f6de2dcc147a454b3a8..6a434be6281930aa4b8d50634d52915717c64ab4 100644 (file)
        status = "okay";
 
        bt656-supply = <&vcc_3v0>;
-       audio-supply = <&vcc_3v0>;
+       audio-supply = <&vcc1v8_codec>;
        sdmmc-supply = <&vcc_sdio>;
        gpio1830-supply = <&vcc_3v0>;
 };
index 63634b4d72c158f3e3ea487b3ae36d8a75f0a398..59c648d518488869b6cc4c6b227933aa3419bedd 100644 (file)
@@ -149,6 +149,7 @@ int load_other_segments(struct kimage *image,
                                           initrd_len, cmdline, 0);
        if (!dtb) {
                pr_err("Preparing for new dtb failed\n");
+               ret = -EINVAL;
                goto out_err;
        }
 
index ba304d4c455c2a449a737d56c65f3a1e4c09b37b..ced0d4e479385aa54ae571be1a05c2bd519f0286 100644 (file)
@@ -76,6 +76,7 @@
                spi-max-frequency = <20000000>;
                voltage-ranges = <3300 3300>;
                disable-wp;
+               gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
        };
 };
 
index 4f66919215f6eb1478d379a675d8c61e11f977fc..6bfa1f24d3deb45e493a0d4bb8bc75b1f06b6ffa 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright (c) 2020 SiFive, Inc */
 
 #include "fu740-c000.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
 /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
        temperature-sensor@4c {
                compatible = "ti,tmp451";
                reg = <0x4c>;
+               vcc-supply = <&vdd_bpro>;
                interrupt-parent = <&gpio>;
                interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
        };
 
+       eeprom@54 {
+               compatible = "microchip,24c02", "atmel,24c02";
+               reg = <0x54>;
+               vcc-supply = <&vdd_bpro>;
+               label = "board-id";
+               pagesize = <16>;
+               read-only;
+               size = <256>;
+       };
+
        pmic@58 {
                compatible = "dlg,da9063";
                reg = <0x58>;
                interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
                interrupt-controller;
 
-               regulators {
-                       vdd_bcore1: bcore1 {
-                               regulator-min-microvolt = <900000>;
-                               regulator-max-microvolt = <900000>;
-                               regulator-min-microamp = <5000000>;
-                               regulator-max-microamp = <5000000>;
-                               regulator-always-on;
-                       };
+               onkey {
+                       compatible = "dlg,da9063-onkey";
+               };
 
-                       vdd_bcore2: bcore2 {
-                               regulator-min-microvolt = <900000>;
-                               regulator-max-microvolt = <900000>;
-                               regulator-min-microamp = <5000000>;
-                               regulator-max-microamp = <5000000>;
+               rtc {
+                       compatible = "dlg,da9063-rtc";
+               };
+
+               wdt {
+                       compatible = "dlg,da9063-watchdog";
+               };
+
+               regulators {
+                       vdd_bcore: bcores-merged {
+                               regulator-min-microvolt = <1050000>;
+                               regulator-max-microvolt = <1050000>;
+                               regulator-min-microamp = <4800000>;
+                               regulator-max-microamp = <4800000>;
                                regulator-always-on;
                        };
 
                        vdd_bpro: bpro {
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <2500000>;
-                               regulator-max-microamp = <2500000>;
+                               regulator-min-microamp = <2400000>;
+                               regulator-max-microamp = <2400000>;
                                regulator-always-on;
                        };
 
                        vdd_bperi: bperi {
-                               regulator-min-microvolt = <1050000>;
-                               regulator-max-microvolt = <1050000>;
+                               regulator-min-microvolt = <1060000>;
+                               regulator-max-microvolt = <1060000>;
                                regulator-min-microamp = <1500000>;
                                regulator-max-microamp = <1500000>;
                                regulator-always-on;
                        };
 
-                       vdd_bmem: bmem {
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <1200000>;
-                               regulator-min-microamp = <3000000>;
-                               regulator-max-microamp = <3000000>;
-                               regulator-always-on;
-                       };
-
-                       vdd_bio: bio {
+                       vdd_bmem_bio: bmem-bio-merged {
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <1200000>;
                                regulator-min-microamp = <3000000>;
                        vdd_ldo1: ldo1 {
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <100000>;
-                               regulator-max-microamp = <100000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo2: ldo2 {
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo3: ldo3 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo4: ldo4 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo5: ldo5 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <100000>;
-                               regulator-max-microamp = <100000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo6: ldo6 {
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo7: ldo7 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
                                regulator-always-on;
                        };
 
                        vdd_ldo8: ldo8 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
                                regulator-always-on;
                        };
 
                        vdd_ld09: ldo9 {
                                regulator-min-microvolt = <1050000>;
                                regulator-max-microvolt = <1050000>;
-                               regulator-min-microamp = <200000>;
-                               regulator-max-microamp = <200000>;
+                               regulator-always-on;
                        };
 
                        vdd_ldo10: ldo10 {
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <1000000>;
-                               regulator-min-microamp = <300000>;
-                               regulator-max-microamp = <300000>;
+                               regulator-always-on;
                        };
 
                        vdd_ldo11: ldo11 {
                                regulator-min-microvolt = <2500000>;
                                regulator-max-microvolt = <2500000>;
-                               regulator-min-microamp = <300000>;
-                               regulator-max-microamp = <300000>;
                                regulator-always-on;
                        };
                };
                spi-max-frequency = <20000000>;
                voltage-ranges = <3300 3300>;
                disable-wp;
+               gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
        };
 };
 
 
 &gpio {
        status = "okay";
+       gpio-line-names = "J29.1", "PMICNTB", "PMICSHDN", "J8.1", "J8.3",
+               "PCIe_PWREN", "THERM", "UBRDG_RSTN", "PCIe_PERSTN",
+               "ULPI_RSTN", "J8.2", "UHUB_RSTN", "GEMGXL_RST", "J8.4",
+               "EN_VDD_SD", "SD_CD";
 };
index b626bc6e0eaf9809a3e81fa06c398a9fb7f01cbc..e45cc27716deee2270a796615982aba8e6c91ca3 100644 (file)
@@ -117,6 +117,7 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=m
 CONFIG_XFRM_USER=m
 CONFIG_NET_KEY=m
+CONFIG_NET_SWITCHDEV=y
 CONFIG_SMC=m
 CONFIG_SMC_DIAG=m
 CONFIG_INET=y
@@ -511,6 +512,7 @@ CONFIG_NLMON=m
 CONFIG_MLX4_EN=m
 CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
+CONFIG_MLX5_ESWITCH=y
 # CONFIG_NET_VENDOR_MICREL is not set
 # CONFIG_NET_VENDOR_MICROCHIP is not set
 # CONFIG_NET_VENDOR_MICROSEMI is not set
index 0056cab273723d9c0423f4aee4f397d6852c4797..1c750bfca2d8dd7750a7f71e027d8467e91401af 100644 (file)
@@ -109,6 +109,7 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=m
 CONFIG_XFRM_USER=m
 CONFIG_NET_KEY=m
+CONFIG_NET_SWITCHDEV=y
 CONFIG_SMC=m
 CONFIG_SMC_DIAG=m
 CONFIG_INET=y
@@ -502,6 +503,7 @@ CONFIG_NLMON=m
 CONFIG_MLX4_EN=m
 CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
+CONFIG_MLX5_ESWITCH=y
 # CONFIG_NET_VENDOR_MICREL is not set
 # CONFIG_NET_VENDOR_MICROCHIP is not set
 # CONFIG_NET_VENDOR_MICROSEMI is not set
index 5510c7d10ddc31fed07af20d57e793bc4a3ae97a..21d62d8b6b9afe7f8698a5d2e796a7fdef0d1639 100644 (file)
@@ -290,7 +290,6 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
                return;
 
        regs = ftrace_get_regs(fregs);
-       preempt_disable_notrace();
        p = get_kprobe((kprobe_opcode_t *)ip);
        if (unlikely(!p) || kprobe_disabled(p))
                goto out;
@@ -318,7 +317,6 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
        }
        __this_cpu_write(current_kprobe, NULL);
 out:
-       preempt_enable_notrace();
        ftrace_test_recursion_unlock(bit);
 }
 NOKPROBE_SYMBOL(kprobe_ftrace_handler);
index 0df83ecaa2e0c0c6e94199fe33b4f6db64baa798..cb70996823401c1b7aef7223f76225c8849b93de 100644 (file)
@@ -138,7 +138,7 @@ void noinstr do_io_irq(struct pt_regs *regs)
        struct pt_regs *old_regs = set_irq_regs(regs);
        int from_idle;
 
-       irq_enter();
+       irq_enter_rcu();
 
        if (user_mode(regs)) {
                update_timer_sys();
@@ -158,7 +158,8 @@ void noinstr do_io_irq(struct pt_regs *regs)
                        do_irq_async(regs, IO_INTERRUPT);
        } while (MACHINE_IS_LPAR && irq_pending(regs));
 
-       irq_exit();
+       irq_exit_rcu();
+
        set_irq_regs(old_regs);
        irqentry_exit(regs, state);
 
@@ -172,7 +173,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
        struct pt_regs *old_regs = set_irq_regs(regs);
        int from_idle;
 
-       irq_enter();
+       irq_enter_rcu();
 
        if (user_mode(regs)) {
                update_timer_sys();
@@ -190,7 +191,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
 
        do_irq_async(regs, EXT_INTERRUPT);
 
-       irq_exit();
+       irq_exit_rcu();
        set_irq_regs(old_regs);
        irqentry_exit(regs, state);
 
index 9975ad200d74790d5aebc2c9c4f72d78a0bdf39b..8f43575a4dd32a33df9a3984880d0a05f0ef480a 100644 (file)
@@ -7,6 +7,8 @@
  * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
  */
 
+#define pr_fmt(fmt)    "kexec: " fmt
+
 #include <linux/elf.h>
 #include <linux/errno.h>
 #include <linux/kexec.h>
@@ -290,8 +292,16 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
                                     const Elf_Shdr *relsec,
                                     const Elf_Shdr *symtab)
 {
+       const char *strtab, *name, *shstrtab;
+       const Elf_Shdr *sechdrs;
        Elf_Rela *relas;
        int i, r_type;
+       int ret;
+
+       /* String & section header string table */
+       sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff;
+       strtab = (char *)pi->ehdr + sechdrs[symtab->sh_link].sh_offset;
+       shstrtab = (char *)pi->ehdr + sechdrs[pi->ehdr->e_shstrndx].sh_offset;
 
        relas = (void *)pi->ehdr + relsec->sh_offset;
 
@@ -304,15 +314,27 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
                sym = (void *)pi->ehdr + symtab->sh_offset;
                sym += ELF64_R_SYM(relas[i].r_info);
 
-               if (sym->st_shndx == SHN_UNDEF)
+               if (sym->st_name)
+                       name = strtab + sym->st_name;
+               else
+                       name = shstrtab + sechdrs[sym->st_shndx].sh_name;
+
+               if (sym->st_shndx == SHN_UNDEF) {
+                       pr_err("Undefined symbol: %s\n", name);
                        return -ENOEXEC;
+               }
 
-               if (sym->st_shndx == SHN_COMMON)
+               if (sym->st_shndx == SHN_COMMON) {
+                       pr_err("symbol '%s' in common section\n", name);
                        return -ENOEXEC;
+               }
 
                if (sym->st_shndx >= pi->ehdr->e_shnum &&
-                   sym->st_shndx != SHN_ABS)
+                   sym->st_shndx != SHN_ABS) {
+                       pr_err("Invalid section %d for symbol %s\n",
+                              sym->st_shndx, name);
                        return -ENOEXEC;
+               }
 
                loc = pi->purgatory_buf;
                loc += section->sh_offset;
@@ -326,7 +348,15 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
                addr = section->sh_addr + relas[i].r_offset;
 
                r_type = ELF64_R_TYPE(relas[i].r_info);
-               arch_kexec_do_relocs(r_type, loc, val, addr);
+
+               if (r_type == R_390_PLT32DBL)
+                       r_type = R_390_PC32DBL;
+
+               ret = arch_kexec_do_relocs(r_type, loc, val, addr);
+               if (ret) {
+                       pr_err("Unknown rela relocation: %d\n", r_type);
+                       return -ENOEXEC;
+               }
        }
        return 0;
 }
index 726700fabca6d4f263b3b45f659a736e4c7013e4..bafe36e69227d81e30d81ef2680ace5b8d8da39b 100644 (file)
@@ -1252,19 +1252,54 @@ st:                     if (is_imm8(insn->off))
                case BPF_LDX | BPF_MEM | BPF_DW:
                case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
                        if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
-                               /* test src_reg, src_reg */
-                               maybe_emit_mod(&prog, src_reg, src_reg, true); /* always 1 byte */
-                               EMIT2(0x85, add_2reg(0xC0, src_reg, src_reg));
-                               /* jne start_of_ldx */
-                               EMIT2(X86_JNE, 0);
+                               /* Though the verifier prevents negative insn->off in BPF_PROBE_MEM
+                                * add abs(insn->off) to the limit to make sure that negative
+                                * offset won't be an issue.
+                                * insn->off is s16, so it won't affect valid pointers.
+                                */
+                               u64 limit = TASK_SIZE_MAX + PAGE_SIZE + abs(insn->off);
+                               u8 *end_of_jmp1, *end_of_jmp2;
+
+                               /* Conservatively check that src_reg + insn->off is a kernel address:
+                                * 1. src_reg + insn->off >= limit
+                                * 2. src_reg + insn->off doesn't become small positive.
+                                * Cannot do src_reg + insn->off >= limit in one branch,
+                                * since it needs two spare registers, but JIT has only one.
+                                */
+
+                               /* movabsq r11, limit */
+                               EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG));
+                               EMIT((u32)limit, 4);
+                               EMIT(limit >> 32, 4);
+                               /* cmp src_reg, r11 */
+                               maybe_emit_mod(&prog, src_reg, AUX_REG, true);
+                               EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG));
+                               /* if unsigned '<' goto end_of_jmp2 */
+                               EMIT2(X86_JB, 0);
+                               end_of_jmp1 = prog;
+
+                               /* mov r11, src_reg */
+                               emit_mov_reg(&prog, true, AUX_REG, src_reg);
+                               /* add r11, insn->off */
+                               maybe_emit_1mod(&prog, AUX_REG, true);
+                               EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off);
+                               /* jmp if not carry to start_of_ldx
+                                * Otherwise ERR_PTR(-EINVAL) + 128 will be the user addr
+                                * that has to be rejected.
+                                */
+                               EMIT2(0x73 /* JNC */, 0);
+                               end_of_jmp2 = prog;
+
                                /* xor dst_reg, dst_reg */
                                emit_mov_imm32(&prog, false, dst_reg, 0);
                                /* jmp byte_after_ldx */
                                EMIT2(0xEB, 0);
 
-                               /* populate jmp_offset for JNE above */
-                               temp[4] = prog - temp - 5 /* sizeof(test + jne) */;
+                               /* populate jmp_offset for JB above to jump to xor dst_reg */
+                               end_of_jmp1[-1] = end_of_jmp2 - end_of_jmp1;
+                               /* populate jmp_offset for JNC above to jump to start_of_ldx */
                                start_of_ldx = prog;
+                               end_of_jmp2[-1] = start_of_ldx - end_of_jmp2;
                        }
                        emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
                        if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
@@ -1305,7 +1340,7 @@ st:                       if (is_imm8(insn->off))
                                 * End result: x86 insn "mov rbx, qword ptr [rax+0x14]"
                                 * of 4 bytes will be ignored and rbx will be zero inited.
                                 */
-                               ex->fixup = (prog - temp) | (reg2pt_regs[dst_reg] << 8);
+                               ex->fixup = (prog - start_of_ldx) | (reg2pt_regs[dst_reg] << 8);
                        }
                        break;
 
index 1378d084c770f6641a911caf8d98d302026fa689..c1833f95cb9728eb3023255fc4e0c42711ded297 100644 (file)
@@ -1484,6 +1484,8 @@ EXPORT_SYMBOL(kblockd_schedule_work);
 int kblockd_mod_delayed_work_on(int cpu, struct delayed_work *dwork,
                                unsigned long delay)
 {
+       if (!delay)
+               return queue_work_on(cpu, kblockd_workqueue, &dwork->work);
        return mod_delayed_work_on(cpu, kblockd_workqueue, dwork, delay);
 }
 EXPORT_SYMBOL(kblockd_mod_delayed_work_on);
index a5b37cc65b171f3362ce87ab590cac8d2c65bee2..769b64394298995288a3005e9e3638897c395d24 100644 (file)
@@ -2311,7 +2311,14 @@ static void ioc_timer_fn(struct timer_list *timer)
                        hwm = current_hweight_max(iocg);
                        new_hwi = hweight_after_donation(iocg, old_hwi, hwm,
                                                         usage, &now);
-                       if (new_hwi < hwm) {
+                       /*
+                        * Donation calculation assumes hweight_after_donation
+                        * to be positive, a condition that a donor w/ hwa < 2
+                        * can't meet. Don't bother with donation if hwa is
+                        * below 2. It's not gonna make a meaningful difference
+                        * anyway.
+                        */
+                       if (new_hwi < hwm && hwa >= 2) {
                                iocg->hweight_donating = hwa;
                                iocg->hweight_after_donation = new_hwi;
                                list_add(&iocg->surplus_list, &surpluses);
index be5d40ae14882ddf7daba9e3df16ce1499bffd3e..a110338c860c770d4affa688375dc2086007a6b5 100644 (file)
@@ -41,8 +41,7 @@ obj-$(CONFIG_DMADEVICES)      += dma/
 # SOC specific infrastructure drivers.
 obj-y                          += soc/
 
-obj-$(CONFIG_VIRTIO)           += virtio/
-obj-$(CONFIG_VIRTIO_PCI_LIB)   += virtio/
+obj-y                          += virtio/
 obj-$(CONFIG_VDPA)             += vdpa/
 obj-$(CONFIG_XEN)              += xen/
 
index 1b84d5526d77a40ff5451e26c6d6b37cf26d94ef..313e9475507b5a7f1f7505331066e32ecf371f0c 100644 (file)
@@ -2859,8 +2859,19 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                goto invalid_fld;
        }
 
-       if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0)
-               tf->protocol = ATA_PROT_NCQ_NODATA;
+       if ((cdb[2 + cdb_offset] & 0x3) == 0) {
+               /*
+                * When T_LENGTH is zero (No data is transferred), dir should
+                * be DMA_NONE.
+                */
+               if (scmd->sc_data_direction != DMA_NONE) {
+                       fp = 2 + cdb_offset;
+                       goto invalid_fld;
+               }
+
+               if (ata_is_ncq(tf->protocol))
+                       tf->protocol = ATA_PROT_NCQ_NODATA;
+       }
 
        /* enable LBA */
        tf->flags |= ATA_TFLAG_LBA;
index f467d63bbf1eefdbc937a324eb477547d6deb5c6..566ee2c78709e344f7361ce5108f4f6d1d7b7f71 100644 (file)
@@ -3418,6 +3418,14 @@ static int __clk_core_init(struct clk_core *core)
 
        clk_prepare_lock();
 
+       /*
+        * Set hw->core after grabbing the prepare_lock to synchronize with
+        * callers of clk_core_fill_parent_index() where we treat hw->core
+        * being NULL as the clk not being registered yet. This is crucial so
+        * that clks aren't parented until their parent is fully registered.
+        */
+       core->hw->core = core;
+
        ret = clk_pm_runtime_get(core);
        if (ret)
                goto unlock;
@@ -3582,8 +3590,10 @@ static int __clk_core_init(struct clk_core *core)
 out:
        clk_pm_runtime_put(core);
 unlock:
-       if (ret)
+       if (ret) {
                hlist_del_init(&core->child_node);
+               core->hw->core = NULL;
+       }
 
        clk_prepare_unlock();
 
@@ -3847,7 +3857,6 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
        core->num_parents = init->num_parents;
        core->min_rate = 0;
        core->max_rate = ULONG_MAX;
-       hw->core = core;
 
        ret = clk_core_populate_parent_map(core, init);
        if (ret)
@@ -3865,7 +3874,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
                goto fail_create_clk;
        }
 
-       clk_core_link_consumer(hw->core, hw->clk);
+       clk_core_link_consumer(core, hw->clk);
 
        ret = __clk_core_init(core);
        if (!ret)
index cd0d745eb0714e6f1c756bc2cbb09c775e7023ba..33baf1591a490590da48dfafc02a7f1b684e0818 100644 (file)
@@ -373,7 +373,7 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
                                      struct axi_dma_desc *first)
 {
        u32 priority = chan->chip->dw->hdata->priority[chan->id];
-       struct axi_dma_chan_config config;
+       struct axi_dma_chan_config config = {};
        u32 irq_mask;
        u8 lms = 0; /* Select AXI0 master for LLI fetching */
 
@@ -391,7 +391,7 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
        config.tt_fc = DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC;
        config.prior = priority;
        config.hs_sel_dst = DWAXIDMAC_HS_SEL_HW;
-       config.hs_sel_dst = DWAXIDMAC_HS_SEL_HW;
+       config.hs_sel_src = DWAXIDMAC_HS_SEL_HW;
        switch (chan->direction) {
        case DMA_MEM_TO_DEV:
                dw_axi_dma_set_byte_halfword(chan, true);
index 198f6cd8ac1be18bd35a6ef534d3e34d90336bd0..cee7aa231d7b19e4dbe0f0af91eb28a2f0989318 100644 (file)
@@ -187,17 +187,9 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev,
 
        /* DMA configuration */
        err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
-       if (!err) {
+       if (err) {
                pci_err(pdev, "DMA mask 64 set failed\n");
                return err;
-       } else {
-               pci_err(pdev, "DMA mask 64 set failed\n");
-
-               err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-               if (err) {
-                       pci_err(pdev, "DMA mask 32 set failed\n");
-                       return err;
-               }
        }
 
        /* Data structure allocation */
index 17f2f8a31b6303638f0e29db18b980b3f8b961e4..cf2c8bc4f147aaacb6c0bd7e0f4f7c895f49fd79 100644 (file)
@@ -137,10 +137,10 @@ halt:
                        INIT_WORK(&idxd->work, idxd_device_reinit);
                        queue_work(idxd->wq, &idxd->work);
                } else {
-                       spin_lock(&idxd->dev_lock);
                        idxd->state = IDXD_DEV_HALTED;
                        idxd_wqs_quiesce(idxd);
                        idxd_wqs_unmap_portal(idxd);
+                       spin_lock(&idxd->dev_lock);
                        idxd_device_clear_state(idxd);
                        dev_err(&idxd->pdev->dev,
                                "idxd halted, need %s.\n",
index de76fb4abac24af94f143f5255ff51aa8fe93c37..83452fbbb168b156ff75f481124198564c3c21d3 100644 (file)
@@ -106,6 +106,7 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
 {
        struct idxd_desc *d, *t, *found = NULL;
        struct llist_node *head;
+       LIST_HEAD(flist);
 
        desc->completion->status = IDXD_COMP_DESC_ABORT;
        /*
@@ -120,7 +121,11 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
                                found = desc;
                                continue;
                        }
-                       list_add_tail(&desc->list, &ie->work_list);
+
+                       if (d->completion->status)
+                               list_add_tail(&d->list, &flist);
+                       else
+                               list_add_tail(&d->list, &ie->work_list);
                }
        }
 
@@ -130,6 +135,17 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
 
        if (found)
                complete_desc(found, IDXD_COMPLETE_ABORT);
+
+       /*
+        * complete_desc() will return desc to allocator and the desc can be
+        * acquired by a different process and the desc->list can be modified.
+        * Delete desc from list so the list trasversing does not get corrupted
+        * by the other process.
+        */
+       list_for_each_entry_safe(d, t, &flist, list) {
+               list_del_init(&d->list);
+               complete_desc(d, IDXD_COMPLETE_NORMAL);
+       }
 }
 
 int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)
index 962b6e05287b5f46f03dcb7df7a0f56cf9c7c80c..d95c421877fb7361b1da14c8ed8a93e34faea985 100644 (file)
@@ -874,4 +874,4 @@ MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
 MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
 MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
-MODULE_ALIAS("platform: " DRIVER_NAME);
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 041d8e32d6300551210769a339d1acafd4ad5a8d..6e56d1cef5eeec0343a65dc9688935cb691647d5 100644 (file)
@@ -4534,45 +4534,60 @@ static int udma_setup_resources(struct udma_dev *ud)
        rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
        if (IS_ERR(rm_res)) {
                bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+               irq_res.sets = 1;
        } else {
                bitmap_fill(ud->tchan_map, ud->tchan_cnt);
                for (i = 0; i < rm_res->sets; i++)
                        udma_mark_resource_ranges(ud, ud->tchan_map,
                                                  &rm_res->desc[i], "tchan");
+               irq_res.sets = rm_res->sets;
        }
-       irq_res.sets = rm_res->sets;
 
        /* rchan and matching default flow ranges */
        rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
        if (IS_ERR(rm_res)) {
                bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+               irq_res.sets++;
        } else {
                bitmap_fill(ud->rchan_map, ud->rchan_cnt);
                for (i = 0; i < rm_res->sets; i++)
                        udma_mark_resource_ranges(ud, ud->rchan_map,
                                                  &rm_res->desc[i], "rchan");
+               irq_res.sets += rm_res->sets;
        }
 
-       irq_res.sets += rm_res->sets;
        irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
+       if (!irq_res.desc)
+               return -ENOMEM;
        rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-       for (i = 0; i < rm_res->sets; i++) {
-               irq_res.desc[i].start = rm_res->desc[i].start;
-               irq_res.desc[i].num = rm_res->desc[i].num;
-               irq_res.desc[i].start_sec = rm_res->desc[i].start_sec;
-               irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+       if (IS_ERR(rm_res)) {
+               irq_res.desc[0].start = 0;
+               irq_res.desc[0].num = ud->tchan_cnt;
+               i = 1;
+       } else {
+               for (i = 0; i < rm_res->sets; i++) {
+                       irq_res.desc[i].start = rm_res->desc[i].start;
+                       irq_res.desc[i].num = rm_res->desc[i].num;
+                       irq_res.desc[i].start_sec = rm_res->desc[i].start_sec;
+                       irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+               }
        }
        rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-       for (j = 0; j < rm_res->sets; j++, i++) {
-               if (rm_res->desc[j].num) {
-                       irq_res.desc[i].start = rm_res->desc[j].start +
-                                       ud->soc_data->oes.udma_rchan;
-                       irq_res.desc[i].num = rm_res->desc[j].num;
-               }
-               if (rm_res->desc[j].num_sec) {
-                       irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
-                                       ud->soc_data->oes.udma_rchan;
-                       irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+       if (IS_ERR(rm_res)) {
+               irq_res.desc[i].start = 0;
+               irq_res.desc[i].num = ud->rchan_cnt;
+       } else {
+               for (j = 0; j < rm_res->sets; j++, i++) {
+                       if (rm_res->desc[j].num) {
+                               irq_res.desc[i].start = rm_res->desc[j].start +
+                                               ud->soc_data->oes.udma_rchan;
+                               irq_res.desc[i].num = rm_res->desc[j].num;
+                       }
+                       if (rm_res->desc[j].num_sec) {
+                               irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+                                               ud->soc_data->oes.udma_rchan;
+                               irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+                       }
                }
        }
        ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
@@ -4690,14 +4705,15 @@ static int bcdma_setup_resources(struct udma_dev *ud)
                rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
                if (IS_ERR(rm_res)) {
                        bitmap_zero(ud->bchan_map, ud->bchan_cnt);
+                       irq_res.sets++;
                } else {
                        bitmap_fill(ud->bchan_map, ud->bchan_cnt);
                        for (i = 0; i < rm_res->sets; i++)
                                udma_mark_resource_ranges(ud, ud->bchan_map,
                                                          &rm_res->desc[i],
                                                          "bchan");
+                       irq_res.sets += rm_res->sets;
                }
-               irq_res.sets += rm_res->sets;
        }
 
        /* tchan ranges */
@@ -4705,14 +4721,15 @@ static int bcdma_setup_resources(struct udma_dev *ud)
                rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
                if (IS_ERR(rm_res)) {
                        bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+                       irq_res.sets += 2;
                } else {
                        bitmap_fill(ud->tchan_map, ud->tchan_cnt);
                        for (i = 0; i < rm_res->sets; i++)
                                udma_mark_resource_ranges(ud, ud->tchan_map,
                                                          &rm_res->desc[i],
                                                          "tchan");
+                       irq_res.sets += rm_res->sets * 2;
                }
-               irq_res.sets += rm_res->sets * 2;
        }
 
        /* rchan ranges */
@@ -4720,47 +4737,72 @@ static int bcdma_setup_resources(struct udma_dev *ud)
                rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
                if (IS_ERR(rm_res)) {
                        bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+                       irq_res.sets += 2;
                } else {
                        bitmap_fill(ud->rchan_map, ud->rchan_cnt);
                        for (i = 0; i < rm_res->sets; i++)
                                udma_mark_resource_ranges(ud, ud->rchan_map,
                                                          &rm_res->desc[i],
                                                          "rchan");
+                       irq_res.sets += rm_res->sets * 2;
                }
-               irq_res.sets += rm_res->sets * 2;
        }
 
        irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
+       if (!irq_res.desc)
+               return -ENOMEM;
        if (ud->bchan_cnt) {
                rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
-               for (i = 0; i < rm_res->sets; i++) {
-                       irq_res.desc[i].start = rm_res->desc[i].start +
-                                               oes->bcdma_bchan_ring;
-                       irq_res.desc[i].num = rm_res->desc[i].num;
+               if (IS_ERR(rm_res)) {
+                       irq_res.desc[0].start = oes->bcdma_bchan_ring;
+                       irq_res.desc[0].num = ud->bchan_cnt;
+                       i = 1;
+               } else {
+                       for (i = 0; i < rm_res->sets; i++) {
+                               irq_res.desc[i].start = rm_res->desc[i].start +
+                                                       oes->bcdma_bchan_ring;
+                               irq_res.desc[i].num = rm_res->desc[i].num;
+                       }
                }
        }
        if (ud->tchan_cnt) {
                rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-               for (j = 0; j < rm_res->sets; j++, i += 2) {
-                       irq_res.desc[i].start = rm_res->desc[j].start +
-                                               oes->bcdma_tchan_data;
-                       irq_res.desc[i].num = rm_res->desc[j].num;
-
-                       irq_res.desc[i + 1].start = rm_res->desc[j].start +
-                                               oes->bcdma_tchan_ring;
-                       irq_res.desc[i + 1].num = rm_res->desc[j].num;
+               if (IS_ERR(rm_res)) {
+                       irq_res.desc[i].start = oes->bcdma_tchan_data;
+                       irq_res.desc[i].num = ud->tchan_cnt;
+                       irq_res.desc[i + 1].start = oes->bcdma_tchan_ring;
+                       irq_res.desc[i + 1].num = ud->tchan_cnt;
+                       i += 2;
+               } else {
+                       for (j = 0; j < rm_res->sets; j++, i += 2) {
+                               irq_res.desc[i].start = rm_res->desc[j].start +
+                                                       oes->bcdma_tchan_data;
+                               irq_res.desc[i].num = rm_res->desc[j].num;
+
+                               irq_res.desc[i + 1].start = rm_res->desc[j].start +
+                                                       oes->bcdma_tchan_ring;
+                               irq_res.desc[i + 1].num = rm_res->desc[j].num;
+                       }
                }
        }
        if (ud->rchan_cnt) {
                rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-               for (j = 0; j < rm_res->sets; j++, i += 2) {
-                       irq_res.desc[i].start = rm_res->desc[j].start +
-                                               oes->bcdma_rchan_data;
-                       irq_res.desc[i].num = rm_res->desc[j].num;
-
-                       irq_res.desc[i + 1].start = rm_res->desc[j].start +
-                                               oes->bcdma_rchan_ring;
-                       irq_res.desc[i + 1].num = rm_res->desc[j].num;
+               if (IS_ERR(rm_res)) {
+                       irq_res.desc[i].start = oes->bcdma_rchan_data;
+                       irq_res.desc[i].num = ud->rchan_cnt;
+                       irq_res.desc[i + 1].start = oes->bcdma_rchan_ring;
+                       irq_res.desc[i + 1].num = ud->rchan_cnt;
+                       i += 2;
+               } else {
+                       for (j = 0; j < rm_res->sets; j++, i += 2) {
+                               irq_res.desc[i].start = rm_res->desc[j].start +
+                                                       oes->bcdma_rchan_data;
+                               irq_res.desc[i].num = rm_res->desc[j].num;
+
+                               irq_res.desc[i + 1].start = rm_res->desc[j].start +
+                                                       oes->bcdma_rchan_ring;
+                               irq_res.desc[i + 1].num = rm_res->desc[j].num;
+                       }
                }
        }
 
@@ -4858,39 +4900,54 @@ static int pktdma_setup_resources(struct udma_dev *ud)
        if (IS_ERR(rm_res)) {
                /* all rflows are assigned exclusively to Linux */
                bitmap_zero(ud->rflow_in_use, ud->rflow_cnt);
+               irq_res.sets = 1;
        } else {
                bitmap_fill(ud->rflow_in_use, ud->rflow_cnt);
                for (i = 0; i < rm_res->sets; i++)
                        udma_mark_resource_ranges(ud, ud->rflow_in_use,
                                                  &rm_res->desc[i], "rflow");
+               irq_res.sets = rm_res->sets;
        }
-       irq_res.sets = rm_res->sets;
 
        /* tflow ranges */
        rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
        if (IS_ERR(rm_res)) {
                /* all tflows are assigned exclusively to Linux */
                bitmap_zero(ud->tflow_map, ud->tflow_cnt);
+               irq_res.sets++;
        } else {
                bitmap_fill(ud->tflow_map, ud->tflow_cnt);
                for (i = 0; i < rm_res->sets; i++)
                        udma_mark_resource_ranges(ud, ud->tflow_map,
                                                  &rm_res->desc[i], "tflow");
+               irq_res.sets += rm_res->sets;
        }
-       irq_res.sets += rm_res->sets;
 
        irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
+       if (!irq_res.desc)
+               return -ENOMEM;
        rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
-       for (i = 0; i < rm_res->sets; i++) {
-               irq_res.desc[i].start = rm_res->desc[i].start +
-                                       oes->pktdma_tchan_flow;
-               irq_res.desc[i].num = rm_res->desc[i].num;
+       if (IS_ERR(rm_res)) {
+               irq_res.desc[0].start = oes->pktdma_tchan_flow;
+               irq_res.desc[0].num = ud->tflow_cnt;
+               i = 1;
+       } else {
+               for (i = 0; i < rm_res->sets; i++) {
+                       irq_res.desc[i].start = rm_res->desc[i].start +
+                                               oes->pktdma_tchan_flow;
+                       irq_res.desc[i].num = rm_res->desc[i].num;
+               }
        }
        rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
-       for (j = 0; j < rm_res->sets; j++, i++) {
-               irq_res.desc[i].start = rm_res->desc[j].start +
-                                       oes->pktdma_rchan_flow;
-               irq_res.desc[i].num = rm_res->desc[j].num;
+       if (IS_ERR(rm_res)) {
+               irq_res.desc[i].start = oes->pktdma_rchan_flow;
+               irq_res.desc[i].num = ud->rflow_cnt;
+       } else {
+               for (j = 0; j < rm_res->sets; j++, i++) {
+                       irq_res.desc[i].start = rm_res->desc[j].start +
+                                               oes->pktdma_rchan_flow;
+                       irq_res.desc[i].num = rm_res->desc[j].num;
+               }
        }
        ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
        kfree(irq_res.desc);
index 51201600d789b9cf6dd4e6c72b59597625b8550d..800673910b5111c837e5aa98dec0096f8848dfc9 100644 (file)
@@ -16,7 +16,6 @@ struct scpi_pm_domain {
        struct generic_pm_domain genpd;
        struct scpi_ops *ops;
        u32 domain;
-       char name[30];
 };
 
 /*
@@ -110,8 +109,13 @@ static int scpi_pm_domain_probe(struct platform_device *pdev)
 
                scpi_pd->domain = i;
                scpi_pd->ops = scpi_ops;
-               sprintf(scpi_pd->name, "%pOFn.%d", np, i);
-               scpi_pd->genpd.name = scpi_pd->name;
+               scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL,
+                                                    "%pOFn.%d", np, i);
+               if (!scpi_pd->genpd.name) {
+                       dev_err(dev, "Failed to allocate genpd name:%pOFn.%d\n",
+                               np, i);
+                       continue;
+               }
                scpi_pd->genpd.power_off = scpi_pd_power_off;
                scpi_pd->genpd.power_on = scpi_pd_power_on;
 
index 6d66fe03fb6afbbd3c6dd74236f24abee92eea8e..fd89899aeeed9ccbbba6ab5e96e202af55f65077 100644 (file)
@@ -77,13 +77,14 @@ static const char *get_filename(struct tegra_bpmp *bpmp,
        const char *root_path, *filename = NULL;
        char *root_path_buf;
        size_t root_len;
+       size_t root_path_buf_len = 512;
 
-       root_path_buf = kzalloc(512, GFP_KERNEL);
+       root_path_buf = kzalloc(root_path_buf_len, GFP_KERNEL);
        if (!root_path_buf)
                goto out;
 
        root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf,
-                               sizeof(root_path_buf));
+                               root_path_buf_len);
        if (IS_ERR(root_path))
                goto out;
 
index b305fd39874fe68a8ab7f5141c3f01aaa0f7517d..edb3e3b08eed8fc6f241d7934d8db133d082ab5c 100644 (file)
@@ -3070,8 +3070,8 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev)
                              AMD_PG_SUPPORT_CP |
                              AMD_PG_SUPPORT_GDS |
                              AMD_PG_SUPPORT_RLC_SMU_HS)) {
-               WREG32(mmRLC_JUMP_TABLE_RESTORE,
-                      adev->gfx.rlc.cp_table_gpu_addr >> 8);
+               WREG32_SOC15(GC, 0, mmRLC_JUMP_TABLE_RESTORE,
+                            adev->gfx.rlc.cp_table_gpu_addr >> 8);
                gfx_v9_0_init_gfx_power_gating(adev);
        }
 }
index 480e41847d7c0b199b1cbf30f6f7c9978dd26bc0..ec4d5e15b766a3effca3e93d4109803b0ba948b0 100644 (file)
@@ -162,7 +162,6 @@ static void gfxhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC);/* XXX for emulation. */
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ATC_EN, 1);
index 14c1c1a297dd3d75c3f585d65e0afa497087e849..6e0ace2fbfab14092d7fa7cd413bb6580e562f4c 100644 (file)
@@ -196,7 +196,6 @@ static void gfxhub_v2_0_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC); /* UC, uncached */
 
index e80d1dc4307909309a54c429548e8f3ca211f670..b4eddf6e98a6a23c861af2d4999d0c220d4a1e06 100644 (file)
@@ -197,7 +197,6 @@ static void gfxhub_v2_1_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC); /* UC, uncached */
 
index cb82404df5342a640d0124271e578a878dfa1368..d84523cf5f75966276f318748b69c426ea827912 100644 (file)
@@ -1808,6 +1808,14 @@ static int gmc_v9_0_hw_fini(void *handle)
                return 0;
        }
 
+       /*
+        * Pair the operations did in gmc_v9_0_hw_init and thus maintain
+        * a correct cached state for GMC. Otherwise, the "gate" again
+        * operation on S3 resuming will fail due to wrong cached state.
+        */
+       if (adev->mmhub.funcs->update_power_gating)
+               adev->mmhub.funcs->update_power_gating(adev, false);
+
        amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0);
        amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
 
index a99953833820ea4c48e21a163794ad0131de5a35..1da2ec692057ee98445620a24b1c9953604fbe2c 100644 (file)
@@ -145,7 +145,6 @@ static void mmhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC);/* XXX for emulation. */
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ATC_EN, 1);
@@ -302,10 +301,10 @@ static void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
        if (amdgpu_sriov_vf(adev))
                return;
 
-       if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) {
-               amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true);
-
-       }
+       if (adev->pg_flags & AMD_PG_SUPPORT_MMHUB)
+               amdgpu_dpm_set_powergating_by_smu(adev,
+                                                 AMD_IP_BLOCK_TYPE_GMC,
+                                                 enable);
 }
 
 static int mmhub_v1_0_gart_enable(struct amdgpu_device *adev)
index f80a14a1b82dc274549eabef38942cf107bf91d5..f5f7181f9af5fd1302365a4522b573576b701b13 100644 (file)
@@ -165,7 +165,6 @@ static void mmhub_v1_7_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC);/* XXX for emulation. */
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ATC_EN, 1);
index 25f8e93e5ec3757828ffa1629c5bea813e7b63d3..3718ff610ab286e97045b42407aaf519258be3ea 100644 (file)
@@ -267,7 +267,6 @@ static void mmhub_v2_0_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC); /* UC, uncached */
 
index a11d60ec63215f13af9975fe879a818bf45d3059..9e16da28505afa5478b40793cfc6de049bd0e74f 100644 (file)
@@ -194,7 +194,6 @@ static void mmhub_v2_3_init_tlb_regs(struct amdgpu_device *adev)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC); /* UC, uncached */
 
index c4ef822bbe8c56dcc94670aab5942a768b1579ce..ff49eeaf78824534c5593614ed1e93cafe8c4fa3 100644 (file)
@@ -189,8 +189,6 @@ static void mmhub_v9_4_init_tlb_regs(struct amdgpu_device *adev, int hubid)
                            ENABLE_ADVANCED_DRIVER_MODEL, 1);
        tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL,
                            SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
-       tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL,
-                           ECO_BITS, 0);
        tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL,
                            MTYPE, MTYPE_UC);/* XXX for emulation. */
        tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL,
index 122dae1a1813b3eed2517d590bc19ea95fe77346..e727f1dd2a9a7ca8840d4c427e31aab299c244bd 100644 (file)
@@ -1051,6 +1051,11 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
                return 0;
        }
 
+       /* Reset DMCUB if it was previously running - before we overwrite its memory. */
+       status = dmub_srv_hw_reset(dmub_srv);
+       if (status != DMUB_STATUS_OK)
+               DRM_WARN("Error resetting DMUB HW: %d\n", status);
+
        hdr = (const struct dmcub_firmware_header_v1_0 *)dmub_fw->data;
 
        fw_inst_const = dmub_fw->data +
index 05335a8c3c2dcffe54bb55bfebd9ba2a126e01a9..4f6e639e9353619e837aaf86d0dd36fc3461a38b 100644 (file)
@@ -101,6 +101,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
        .z10_restore = dcn31_z10_restore,
        .z10_save_init = dcn31_z10_save_init,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
+       .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
        .update_visual_confirm_color = dcn20_update_visual_confirm_color,
 };
 
index 8d796ed3b7d16f40369363969499caf7bbb1bf94..619f8d305292045ecd41ee6f0e04e81e4d90942c 100644 (file)
@@ -1328,7 +1328,12 @@ static int pp_set_powergating_by_smu(void *handle,
                pp_dpm_powergate_vce(handle, gate);
                break;
        case AMD_IP_BLOCK_TYPE_GMC:
-               pp_dpm_powergate_mmhub(handle);
+               /*
+                * For now, this is only used on PICASSO.
+                * And only "gate" operation is supported.
+                */
+               if (gate)
+                       pp_dpm_powergate_mmhub(handle);
                break;
        case AMD_IP_BLOCK_TYPE_GFX:
                ret = pp_dpm_powergate_gfx(handle, gate);
index d60b8c5e871575b2ea617e1c7c471f12b9020f38..43028f2cd28b5e57cda8d2a78294022c025b5318 100644 (file)
@@ -191,6 +191,9 @@ int smu_v12_0_fini_smc_tables(struct smu_context *smu)
        kfree(smu_table->watermarks_table);
        smu_table->watermarks_table = NULL;
 
+       kfree(smu_table->gpu_metrics_table);
+       smu_table->gpu_metrics_table = NULL;
+
        return 0;
 }
 
index 35145db6eedfc9e23df68d2ff71c11bd5a7e04d7..19a5d2c39c8d8ac170567b4a323db36ccc6f9e28 100644 (file)
@@ -198,6 +198,7 @@ int smu_v13_0_check_fw_status(struct smu_context *smu)
 
 int smu_v13_0_check_fw_version(struct smu_context *smu)
 {
+       struct amdgpu_device *adev = smu->adev;
        uint32_t if_version = 0xff, smu_version = 0xff;
        uint16_t smu_major;
        uint8_t smu_minor, smu_debug;
@@ -210,6 +211,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
        smu_major = (smu_version >> 16) & 0xffff;
        smu_minor = (smu_version >> 8) & 0xff;
        smu_debug = (smu_version >> 0) & 0xff;
+       if (smu->is_apu)
+               adev->pm.fw_version = smu_version;
 
        switch (smu->adev->ip_versions[MP1_HWIP][0]) {
        case IP_VERSION(13, 0, 2):
index 1e30eaeb0e1b3a75d33eea41ad508d686284c4d1..d5c98f79d58d337f454bdf566e7d5738885554ca 100644 (file)
@@ -1121,7 +1121,10 @@ static void ast_crtc_reset(struct drm_crtc *crtc)
        if (crtc->state)
                crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 
-       __drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
+       if (ast_state)
+               __drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
+       else
+               __drm_atomic_helper_crtc_reset(crtc, NULL);
 }
 
 static struct drm_crtc_state *
index 8e7a124d6c5a3ae27f18c268af7d02e4fa952b77..22bf690910b253be6322ae506bbaa4872d534735 100644 (file)
@@ -1743,7 +1743,13 @@ void drm_fb_helper_fill_info(struct fb_info *info,
                               sizes->fb_width, sizes->fb_height);
 
        info->par = fb_helper;
-       snprintf(info->fix.id, sizeof(info->fix.id), "%s",
+       /*
+        * The DRM drivers fbdev emulation device name can be confusing if the
+        * driver name also has a "drm" suffix on it. Leading to names such as
+        * "simpledrmdrmfb" in /proc/fb. Unfortunately, it's an uAPI and can't
+        * be changed due user-space tools (e.g: pm-utils) matching against it.
+        */
+       snprintf(info->fix.id, sizeof(info->fix.id), "%sdrmfb",
                 fb_helper->dev->driver->name);
 
 }
index 2dc9d632969dbca821d4ec7d2f2d5f91aa6df422..aef69522f0be3db0cc626078c6ff9e387a7cbeb8 100644 (file)
@@ -596,7 +596,7 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv,
                        continue;
 
                offset = readcount + dmc->dmc_info[id].dmc_offset * 4;
-               if (fw->size - offset < 0) {
+               if (offset > fw->size) {
                        drm_err(&dev_priv->drm, "Reading beyond the fw_size\n");
                        continue;
                }
index 481b48bde0473fe56a9f56e970ce4ba130111c2b..5a6e89825bc2fc54ec02dcda1da5a47cc2212f02 100644 (file)
@@ -458,7 +458,7 @@ static struct drm_display_mode simpledrm_mode(unsigned int width,
 {
        struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) };
 
-       mode.clock = 60 /* Hz */ * mode.hdisplay * mode.vdisplay;
+       mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */;
        drm_mode_set_name(&mode);
 
        return mode;
index dd12af20e467edab92ad26ee3a51e6c627468185..0747a8f1fceec956ee8174c738f8bf7bcadc1a16 100644 (file)
@@ -19,6 +19,7 @@ config HYPERV_TIMER
 config HYPERV_UTILS
        tristate "Microsoft Hyper-V Utilities driver"
        depends on HYPERV && CONNECTOR && NLS
+       depends on PTP_1588_CLOCK_OPTIONAL
        help
          Select this option to enable the Hyper-V Utilities.
 
index 86b9e355c583760f564beaeb4988b9c628676cc7..140f35dc0c4579bdd473629bbf86344b42a21e77 100644 (file)
@@ -1139,6 +1139,7 @@ static void cancel_writeback_rate_update_dwork(struct cached_dev *dc)
 static void cached_dev_detach_finish(struct work_struct *w)
 {
        struct cached_dev *dc = container_of(w, struct cached_dev, detach);
+       struct cache_set *c = dc->disk.c;
 
        BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags));
        BUG_ON(refcount_read(&dc->count));
@@ -1156,7 +1157,7 @@ static void cached_dev_detach_finish(struct work_struct *w)
 
        bcache_device_detach(&dc->disk);
        list_move(&dc->list, &uncached_devices);
-       calc_cached_dev_sectors(dc->disk.c);
+       calc_cached_dev_sectors(c);
 
        clear_bit(BCACHE_DEV_DETACHING, &dc->disk.flags);
        clear_bit(BCACHE_DEV_UNLINK_DONE, &dc->disk.flags);
index 6319deccbe09eb0446ae53a06a3456f0011fe30a..7af242de3202ee4ba9bbffd3ee1992e06ad43fe8 100644 (file)
@@ -1963,7 +1963,7 @@ static bool __journal_read_write(struct dm_integrity_io *dio, struct bio *bio,
                n_sectors -= bv.bv_len >> SECTOR_SHIFT;
                bio_advance_iter(bio, &bio->bi_iter, bv.bv_len);
 retry_kmap:
-               mem = bvec_kmap_local(&bv);
+               mem = kmap_local_page(bv.bv_page);
                if (likely(dio->op == REQ_OP_WRITE))
                        flush_dcache_page(bv.bv_page);
 
index 70532335c7c7ed7b864c392720a89f968918b918..cb670f16e98e9a2003d6a6b7c52e83c50bb284b0 100644 (file)
@@ -423,9 +423,9 @@ static int rebalance_children(struct shadow_spine *s,
 
                memcpy(n, dm_block_data(child),
                       dm_bm_block_size(dm_tm_get_bm(info->tm)));
-               dm_tm_unlock(info->tm, child);
 
                dm_tm_dec(info->tm, dm_block_location(child));
+               dm_tm_unlock(info->tm, child);
                return 0;
        }
 
index 14f87f6ac479a9922cb9474f78174be182bded83..cd8462d1e27c04f09dae7702d8ff2a391cd35373 100644 (file)
@@ -768,6 +768,10 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
        if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
             mode == MLO_AN_FIXED) && ops->port_sync_link)
                err = ops->port_sync_link(chip, port, mode, false);
+
+       if (!err && ops->port_set_speed_duplex)
+               err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED,
+                                                DUPLEX_UNFORCED);
        mv88e6xxx_reg_unlock(chip);
 
        if (err)
index d9817b20ea641f9b642435e693b5ee7e86398a7e..ab41619a809b3e98c3da9a53ec455c42a79a7293 100644 (file)
@@ -283,7 +283,7 @@ static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
        if (err)
                return err;
 
-       if (speed)
+       if (speed != SPEED_UNFORCED)
                dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
        else
                dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
@@ -516,7 +516,7 @@ int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
        if (err)
                return err;
 
-       if (speed)
+       if (speed != SPEED_UNFORCED)
                dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
        else
                dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
index 40933bf5a71007ca2e31c2b4ffbf23e7d4f92ada..60dde29974bfea53f8092fda078f348d36c6a6ef 100644 (file)
@@ -1309,11 +1309,11 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
        struct bcm_sysport_priv *priv = netdev_priv(dev);
        struct device *kdev = &priv->pdev->dev;
        struct bcm_sysport_tx_ring *ring;
+       unsigned long flags, desc_flags;
        struct bcm_sysport_cb *cb;
        struct netdev_queue *txq;
        u32 len_status, addr_lo;
        unsigned int skb_len;
-       unsigned long flags;
        dma_addr_t mapping;
        u16 queue;
        int ret;
@@ -1373,8 +1373,10 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
        ring->desc_count--;
 
        /* Ports are latched, so write upper address first */
+       spin_lock_irqsave(&priv->desc_lock, desc_flags);
        tdma_writel(priv, len_status, TDMA_WRITE_PORT_HI(ring->index));
        tdma_writel(priv, addr_lo, TDMA_WRITE_PORT_LO(ring->index));
+       spin_unlock_irqrestore(&priv->desc_lock, desc_flags);
 
        /* Check ring space and update SW control flow */
        if (ring->desc_count == 0)
@@ -2013,6 +2015,7 @@ static int bcm_sysport_open(struct net_device *dev)
        }
 
        /* Initialize both hardware and software ring */
+       spin_lock_init(&priv->desc_lock);
        for (i = 0; i < dev->num_tx_queues; i++) {
                ret = bcm_sysport_init_tx_ring(priv, i);
                if (ret) {
index 984f76e74b43effde480fd2ce8f4612d75300a6c..16b73bb9acc783b41aefb2e6198f354d9e9cc6bd 100644 (file)
@@ -711,6 +711,7 @@ struct bcm_sysport_priv {
        int                     wol_irq;
 
        /* Transmit rings */
+       spinlock_t              desc_lock;
        struct bcm_sysport_tx_ring *tx_rings;
 
        /* Receive queue */
index 5f259641437a720c65dd4b3d70867a7bedbe5d0a..c888ddee1fc41628fc13036aa1fa1838b2c3e055 100644 (file)
@@ -589,9 +589,9 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
                 * Internal or external PHY with MDIO access
                 */
                phydev = phy_attach(priv->dev, phy_name, pd->phy_interface);
-               if (!phydev) {
+               if (IS_ERR(phydev)) {
                        dev_err(kdev, "failed to register PHY device\n");
-                       return -ENODEV;
+                       return PTR_ERR(phydev);
                }
        } else {
                /*
index 2085844227fe535d190df8ec73d52975638367d2..e54e70ebdd059fa1a4ed98af2721b4f726d865af 100644 (file)
@@ -388,6 +388,8 @@ struct dpaa2_eth_ch_stats {
        __u64 bytes_per_cdan;
 };
 
+#define DPAA2_ETH_CH_STATS     7
+
 /* Maximum number of queues associated with a DPNI */
 #define DPAA2_ETH_MAX_TCS              8
 #define DPAA2_ETH_MAX_RX_QUEUES_PER_TC 16
index adb8ce5306ee84240f6b8b637d1dcd64d8694d61..3fdbf87dccb1ea5abb0841d6c4d452e673c10b01 100644 (file)
@@ -278,7 +278,7 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
        /* Per-channel stats */
        for (k = 0; k < priv->num_channels; k++) {
                ch_stats = &priv->channel[k]->stats;
-               for (j = 0; j < sizeof(*ch_stats) / sizeof(__u64) - 1; j++)
+               for (j = 0; j < DPAA2_ETH_CH_STATS; j++)
                        *((__u64 *)data + i + j) += *((__u64 *)ch_stats + j);
        }
        i += j;
index 3f7a9a4c59d566a9f368c47348aa3994bf254585..63f5abcc6bf4113e29f280b1c234c378b356b0e3 100644 (file)
@@ -839,6 +839,8 @@ struct hnae3_handle {
 
        u8 netdev_flags;
        struct dentry *hnae3_dbgfs;
+       /* protects concurrent contention between debugfs commands */
+       struct mutex dbgfs_lock;
 
        /* Network interface message level enabled bits */
        u32 msg_enable;
index 081295bff7654930d243c3eee10379cf65ae4b46..c381f8af67f082f154ad65cdb279c36e64fe7256 100644 (file)
@@ -1226,6 +1226,7 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
        if (ret)
                return ret;
 
+       mutex_lock(&handle->dbgfs_lock);
        save_buf = &hns3_dbg_cmd[index].buf;
 
        if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
@@ -1238,15 +1239,15 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
                read_buf = *save_buf;
        } else {
                read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
-               if (!read_buf)
-                       return -ENOMEM;
+               if (!read_buf) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
 
                /* save the buffer addr until the last read operation */
                *save_buf = read_buf;
-       }
 
-       /* get data ready for the first time to read */
-       if (!*ppos) {
+               /* get data ready for the first time to read */
                ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
                                        read_buf, hns3_dbg_cmd[index].buf_len);
                if (ret)
@@ -1255,8 +1256,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
 
        size = simple_read_from_buffer(buffer, count, ppos, read_buf,
                                       strlen(read_buf));
-       if (size > 0)
+       if (size > 0) {
+               mutex_unlock(&handle->dbgfs_lock);
                return size;
+       }
 
 out:
        /* free the buffer for the last read operation */
@@ -1265,6 +1268,7 @@ out:
                *save_buf = NULL;
        }
 
+       mutex_unlock(&handle->dbgfs_lock);
        return ret;
 }
 
@@ -1337,6 +1341,8 @@ int hns3_dbg_init(struct hnae3_handle *handle)
                        debugfs_create_dir(hns3_dbg_dentry[i].name,
                                           handle->hnae3_dbgfs);
 
+       mutex_init(&handle->dbgfs_lock);
+
        for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
                if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
                     ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
@@ -1363,6 +1369,7 @@ int hns3_dbg_init(struct hnae3_handle *handle)
        return 0;
 
 out:
+       mutex_destroy(&handle->dbgfs_lock);
        debugfs_remove_recursive(handle->hnae3_dbgfs);
        handle->hnae3_dbgfs = NULL;
        return ret;
@@ -1378,6 +1385,7 @@ void hns3_dbg_uninit(struct hnae3_handle *handle)
                        hns3_dbg_cmd[i].buf = NULL;
                }
 
+       mutex_destroy(&handle->dbgfs_lock);
        debugfs_remove_recursive(handle->hnae3_dbgfs);
        handle->hnae3_dbgfs = NULL;
 }
index fdc66fae096011a21a86b84b590604f0de152b27..c5ac6ecf36e107e6bdaf4a111814eae62d877f89 100644 (file)
@@ -114,7 +114,8 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev,
 
        memcpy(&req->msg, send_msg, sizeof(struct hclge_vf_to_pf_msg));
 
-       trace_hclge_vf_mbx_send(hdev, req);
+       if (test_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state))
+               trace_hclge_vf_mbx_send(hdev, req);
 
        /* synchronous send */
        if (need_resp) {
index cfdbf8c08d18bcd82050dc089705850c640481e4..4e7c04047f91760a88e7232415588a1f1d91b16d 100644 (file)
@@ -2046,6 +2046,7 @@ static void iavf_watchdog_task(struct work_struct *work)
                }
                adapter->aq_required = 0;
                adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+               mutex_unlock(&adapter->crit_lock);
                queue_delayed_work(iavf_wq,
                                   &adapter->watchdog_task,
                                   msecs_to_jiffies(10));
@@ -2076,16 +2077,14 @@ static void iavf_watchdog_task(struct work_struct *work)
                        iavf_detect_recover_hung(&adapter->vsi);
                break;
        case __IAVF_REMOVE:
-               mutex_unlock(&adapter->crit_lock);
-               return;
        default:
+               mutex_unlock(&adapter->crit_lock);
                return;
        }
 
        /* check for hw reset */
        reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK;
        if (!reg_val) {
-               iavf_change_state(adapter, __IAVF_RESETTING);
                adapter->flags |= IAVF_FLAG_RESET_PENDING;
                adapter->aq_required = 0;
                adapter->current_op = VIRTCHNL_OP_UNKNOWN;
index bf7247c6f58e259406e20cb456c750a8997a44d1..442b031b0edc04b5ffff932e65bb63d927dbddd8 100644 (file)
@@ -705,7 +705,7 @@ static int ice_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
                scaled_ppm = -scaled_ppm;
        }
 
-       while ((u64)scaled_ppm > div_u64(U64_MAX, incval)) {
+       while ((u64)scaled_ppm > div64_u64(U64_MAX, incval)) {
                /* handle overflow by scaling down the scaled_ppm and
                 * the divisor, losing some precision
                 */
@@ -1540,19 +1540,16 @@ static void ice_ptp_tx_tstamp_work(struct kthread_work *work)
                if (err)
                        continue;
 
-               /* Check if the timestamp is valid */
-               if (!(raw_tstamp & ICE_PTP_TS_VALID))
+               /* Check if the timestamp is invalid or stale */
+               if (!(raw_tstamp & ICE_PTP_TS_VALID) ||
+                   raw_tstamp == tx->tstamps[idx].cached_tstamp)
                        continue;
 
-               /* clear the timestamp register, so that it won't show valid
-                * again when re-used.
-                */
-               ice_clear_phy_tstamp(hw, tx->quad, phy_idx);
-
                /* The timestamp is valid, so we'll go ahead and clear this
                 * index and then send the timestamp up to the stack.
                 */
                spin_lock(&tx->lock);
+               tx->tstamps[idx].cached_tstamp = raw_tstamp;
                clear_bit(idx, tx->in_use);
                skb = tx->tstamps[idx].skb;
                tx->tstamps[idx].skb = NULL;
index f71ad317d6c8f033c66e5e424669173886d3764a..53c15fc9d9961f3e540b33b33d7278f12ffc6001 100644 (file)
@@ -55,15 +55,21 @@ struct ice_perout_channel {
  * struct ice_tx_tstamp - Tracking for a single Tx timestamp
  * @skb: pointer to the SKB for this timestamp request
  * @start: jiffies when the timestamp was first requested
+ * @cached_tstamp: last read timestamp
  *
  * This structure tracks a single timestamp request. The SKB pointer is
  * provided when initiating a request. The start time is used to ensure that
  * we discard old requests that were not fulfilled within a 2 second time
  * window.
+ * Timestamp values in the PHY are read only and do not get cleared except at
+ * hardware reset or when a new timestamp value is captured. The cached_tstamp
+ * field is used to detect the case where a new timestamp has not yet been
+ * captured, ensuring that we avoid sending stale timestamp data to the stack.
  */
 struct ice_tx_tstamp {
        struct sk_buff *skb;
        unsigned long start;
+       u64 cached_tstamp;
 };
 
 /**
index fd54d3ef890bc191503d5ace25e91ead932a2098..b597b8bfb9103bff34e4eb61a46dc47cc24aecec 100644 (file)
@@ -7648,6 +7648,20 @@ static int igb_set_vf_mac_filter(struct igb_adapter *adapter, const int vf,
        struct vf_mac_filter *entry = NULL;
        int ret = 0;
 
+       if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) &&
+           !vf_data->trusted) {
+               dev_warn(&pdev->dev,
+                        "VF %d requested MAC filter but is administratively denied\n",
+                         vf);
+               return -EINVAL;
+       }
+       if (!is_valid_ether_addr(addr)) {
+               dev_warn(&pdev->dev,
+                        "VF %d attempted to set invalid MAC filter\n",
+                         vf);
+               return -EINVAL;
+       }
+
        switch (info) {
        case E1000_VF_MAC_FILTER_CLR:
                /* remove all unicast MAC filters related to the current VF */
@@ -7661,20 +7675,6 @@ static int igb_set_vf_mac_filter(struct igb_adapter *adapter, const int vf,
                }
                break;
        case E1000_VF_MAC_FILTER_ADD:
-               if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) &&
-                   !vf_data->trusted) {
-                       dev_warn(&pdev->dev,
-                                "VF %d requested MAC filter but is administratively denied\n",
-                                vf);
-                       return -EINVAL;
-               }
-               if (!is_valid_ether_addr(addr)) {
-                       dev_warn(&pdev->dev,
-                                "VF %d attempted to set invalid MAC filter\n",
-                                vf);
-                       return -EINVAL;
-               }
-
                /* try to find empty slot in the list */
                list_for_each(pos, &adapter->vf_macs.l) {
                        entry = list_entry(pos, struct vf_mac_filter, l);
index 74ccd622251a2396d3628dc38f5f287534de3eec..4d988da68394dc1c0efc63cb56614231c8d39bc2 100644 (file)
@@ -2859,6 +2859,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 
 err_hw_init:
+       netif_napi_del(&adapter->rx_ring->napi);
        kfree(adapter->tx_ring);
        kfree(adapter->rx_ring);
 err_sw_init:
index b2ef9fde97b38a7def197b6b844b5e6909c54d96..b6807e16eea9393304c7abb68f90648a7bd1c968 100644 (file)
@@ -636,7 +636,7 @@ s32 igc_set_ltr_i225(struct igc_hw *hw, bool link)
                ltrv = rd32(IGC_LTRMAXV);
                if (ltr_max != (ltrv & IGC_LTRMAXV_LTRV_MASK)) {
                        ltrv = IGC_LTRMAXV_LSNP_REQ | ltr_max |
-                              (scale_min << IGC_LTRMAXV_SCALE_SHIFT);
+                              (scale_max << IGC_LTRMAXV_SCALE_SHIFT);
                        wr32(IGC_LTRMAXV, ltrv);
                }
        }
index 0f9f022260d70f0653960690a19e89d6ac4bed8c..45e2ec4d264d9aa2b300e14429b857271a9ef14c 100644 (file)
@@ -5531,6 +5531,10 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
        if (!speed && hw->mac.ops.get_link_capabilities) {
                ret = hw->mac.ops.get_link_capabilities(hw, &speed,
                                                        &autoneg);
+               /* remove NBASE-T speeds from default autonegotiation
+                * to accommodate broken network switches in the field
+                * which cannot cope with advertised NBASE-T speeds
+                */
                speed &= ~(IXGBE_LINK_SPEED_5GB_FULL |
                           IXGBE_LINK_SPEED_2_5GB_FULL);
        }
index 9724ffb165189e4629bc8665390d6b939896cffe..e4b50c7781ffaca5cbda799a0c3633d82648e6d8 100644 (file)
@@ -3405,6 +3405,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
        /* flush pending Tx transactions */
        ixgbe_clear_tx_pending(hw);
 
+       /* set MDIO speed before talking to the PHY in case it's the 1st time */
+       ixgbe_set_mdio_speed(hw);
+
        /* PHY ops must be identified and initialized prior to reset */
        status = hw->phy.ops.init(hw);
        if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
index 217e3b351dfe6048f90e9f93930a23fde8b2e09f..c34833ff1dded21a29c0af0f296ec4749c13f454 100644 (file)
@@ -8494,7 +8494,8 @@ mlxsw_sp_rif_mac_profile_replace(struct mlxsw_sp *mlxsw_sp,
        u8 mac_profile;
        int err;
 
-       if (!mlxsw_sp_rif_mac_profile_is_shared(rif))
+       if (!mlxsw_sp_rif_mac_profile_is_shared(rif) &&
+           !mlxsw_sp_rif_mac_profile_find(mlxsw_sp, new_mac))
                return mlxsw_sp_rif_mac_profile_edit(rif, new_mac);
 
        err = mlxsw_sp_rif_mac_profile_get(mlxsw_sp, new_mac,
index 6aa81229b68a9e02ff34273cbb82563fd2d3001c..e77a5cb4e40d794ace1b4efee5bc4aee51b45e1b 100644 (file)
@@ -609,6 +609,9 @@ static size_t ef100_update_stats(struct efx_nic *efx,
        ef100_common_stat_mask(mask);
        ef100_ethtool_stat_mask(mask);
 
+       if (!mc_stats)
+               return 0;
+
        efx_nic_copy_stats(efx, mc_stats);
        efx_nic_update_stats(ef100_stat_desc, EF100_STAT_COUNT, mask,
                             stats, mc_stats, false);
index 6924a6aacbd53c8310a1476b82d5978f87094b5b..c469abc91fa1b04966f276042c60e1fa0f8696a3 100644 (file)
@@ -33,6 +33,7 @@ struct rk_gmac_ops {
        void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
        void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
        void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
+       bool regs_valid;
        u32 regs[];
 };
 
@@ -1092,6 +1093,7 @@ static const struct rk_gmac_ops rk3568_ops = {
        .set_to_rmii = rk3568_set_to_rmii,
        .set_rgmii_speed = rk3568_set_gmac_speed,
        .set_rmii_speed = rk3568_set_gmac_speed,
+       .regs_valid = true,
        .regs = {
                0xfe2a0000, /* gmac0 */
                0xfe010000, /* gmac1 */
@@ -1383,7 +1385,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
         * to be distinguished.
         */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res) {
+       if (res && ops->regs_valid) {
                int i = 0;
 
                while (ops->regs[i]) {
index 5f129733aabd2e914a84a89b72e90bd3a41caaa2..873b9e3e5da25ba1e357db7761514b85e0ebb9c1 100644 (file)
@@ -172,6 +172,19 @@ struct stmmac_flow_entry {
        int is_l4;
 };
 
+/* Rx Frame Steering */
+enum stmmac_rfs_type {
+       STMMAC_RFS_T_VLAN,
+       STMMAC_RFS_T_MAX,
+};
+
+struct stmmac_rfs_entry {
+       unsigned long cookie;
+       int in_use;
+       int type;
+       int tc;
+};
+
 struct stmmac_priv {
        /* Frequently used values are kept adjacent for cache effect */
        u32 tx_coal_frames[MTL_MAX_TX_QUEUES];
@@ -289,6 +302,10 @@ struct stmmac_priv {
        struct stmmac_tc_entry *tc_entries;
        unsigned int flow_entries_max;
        struct stmmac_flow_entry *flow_entries;
+       unsigned int rfs_entries_max[STMMAC_RFS_T_MAX];
+       unsigned int rfs_entries_cnt[STMMAC_RFS_T_MAX];
+       unsigned int rfs_entries_total;
+       struct stmmac_rfs_entry *rfs_entries;
 
        /* Pulse Per Second output */
        struct stmmac_pps_cfg pps[STMMAC_PPS_MAX];
index da8306f6073027ac99d57423d1cc50bf426ae233..8ded4be08b001fdc7429871883907b4a93113b64 100644 (file)
@@ -1461,16 +1461,20 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
 {
        struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
        struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
+       gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
+
+       if (priv->dma_cap.addr64 <= 32)
+               gfp |= GFP_DMA32;
 
        if (!buf->page) {
-               buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
+               buf->page = page_pool_alloc_pages(rx_q->page_pool, gfp);
                if (!buf->page)
                        return -ENOMEM;
                buf->page_offset = stmmac_rx_offset(priv);
        }
 
        if (priv->sph && !buf->sec_page) {
-               buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
+               buf->sec_page = page_pool_alloc_pages(rx_q->page_pool, gfp);
                if (!buf->sec_page)
                        return -ENOMEM;
 
@@ -4482,6 +4486,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
        struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
        int dirty = stmmac_rx_dirty(priv, queue);
        unsigned int entry = rx_q->dirty_rx;
+       gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
+
+       if (priv->dma_cap.addr64 <= 32)
+               gfp |= GFP_DMA32;
 
        while (dirty-- > 0) {
                struct stmmac_rx_buffer *buf = &rx_q->buf_pool[entry];
@@ -4494,13 +4502,13 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
                        p = rx_q->dma_rx + entry;
 
                if (!buf->page) {
-                       buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
+                       buf->page = page_pool_alloc_pages(rx_q->page_pool, gfp);
                        if (!buf->page)
                                break;
                }
 
                if (priv->sph && !buf->sec_page) {
-                       buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
+                       buf->sec_page = page_pool_alloc_pages(rx_q->page_pool, gfp);
                        if (!buf->sec_page)
                                break;
 
index 1c4ea0b1b845b3c162f533656a0eadca56f8600e..d0a2b289f4603ce1b594ff03689240c6f52f8e1a 100644 (file)
@@ -232,11 +232,33 @@ static int tc_setup_cls_u32(struct stmmac_priv *priv,
        }
 }
 
+static int tc_rfs_init(struct stmmac_priv *priv)
+{
+       int i;
+
+       priv->rfs_entries_max[STMMAC_RFS_T_VLAN] = 8;
+
+       for (i = 0; i < STMMAC_RFS_T_MAX; i++)
+               priv->rfs_entries_total += priv->rfs_entries_max[i];
+
+       priv->rfs_entries = devm_kcalloc(priv->device,
+                                        priv->rfs_entries_total,
+                                        sizeof(*priv->rfs_entries),
+                                        GFP_KERNEL);
+       if (!priv->rfs_entries)
+               return -ENOMEM;
+
+       dev_info(priv->device, "Enabled RFS Flow TC (entries=%d)\n",
+                priv->rfs_entries_total);
+
+       return 0;
+}
+
 static int tc_init(struct stmmac_priv *priv)
 {
        struct dma_features *dma_cap = &priv->dma_cap;
        unsigned int count;
-       int i;
+       int ret, i;
 
        if (dma_cap->l3l4fnum) {
                priv->flow_entries_max = dma_cap->l3l4fnum;
@@ -250,10 +272,14 @@ static int tc_init(struct stmmac_priv *priv)
                for (i = 0; i < priv->flow_entries_max; i++)
                        priv->flow_entries[i].idx = i;
 
-               dev_info(priv->device, "Enabled Flow TC (entries=%d)\n",
+               dev_info(priv->device, "Enabled L3L4 Flow TC (entries=%d)\n",
                         priv->flow_entries_max);
        }
 
+       ret = tc_rfs_init(priv);
+       if (ret)
+               return -ENOMEM;
+
        if (!priv->plat->fpe_cfg) {
                priv->plat->fpe_cfg = devm_kzalloc(priv->device,
                                                   sizeof(*priv->plat->fpe_cfg),
@@ -607,16 +633,45 @@ static int tc_del_flow(struct stmmac_priv *priv,
        return ret;
 }
 
+static struct stmmac_rfs_entry *tc_find_rfs(struct stmmac_priv *priv,
+                                           struct flow_cls_offload *cls,
+                                           bool get_free)
+{
+       int i;
+
+       for (i = 0; i < priv->rfs_entries_total; i++) {
+               struct stmmac_rfs_entry *entry = &priv->rfs_entries[i];
+
+               if (entry->cookie == cls->cookie)
+                       return entry;
+               if (get_free && entry->in_use == false)
+                       return entry;
+       }
+
+       return NULL;
+}
+
 #define VLAN_PRIO_FULL_MASK (0x07)
 
 static int tc_add_vlan_flow(struct stmmac_priv *priv,
                            struct flow_cls_offload *cls)
 {
+       struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false);
        struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
        struct flow_dissector *dissector = rule->match.dissector;
        int tc = tc_classid_to_hwtc(priv->dev, cls->classid);
        struct flow_match_vlan match;
 
+       if (!entry) {
+               entry = tc_find_rfs(priv, cls, true);
+               if (!entry)
+                       return -ENOENT;
+       }
+
+       if (priv->rfs_entries_cnt[STMMAC_RFS_T_VLAN] >=
+           priv->rfs_entries_max[STMMAC_RFS_T_VLAN])
+               return -ENOENT;
+
        /* Nothing to do here */
        if (!dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_VLAN))
                return -EINVAL;
@@ -638,6 +693,12 @@ static int tc_add_vlan_flow(struct stmmac_priv *priv,
 
                prio = BIT(match.key->vlan_priority);
                stmmac_rx_queue_prio(priv, priv->hw, prio, tc);
+
+               entry->in_use = true;
+               entry->cookie = cls->cookie;
+               entry->tc = tc;
+               entry->type = STMMAC_RFS_T_VLAN;
+               priv->rfs_entries_cnt[STMMAC_RFS_T_VLAN]++;
        }
 
        return 0;
@@ -646,20 +707,19 @@ static int tc_add_vlan_flow(struct stmmac_priv *priv,
 static int tc_del_vlan_flow(struct stmmac_priv *priv,
                            struct flow_cls_offload *cls)
 {
-       struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
-       struct flow_dissector *dissector = rule->match.dissector;
-       int tc = tc_classid_to_hwtc(priv->dev, cls->classid);
+       struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false);
 
-       /* Nothing to do here */
-       if (!dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_VLAN))
-               return -EINVAL;
+       if (!entry || !entry->in_use || entry->type != STMMAC_RFS_T_VLAN)
+               return -ENOENT;
 
-       if (tc < 0) {
-               netdev_err(priv->dev, "Invalid traffic class\n");
-               return -EINVAL;
-       }
+       stmmac_rx_queue_prio(priv, priv->hw, 0, entry->tc);
+
+       entry->in_use = false;
+       entry->cookie = 0;
+       entry->tc = 0;
+       entry->type = 0;
 
-       stmmac_rx_queue_prio(priv, priv->hw, 0, tc);
+       priv->rfs_entries_cnt[STMMAC_RFS_T_VLAN]--;
 
        return 0;
 }
index c092cb61416a180a5ce1d0d28bd163e4a1dab302..ffbbda8f4d41671d556fa1a019f9495b23fa83eb 100644 (file)
@@ -1844,13 +1844,14 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
                if (ret < 0) {
                        dev_err(dev, "%pOF error reading port_id %d\n",
                                port_np, ret);
-                       return ret;
+                       goto of_node_put;
                }
 
                if (!port_id || port_id > common->port_num) {
                        dev_err(dev, "%pOF has invalid port_id %u %s\n",
                                port_np, port_id, port_np->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto of_node_put;
                }
 
                port = am65_common_get_port(common, port_id);
@@ -1866,8 +1867,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
                                (AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1));
 
                port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base);
-               if (IS_ERR(port->slave.mac_sl))
-                       return PTR_ERR(port->slave.mac_sl);
+               if (IS_ERR(port->slave.mac_sl)) {
+                       ret = PTR_ERR(port->slave.mac_sl);
+                       goto of_node_put;
+               }
 
                port->disabled = !of_device_is_available(port_np);
                if (port->disabled) {
@@ -1880,7 +1883,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
                        ret = PTR_ERR(port->slave.ifphy);
                        dev_err(dev, "%pOF error retrieving port phy: %d\n",
                                port_np, ret);
-                       return ret;
+                       goto of_node_put;
                }
 
                port->slave.mac_only =
@@ -1889,10 +1892,12 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
                /* get phy/link info */
                if (of_phy_is_fixed_link(port_np)) {
                        ret = of_phy_register_fixed_link(port_np);
-                       if (ret)
-                               return dev_err_probe(dev, ret,
+                       if (ret) {
+                               ret = dev_err_probe(dev, ret,
                                                     "failed to register fixed-link phy %pOF\n",
                                                     port_np);
+                               goto of_node_put;
+                       }
                        port->slave.phy_node = of_node_get(port_np);
                } else {
                        port->slave.phy_node =
@@ -1902,14 +1907,15 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
                if (!port->slave.phy_node) {
                        dev_err(dev,
                                "slave[%d] no phy found\n", port_id);
-                       return -ENODEV;
+                       ret = -ENODEV;
+                       goto of_node_put;
                }
 
                ret = of_get_phy_mode(port_np, &port->slave.phy_if);
                if (ret) {
                        dev_err(dev, "%pOF read phy-mode err %d\n",
                                port_np, ret);
-                       return ret;
+                       goto of_node_put;
                }
 
                ret = of_get_mac_address(port_np, port->slave.mac_addr);
@@ -1932,6 +1938,11 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
        }
 
        return 0;
+
+of_node_put:
+       of_node_put(port_np);
+       of_node_put(node);
+       return ret;
 }
 
 static void am65_cpsw_pcpu_stats_free(void *data)
index 90aafb56f1409ed7be70dd5c4e8b4a8cce7f7dda..a438202129323860798fc23708d1105d1ad5d446 100644 (file)
@@ -514,6 +514,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
                                goto err_free;
                        key = nmap->entry[i].key;
                        *key = i;
+                       memset(nmap->entry[i].value, 0, offmap->map.value_size);
                }
        }
 
index 0ab6a40be61147bde13b41279e32a8e9296417dd..a6a713b31aad93c807722458e27f3eec594118b4 100644 (file)
@@ -77,7 +77,10 @@ static int nsim_set_ringparam(struct net_device *dev,
 {
        struct netdevsim *ns = netdev_priv(dev);
 
-       memcpy(&ns->ethtool.ring, ring, sizeof(ns->ethtool.ring));
+       ns->ethtool.ring.rx_pending = ring->rx_pending;
+       ns->ethtool.ring.rx_jumbo_pending = ring->rx_jumbo_pending;
+       ns->ethtool.ring.rx_mini_pending = ring->rx_mini_pending;
+       ns->ethtool.ring.tx_pending = ring->tx_pending;
        return 0;
 }
 
index c204067f189026266373c4f06b149071da9c632c..c198722e4871d73685fbd012d68d31d0e592250f 100644 (file)
@@ -460,6 +460,9 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
 
                if (addr == mdiodev->addr) {
                        device_set_node(dev, of_fwnode_handle(child));
+                       /* The refcount on "child" is passed to the mdio
+                        * device. Do _not_ use of_node_put(child) here.
+                        */
                        return;
                }
        }
index 8cd265fc1fd9d4eb11b5196e7d831d2ec828f58c..075f8abde5cd7ff77208a9e648e73868c04642ef 100644 (file)
@@ -76,6 +76,8 @@
 #define LAN7801_USB_PRODUCT_ID         (0x7801)
 #define LAN78XX_EEPROM_MAGIC           (0x78A5)
 #define LAN78XX_OTP_MAGIC              (0x78F3)
+#define AT29M2AF_USB_VENDOR_ID         (0x07C9)
+#define AT29M2AF_USB_PRODUCT_ID        (0x0012)
 
 #define        MII_READ                        1
 #define        MII_WRITE                       0
@@ -4734,6 +4736,10 @@ static const struct usb_device_id products[] = {
        /* LAN7801 USB Gigabit Ethernet Device */
        USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID),
        },
+       {
+       /* ATM2-AF USB Gigabit Ethernet Device */
+       USB_DEVICE(AT29M2AF_USB_VENDOR_ID, AT29M2AF_USB_PRODUCT_ID),
+       },
        {},
 };
 MODULE_DEVICE_TABLE(usb, products);
index 86b814e99224c54ff99ee9b5c82fb73821486df1..f510e82194705d5ccc50e94606bc10acf4774006 100644 (file)
@@ -1358,6 +1358,7 @@ static const struct usb_device_id products[] = {
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */
        {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},    /* Telit ME910 */
        {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},    /* Telit ME910 dual modem */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
index 55db6a336f7ead862ab98ab99e4518a7d2b3b87f..b107835242ade6c2f7411b2a019e44a9b0c85748 100644 (file)
@@ -733,7 +733,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
                pr_debug("%s: rx error: len %u exceeds max size %d\n",
                         dev->name, len, GOOD_PACKET_LEN);
                dev->stats.rx_length_errors++;
-               goto err_len;
+               goto err;
        }
 
        if (likely(!vi->xdp_enabled)) {
@@ -825,10 +825,8 @@ static struct sk_buff *receive_small(struct net_device *dev,
 
 skip_xdp:
        skb = build_skb(buf, buflen);
-       if (!skb) {
-               put_page(page);
+       if (!skb)
                goto err;
-       }
        skb_reserve(skb, headroom - delta);
        skb_put(skb, len);
        if (!xdp_prog) {
@@ -839,13 +837,12 @@ skip_xdp:
        if (metasize)
                skb_metadata_set(skb, metasize);
 
-err:
        return skb;
 
 err_xdp:
        rcu_read_unlock();
        stats->xdp_drops++;
-err_len:
+err:
        stats->drops++;
        put_page(page);
 xdp_xmit:
index 5bf2318763c55b5a11a7d2cebc3114ffd61a6373..3a1a35b5672f1a27911a287579a7ce737a157f0e 100644 (file)
@@ -7,16 +7,20 @@ config BRCMSMAC
        depends on MAC80211
        depends on BCMA_POSSIBLE
        select BCMA
-       select NEW_LEDS if BCMA_DRIVER_GPIO
-       select LEDS_CLASS if BCMA_DRIVER_GPIO
        select BRCMUTIL
        select FW_LOADER
        select CORDIC
        help
          This module adds support for PCIe wireless adapters based on Broadcom
-         IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will
-         be available if you select BCMA_DRIVER_GPIO. If you choose to build a
-         module, the driver will be called brcmsmac.ko.
+         IEEE802.11n SoftMAC chipsets. If you choose to build a module, the
+         driver will be called brcmsmac.ko.
+
+config BRCMSMAC_LEDS
+       def_bool BRCMSMAC && BCMA_DRIVER_GPIO && MAC80211_LEDS
+       help
+         The brcmsmac LED support depends on the presence of the
+         BCMA_DRIVER_GPIO driver, and it only works if LED support
+         is enabled and reachable from the driver module.
 
 source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
 
index 482d7737764da76c4ae253641f0d30408dbe28ec..090757730ba60db0708afb5093ddb4cc90ce8e00 100644 (file)
@@ -42,6 +42,6 @@ brcmsmac-y := \
        brcms_trace_events.o \
        debug.o
 
-brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
+brcmsmac-$(CONFIG_BRCMSMAC_LEDS) += led.o
 
 obj-$(CONFIG_BRCMSMAC) += brcmsmac.o
index d65f5c268fd77490a3b2a7d573fe229542408f06..2a5cbeb9e783122b00266b809b3b8853815d246e 100644 (file)
@@ -24,7 +24,7 @@ struct brcms_led {
        struct gpio_desc *gpiod;
 };
 
-#ifdef CONFIG_BCMA_DRIVER_GPIO
+#ifdef CONFIG_BRCMSMAC_LEDS
 void brcms_led_unregister(struct brcms_info *wl);
 int brcms_led_register(struct brcms_info *wl);
 #else
index 24fe3f63c3215aca38913279318a77abb3001431..7eacc8e58ee1440be729eb07fc5f82270d0e4773 100644 (file)
@@ -2,14 +2,13 @@
 config IWLEGACY
        tristate
        select FW_LOADER
-       select NEW_LEDS
-       select LEDS_CLASS
        select LEDS_TRIGGERS
        select MAC80211_LEDS
 
 config IWL4965
        tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
        depends on PCI && MAC80211
+       depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
        select IWLEGACY
        help
          This option enables support for
@@ -38,6 +37,7 @@ config IWL4965
 config IWL3945
        tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
        depends on PCI && MAC80211
+       depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
        select IWLEGACY
        help
          Select to build the driver supporting the:
index 1085afbefba873f792b0ee38dba15c4a7a358795..418ae4f870ab7086a773e78a9bb2f14c1485c08e 100644 (file)
@@ -47,7 +47,7 @@ if IWLWIFI
 
 config IWLWIFI_LEDS
        bool
-       depends on LEDS_CLASS=y || LEDS_CLASS=IWLWIFI
+       depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
        depends on IWLMVM || IWLDVM
        select LEDS_TRIGGERS
        select MAC80211_LEDS
index bdd4ee43254835e05d1a8dd18cd67d9c4acbb507..76e0b7b45980d779f19b0a969ed7a2162c583c76 100644 (file)
@@ -269,17 +269,18 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
        u8 rate_plcp;
        u32 rate_flags = 0;
        bool is_cck;
-       struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
        /* info->control is only relevant for non HW rate control */
        if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
+               struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+
                /* HT rate doesn't make sense for a non data frame */
                WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS &&
                          !ieee80211_is_data(fc),
                          "Got a HT rate (flags:0x%x/mcs:%d/fc:0x%x/state:%d) for a non data frame\n",
                          info->control.rates[0].flags,
                          info->control.rates[0].idx,
-                         le16_to_cpu(fc), mvmsta->sta_state);
+                         le16_to_cpu(fc), sta ? mvmsta->sta_state : -1);
 
                rate_idx = info->control.rates[0].idx;
        }
index 79ab850a45a28eb81b997204ac3c485fb902e044..c78ae4b897619827148ba14cbd245483222fbb8c 100644 (file)
@@ -34,4 +34,4 @@ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
 obj-$(CONFIG_MT7603E) += mt7603/
 obj-$(CONFIG_MT7615_COMMON) += mt7615/
 obj-$(CONFIG_MT7915E) += mt7915/
-obj-$(CONFIG_MT7921E) += mt7921/
+obj-$(CONFIG_MT7921_COMMON) += mt7921/
index 93b1411105373cd21fe4625bca0e339e8f446c66..7fc5135ffbbfd49be057fe5c33e68d38175d368d 100644 (file)
@@ -332,8 +332,8 @@ config PCIE_APPLE
          If unsure, say Y if you have an Apple Silicon system.
 
 config PCIE_MT7621
-       tristate "MediaTek MT7621 PCIe Controller"
-       depends on (RALINK && SOC_MT7621) || (MIPS && COMPILE_TEST)
+       bool "MediaTek MT7621 PCIe Controller"
+       depends on SOC_MT7621 || (MIPS && COMPILE_TEST)
        select PHY_MT7621_PCI
        default SOC_MT7621
        help
index 4c5bba52b10593890c9a95ccea929148db9cdc5f..24d3395964cc4ba2d3934a32299fef3f667cd45f 100644 (file)
@@ -20,7 +20,6 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
        struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
        struct mrq_reset_request request;
        struct tegra_bpmp_message msg;
-       int err;
 
        memset(&request, 0, sizeof(request));
        request.cmd = command;
@@ -31,13 +30,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
        msg.tx.data = &request;
        msg.tx.size = sizeof(request);
 
-       err = tegra_bpmp_transfer(bpmp, &msg);
-       if (err)
-               return err;
-       if (msg.rx.ret)
-               return -EINVAL;
-
-       return 0;
+       return tegra_bpmp_transfer(bpmp, &msg);
 }
 
 static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc,
index b9f6d83ff380c872bba3d5e40f65043d2a892d7f..2101fc5761c3c2c00f049255a6c2aa3162f09eb8 100644 (file)
@@ -3053,7 +3053,6 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
        struct smp_completion_resp *psmpPayload;
        struct task_status_struct *ts;
        struct pm8001_device *pm8001_dev;
-       char *pdma_respaddr = NULL;
 
        psmpPayload = (struct smp_completion_resp *)(piomb + 4);
        status = le32_to_cpu(psmpPayload->status);
@@ -3080,19 +3079,23 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
                if (pm8001_dev)
                        atomic_dec(&pm8001_dev->running_req);
                if (pm8001_ha->smp_exp_mode == SMP_DIRECT) {
+                       struct scatterlist *sg_resp = &t->smp_task.smp_resp;
+                       u8 *payload;
+                       void *to;
+
                        pm8001_dbg(pm8001_ha, IO,
                                   "DIRECT RESPONSE Length:%d\n",
                                   param);
-                       pdma_respaddr = (char *)(phys_to_virt(cpu_to_le64
-                                               ((u64)sg_dma_address
-                                               (&t->smp_task.smp_resp))));
+                       to = kmap_atomic(sg_page(sg_resp));
+                       payload = to + sg_resp->offset;
                        for (i = 0; i < param; i++) {
-                               *(pdma_respaddr+i) = psmpPayload->_r_a[i];
+                               *(payload + i) = psmpPayload->_r_a[i];
                                pm8001_dbg(pm8001_ha, IO,
                                           "SMP Byte%d DMA data 0x%x psmp 0x%x\n",
-                                          i, *(pdma_respaddr + i),
+                                          i, *(payload + i),
                                           psmpPayload->_r_a[i]);
                        }
+                       kunmap_atomic(to);
                }
                break;
        case IO_ABORTED:
@@ -4236,14 +4239,14 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
        struct sas_task *task = ccb->task;
        struct domain_device *dev = task->dev;
        struct pm8001_device *pm8001_dev = dev->lldd_dev;
-       struct scatterlist *sg_req, *sg_resp;
+       struct scatterlist *sg_req, *sg_resp, *smp_req;
        u32 req_len, resp_len;
        struct smp_req smp_cmd;
        u32 opc;
        struct inbound_queue_table *circularQ;
-       char *preq_dma_addr = NULL;
-       __le64 tmp_addr;
        u32 i, length;
+       u8 *payload;
+       u8 *to;
 
        memset(&smp_cmd, 0, sizeof(smp_cmd));
        /*
@@ -4280,8 +4283,9 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
                pm8001_ha->smp_exp_mode = SMP_INDIRECT;
 
 
-       tmp_addr = cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
-       preq_dma_addr = (char *)phys_to_virt(tmp_addr);
+       smp_req = &task->smp_task.smp_req;
+       to = kmap_atomic(sg_page(smp_req));
+       payload = to + smp_req->offset;
 
        /* INDIRECT MODE command settings. Use DMA */
        if (pm8001_ha->smp_exp_mode == SMP_INDIRECT) {
@@ -4289,7 +4293,7 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
                /* for SPCv indirect mode. Place the top 4 bytes of
                 * SMP Request header here. */
                for (i = 0; i < 4; i++)
-                       smp_cmd.smp_req16[i] = *(preq_dma_addr + i);
+                       smp_cmd.smp_req16[i] = *(payload + i);
                /* exclude top 4 bytes for SMP req header */
                smp_cmd.long_smp_req.long_req_addr =
                        cpu_to_le64((u64)sg_dma_address
@@ -4320,20 +4324,20 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
                pm8001_dbg(pm8001_ha, IO, "SMP REQUEST DIRECT MODE\n");
                for (i = 0; i < length; i++)
                        if (i < 16) {
-                               smp_cmd.smp_req16[i] = *(preq_dma_addr+i);
+                               smp_cmd.smp_req16[i] = *(payload + i);
                                pm8001_dbg(pm8001_ha, IO,
                                           "Byte[%d]:%x (DMA data:%x)\n",
                                           i, smp_cmd.smp_req16[i],
-                                          *(preq_dma_addr));
+                                          *(payload));
                        } else {
-                               smp_cmd.smp_req[i] = *(preq_dma_addr+i);
+                               smp_cmd.smp_req[i] = *(payload + i);
                                pm8001_dbg(pm8001_ha, IO,
                                           "Byte[%d]:%x (DMA data:%x)\n",
                                           i, smp_cmd.smp_req[i],
-                                          *(preq_dma_addr));
+                                          *(payload));
                        }
        }
-
+       kunmap_atomic(to);
        build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag,
                                &smp_cmd, pm8001_ha->smp_exp_mode, length);
        rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &smp_cmd,
index 519b3651d1d966903b8c9e7bf0a1c21c550def12..c2f076b56e2471f1736baaf1042a6e6ffcd49e00 100644 (file)
@@ -17,6 +17,7 @@
 
 #define BLK_SFT_RSTN   0x0
 #define BLK_CLK_EN     0x4
+#define BLK_MIPI_RESET_DIV     0x8 /* Mini/Nano DISPLAY_BLK_CTRL only */
 
 struct imx8m_blk_ctrl_domain;
 
@@ -36,6 +37,15 @@ struct imx8m_blk_ctrl_domain_data {
        const char *gpc_name;
        u32 rst_mask;
        u32 clk_mask;
+
+       /*
+        * i.MX8M Mini and Nano have a third DISPLAY_BLK_CTRL register
+        * which is used to control the reset for the MIPI Phy.
+        * Since it's only present in certain circumstances,
+        * an if-statement should be used before setting and clearing this
+        * register.
+        */
+       u32 mipi_phy_rst_mask;
 };
 
 #define DOMAIN_MAX_CLKS 3
@@ -78,6 +88,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 
        /* put devices into reset */
        regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask);
+       if (data->mipi_phy_rst_mask)
+               regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
 
        /* enable upstream and blk-ctrl clocks to allow reset to propagate */
        ret = clk_bulk_prepare_enable(data->num_clks, domain->clks);
@@ -99,6 +111,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 
        /* release reset */
        regmap_set_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask);
+       if (data->mipi_phy_rst_mask)
+               regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
 
        /* disable upstream clocks */
        clk_bulk_disable_unprepare(data->num_clks, domain->clks);
@@ -120,6 +134,9 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
        struct imx8m_blk_ctrl *bc = domain->bc;
 
        /* put devices into reset and disable clocks */
+       if (data->mipi_phy_rst_mask)
+               regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
+
        regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask);
        regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
 
@@ -480,6 +497,7 @@ static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[]
                .gpc_name = "mipi-dsi",
                .rst_mask = BIT(5),
                .clk_mask = BIT(8) | BIT(9),
+               .mipi_phy_rst_mask = BIT(17),
        },
        [IMX8MM_DISPBLK_PD_MIPI_CSI] = {
                .name = "dispblk-mipi-csi",
@@ -488,6 +506,7 @@ static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[]
                .gpc_name = "mipi-csi",
                .rst_mask = BIT(3) | BIT(4),
                .clk_mask = BIT(10) | BIT(11),
+               .mipi_phy_rst_mask = BIT(16),
        },
 };
 
index ac6d856ba228d451d5abfdb8525c670c812ffdc4..77bc12039c3d444ef81a7404b767523d7acf166b 100644 (file)
@@ -36,6 +36,10 @@ static int __init imx_soc_device_init(void)
        int ret;
        int i;
 
+       /* Return early if this is running on devices with different SoCs */
+       if (!__mxc_cpu_type)
+               return 0;
+
        if (of_machine_is_compatible("fsl,ls1021a"))
                return 0;
 
index f2151815db585b3f22bd968f0f1e984069b3b3fb..e714ed3b61bc368a7100869253657bef32da25e7 100644 (file)
@@ -320,7 +320,7 @@ static struct platform_driver tegra_fuse_driver = {
 };
 builtin_platform_driver(tegra_fuse_driver);
 
-bool __init tegra_fuse_read_spare(unsigned int spare)
+u32 __init tegra_fuse_read_spare(unsigned int spare)
 {
        unsigned int offset = fuse->soc->info->spare + spare * 4;
 
index de58feba0435015fecd06f20acdcbd911f52f464..ecff0c08e9595ace7f69deb0d99183d4ba0a6235 100644 (file)
@@ -65,7 +65,7 @@ struct tegra_fuse {
 void tegra_init_revision(void);
 void tegra_init_apbmisc(void);
 
-bool __init tegra_fuse_read_spare(unsigned int spare);
+u32 __init tegra_fuse_read_spare(unsigned int spare);
 u32 __init tegra_fuse_read_early(unsigned int offset);
 
 u8 tegra_get_major_rev(void);
index da6b88e80dc07e0afd1fc1d7eb9235c27a53a60b..297dc62bca2986f014c4b4060c95d112a807fe7d 100644 (file)
@@ -203,9 +203,8 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
 
        *ta_size = roundup(fw->size, PAGE_SIZE);
        *ta = (void *)__get_free_pages(GFP_KERNEL, get_order(*ta_size));
-       if (IS_ERR(*ta)) {
-               pr_err("%s: get_free_pages failed 0x%llx\n", __func__,
-                      (u64)*ta);
+       if (!*ta) {
+               pr_err("%s: get_free_pages failed\n", __func__);
                rc = -ENOMEM;
                goto rel_fw;
        }
index 7332a74a4b00c504014eb1d39b4873017dcab1a3..09bbe53c3ac4ec193717af888f58a0ba1347e636 100644 (file)
@@ -404,7 +404,8 @@ static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *m
                goto msg_err;
 
        while (mdev->id_table[i].device) {
-               supported_classes |= BIT(mdev->id_table[i].device);
+               if (mdev->id_table[i].device <= 63)
+                       supported_classes |= BIT_ULL(mdev->id_table[i].device);
                i++;
        }
 
index c9204c62f339c33ab484f60166d03816ecbf15d8..eddcb64a910acf2e3beafed805581ba10d1a699e 100644 (file)
@@ -655,7 +655,8 @@ static void vduse_vdpa_get_config(struct vdpa_device *vdpa, unsigned int offset,
 {
        struct vduse_dev *dev = vdpa_to_vduse(vdpa);
 
-       if (len > dev->config_size - offset)
+       if (offset > dev->config_size ||
+           len > dev->config_size - offset)
                return;
 
        memcpy(buf, dev->config + offset, len);
@@ -975,7 +976,8 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
                        break;
 
                ret = -EINVAL;
-               if (config.length == 0 ||
+               if (config.offset > dev->config_size ||
+                   config.length == 0 ||
                    config.length > dev->config_size - config.offset)
                        break;
 
index 29cced1cd27784a708df783b2f81e2340c86f145..e3c4f059b21a202b36e8a18930432b546bac9bc2 100644 (file)
@@ -197,7 +197,7 @@ static int vhost_vdpa_config_validate(struct vhost_vdpa *v,
        struct vdpa_device *vdpa = v->vdpa;
        long size = vdpa->config->get_config_size(vdpa);
 
-       if (c->len == 0)
+       if (c->len == 0 || c->off > size)
                return -EINVAL;
 
        if (c->len > size - c->off)
index 6d2614e34470f463bb553e7e9e80f7bb0a0cef4a..028b05d4454604d5aee636895f8fcfee77a2b46a 100644 (file)
@@ -268,7 +268,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev)
        size_t max_segment_size = SIZE_MAX;
 
        if (vring_use_dma_api(vdev))
-               max_segment_size = dma_max_mapping_size(&vdev->dev);
+               max_segment_size = dma_max_mapping_size(vdev->dev.parent);
 
        return max_segment_size;
 }
index cb6ad61eec3bf5f30d5d6477b0bb7635f131b4bc..afe4b803f84b46d319e4885fdbc6ea8a1919cf40 100644 (file)
@@ -514,8 +514,9 @@ static void afs_add_open_mmap(struct afs_vnode *vnode)
        if (atomic_inc_return(&vnode->cb_nr_mmap) == 1) {
                down_write(&vnode->volume->cell->fs_open_mmaps_lock);
 
-               list_add_tail(&vnode->cb_mmap_link,
-                             &vnode->volume->cell->fs_open_mmaps);
+               if (list_empty(&vnode->cb_mmap_link))
+                       list_add_tail(&vnode->cb_mmap_link,
+                                     &vnode->volume->cell->fs_open_mmaps);
 
                up_write(&vnode->volume->cell->fs_open_mmaps_lock);
        }
index d110def8aa8eb993212c00ed161089eba89a7545..34c68724c98bec4070dd56de816c07ea78c2db99 100644 (file)
@@ -667,6 +667,7 @@ static void afs_i_init_once(void *_vnode)
        INIT_LIST_HEAD(&vnode->pending_locks);
        INIT_LIST_HEAD(&vnode->granted_locks);
        INIT_DELAYED_WORK(&vnode->lock_work, afs_lock_work);
+       INIT_LIST_HEAD(&vnode->cb_mmap_link);
        seqlock_init(&vnode->cb_lock);
 }
 
index c3983bdaf4b886d1daa60c49c769c04c4702835e..f704339c6b8652a0c3cc1dded80c20b2426a7fb2 100644 (file)
@@ -463,8 +463,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
                BUG_ON(ret < 0);
                rcu_assign_pointer(root->node, cow);
 
-               btrfs_free_tree_block(trans, root, buf, parent_start,
-                                     last_ref);
+               btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
+                                     parent_start, last_ref);
                free_extent_buffer(buf);
                add_root_to_dirty_list(root);
        } else {
@@ -485,8 +485,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
                                return ret;
                        }
                }
-               btrfs_free_tree_block(trans, root, buf, parent_start,
-                                     last_ref);
+               btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
+                                     parent_start, last_ref);
        }
        if (unlock_orig)
                btrfs_tree_unlock(buf);
@@ -927,7 +927,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                free_extent_buffer(mid);
 
                root_sub_used(root, mid->len);
-               btrfs_free_tree_block(trans, root, mid, 0, 1);
+               btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
                /* once for the root ptr */
                free_extent_buffer_stale(mid);
                return 0;
@@ -986,7 +986,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                        btrfs_tree_unlock(right);
                        del_ptr(root, path, level + 1, pslot + 1);
                        root_sub_used(root, right->len);
-                       btrfs_free_tree_block(trans, root, right, 0, 1);
+                       btrfs_free_tree_block(trans, btrfs_root_id(root), right,
+                                             0, 1);
                        free_extent_buffer_stale(right);
                        right = NULL;
                } else {
@@ -1031,7 +1032,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                btrfs_tree_unlock(mid);
                del_ptr(root, path, level + 1, pslot);
                root_sub_used(root, mid->len);
-               btrfs_free_tree_block(trans, root, mid, 0, 1);
+               btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
                free_extent_buffer_stale(mid);
                mid = NULL;
        } else {
@@ -4032,7 +4033,7 @@ static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans,
        root_sub_used(root, leaf->len);
 
        atomic_inc(&leaf->refs);
-       btrfs_free_tree_block(trans, root, leaf, 0, 1);
+       btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1);
        free_extent_buffer_stale(leaf);
 }
 /*
index 7553e9dc5f93830ffcaa1deeb407c13c5c4effc5..5fe5eccb3c874b5e978c2bb38149bddf77a1d5b7 100644 (file)
@@ -2257,6 +2257,11 @@ static inline bool btrfs_root_dead(const struct btrfs_root *root)
        return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0;
 }
 
+static inline u64 btrfs_root_id(const struct btrfs_root *root)
+{
+       return root->root_key.objectid;
+}
+
 /* struct btrfs_root_backup */
 BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup,
                   tree_root, 64);
@@ -2719,7 +2724,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
                                             u64 empty_size,
                                             enum btrfs_lock_nesting nest);
 void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root,
+                          u64 root_id,
                           struct extent_buffer *buf,
                           u64 parent, int last_ref);
 int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
index 514ead6e93b6f2fc5dd687e365cedd1de4f8997f..b3f2e2232326ccca6185dc310628b273ddcd48f1 100644 (file)
@@ -1732,6 +1732,14 @@ again:
        }
        return root;
 fail:
+       /*
+        * If our caller provided us an anonymous device, then it's his
+        * responsability to free it in case we fail. So we have to set our
+        * root's anon_dev to 0 to avoid a double free, once by btrfs_put_root()
+        * and once again by our caller.
+        */
+       if (anon_dev)
+               root->anon_dev = 0;
        btrfs_put_root(root);
        return ERR_PTR(ret);
 }
index fc4895e6a62cd18ca6110b3c87d1874d47d237f0..25ef6e3fd3069f7b113be393fac05bc83c9c8295 100644 (file)
@@ -3275,20 +3275,20 @@ out_delayed_unlock:
 }
 
 void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root,
+                          u64 root_id,
                           struct extent_buffer *buf,
                           u64 parent, int last_ref)
 {
-       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_ref generic_ref = { 0 };
        int ret;
 
        btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF,
                               buf->start, buf->len, parent);
        btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
-                           root->root_key.objectid, 0, false);
+                           root_id, 0, false);
 
-       if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
+       if (root_id != BTRFS_TREE_LOG_OBJECTID) {
                btrfs_ref_tree_mod(fs_info, &generic_ref);
                ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL);
                BUG_ON(ret); /* -ENOMEM */
@@ -3298,7 +3298,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
                struct btrfs_block_group *cache;
                bool must_pin = false;
 
-               if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
+               if (root_id != BTRFS_TREE_LOG_OBJECTID) {
                        ret = check_ref_cleanup(trans, buf->start);
                        if (!ret) {
                                btrfs_redirty_list_add(trans->transaction, buf);
@@ -5472,7 +5472,8 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
                        goto owner_mismatch;
        }
 
-       btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1);
+       btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent,
+                             wc->refs[level] == 1);
 out:
        wc->refs[level] = 0;
        wc->flags[level] = 0;
index 3258b6f01e85b3601ad8b93553e0811e05e71190..9234d96a7fd5c5e4647d3a29edd2b3a2f5b85767 100644 (file)
@@ -6611,6 +6611,14 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num)
        if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
                return 0;
 
+       /*
+        * We could have had EXTENT_BUFFER_UPTODATE cleared by the write
+        * operation, which could potentially still be in flight.  In this case
+        * we simply want to return an error.
+        */
+       if (unlikely(test_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)))
+               return -EIO;
+
        if (eb->fs_info->sectorsize < PAGE_SIZE)
                return read_extent_buffer_subpage(eb, wait, mirror_num);
 
index a33bca94d133ecb6022df27da5e2655f58c93fc3..3abec44c62559df0b926230f6776bbf2a0e2e88b 100644 (file)
@@ -1256,8 +1256,8 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
        btrfs_tree_lock(free_space_root->node);
        btrfs_clean_tree_block(free_space_root->node);
        btrfs_tree_unlock(free_space_root->node);
-       btrfs_free_tree_block(trans, free_space_root, free_space_root->node,
-                             0, 1);
+       btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
+                             free_space_root->node, 0, 1);
 
        btrfs_put_root(free_space_root);
 
index 2b84846ed9343f193485d7639b9cc9417fc31b2a..edfecfe62b4b6f5dec5cdfe811474f3abd3d60ec 100644 (file)
@@ -617,11 +617,13 @@ static noinline int create_subvol(struct user_namespace *mnt_userns,
                 * Since we don't abort the transaction in this case, free the
                 * tree block so that we don't leak space and leave the
                 * filesystem in an inconsistent state (an extent item in the
-                * extent tree without backreferences). Also no need to have
-                * the tree block locked since it is not in any tree at this
-                * point, so no other task can find it and use it.
+                * extent tree with a backreference for a root that does not
+                * exists).
                 */
-               btrfs_free_tree_block(trans, root, leaf, 0, 1);
+               btrfs_tree_lock(leaf);
+               btrfs_clean_tree_block(leaf);
+               btrfs_tree_unlock(leaf);
+               btrfs_free_tree_block(trans, objectid, leaf, 0, 1);
                free_extent_buffer(leaf);
                goto fail;
        }
index db680f5be745a0fd80cd8678b2190dfff8bdaa5c..6c037f1252b776279e8e2fe294264bc8091bb4dd 100644 (file)
@@ -1219,7 +1219,8 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        btrfs_tree_lock(quota_root->node);
        btrfs_clean_tree_block(quota_root->node);
        btrfs_tree_unlock(quota_root->node);
-       btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1);
+       btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
+                             quota_root->node, 0, 1);
 
        btrfs_put_root(quota_root);
 
index 3e6f14e13918b9485d5d427a1cf17f340a7d4c84..6993dcdba6f1ad6dd466675b96fd7e5bfe459c4b 100644 (file)
@@ -1181,6 +1181,7 @@ again:
                                             parent_objectid, victim_name,
                                             victim_name_len);
                        if (ret < 0) {
+                               kfree(victim_name);
                                return ret;
                        } else if (!ret) {
                                ret = -ENOENT;
@@ -3977,6 +3978,7 @@ search:
                        goto done;
                }
                if (btrfs_header_generation(path->nodes[0]) != trans->transid) {
+                       ctx->last_dir_item_offset = min_key.offset;
                        ret = overwrite_item(trans, log, dst_path,
                                             path->nodes[0], path->slots[0],
                                             &min_key);
index 0997e3cd74e915c3f056eeff302a7cc1de7dba96..fd0ced829edb8288aad16b9222c7d8bd30801a63 100644 (file)
@@ -1370,8 +1370,10 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags,
 
        bytenr_orig = btrfs_sb_offset(0);
        ret = btrfs_sb_log_location_bdev(bdev, 0, READ, &bytenr);
-       if (ret)
-               return ERR_PTR(ret);
+       if (ret) {
+               device = ERR_PTR(ret);
+               goto error_bdev_put;
+       }
 
        disk_super = btrfs_read_disk_super(bdev, bytenr, bytenr_orig);
        if (IS_ERR(disk_super)) {
index b9460b6fb76f7c55999f9be71dcd93d014699a08..c447fa2e2d1feb89ff9333a22203ad81fe41b436 100644 (file)
@@ -4350,7 +4350,7 @@ void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb);
        int bits = (fmode << 1) | 1;
-       bool is_opened = false;
+       bool already_opened = false;
        int i;
 
        if (count == 1)
@@ -4358,19 +4358,19 @@ void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count)
 
        spin_lock(&ci->i_ceph_lock);
        for (i = 0; i < CEPH_FILE_MODE_BITS; i++) {
-               if (bits & (1 << i))
-                       ci->i_nr_by_mode[i] += count;
-
                /*
-                * If any of the mode ref is larger than 1,
+                * If any of the mode ref is larger than 0,
                 * that means it has been already opened by
                 * others. Just skip checking the PIN ref.
                 */
-               if (i && ci->i_nr_by_mode[i] > 1)
-                       is_opened = true;
+               if (i && ci->i_nr_by_mode[i])
+                       already_opened = true;
+
+               if (bits & (1 << i))
+                       ci->i_nr_by_mode[i] += count;
        }
 
-       if (!is_opened)
+       if (!already_opened)
                percpu_counter_inc(&mdsc->metric.opened_inodes);
        spin_unlock(&ci->i_ceph_lock);
 }
index 02a0a0fd9ccd51c7f4d11b60c875eaa081d0e2a6..c138e8126286cfe52996f982071003fbc95243a6 100644 (file)
@@ -605,13 +605,25 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
        in.cap.realm = cpu_to_le64(ci->i_snap_realm->ino);
        in.cap.flags = CEPH_CAP_FLAG_AUTH;
        in.ctime = in.mtime = in.atime = iinfo.btime;
-       in.mode = cpu_to_le32((u32)mode);
        in.truncate_seq = cpu_to_le32(1);
        in.truncate_size = cpu_to_le64(-1ULL);
        in.xattr_version = cpu_to_le64(1);
        in.uid = cpu_to_le32(from_kuid(&init_user_ns, current_fsuid()));
-       in.gid = cpu_to_le32(from_kgid(&init_user_ns, dir->i_mode & S_ISGID ?
-                               dir->i_gid : current_fsgid()));
+       if (dir->i_mode & S_ISGID) {
+               in.gid = cpu_to_le32(from_kgid(&init_user_ns, dir->i_gid));
+
+               /* Directories always inherit the setgid bit. */
+               if (S_ISDIR(mode))
+                       mode |= S_ISGID;
+               else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
+                        !in_group_p(dir->i_gid) &&
+                        !capable_wrt_inode_uidgid(&init_user_ns, dir, CAP_FSETID))
+                       mode &= ~S_ISGID;
+       } else {
+               in.gid = cpu_to_le32(from_kgid(&init_user_ns, current_fsgid()));
+       }
+       in.mode = cpu_to_le32((u32)mode);
+
        in.nlink = cpu_to_le32(1);
        in.max_size = cpu_to_le64(lo->stripe_unit);
 
@@ -847,7 +859,7 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
        ssize_t ret;
        u64 off = iocb->ki_pos;
        u64 len = iov_iter_count(to);
-       u64 i_size;
+       u64 i_size = i_size_read(inode);
 
        dout("sync_read on file %p %llu~%u %s\n", file, off, (unsigned)len,
             (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
index 250aad330a1062a5cbfef584f8c60819ffb5a929..c30eefc0ac19346e086128e3872a8d1848ea1dc2 100644 (file)
@@ -3683,7 +3683,7 @@ static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
        struct ceph_pagelist *pagelist = recon_state->pagelist;
        struct dentry *dentry;
        char *path;
-       int pathlen, err;
+       int pathlen = 0, err;
        u64 pathbase;
        u64 snap_follows;
 
@@ -3703,7 +3703,6 @@ static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
                }
        } else {
                path = NULL;
-               pathlen = 0;
                pathbase = 0;
        }
 
index ad4a8bf3cf109fd984449eedef5de6bf9fa342e8..97d212a9b814454b83091e9a1dc40b76fe908b38 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -841,28 +841,68 @@ void do_close_on_exec(struct files_struct *files)
        spin_unlock(&files->file_lock);
 }
 
-static struct file *__fget_files(struct files_struct *files, unsigned int fd,
-                                fmode_t mask, unsigned int refs)
+static inline struct file *__fget_files_rcu(struct files_struct *files,
+       unsigned int fd, fmode_t mask, unsigned int refs)
 {
-       struct file *file;
+       for (;;) {
+               struct file *file;
+               struct fdtable *fdt = rcu_dereference_raw(files->fdt);
+               struct file __rcu **fdentry;
 
-       rcu_read_lock();
-loop:
-       file = files_lookup_fd_rcu(files, fd);
-       if (file) {
-               /* File object ref couldn't be taken.
-                * dup2() atomicity guarantee is the reason
-                * we loop to catch the new file (or NULL pointer)
+               if (unlikely(fd >= fdt->max_fds))
+                       return NULL;
+
+               fdentry = fdt->fd + array_index_nospec(fd, fdt->max_fds);
+               file = rcu_dereference_raw(*fdentry);
+               if (unlikely(!file))
+                       return NULL;
+
+               if (unlikely(file->f_mode & mask))
+                       return NULL;
+
+               /*
+                * Ok, we have a file pointer. However, because we do
+                * this all locklessly under RCU, we may be racing with
+                * that file being closed.
+                *
+                * Such a race can take two forms:
+                *
+                *  (a) the file ref already went down to zero,
+                *      and get_file_rcu_many() fails. Just try
+                *      again:
                 */
-               if (file->f_mode & mask)
-                       file = NULL;
-               else if (!get_file_rcu_many(file, refs))
-                       goto loop;
-               else if (files_lookup_fd_raw(files, fd) != file) {
+               if (unlikely(!get_file_rcu_many(file, refs)))
+                       continue;
+
+               /*
+                *  (b) the file table entry has changed under us.
+                *       Note that we don't need to re-check the 'fdt->fd'
+                *       pointer having changed, because it always goes
+                *       hand-in-hand with 'fdt'.
+                *
+                * If so, we need to put our refs and try again.
+                */
+               if (unlikely(rcu_dereference_raw(files->fdt) != fdt) ||
+                   unlikely(rcu_dereference_raw(*fdentry) != file)) {
                        fput_many(file, refs);
-                       goto loop;
+                       continue;
                }
+
+               /*
+                * Ok, we have a ref to the file, and checked that it
+                * still exists.
+                */
+               return file;
        }
+}
+
+static struct file *__fget_files(struct files_struct *files, unsigned int fd,
+                                fmode_t mask, unsigned int refs)
+{
+       struct file *file;
+
+       rcu_read_lock();
+       file = __fget_files_rcu(files, fd, mask, refs);
        rcu_read_unlock();
 
        return file;
index 8d2bb818a3bb009f51c71c0da93d637f7f80ec2b..5c4f582d6549a11a8301fd793488a516fc41aaf0 100644 (file)
@@ -395,7 +395,9 @@ static void io_wqe_dec_running(struct io_worker *worker)
        if (atomic_dec_and_test(&acct->nr_running) && io_acct_run_queue(acct)) {
                atomic_inc(&acct->nr_running);
                atomic_inc(&wqe->wq->worker_refs);
+               raw_spin_unlock(&wqe->lock);
                io_queue_worker_create(worker, acct, create_worker_cb);
+               raw_spin_lock(&wqe->lock);
        }
 }
 
index 259ee2bda4926478f0feb3105d2404875ce5bbc5..b76dfb310ab650c24adfb2b6f3f329928e61a1fc 100644 (file)
@@ -1787,5 +1787,6 @@ static void __exit zonefs_exit(void)
 MODULE_AUTHOR("Damien Le Moal");
 MODULE_DESCRIPTION("Zone file system for zoned block devices");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_FS("zonefs");
 module_init(zonefs_init);
 module_exit(zonefs_exit);
index c8cc46f80a1619a5529732c6bf5b3c8083502330..f106a3941cdf35397503a9cbccf5b96bac5b81d1 100644 (file)
@@ -136,19 +136,21 @@ struct mptcp_info {
  * MPTCP_EVENT_REMOVED: token, rem_id
  * An address has been lost by the peer.
  *
- * MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6,
- *                              daddr4 | daddr6, sport, dport, backup,
- *                              if_idx [, error]
+ * MPTCP_EVENT_SUB_ESTABLISHED: token, family, loc_id, rem_id,
+ *                              saddr4 | saddr6, daddr4 | daddr6, sport,
+ *                              dport, backup, if_idx [, error]
  * A new subflow has been established. 'error' should not be set.
  *
- * MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6,
- *                         sport, dport, backup, if_idx [, error]
+ * MPTCP_EVENT_SUB_CLOSED: token, family, loc_id, rem_id, saddr4 | saddr6,
+ *                         daddr4 | daddr6, sport, dport, backup, if_idx
+ *                         [, error]
  * A subflow has been closed. An error (copy of sk_err) could be set if an
  * error has been detected for this subflow.
  *
- * MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6,
- *                           sport, dport, backup, if_idx [, error]
- *       The priority of a subflow has changed. 'error' should not be set.
+ * MPTCP_EVENT_SUB_PRIORITY: token, family, loc_id, rem_id, saddr4 | saddr6,
+ *                           daddr4 | daddr6, sport, dport, backup, if_idx
+ *                           [, error]
+ * The priority of a subflow has changed. 'error' should not be set.
  */
 enum mptcp_event_type {
        MPTCP_EVENT_UNSPEC = 0,
index 121d37e700a62b53854c06199d9a89850ec39dd4..4cebadb5f30db908e1127550fe1d84a419d81d10 100644 (file)
@@ -718,7 +718,7 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
 {
        int rc = 0;
        struct sk_buff *skb;
-       static unsigned int failed = 0;
+       unsigned int failed = 0;
 
        /* NOTE: kauditd_thread takes care of all our locking, we just use
         *       the netlink info passed to us (e.g. sk and portid) */
@@ -735,32 +735,30 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
                        continue;
                }
 
+retry:
                /* grab an extra skb reference in case of error */
                skb_get(skb);
                rc = netlink_unicast(sk, skb, portid, 0);
                if (rc < 0) {
-                       /* fatal failure for our queue flush attempt? */
+                       /* send failed - try a few times unless fatal error */
                        if (++failed >= retry_limit ||
                            rc == -ECONNREFUSED || rc == -EPERM) {
-                               /* yes - error processing for the queue */
                                sk = NULL;
                                if (err_hook)
                                        (*err_hook)(skb);
-                               if (!skb_hook)
-                                       goto out;
-                               /* keep processing with the skb_hook */
+                               if (rc == -EAGAIN)
+                                       rc = 0;
+                               /* continue to drain the queue */
                                continue;
                        } else
-                               /* no - requeue to preserve ordering */
-                               skb_queue_head(queue, skb);
+                               goto retry;
                } else {
-                       /* it worked - drop the extra reference and continue */
+                       /* skb sent - drop the extra reference and continue */
                        consume_skb(skb);
                        failed = 0;
                }
        }
 
-out:
        return (rc >= 0 ? 0 : rc);
 }
 
@@ -1609,7 +1607,8 @@ static int __net_init audit_net_init(struct net *net)
                audit_panic("cannot initialize netlink socket in namespace");
                return -ENOMEM;
        }
-       aunet->sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+       /* limit the timeout in case auditd is blocked/stopped */
+       aunet->sk->sk_sndtimeo = HZ / 10;
 
        return 0;
 }
index f3001937bbb931bba0990ad664847a07d25abc6b..b532f1058d35f3f35bac760e29704b20f79f1252 100644 (file)
@@ -1366,22 +1366,28 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
        reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
 }
 
+static bool __reg32_bound_s64(s32 a)
+{
+       return a >= 0 && a <= S32_MAX;
+}
+
 static void __reg_assign_32_into_64(struct bpf_reg_state *reg)
 {
        reg->umin_value = reg->u32_min_value;
        reg->umax_value = reg->u32_max_value;
-       /* Attempt to pull 32-bit signed bounds into 64-bit bounds
-        * but must be positive otherwise set to worse case bounds
-        * and refine later from tnum.
+
+       /* Attempt to pull 32-bit signed bounds into 64-bit bounds but must
+        * be positive otherwise set to worse case bounds and refine later
+        * from tnum.
         */
-       if (reg->s32_min_value >= 0 && reg->s32_max_value >= 0)
-               reg->smax_value = reg->s32_max_value;
-       else
-               reg->smax_value = U32_MAX;
-       if (reg->s32_min_value >= 0)
+       if (__reg32_bound_s64(reg->s32_min_value) &&
+           __reg32_bound_s64(reg->s32_max_value)) {
                reg->smin_value = reg->s32_min_value;
-       else
+               reg->smax_value = reg->s32_max_value;
+       } else {
                reg->smin_value = 0;
+               reg->smax_value = U32_MAX;
+       }
 }
 
 static void __reg_combine_32_into_64(struct bpf_reg_state *reg)
@@ -2379,8 +2385,6 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                 */
                if (insn->src_reg != BPF_REG_FP)
                        return 0;
-               if (BPF_SIZE(insn->code) != BPF_DW)
-                       return 0;
 
                /* dreg = *(u64 *)[fp - off] was a fill from the stack.
                 * that [fp - off] slot contains scalar that needs to be
@@ -2403,8 +2407,6 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                /* scalars can only be spilled into stack */
                if (insn->dst_reg != BPF_REG_FP)
                        return 0;
-               if (BPF_SIZE(insn->code) != BPF_DW)
-                       return 0;
                spi = (-insn->off - 1) / BPF_REG_SIZE;
                if (spi >= 64) {
                        verbose(env, "BUG spi %d\n", spi);
@@ -4551,9 +4553,16 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
 
        if (insn->imm == BPF_CMPXCHG) {
                /* Check comparison of R0 with memory location */
-               err = check_reg_arg(env, BPF_REG_0, SRC_OP);
+               const u32 aux_reg = BPF_REG_0;
+
+               err = check_reg_arg(env, aux_reg, SRC_OP);
                if (err)
                        return err;
+
+               if (is_pointer_value(env, aux_reg)) {
+                       verbose(env, "R%d leaks addr into mem\n", aux_reg);
+                       return -EACCES;
+               }
        }
 
        if (is_pointer_value(env, insn->src_reg)) {
@@ -4588,13 +4597,19 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
                load_reg = -1;
        }
 
-       /* check whether we can read the memory */
+       /* Check whether we can read the memory, with second call for fetch
+        * case to simulate the register fill.
+        */
        err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
-                              BPF_SIZE(insn->code), BPF_READ, load_reg, true);
+                              BPF_SIZE(insn->code), BPF_READ, -1, true);
+       if (!err && load_reg >= 0)
+               err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
+                                      BPF_SIZE(insn->code), BPF_READ, load_reg,
+                                      true);
        if (err)
                return err;
 
-       /* check whether we can write into the same memory */
+       /* Check whether we can write into the same memory. */
        err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
                               BPF_SIZE(insn->code), BPF_WRITE, -1, true);
        if (err)
@@ -8308,6 +8323,10 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
                                                         insn->dst_reg);
                                }
                                zext_32_to_64(dst_reg);
+
+                               __update_reg_bounds(dst_reg);
+                               __reg_deduce_bounds(dst_reg);
+                               __reg_bound_offset(dst_reg);
                        }
                } else {
                        /* case: R = imm
index ba2f38246f07e5ba5a4f97922b4be33bdb8ad6d6..909db87d7383d25232e1f8ea7b7426b291a5d1c8 100644 (file)
@@ -832,7 +832,7 @@ void skb_dump(const char *level, const struct sk_buff *skb, bool full_pkt)
               ntohs(skb->protocol), skb->pkt_type, skb->skb_iif);
 
        if (dev)
-               printk("%sdev name=%s feat=0x%pNF\n",
+               printk("%sdev name=%s feat=%pNF\n",
                       level, dev->name, &dev->features);
        if (sk)
                printk("%ssk family=%hu type=%u proto=%u\n",
index c8fa6e7f7d1241691e048c868878b388e04b6f80..581b5b2d72a5bcc9c1ddf2b3664ef9ff669f63a5 100644 (file)
@@ -261,6 +261,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
        r->idiag_state = sk->sk_state;
        r->idiag_timer = 0;
        r->idiag_retrans = 0;
+       r->idiag_expires = 0;
 
        if (inet_diag_msg_attrs_fill(sk, skb, r, ext,
                                     sk_user_ns(NETLINK_CB(cb->skb).sk),
@@ -314,9 +315,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
                r->idiag_retrans = icsk->icsk_probes_out;
                r->idiag_expires =
                        jiffies_delta_to_msecs(sk->sk_timer.expires - jiffies);
-       } else {
-               r->idiag_timer = 0;
-               r->idiag_expires = 0;
        }
 
        if ((ext & (1 << (INET_DIAG_INFO - 1))) && handler->idiag_info_size) {
index 1b57ee36d6682e04085aa271c6c5c09e6e3a7b7e..8a3618a30632a8fab997edff82065a194dcaac1b 100644 (file)
@@ -1933,7 +1933,6 @@ static int __net_init sit_init_net(struct net *net)
        return 0;
 
 err_reg_dev:
-       ipip6_dev_free(sitn->fb_tunnel_dev);
        free_netdev(sitn->fb_tunnel_dev);
 err_alloc_dev:
        return err;
index 470ff0ce3dc7634a52c738a87bff3d23aae7b520..7d2925bb966e03e164298581cab09d3a6eb802d9 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
  * Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
  */
 
 /**
@@ -191,7 +191,8 @@ static void ieee80211_add_addbaext(struct ieee80211_sub_if_data *sdata,
        sband = ieee80211_get_sband(sdata);
        if (!sband)
                return;
-       he_cap = ieee80211_get_he_iftype_cap(sband, sdata->vif.type);
+       he_cap = ieee80211_get_he_iftype_cap(sband,
+                                            ieee80211_vif_type_p2p(&sdata->vif));
        if (!he_cap)
                return;
 
index 430a585875388f841001c3dfc6a14453179c7618..74a878f213d3ef352d0d934f288664ed3a1a263f 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
  * Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2020 Intel Corporation
+ * Copyright (C) 2018 - 2021 Intel Corporation
  */
 
 #include <linux/ieee80211.h>
@@ -106,7 +106,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
        mgmt->u.action.u.addba_req.start_seq_num =
                                        cpu_to_le16(start_seq_num << 4);
 
-       ieee80211_tx_skb(sdata, skb);
+       ieee80211_tx_skb_tid(sdata, skb, tid);
 }
 
 void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
@@ -213,6 +213,8 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
        struct ieee80211_txq *txq = sta->sta.txq[tid];
        struct txq_info *txqi;
 
+       lockdep_assert_held(&sta->ampdu_mlme.mtx);
+
        if (!txq)
                return;
 
@@ -290,7 +292,6 @@ static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid)
        ieee80211_assign_tid_tx(sta, tid, NULL);
 
        ieee80211_agg_splice_finish(sta->sdata, tid);
-       ieee80211_agg_start_txq(sta, tid, false);
 
        kfree_rcu(tid_tx, rcu_head);
 }
@@ -480,8 +481,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
 
        /* send AddBA request */
        ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
-                                    tid_tx->dialog_token,
-                                    sta->tid_seq[tid] >> 4,
+                                    tid_tx->dialog_token, tid_tx->ssn,
                                     buf_size, tid_tx->timeout);
 
        WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state));
@@ -523,6 +523,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 
        params.ssn = sta->tid_seq[tid] >> 4;
        ret = drv_ampdu_action(local, sdata, &params);
+       tid_tx->ssn = params.ssn;
        if (ret == IEEE80211_AMPDU_TX_START_DELAY_ADDBA) {
                return;
        } else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
@@ -889,6 +890,7 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        bool send_delba = false;
+       bool start_txq = false;
 
        ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
               sta->sta.addr, tid);
@@ -906,10 +908,14 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
                send_delba = true;
 
        ieee80211_remove_tid_tx(sta, tid);
+       start_txq = true;
 
  unlock_sta:
        spin_unlock_bh(&sta->lock);
 
+       if (start_txq)
+               ieee80211_agg_start_txq(sta, tid, false);
+
        if (send_delba)
                ieee80211_send_delba(sdata, sta->sta.addr, tid,
                        WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
index cd3731cbf6c6814dbc266b404774ae733bd05d8e..c336267f4599c430812d67ba1fb97cd5404a7481 100644 (file)
@@ -1219,8 +1219,11 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local,
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
 
-       if (local->in_reconfig)
+       /* In reconfig don't transmit now, but mark for waking later */
+       if (local->in_reconfig) {
+               set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txq->flags);
                return;
+       }
 
        if (!check_sdata_in_driver(sdata))
                return;
index 54ab0e1ef6ca5828ac56596bce0bb096f31311e6..37f7d975f3dac66bb5a8056203c7e3a58aeff57c 100644 (file)
@@ -2452,11 +2452,18 @@ static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
                                           u16 tx_time)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-       u16 tid = ieee80211_get_tid(hdr);
-       int ac = ieee80211_ac_from_tid(tid);
-       struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
+       u16 tid;
+       int ac;
+       struct ieee80211_sta_tx_tspec *tx_tspec;
        unsigned long now = jiffies;
 
+       if (!ieee80211_is_data_qos(hdr->frame_control))
+               return;
+
+       tid = ieee80211_get_tid(hdr);
+       ac = ieee80211_ac_from_tid(tid);
+       tx_tspec = &ifmgd->tx_tspec[ac];
+
        if (likely(!tx_tspec->admitted_time))
                return;
 
index 9541a4c30aca7c071d254c987839f723728312eb..0544563ede522493bba3053650932c81110dff85 100644 (file)
@@ -2944,6 +2944,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
        if (!fwd_skb)
                goto out;
 
+       fwd_skb->dev = sdata->dev;
        fwd_hdr =  (struct ieee80211_hdr *) fwd_skb->data;
        fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
        info = IEEE80211_SKB_CB(fwd_skb);
index 51b49f0d3ad48ac1a5466d58618286eaeeee7dae..537535a88990cf86877713b4cf46d086f6cc2fc0 100644 (file)
@@ -644,13 +644,13 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
        /* check if STA exists already */
        if (sta_info_get_bss(sdata, sta->sta.addr)) {
                err = -EEXIST;
-               goto out_err;
+               goto out_cleanup;
        }
 
        sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
        if (!sinfo) {
                err = -ENOMEM;
-               goto out_err;
+               goto out_cleanup;
        }
 
        local->num_sta++;
@@ -667,6 +667,15 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
 
        list_add_tail_rcu(&sta->list, &local->sta_list);
 
+       /* update channel context before notifying the driver about state
+        * change, this enables driver using the updated channel context right away.
+        */
+       if (sta->sta_state >= IEEE80211_STA_ASSOC) {
+               ieee80211_recalc_min_chandef(sta->sdata);
+               if (!sta->sta.support_p2p_ps)
+                       ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
+       }
+
        /* notify driver */
        err = sta_info_insert_drv_state(local, sdata, sta);
        if (err)
@@ -674,12 +683,6 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
 
        set_sta_flag(sta, WLAN_STA_INSERTED);
 
-       if (sta->sta_state >= IEEE80211_STA_ASSOC) {
-               ieee80211_recalc_min_chandef(sta->sdata);
-               if (!sta->sta.support_p2p_ps)
-                       ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
-       }
-
        /* accept BA sessions now */
        clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
 
@@ -706,8 +709,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
  out_drop_sta:
        local->num_sta--;
        synchronize_net();
+ out_cleanup:
        cleanup_single_sta(sta);
- out_err:
        mutex_unlock(&local->sta_mtx);
        kfree(sinfo);
        rcu_read_lock();
index ba279678200843aeb4f5ccde641271a901d37765..379fd367197f9e035504536a34ffc115b00d5b63 100644 (file)
@@ -176,6 +176,7 @@ struct sta_info;
  * @failed_bar_ssn: ssn of the last failed BAR tx attempt
  * @bar_pending: BAR needs to be re-sent
  * @amsdu: support A-MSDU withing A-MDPU
+ * @ssn: starting sequence number of the session
  *
  * This structure's lifetime is managed by RCU, assignments to
  * the array holding it must hold the aggregation mutex.
@@ -199,6 +200,7 @@ struct tid_ampdu_tx {
        u8 stop_initiator;
        bool tx_stop;
        u16 buf_size;
+       u16 ssn;
 
        u16 failed_bar_ssn;
        bool bar_pending;
index 278945e3e08acc846782411b02307c09705d839b..86a54df3aabdd2e697bcbb206815ba7cf382b180 100644 (file)
@@ -1822,15 +1822,15 @@ static int invoke_tx_handlers_late(struct ieee80211_tx_data *tx)
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        ieee80211_tx_result res = TX_CONTINUE;
 
+       if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
+               CALL_TXH(ieee80211_tx_h_rate_ctrl);
+
        if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
                __skb_queue_tail(&tx->skbs, tx->skb);
                tx->skb = NULL;
                goto txh_done;
        }
 
-       if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
-               CALL_TXH(ieee80211_tx_h_rate_ctrl);
-
        CALL_TXH(ieee80211_tx_h_michael_mic_add);
        CALL_TXH(ieee80211_tx_h_sequence);
        CALL_TXH(ieee80211_tx_h_fragment);
@@ -4191,11 +4191,11 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 
        ieee80211_aggr_check(sdata, sta, skb);
 
+       sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
+
        if (sta) {
                struct ieee80211_fast_tx *fast_tx;
 
-               sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
-
                fast_tx = rcu_dereference(sta->fast_tx);
 
                if (fast_tx &&
index 43df2f0c5db9c52b2484196946d2008b22ff3cf0..0e4e1956bcea1f874542f27862b27116d9441c77 100644 (file)
@@ -943,7 +943,12 @@ static void ieee80211_parse_extension_element(u32 *crc,
                                              struct ieee802_11_elems *elems)
 {
        const void *data = elem->data + 1;
-       u8 len = elem->datalen - 1;
+       u8 len;
+
+       if (!elem->datalen)
+               return;
+
+       len = elem->datalen - 1;
 
        switch (elem->data[0]) {
        case WLAN_EID_EXT_HE_MU_EDCA:
@@ -2063,7 +2068,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                chandef.chan = chan;
 
        skb = ieee80211_probereq_get(&local->hw, src, ssid, ssid_len,
-                                    100 + ie_len);
+                                    local->scan_ies_len + ie_len);
        if (!skb)
                return NULL;
 
@@ -2646,6 +2651,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                mutex_unlock(&local->sta_mtx);
        }
 
+       /*
+        * If this is for hw restart things are still running.
+        * We may want to change that later, however.
+        */
+       if (local->open_count && (!suspended || reconfig_due_to_wowlan))
+               drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
+
        if (local->in_reconfig) {
                local->in_reconfig = false;
                barrier();
@@ -2664,13 +2676,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                        IEEE80211_QUEUE_STOP_REASON_SUSPEND,
                                        false);
 
-       /*
-        * If this is for hw restart things are still running.
-        * We may want to change that later, however.
-        */
-       if (local->open_count && (!suspended || reconfig_due_to_wowlan))
-               drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
-
        if (!suspended)
                return 0;
 
index 7b96be1e9f14a11ddcfe41f609fdc1730e33106e..f523051f5aef3c2ccb9bdcb87c07de916ee65d1c 100644 (file)
@@ -700,6 +700,9 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 
        msk_owned_by_me(msk);
 
+       if (sk->sk_state == TCP_LISTEN)
+               return;
+
        if (!rm_list->nr)
                return;
 
index c82a76d2d0bfeb3761d7eee60e6c0936cc8d14bd..54613f5b7521719df36014e9901351cac8328d87 100644 (file)
@@ -1524,7 +1524,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
                        int ret = 0;
 
                        prev_ssk = ssk;
-                       mptcp_flush_join_list(msk);
+                       __mptcp_flush_join_list(msk);
                        ssk = mptcp_subflow_get_send(msk);
 
                        /* First check. If the ssk has changed since
@@ -2879,7 +2879,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
                 */
                if (WARN_ON_ONCE(!new_mptcp_sock)) {
                        tcp_sk(newsk)->is_mptcp = 0;
-                       return newsk;
+                       goto out;
                }
 
                /* acquire the 2nd reference for the owning socket */
@@ -2891,6 +2891,8 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
                                MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK);
        }
 
+out:
+       newsk->sk_kern_sock = kern;
        return newsk;
 }
 
index 0f1e661c2032b1977021db8684101dbc82d8f9fc..f8efd478ac97f7ef359348cd7215867995f9e0eb 100644 (file)
@@ -525,7 +525,6 @@ static bool mptcp_supported_sockopt(int level, int optname)
                case TCP_NODELAY:
                case TCP_THIN_LINEAR_TIMEOUTS:
                case TCP_CONGESTION:
-               case TCP_ULP:
                case TCP_CORK:
                case TCP_KEEPIDLE:
                case TCP_KEEPINTVL:
index 46943a18a10d5413db57955dbd24302af7ef1d97..76c2dca7f0a594b859ec791f422fe514f1470df0 100644 (file)
@@ -4492,9 +4492,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        }
 
 out_free_pg_vec:
-       bitmap_free(rx_owner_map);
-       if (pg_vec)
+       if (pg_vec) {
+               bitmap_free(rx_owner_map);
                free_pg_vec(pg_vec, order, req->tp_block_nr);
+       }
 out:
        return err;
 }
index a1525916885ae9741972e32b16363319edc1aa31..b4f90afb0638b7e6b2f7668cfe2498f35625f79c 100644 (file)
@@ -868,6 +868,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp,
 
        err = pep_accept_conn(newsk, skb);
        if (err) {
+               __sock_put(sk);
                sock_put(newsk);
                newsk = NULL;
                goto drop;
index a3bc4b54d4910567c915f41cd6bc44f279eaadf3..b4cc699c5fad37736a31619db2b0ac41babd164e 100644 (file)
@@ -253,6 +253,7 @@ static struct rds_connection *__rds_conn_create(struct net *net,
                                 * should end up here, but if it
                                 * does, reset/destroy the connection.
                                 */
+                               kfree(conn->c_path);
                                kmem_cache_free(rds_conn_slab, conn);
                                conn = ERR_PTR(-EOPNOTSUPP);
                                goto out;
index 2ef8f5a6205a9d92c2195444cb0469702be93da5..e54f0a42270c1ba9f47bdb3968c11b5c777c8bb1 100644 (file)
@@ -3687,6 +3687,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
                                entry->mpls_mangle.ttl = tcf_mpls_ttl(act);
                                break;
                        default:
+                               err = -EOPNOTSUPP;
                                goto err_out_locked;
                        }
                } else if (is_tcf_skbedit_ptype(act)) {
index 3c2300d144681869a37ada0d20966f9b5b145653..857aaebd49f4315502928fb1f75d2c85eb63eb51 100644 (file)
@@ -2736,7 +2736,7 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt,
        q->tins = kvcalloc(CAKE_MAX_TINS, sizeof(struct cake_tin_data),
                           GFP_KERNEL);
        if (!q->tins)
-               goto nomem;
+               return -ENOMEM;
 
        for (i = 0; i < CAKE_MAX_TINS; i++) {
                struct cake_tin_data *b = q->tins + i;
@@ -2766,10 +2766,6 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt,
        q->min_netlen = ~0;
        q->min_adjlen = ~0;
        return 0;
-
-nomem:
-       cake_destroy(sch);
-       return -ENOMEM;
 }
 
 static int cake_dump(struct Qdisc *sch, struct sk_buff *skb)
index e007fc75ef2feffdda6435031d548ff38fb1a790..d73393493553389ac77fa7d16c500ad6c7f49404 100644 (file)
@@ -666,9 +666,9 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
                }
        }
        for (i = q->nbands; i < oldbands; i++) {
-               qdisc_tree_flush_backlog(q->classes[i].qdisc);
-               if (i >= q->nstrict)
+               if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
                        list_del(&q->classes[i].alist);
+               qdisc_tree_flush_backlog(q->classes[i].qdisc);
        }
        q->nstrict = nstrict;
        memcpy(q->prio2band, priomap, sizeof(priomap));
index 230072f9ec48e3bf3cd43f9aa7fafa4a096ac402..1c9289f56dc471d33b08f6138bee3bea8aabe26f 100644 (file)
@@ -194,7 +194,9 @@ static int smc_release(struct socket *sock)
        /* cleanup for a dangling non-blocking connect */
        if (smc->connect_nonblock && sk->sk_state == SMC_INIT)
                tcp_abort(smc->clcsock->sk, ECONNABORTED);
-       flush_work(&smc->connect_work);
+
+       if (cancel_work_sync(&smc->connect_work))
+               sock_put(&smc->sk); /* sock_hold in smc_connect for passive closing */
 
        if (sk->sk_state == SMC_LISTEN)
                /* smc_close_non_accepted() is called and acquires
index 59ee1be5a6dd3631155d4fe47b5f9fca7d0fa716..ec2c2afbf0d060b4f6335a7616c8deba0a95fde6 100644 (file)
@@ -1299,7 +1299,8 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
        space_available = virtio_transport_space_update(sk, pkt);
 
        /* Update CID in case it has changed after a transport reset event */
-       vsk->local_addr.svm_cid = dst.svm_cid;
+       if (vsk->local_addr.svm_cid != VMADDR_CID_ANY)
+               vsk->local_addr.svm_cid = dst.svm_cid;
 
        if (space_available)
                sk->sk_write_space(sk);
index df87c7f3a04921d43ae0f536444101bc4ddfdab6..f8f01a3e020ba9371af6c304d52e385487ce3ff9 100644 (file)
@@ -133,6 +133,7 @@ static u32 reg_is_indoor_portid;
 
 static void restore_regulatory_settings(bool reset_user, bool cached);
 static void print_regdomain(const struct ieee80211_regdomain *rd);
+static void reg_process_hint(struct regulatory_request *reg_request);
 
 static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
 {
@@ -1098,6 +1099,8 @@ int reg_reload_regdb(void)
        const struct firmware *fw;
        void *db;
        int err;
+       const struct ieee80211_regdomain *current_regdomain;
+       struct regulatory_request *request;
 
        err = request_firmware(&fw, "regulatory.db", &reg_pdev->dev);
        if (err)
@@ -1118,8 +1121,26 @@ int reg_reload_regdb(void)
        if (!IS_ERR_OR_NULL(regdb))
                kfree(regdb);
        regdb = db;
-       rtnl_unlock();
 
+       /* reset regulatory domain */
+       current_regdomain = get_cfg80211_regdom();
+
+       request = kzalloc(sizeof(*request), GFP_KERNEL);
+       if (!request) {
+               err = -ENOMEM;
+               goto out_unlock;
+       }
+
+       request->wiphy_idx = WIPHY_IDX_INVALID;
+       request->alpha2[0] = current_regdomain->alpha2[0];
+       request->alpha2[1] = current_regdomain->alpha2[1];
+       request->initiator = NL80211_REGDOM_SET_BY_CORE;
+       request->user_reg_hint_type = NL80211_USER_REG_HINT_USER;
+
+       reg_process_hint(request);
+
+out_unlock:
+       rtnl_unlock();
  out:
        release_firmware(fw);
        return err;
@@ -2338,6 +2359,7 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
        struct cfg80211_chan_def chandef = {};
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
        enum nl80211_iftype iftype;
+       bool ret;
 
        wdev_lock(wdev);
        iftype = wdev->iftype;
@@ -2387,7 +2409,11 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_P2P_GO:
        case NL80211_IFTYPE_ADHOC:
-               return cfg80211_reg_can_beacon_relax(wiphy, &chandef, iftype);
+               wiphy_lock(wiphy);
+               ret = cfg80211_reg_can_beacon_relax(wiphy, &chandef, iftype);
+               wiphy_unlock(wiphy);
+
+               return ret;
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_P2P_CLIENT:
                return cfg80211_chandef_usable(wiphy, &chandef,
index f16074eb53c72a7040421d23028d5762e0c5658d..7a466ea962c57f013454bde2892dfa38db7dd86b 100644 (file)
@@ -677,8 +677,6 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock,
        struct xdp_sock *xs = xdp_sk(sk);
        struct xsk_buff_pool *pool;
 
-       sock_poll_wait(file, sock, wait);
-
        if (unlikely(!xsk_is_bound(xs)))
                return mask;
 
@@ -690,6 +688,8 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock,
                else
                        /* Poll needs to drive Tx also in copy mode */
                        __xsk_sendmsg(sk);
+       } else {
+               sock_poll_wait(file, sock, wait);
        }
 
        if (xs->rx && !xskq_prod_is_empty(xs->rx))
index 7d631aaa0ae118bc41e9649d811beaf4ee4fe6ec..52a000b057a575995f5a0dab27d70c1e1e0d463f 100755 (executable)
@@ -219,7 +219,7 @@ if ($arch eq "x86_64") {
 
 } elsif ($arch eq "s390" && $bits == 64) {
     if ($cc =~ /-DCC_USING_HOTPATCH/) {
-       $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$";
+       $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*(bcrl\\s*0,|jgnop\\s*)[0-9a-f]+ <([^\+]*)>\$";
        $mcount_adjust = 0;
     }
     $alignment = 8;
index 62d30c0a30c291753bdf1df23d7909394b204286..1afc06ffd969fc9479cea666d7741b6eb37b5a70 100644 (file)
@@ -611,10 +611,11 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
        return 0;
 }
 
-static int parse_sid(struct super_block *sb, const char *s, u32 *sid)
+static int parse_sid(struct super_block *sb, const char *s, u32 *sid,
+                    gfp_t gfp)
 {
        int rc = security_context_str_to_sid(&selinux_state, s,
-                                            sid, GFP_KERNEL);
+                                            sid, gfp);
        if (rc)
                pr_warn("SELinux: security_context_str_to_sid"
                       "(%s) failed for (dev %s, type %s) errno=%d\n",
@@ -685,7 +686,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
         */
        if (opts) {
                if (opts->fscontext) {
-                       rc = parse_sid(sb, opts->fscontext, &fscontext_sid);
+                       rc = parse_sid(sb, opts->fscontext, &fscontext_sid,
+                                       GFP_KERNEL);
                        if (rc)
                                goto out;
                        if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
@@ -694,7 +696,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                        sbsec->flags |= FSCONTEXT_MNT;
                }
                if (opts->context) {
-                       rc = parse_sid(sb, opts->context, &context_sid);
+                       rc = parse_sid(sb, opts->context, &context_sid,
+                                       GFP_KERNEL);
                        if (rc)
                                goto out;
                        if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
@@ -703,7 +706,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                        sbsec->flags |= CONTEXT_MNT;
                }
                if (opts->rootcontext) {
-                       rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid);
+                       rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid,
+                                       GFP_KERNEL);
                        if (rc)
                                goto out;
                        if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
@@ -712,7 +716,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                        sbsec->flags |= ROOTCONTEXT_MNT;
                }
                if (opts->defcontext) {
-                       rc = parse_sid(sb, opts->defcontext, &defcontext_sid);
+                       rc = parse_sid(sb, opts->defcontext, &defcontext_sid,
+                                       GFP_KERNEL);
                        if (rc)
                                goto out;
                        if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
@@ -2702,14 +2707,14 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
                return (sbsec->flags & SE_MNTMASK) ? 1 : 0;
 
        if (opts->fscontext) {
-               rc = parse_sid(sb, opts->fscontext, &sid);
+               rc = parse_sid(sb, opts->fscontext, &sid, GFP_NOWAIT);
                if (rc)
                        return 1;
                if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
                        return 1;
        }
        if (opts->context) {
-               rc = parse_sid(sb, opts->context, &sid);
+               rc = parse_sid(sb, opts->context, &sid, GFP_NOWAIT);
                if (rc)
                        return 1;
                if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
@@ -2719,14 +2724,14 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
                struct inode_security_struct *root_isec;
 
                root_isec = backing_inode_security(sb->s_root);
-               rc = parse_sid(sb, opts->rootcontext, &sid);
+               rc = parse_sid(sb, opts->rootcontext, &sid, GFP_NOWAIT);
                if (rc)
                        return 1;
                if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
                        return 1;
        }
        if (opts->defcontext) {
-               rc = parse_sid(sb, opts->defcontext, &sid);
+               rc = parse_sid(sb, opts->defcontext, &sid, GFP_NOWAIT);
                if (rc)
                        return 1;
                if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
@@ -2749,14 +2754,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
                return 0;
 
        if (opts->fscontext) {
-               rc = parse_sid(sb, opts->fscontext, &sid);
+               rc = parse_sid(sb, opts->fscontext, &sid, GFP_KERNEL);
                if (rc)
                        return rc;
                if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
                        goto out_bad_option;
        }
        if (opts->context) {
-               rc = parse_sid(sb, opts->context, &sid);
+               rc = parse_sid(sb, opts->context, &sid, GFP_KERNEL);
                if (rc)
                        return rc;
                if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
@@ -2765,14 +2770,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
        if (opts->rootcontext) {
                struct inode_security_struct *root_isec;
                root_isec = backing_inode_security(sb->s_root);
-               rc = parse_sid(sb, opts->rootcontext, &sid);
+               rc = parse_sid(sb, opts->rootcontext, &sid, GFP_KERNEL);
                if (rc)
                        return rc;
                if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
                        goto out_bad_option;
        }
        if (opts->defcontext) {
-               rc = parse_sid(sb, opts->defcontext, &sid);
+               rc = parse_sid(sb, opts->defcontext, &sid, GFP_KERNEL);
                if (rc)
                        return rc;
                if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
index b9d6306cc14ea0079e24876596dc8a4420e3230e..409b721666cba393adfd398969783d51f834f2f4 100644 (file)
@@ -755,12 +755,16 @@ static int parse_vm_time_correlation(const struct option *opt, const char *str,
        return inject->itrace_synth_opts.vm_tm_corr_args ? 0 : -ENOMEM;
 }
 
+static int output_fd(struct perf_inject *inject)
+{
+       return inject->in_place_update ? -1 : perf_data__fd(&inject->output);
+}
+
 static int __cmd_inject(struct perf_inject *inject)
 {
        int ret = -EINVAL;
        struct perf_session *session = inject->session;
-       struct perf_data *data_out = &inject->output;
-       int fd = inject->in_place_update ? -1 : perf_data__fd(data_out);
+       int fd = output_fd(inject);
        u64 output_data_offset;
 
        signal(SIGINT, sig_handler);
@@ -1015,7 +1019,7 @@ int cmd_inject(int argc, const char **argv)
        }
 
        inject.session = __perf_session__new(&data, repipe,
-                                            perf_data__fd(&inject.output),
+                                            output_fd(&inject),
                                             &inject.tool);
        if (IS_ERR(inject.session)) {
                ret = PTR_ERR(inject.session);
@@ -1078,7 +1082,8 @@ out_delete:
        zstd_fini(&(inject.session->zstd_data));
        perf_session__delete(inject.session);
 out_close_output:
-       perf_data__close(&inject.output);
+       if (!inject.in_place_update)
+               perf_data__close(&inject.output);
        free(inject.itrace_synth_opts.vm_tm_corr_args);
        return ret;
 }
index 1d532b9fed29c2cf1349f5e730dfd5e77535a694..254601060b392c421a5e43f47c5403c99d074b6b 100644 (file)
@@ -12,6 +12,7 @@
 #include "expr-bison.h"
 #include "expr-flex.h"
 #include "smt.h"
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/zalloc.h>
 #include <ctype.h>
@@ -299,6 +300,10 @@ struct expr_parse_ctx *expr__ctx_new(void)
                return NULL;
 
        ctx->ids = hashmap__new(key_hash, key_equal, NULL);
+       if (IS_ERR(ctx->ids)) {
+               free(ctx);
+               return NULL;
+       }
        ctx->runtime = 0;
 
        return ctx;
index 5d52ea2768df4480a496ad87457fe8b862d57457..df3b292a8ffec06b0d902b6eb815f40742a35aad 100644 (file)
@@ -33,6 +33,22 @@ noinline int bpf_testmod_loop_test(int n)
        return sum;
 }
 
+__weak noinline struct file *bpf_testmod_return_ptr(int arg)
+{
+       static struct file f = {};
+
+       switch (arg) {
+       case 1: return (void *)EINVAL;          /* user addr */
+       case 2: return (void *)0xcafe4a11;      /* user addr */
+       case 3: return (void *)-EINVAL;         /* canonical, but invalid */
+       case 4: return (void *)(1ull << 60);    /* non-canonical and invalid */
+       case 5: return (void *)~(1ull << 30);   /* trigger extable */
+       case 6: return &f;                      /* valid addr */
+       case 7: return (void *)((long)&f | 1);  /* kernel tricks */
+       default: return NULL;
+       }
+}
+
 noinline ssize_t
 bpf_testmod_test_read(struct file *file, struct kobject *kobj,
                      struct bin_attribute *bin_attr,
@@ -43,6 +59,10 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
                .off = off,
                .len = len,
        };
+       int i = 1;
+
+       while (bpf_testmod_return_ptr(i))
+               i++;
 
        /* This is always true. Use the check to make sure the compiler
         * doesn't remove bpf_testmod_loop_test.
index 762f6a9da8b5e9bdf89d888fe561c1e8b2622555..664ffc0364f4f0e3a4dea2ee7a46ba5eb61cd3d2 100644 (file)
@@ -90,7 +90,7 @@ static void print_err_line(void)
 
 static void test_conn(void)
 {
-       int listen_fd = -1, cli_fd = -1, err;
+       int listen_fd = -1, cli_fd = -1, srv_fd = -1, err;
        socklen_t addrlen = sizeof(srv_sa6);
        int srv_port;
 
@@ -112,6 +112,10 @@ static void test_conn(void)
        if (CHECK_FAIL(cli_fd == -1))
                goto done;
 
+       srv_fd = accept(listen_fd, NULL, NULL);
+       if (CHECK_FAIL(srv_fd == -1))
+               goto done;
+
        if (CHECK(skel->bss->listen_tp_sport != srv_port ||
                  skel->bss->req_sk_sport != srv_port,
                  "Unexpected sk src port",
@@ -134,11 +138,13 @@ done:
                close(listen_fd);
        if (cli_fd != -1)
                close(cli_fd);
+       if (srv_fd != -1)
+               close(srv_fd);
 }
 
 static void test_syncookie(void)
 {
-       int listen_fd = -1, cli_fd = -1, err;
+       int listen_fd = -1, cli_fd = -1, srv_fd = -1, err;
        socklen_t addrlen = sizeof(srv_sa6);
        int srv_port;
 
@@ -161,6 +167,10 @@ static void test_syncookie(void)
        if (CHECK_FAIL(cli_fd == -1))
                goto done;
 
+       srv_fd = accept(listen_fd, NULL, NULL);
+       if (CHECK_FAIL(srv_fd == -1))
+               goto done;
+
        if (CHECK(skel->bss->listen_tp_sport != srv_port,
                  "Unexpected tp src port",
                  "listen_tp_sport:%u expected:%u\n",
@@ -188,6 +198,8 @@ done:
                close(listen_fd);
        if (cli_fd != -1)
                close(cli_fd);
+       if (srv_fd != -1)
+               close(srv_fd);
 }
 
 struct test {
index b36857093f71fea44eb42b068e0aff1e5d5b70b1..50ce16d02da7b1a9a4bdfe1ec0f0276e8603e1e3 100644 (file)
@@ -87,6 +87,18 @@ int BPF_PROG(handle_fexit,
        return 0;
 }
 
+SEC("fexit/bpf_testmod_return_ptr")
+int BPF_PROG(handle_fexit_ret, int arg, struct file *ret)
+{
+       long buf = 0;
+
+       bpf_probe_read_kernel(&buf, 8, ret);
+       bpf_probe_read_kernel(&buf, 8, (char *)ret + 256);
+       *(volatile long long *)ret;
+       *(volatile int *)&ret->f_mode;
+       return 0;
+}
+
 __u32 fmod_ret_read_sz = 0;
 
 SEC("fmod_ret/bpf_testmod_test_read")
index 465ef3f112c0c96446e48dbbfc3f73eac170bbeb..d3bf83d5c6cff2dafc48e6edfec57601c1efc689 100644 (file)
@@ -54,7 +54,7 @@
 #define MAX_INSNS      BPF_MAXINSNS
 #define MAX_TEST_INSNS 1000000
 #define MAX_FIXUPS     8
-#define MAX_NR_MAPS    21
+#define MAX_NR_MAPS    22
 #define MAX_TEST_RUNS  8
 #define POINTER_VALUE  0xcafe4all
 #define TEST_DATA_LEN  64
index c22dc83a41fdc43350285d1db6eb729fe67a7bfd..b39665f33524faba5927f8be8b59bc1211736662 100644 (file)
                BPF_EXIT_INSN(),
        },
        .result = ACCEPT,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "R0 leaks addr into mem",
 },
 {
        "Dest pointer in r0 - succeed",
                BPF_EXIT_INSN(),
        },
        .result = ACCEPT,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "R0 leaks addr into mem",
+},
+{
+       "Dest pointer in r0 - succeed, check 2",
+       .insns = {
+               /* r0 = &val */
+               BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
+               /* val = r0; */
+               BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+               /* r5 = &val */
+               BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
+               /* r0 = atomic_cmpxchg(&val, r0, r5); */
+               BPF_ATOMIC_OP(BPF_DW, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
+               /* r1 = *r0 */
+               BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
+               /* exit(0); */
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "R0 leaks addr into mem",
+},
+{
+       "Dest pointer in r0 - succeed, check 3",
+       .insns = {
+               /* r0 = &val */
+               BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
+               /* val = r0; */
+               BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+               /* r5 = &val */
+               BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
+               /* r0 = atomic_cmpxchg(&val, r0, r5); */
+               BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
+               /* exit(0); */
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = REJECT,
+       .errstr = "invalid size of register fill",
+       .errstr_unpriv = "R0 leaks addr into mem",
+},
+{
+       "Dest pointer in r0 - succeed, check 4",
+       .insns = {
+               /* r0 = &val */
+               BPF_MOV32_REG(BPF_REG_0, BPF_REG_10),
+               /* val = r0; */
+               BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
+               /* r5 = &val */
+               BPF_MOV32_REG(BPF_REG_5, BPF_REG_10),
+               /* r0 = atomic_cmpxchg(&val, r0, r5); */
+               BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
+               /* r1 = *r10 */
+               BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, -8),
+               /* exit(0); */
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = ACCEPT,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "R10 partial copy of pointer",
+},
+{
+       "Dest pointer in r0 - succeed, check 5",
+       .insns = {
+               /* r0 = &val */
+               BPF_MOV32_REG(BPF_REG_0, BPF_REG_10),
+               /* val = r0; */
+               BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
+               /* r5 = &val */
+               BPF_MOV32_REG(BPF_REG_5, BPF_REG_10),
+               /* r0 = atomic_cmpxchg(&val, r0, r5); */
+               BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
+               /* r1 = *r0 */
+               BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -8),
+               /* exit(0); */
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = REJECT,
+       .errstr = "R0 invalid mem access",
+       .errstr_unpriv = "R10 partial copy of pointer",
 },
index 3bc9ff7a860b7fa4c85ab8b79fe9b0bb19e84e88..5bf03fb4fa2b6ad6fb450f6993baeb243f853cf0 100644 (file)
@@ -1,3 +1,97 @@
+{
+       "atomic dw/fetch and address leakage of (map ptr & -1) via stack slot",
+       .insns = {
+               BPF_LD_IMM64(BPF_REG_1, -1),
+               BPF_LD_MAP_FD(BPF_REG_8, 0),
+               BPF_LD_MAP_FD(BPF_REG_9, 0),
+               BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+               BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
+               BPF_ATOMIC_OP(BPF_DW, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
+               BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_2, 0),
+               BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+               BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
+               BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_array_48b = { 2, 4 },
+       .result = ACCEPT,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "leaking pointer from stack off -8",
+},
+{
+       "atomic dw/fetch and address leakage of (map ptr & -1) via returned value",
+       .insns = {
+               BPF_LD_IMM64(BPF_REG_1, -1),
+               BPF_LD_MAP_FD(BPF_REG_8, 0),
+               BPF_LD_MAP_FD(BPF_REG_9, 0),
+               BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+               BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
+               BPF_ATOMIC_OP(BPF_DW, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
+               BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
+               BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+               BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
+               BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_array_48b = { 2, 4 },
+       .result = ACCEPT,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "leaking pointer from stack off -8",
+},
+{
+       "atomic w/fetch and address leakage of (map ptr & -1) via stack slot",
+       .insns = {
+               BPF_LD_IMM64(BPF_REG_1, -1),
+               BPF_LD_MAP_FD(BPF_REG_8, 0),
+               BPF_LD_MAP_FD(BPF_REG_9, 0),
+               BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+               BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
+               BPF_ATOMIC_OP(BPF_W, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
+               BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_2, 0),
+               BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+               BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
+               BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_array_48b = { 2, 4 },
+       .result = REJECT,
+       .errstr = "invalid size of register fill",
+},
+{
+       "atomic w/fetch and address leakage of (map ptr & -1) via returned value",
+       .insns = {
+               BPF_LD_IMM64(BPF_REG_1, -1),
+               BPF_LD_MAP_FD(BPF_REG_8, 0),
+               BPF_LD_MAP_FD(BPF_REG_9, 0),
+               BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+               BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
+               BPF_ATOMIC_OP(BPF_W, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
+               BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
+               BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+               BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
+               BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_array_48b = { 2, 4 },
+       .result = REJECT,
+       .errstr = "invalid size of register fill",
+},
 #define __ATOMIC_FETCH_OP_TEST(src_reg, dst_reg, operand1, op, operand2, expect) \
        {                                                               \
                "atomic fetch " #op ", src=" #dst_reg " dst=" #dst_reg, \
index 7e50cb80873a5b7c08f607fe27006bda2afc6bf5..682519769fe3c0019e53b151e27c3c4c8d37d5e7 100644 (file)
        .result = REJECT,
        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
 },
+{
+       "precision tracking for u32 spill/fill",
+       .insns = {
+               BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
+               BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+               BPF_MOV32_IMM(BPF_REG_6, 32),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_MOV32_IMM(BPF_REG_6, 4),
+               /* Additional insns to introduce a pruning point. */
+               BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_MOV64_IMM(BPF_REG_3, 0),
+               /* u32 spill/fill */
+               BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -8),
+               BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_10, -8),
+               /* out-of-bound map value access for r6=32 */
+               BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
+               BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
+               BPF_LD_MAP_FD(BPF_REG_1, 0),
+               BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
+               BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
+               BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .fixup_map_hash_8b = { 15 },
+       .result = REJECT,
+       .errstr = "R0 min value is outside of the allowed memory range",
+       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+},
+{
+       "precision tracking for u32 spills, u64 fill",
+       .insns = {
+               BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+               BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
+               BPF_MOV32_IMM(BPF_REG_7, 0xffffffff),
+               /* Additional insns to introduce a pruning point. */
+               BPF_MOV64_IMM(BPF_REG_3, 1),
+               BPF_MOV64_IMM(BPF_REG_3, 1),
+               BPF_MOV64_IMM(BPF_REG_3, 1),
+               BPF_MOV64_IMM(BPF_REG_3, 1),
+               BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+               BPF_MOV64_IMM(BPF_REG_3, 1),
+               BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
+               /* u32 spills, u64 fill */
+               BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
+               BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
+               BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, -8),
+               /* if r8 != X goto pc+1  r8 known in fallthrough branch */
+               BPF_JMP_IMM(BPF_JNE, BPF_REG_8, 0xffffffff, 1),
+               BPF_MOV64_IMM(BPF_REG_3, 1),
+               /* if r8 == X goto pc+1  condition always true on first
+                * traversal, so starts backtracking to mark r8 as requiring
+                * precision. r7 marked as needing precision. r6 not marked
+                * since it's not tracked.
+                */
+               BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 0xffffffff, 1),
+               /* fails if r8 correctly marked unknown after fill. */
+               BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .result = REJECT,
+       .errstr = "div by zero",
+       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+},
 {
        "allocated_stack",
        .insns = {
index 7ab3de1087614663dcb6f3cd0f775f9762ba1681..6c907144311f81c4ab39a95e61941cce13ba418f 100644 (file)
        .errstr = "invalid access to packet",
        .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 },
+{
+       "Spill u32 const scalars.  Refill as u64.  Offset to skb->data",
+       .insns = {
+       BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
+                   offsetof(struct __sk_buff, data)),
+       BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
+                   offsetof(struct __sk_buff, data_end)),
+       /* r6 = 0 */
+       BPF_MOV32_IMM(BPF_REG_6, 0),
+       /* r7 = 20 */
+       BPF_MOV32_IMM(BPF_REG_7, 20),
+       /* *(u32 *)(r10 -4) = r6 */
+       BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
+       /* *(u32 *)(r10 -8) = r7 */
+       BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
+       /* r4 = *(u64 *)(r10 -8) */
+       BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -8),
+       /* r0 = r2 */
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
+       /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv,umax=65535 */
+       BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
+       /* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv,umax=65535 */
+       BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
+       /* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv20 */
+       BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .result = REJECT,
+       .errstr = "invalid access to packet",
+       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+},
 {
        "Spill a u32 const scalar.  Refill as u16 from fp-6.  Offset to skb->data",
        .insns = {
index 2debba4e8a3a8ef060dccbd62cb8ee598606adb3..4d347bc53aa28e2c439ce225402731d5d08e512c 100644 (file)
        .errstr = "R0 invalid mem access 'inv'",
        .errstr_unpriv = "R0 pointer -= pointer prohibited",
 },
+{
+       "map access: trying to leak tained dst reg",
+       .insns = {
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
+       BPF_MOV32_IMM(BPF_REG_1, 0xFFFFFFFF),
+       BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
+       BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_1),
+       BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_array_48b = { 4 },
+       .result = REJECT,
+       .errstr = "math between map_value pointer and 4294967295 is not allowed",
+},
 {
        "32bit pkt_ptr -= scalar",
        .insns = {
index b513f64d9092d1a35e7f33aba79580f7bbdcfb4f..026a126f584d76f01adef295a1449516fcbf6efb 100755 (executable)
@@ -72,6 +72,35 @@ rif_mac_profile_replacement_test()
        ip link set $h1.10 address $h1_10_mac
 }
 
+rif_mac_profile_consolidation_test()
+{
+       local count=$1; shift
+       local h1_20_mac
+
+       RET=0
+
+       if [[ $count -eq 1 ]]; then
+               return
+       fi
+
+       h1_20_mac=$(mac_get $h1.20)
+
+       # Set the MAC of $h1.20 to that of $h1.10 and confirm that they are
+       # using the same MAC profile.
+       ip link set $h1.20 address 00:11:11:11:11:11
+       check_err $?
+
+       occ=$(devlink -j resource show $DEVLINK_DEV \
+             | jq '.[][][] | select(.name=="rif_mac_profiles") |.["occ"]')
+
+       [[ $occ -eq $((count - 1)) ]]
+       check_err $? "MAC profile occupancy did not decrease"
+
+       log_test "RIF MAC profile consolidation"
+
+       ip link set $h1.20 address $h1_20_mac
+}
+
 rif_mac_profile_shared_replacement_test()
 {
        local count=$1; shift
@@ -104,6 +133,7 @@ rif_mac_profile_edit_test()
        create_max_rif_mac_profiles $count
 
        rif_mac_profile_replacement_test
+       rif_mac_profile_consolidation_test $count
        rif_mac_profile_shared_replacement_test $count
 }
 
index a1da013d847b9a2fb86b450ab4be29edcd9aea16..ad2982b72e02b9d580a97958188d1d3507a1bb05 100755 (executable)
@@ -455,6 +455,22 @@ cleanup()
        ip netns del ${NSC} >/dev/null 2>&1
 }
 
+cleanup_vrf_dup()
+{
+       ip link del ${NSA_DEV2} >/dev/null 2>&1
+       ip netns pids ${NSC} | xargs kill 2>/dev/null
+       ip netns del ${NSC} >/dev/null 2>&1
+}
+
+setup_vrf_dup()
+{
+       # some VRF tests use ns-C which has the same config as
+       # ns-B but for a device NOT in the VRF
+       create_ns ${NSC} "-" "-"
+       connect_ns ${NSA} ${NSA_DEV2} ${NSA_IP}/24 ${NSA_IP6}/64 \
+                  ${NSC} ${NSC_DEV} ${NSB_IP}/24 ${NSB_IP6}/64
+}
+
 setup()
 {
        local with_vrf=${1}
@@ -484,12 +500,6 @@ setup()
 
                ip -netns ${NSB} ro add ${VRF_IP}/32 via ${NSA_IP} dev ${NSB_DEV}
                ip -netns ${NSB} -6 ro add ${VRF_IP6}/128 via ${NSA_IP6} dev ${NSB_DEV}
-
-               # some VRF tests use ns-C which has the same config as
-               # ns-B but for a device NOT in the VRF
-               create_ns ${NSC} "-" "-"
-               connect_ns ${NSA} ${NSA_DEV2} ${NSA_IP}/24 ${NSA_IP6}/64 \
-                          ${NSC} ${NSC_DEV} ${NSB_IP}/24 ${NSB_IP6}/64
        else
                ip -netns ${NSA} ro add ${NSB_LO_IP}/32 via ${NSB_IP} dev ${NSA_DEV}
                ip -netns ${NSA} ro add ${NSB_LO_IP6}/128 via ${NSB_IP6} dev ${NSA_DEV}
@@ -1240,7 +1250,9 @@ ipv4_tcp_vrf()
        log_test_addr ${a} $? 1 "Global server, local connection"
 
        # run MD5 tests
+       setup_vrf_dup
        ipv4_tcp_md5
+       cleanup_vrf_dup
 
        #
        # enable VRF global server
@@ -1798,8 +1810,9 @@ ipv4_addr_bind_vrf()
        for a in ${NSA_IP} ${VRF_IP}
        do
                log_start
+               show_hint "Socket not bound to VRF, but address is in VRF"
                run_cmd nettest -s -R -P icmp -l ${a} -b
-               log_test_addr ${a} $? 0 "Raw socket bind to local address"
+               log_test_addr ${a} $? 1 "Raw socket bind to local address"
 
                log_start
                run_cmd nettest -s -R -P icmp -l ${a} -I ${NSA_DEV} -b
@@ -2191,7 +2204,7 @@ ipv6_ping_vrf()
                log_start
                show_hint "Fails since VRF device does not support linklocal or multicast"
                run_cmd ${ping6} -c1 -w1 ${a}
-               log_test_addr ${a} $? 2 "ping out, VRF bind"
+               log_test_addr ${a} $? 1 "ping out, VRF bind"
        done
 
        for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
@@ -2719,7 +2732,9 @@ ipv6_tcp_vrf()
        log_test_addr ${a} $? 1 "Global server, local connection"
 
        # run MD5 tests
+       setup_vrf_dup
        ipv6_tcp_md5
+       cleanup_vrf_dup
 
        #
        # enable VRF global server
@@ -3414,11 +3429,14 @@ ipv6_addr_bind_novrf()
        run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
        log_test_addr ${a} $? 0 "TCP socket bind to local address after device bind"
 
+       # Sadly, the kernel allows binding a socket to a device and then
+       # binding to an address not on the device. So this test passes
+       # when it really should not
        a=${NSA_LO_IP6}
        log_start
-       show_hint "Should fail with 'Cannot assign requested address'"
+       show_hint "Tecnically should fail since address is not on device but kernel allows"
        run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
-       log_test_addr ${a} $? 1 "TCP socket bind to out of scope local address"
+       log_test_addr ${a} $? 0 "TCP socket bind to out of scope local address"
 }
 
 ipv6_addr_bind_vrf()
@@ -3459,10 +3477,15 @@ ipv6_addr_bind_vrf()
        run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
        log_test_addr ${a} $? 0 "TCP socket bind to local address with device bind"
 
+       # Sadly, the kernel allows binding a socket to a device and then
+       # binding to an address not on the device. The only restriction
+       # is that the address is valid in the L3 domain. So this test
+       # passes when it really should not
        a=${VRF_IP6}
        log_start
+       show_hint "Tecnically should fail since address is not on device but kernel allows"
        run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
-       log_test_addr ${a} $? 1 "TCP socket bind to VRF address with device bind"
+       log_test_addr ${a} $? 0 "TCP socket bind to VRF address with device bind"
 
        a=${NSA_LO_IP6}
        log_start
index bf17e485684f0d3b3f1cba27f3d1d250ce15ee24..b0980a2efa3172562361548f80ea4f615b1a3363 100644 (file)
@@ -13,6 +13,8 @@ NETIFS[p5]=veth4
 NETIFS[p6]=veth5
 NETIFS[p7]=veth6
 NETIFS[p8]=veth7
+NETIFS[p9]=veth8
+NETIFS[p10]=veth9
 
 # Port that does not have a cable connected.
 NETIF_NO_CABLE=eth8
index ecbf57f264ed937344deef8abf1707e8ac222c5b..7b9d6e31b8e7d7d4afccdebdf6492f46fa611674 100755 (executable)
@@ -311,7 +311,7 @@ check_exception()
                ip -netns h1 ro get ${H1_VRF_ARG} ${H2_N2_IP} | \
                grep -E -v 'mtu|redirected' | grep -q "cache"
        fi
-       log_test $? 0 "IPv4: ${desc}"
+       log_test $? 0 "IPv4: ${desc}" 0
 
        # No PMTU info for test "redirect" and "mtu exception plus redirect"
        if [ "$with_redirect" = "yes" ] && [ "$desc" != "redirect exception plus mtu" ]; then
index 710ac956bdb33fae80b1cda79c9dc57370dbcc82..c5489341cfb80487375e2b2ceeb21c9fd0aa035e 100644 (file)
@@ -498,7 +498,7 @@ static void parse_opts(int argc, char **argv)
        bool have_toeplitz = false;
        int index, c;
 
-       while ((c = getopt_long(argc, argv, "46C:d:i:k:r:stT:u:v", long_options, &index)) != -1) {
+       while ((c = getopt_long(argc, argv, "46C:d:i:k:r:stT:uv", long_options, &index)) != -1) {
                switch (c) {
                case '4':
                        cfg_family = AF_INET;