commit: 387de4a9273f6e5a4bc69bbc9bcf5d4f4bdce3ea Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Fri Aug 9 17:47:28 2019 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Fri Aug 9 17:47:28 2019 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=387de4a9
Linux patch 5.2.8 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1007_linux-5.2.8.patch | 2838 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2842 insertions(+) diff --git a/0000_README b/0000_README index 139084e..6e8d29d 100644 --- a/0000_README +++ b/0000_README @@ -71,6 +71,10 @@ Patch: 1006_linux-5.2.7.patch From: https://www.kernel.org Desc: Linux 5.2.7 +Patch: 1007_linux-5.2.8.patch +From: https://www.kernel.org +Desc: Linux 5.2.8 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1007_linux-5.2.8.patch b/1007_linux-5.2.8.patch new file mode 100644 index 0000000..25fd638 --- /dev/null +++ b/1007_linux-5.2.8.patch @@ -0,0 +1,2838 @@ +diff --git a/Makefile b/Makefile +index 359a6b49e576..bad87c4c8117 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 2 +-SUBLEVEL = 7 ++SUBLEVEL = 8 + EXTRAVERSION = + NAME = Bobtail Squid + +diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c +index 302cf0ba1600..8c7a996d1f16 100644 +--- a/drivers/atm/iphase.c ++++ b/drivers/atm/iphase.c +@@ -63,6 +63,7 @@ + #include <asm/byteorder.h> + #include <linux/vmalloc.h> + #include <linux/jiffies.h> ++#include <linux/nospec.h> + #include "iphase.h" + #include "suni.h" + #define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) +@@ -2760,8 +2761,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) + } + if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; + board = ia_cmds.status; +- if ((board < 0) || (board > iadev_count)) +- board = 0; ++ ++ if ((board < 0) || (board > iadev_count)) ++ board = 0; ++ board = array_index_nospec(board, iadev_count + 1); ++ + iadev = ia_dev[board]; + switch (ia_cmds.cmd) { + case MEMDUMP: +diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c +index 1dc8d03ff127..ee6fa75d65a2 100644 +--- a/drivers/gpu/drm/i915/intel_bios.c ++++ b/drivers/gpu/drm/i915/intel_bios.c +@@ -762,7 +762,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) + } + + if (bdb->version >= 226) { +- u32 wakeup_time = psr_table->psr2_tp2_tp3_wakeup_time; ++ u32 wakeup_time = psr->psr2_tp2_tp3_wakeup_time; + + wakeup_time = (wakeup_time >> (2 * panel_type)) & 0x3; + switch (wakeup_time) { +diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h +index fdbbb9a53804..796c070bbe6f 100644 +--- a/drivers/gpu/drm/i915/intel_vbt_defs.h ++++ b/drivers/gpu/drm/i915/intel_vbt_defs.h +@@ -772,13 +772,13 @@ struct psr_table { + /* TP wake up time in multiple of 100 */ + u16 tp1_wakeup_time; + u16 tp2_tp3_wakeup_time; +- +- /* PSR2 TP2/TP3 wakeup time for 16 panels */ +- u32 psr2_tp2_tp3_wakeup_time; + } __packed; + + struct bdb_psr { + struct psr_table psr_table[16]; ++ ++ /* PSR2 TP2/TP3 wakeup time for 16 panels */ ++ u32 psr2_tp2_tp3_wakeup_time; + } __packed; + + /* +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index bfc584ada4eb..34a812025b94 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -568,6 +568,7 @@ + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a + #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a + #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a ++#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641 + + #define USB_VENDOR_ID_HUION 0x256c + #define USB_DEVICE_ID_HUION_TABLET 0x006e +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 1549c7a2f04c..5b669f7d653f 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -91,6 +91,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT }, +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 489436503e49..926c597f5f46 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -533,14 +533,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) + */ + buttons = (data[4] << 1) | (data[3] & 0x01); + } else if (features->type == CINTIQ_COMPANION_2) { +- /* d-pad right -> data[4] & 0x10 +- * d-pad up -> data[4] & 0x20 +- * d-pad left -> data[4] & 0x40 +- * d-pad down -> data[4] & 0x80 +- * d-pad center -> data[3] & 0x01 ++ /* d-pad right -> data[2] & 0x10 ++ * d-pad up -> data[2] & 0x20 ++ * d-pad left -> data[2] & 0x40 ++ * d-pad down -> data[2] & 0x80 ++ * d-pad center -> data[1] & 0x01 + */ + buttons = ((data[2] >> 4) << 7) | +- ((data[1] & 0x04) << 6) | ++ ((data[1] & 0x04) << 4) | + ((data[2] & 0x0F) << 2) | + (data[1] & 0x03); + } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index bf39fc83d577..4039a9599d79 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -1934,8 +1934,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, + } + + /* select a non-FCoE queue */ +- return netdev_pick_tx(dev, skb, NULL) % +- (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos); ++ return netdev_pick_tx(dev, skb, NULL) % (BNX2X_NUM_ETH_QUEUES(bp)); + } + + void bnx2x_set_num_queues(struct bnx2x *bp) +diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c +index ee7857298361..aca878a3f81f 100644 +--- a/drivers/net/ethernet/marvell/mvmdio.c ++++ b/drivers/net/ethernet/marvell/mvmdio.c +@@ -319,15 +319,31 @@ static int orion_mdio_probe(struct platform_device *pdev) + + init_waitqueue_head(&dev->smi_busy_wait); + +- for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { +- dev->clk[i] = of_clk_get(pdev->dev.of_node, i); +- if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) { ++ if (pdev->dev.of_node) { ++ for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { ++ dev->clk[i] = of_clk_get(pdev->dev.of_node, i); ++ if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) { ++ ret = -EPROBE_DEFER; ++ goto out_clk; ++ } ++ if (IS_ERR(dev->clk[i])) ++ break; ++ clk_prepare_enable(dev->clk[i]); ++ } ++ ++ if (!IS_ERR(of_clk_get(pdev->dev.of_node, ++ ARRAY_SIZE(dev->clk)))) ++ dev_warn(&pdev->dev, ++ "unsupported number of clocks, limiting to the first " ++ __stringify(ARRAY_SIZE(dev->clk)) "\n"); ++ } else { ++ dev->clk[0] = clk_get(&pdev->dev, NULL); ++ if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto out_clk; + } +- if (IS_ERR(dev->clk[i])) +- break; +- clk_prepare_enable(dev->clk[i]); ++ if (!IS_ERR(dev->clk[0])) ++ clk_prepare_enable(dev->clk[0]); + } + + dev->err_interrupt = platform_get_irq(pdev, 0); +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index d8e5241097a9..50ed1bdb632d 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -3609,6 +3609,7 @@ static int mvpp2_set_mac_address(struct net_device *dev, void *p) + static int mvpp2_change_mtu(struct net_device *dev, int mtu) + { + struct mvpp2_port *port = netdev_priv(dev); ++ bool running = netif_running(dev); + int err; + + if (!IS_ALIGNED(MVPP2_RX_PKT_SIZE(mtu), 8)) { +@@ -3617,40 +3618,24 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu) + mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8); + } + +- if (!netif_running(dev)) { +- err = mvpp2_bm_update_mtu(dev, mtu); +- if (!err) { +- port->pkt_size = MVPP2_RX_PKT_SIZE(mtu); +- return 0; +- } +- +- /* Reconfigure BM to the original MTU */ +- err = mvpp2_bm_update_mtu(dev, dev->mtu); +- if (err) +- goto log_error; +- } +- +- mvpp2_stop_dev(port); ++ if (running) ++ mvpp2_stop_dev(port); + + err = mvpp2_bm_update_mtu(dev, mtu); +- if (!err) { ++ if (err) { ++ netdev_err(dev, "failed to change MTU\n"); ++ /* Reconfigure BM to the original MTU */ ++ mvpp2_bm_update_mtu(dev, dev->mtu); ++ } else { + port->pkt_size = MVPP2_RX_PKT_SIZE(mtu); +- goto out_start; + } + +- /* Reconfigure BM to the original MTU */ +- err = mvpp2_bm_update_mtu(dev, dev->mtu); +- if (err) +- goto log_error; +- +-out_start: +- mvpp2_start_dev(port); +- mvpp2_egress_enable(port); +- mvpp2_ingress_enable(port); ++ if (running) { ++ mvpp2_start_dev(port); ++ mvpp2_egress_enable(port); ++ mvpp2_ingress_enable(port); ++ } + +- return 0; +-log_error: +- netdev_err(dev, "failed to change MTU\n"); + return err; + } + +@@ -5609,9 +5594,6 @@ static int mvpp2_remove(struct platform_device *pdev) + + mvpp2_dbgfs_cleanup(priv); + +- flush_workqueue(priv->stats_queue); +- destroy_workqueue(priv->stats_queue); +- + fwnode_for_each_available_child_node(fwnode, port_fwnode) { + if (priv->port_list[i]) { + mutex_destroy(&priv->port_list[i]->gather_stats_lock); +@@ -5620,6 +5602,8 @@ static int mvpp2_remove(struct platform_device *pdev) + i++; + } + ++ destroy_workqueue(priv->stats_queue); ++ + for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { + struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i]; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c +index f6b1da99e6c2..ba5f46da1c5c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c +@@ -213,7 +213,7 @@ void mlx5_unregister_device(struct mlx5_core_dev *dev) + struct mlx5_interface *intf; + + mutex_lock(&mlx5_intf_mutex); +- list_for_each_entry(intf, &intf_list, list) ++ list_for_each_entry_reverse(intf, &intf_list, list) + mlx5_remove_device(intf, priv); + list_del(&priv->dev_list); + mutex_unlock(&mlx5_intf_mutex); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c +index d5e5afbdca6d..f777994f3005 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c +@@ -78,9 +78,10 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = { + }; + + static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev, +- const u32 **arr, u32 *size) ++ const u32 **arr, u32 *size, ++ bool force_legacy) + { +- bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); ++ bool ext = force_legacy ? false : MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + + *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) : + ARRAY_SIZE(mlx5e_link_speed); +@@ -152,7 +153,8 @@ int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable, + sizeof(out), MLX5_REG_PTYS, 0, 1); + } + +-u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper) ++u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper, ++ bool force_legacy) + { + unsigned long temp = eth_proto_oper; + const u32 *table; +@@ -160,7 +162,7 @@ u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper) + u32 max_size; + int i; + +- mlx5e_port_get_speed_arr(mdev, &table, &max_size); ++ mlx5e_port_get_speed_arr(mdev, &table, &max_size, force_legacy); + i = find_first_bit(&temp, max_size); + if (i < max_size) + speed = table[i]; +@@ -170,6 +172,7 @@ u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper) + int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) + { + struct mlx5e_port_eth_proto eproto; ++ bool force_legacy = false; + bool ext; + int err; + +@@ -177,8 +180,13 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) + err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); + if (err) + goto out; +- +- *speed = mlx5e_port_ptys2speed(mdev, eproto.oper); ++ if (ext && !eproto.admin) { ++ force_legacy = true; ++ err = mlx5_port_query_eth_proto(mdev, 1, false, &eproto); ++ if (err) ++ goto out; ++ } ++ *speed = mlx5e_port_ptys2speed(mdev, eproto.oper, force_legacy); + if (!(*speed)) + err = -EINVAL; + +@@ -201,7 +209,7 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) + if (err) + return err; + +- mlx5e_port_get_speed_arr(mdev, &table, &max_size); ++ mlx5e_port_get_speed_arr(mdev, &table, &max_size, false); + for (i = 0; i < max_size; ++i) + if (eproto.cap & MLX5E_PROT_MASK(i)) + max_speed = max(max_speed, table[i]); +@@ -210,14 +218,15 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) + return 0; + } + +-u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed) ++u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, ++ bool force_legacy) + { + u32 link_modes = 0; + const u32 *table; + u32 max_size; + int i; + +- mlx5e_port_get_speed_arr(mdev, &table, &max_size); ++ mlx5e_port_get_speed_arr(mdev, &table, &max_size, force_legacy); + for (i = 0; i < max_size; ++i) { + if (table[i] == speed) + link_modes |= MLX5E_PROT_MASK(i); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h +index 70f536ec51c4..4a7f4497692b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h +@@ -48,10 +48,12 @@ void mlx5_port_query_eth_autoneg(struct mlx5_core_dev *dev, u8 *an_status, + u8 *an_disable_cap, u8 *an_disable_admin); + int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable, + u32 proto_admin, bool ext); +-u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper); ++u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper, ++ bool force_legacy); + int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); + int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); +-u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed); ++u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, ++ bool force_legacy); + + int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out); + int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index dd764e0471f2..f637d81f08bc 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -764,7 +764,7 @@ static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings + } + + static void get_speed_duplex(struct net_device *netdev, +- u32 eth_proto_oper, ++ u32 eth_proto_oper, bool force_legacy, + struct ethtool_link_ksettings *link_ksettings) + { + struct mlx5e_priv *priv = netdev_priv(netdev); +@@ -774,7 +774,7 @@ static void get_speed_duplex(struct net_device *netdev, + if (!netif_carrier_ok(netdev)) + goto out; + +- speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper); ++ speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper, force_legacy); + if (!speed) { + speed = SPEED_UNKNOWN; + goto out; +@@ -893,8 +893,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, + /* Fields: eth_proto_admin and ext_eth_proto_admin are + * mutually exclusive. Hence try reading legacy advertising + * when extended advertising is zero. +- * admin_ext indicates how eth_proto_admin should be +- * interpreted ++ * admin_ext indicates which proto_admin (ext vs. legacy) ++ * should be read and interpreted + */ + admin_ext = ext; + if (ext && !eth_proto_admin) { +@@ -903,7 +903,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, + admin_ext = false; + } + +- eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, ++ eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, admin_ext, + eth_proto_oper); + eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise); + an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin); +@@ -918,7 +918,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, + get_supported(mdev, eth_proto_cap, link_ksettings); + get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings, + admin_ext); +- get_speed_duplex(priv->netdev, eth_proto_oper, link_ksettings); ++ get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext, ++ link_ksettings); + + eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; + +@@ -995,45 +996,69 @@ static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes) + return ptys_modes; + } + ++static bool ext_link_mode_requested(const unsigned long *adver) ++{ ++#define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT ++ int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT; ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(modes); ++ ++ bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size); ++ return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS); ++} ++ ++static bool ext_speed_requested(u32 speed) ++{ ++#define MLX5E_MAX_PTYS_LEGACY_SPEED 100000 ++ return !!(speed > MLX5E_MAX_PTYS_LEGACY_SPEED); ++} ++ ++static bool ext_requested(u8 autoneg, const unsigned long *adver, u32 speed) ++{ ++ bool ext_link_mode = ext_link_mode_requested(adver); ++ bool ext_speed = ext_speed_requested(speed); ++ ++ return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_speed; ++} ++ + int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, + const struct ethtool_link_ksettings *link_ksettings) + { + struct mlx5_core_dev *mdev = priv->mdev; + struct mlx5e_port_eth_proto eproto; ++ const unsigned long *adver; + bool an_changes = false; + u8 an_disable_admin; + bool ext_supported; +- bool ext_requested; + u8 an_disable_cap; + bool an_disable; + u32 link_modes; + u8 an_status; ++ u8 autoneg; + u32 speed; ++ bool ext; + int err; + + u32 (*ethtool2ptys_adver_func)(const unsigned long *adver); + +-#define MLX5E_PTYS_EXT ((1ULL << ETHTOOL_LINK_MODE_50000baseKR_Full_BIT) - 1) ++ adver = link_ksettings->link_modes.advertising; ++ autoneg = link_ksettings->base.autoneg; ++ speed = link_ksettings->base.speed; + +- ext_requested = !!(link_ksettings->link_modes.advertising[0] > +- MLX5E_PTYS_EXT || +- link_ksettings->link_modes.advertising[1]); ++ ext = ext_requested(autoneg, adver, speed), + ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); +- ext_requested &= ext_supported; ++ if (!ext_supported && ext) ++ return -EOPNOTSUPP; + +- speed = link_ksettings->base.speed; +- ethtool2ptys_adver_func = ext_requested ? +- mlx5e_ethtool2ptys_ext_adver_link : ++ ethtool2ptys_adver_func = ext ? mlx5e_ethtool2ptys_ext_adver_link : + mlx5e_ethtool2ptys_adver_link; +- err = mlx5_port_query_eth_proto(mdev, 1, ext_requested, &eproto); ++ err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); + if (err) { + netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n", + __func__, err); + goto out; + } +- link_modes = link_ksettings->base.autoneg == AUTONEG_ENABLE ? +- ethtool2ptys_adver_func(link_ksettings->link_modes.advertising) : +- mlx5e_port_speed2linkmodes(mdev, speed); ++ link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : ++ mlx5e_port_speed2linkmodes(mdev, speed, !ext); + + link_modes = link_modes & eproto.cap; + if (!link_modes) { +@@ -1046,14 +1071,14 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, + mlx5_port_query_eth_autoneg(mdev, &an_status, &an_disable_cap, + &an_disable_admin); + +- an_disable = link_ksettings->base.autoneg == AUTONEG_DISABLE; ++ an_disable = autoneg == AUTONEG_DISABLE; + an_changes = ((!an_disable && an_disable_admin) || + (an_disable && !an_disable_admin)); + + if (!an_changes && link_modes == eproto.admin) + goto out; + +- mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext_requested); ++ mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext); + mlx5_toggle_port_link(mdev); + + out: +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index a44c24280128..882d26b8095d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -340,12 +340,11 @@ static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix) + + static void mlx5e_init_frags_partition(struct mlx5e_rq *rq) + { +- struct mlx5e_wqe_frag_info next_frag, *prev; ++ struct mlx5e_wqe_frag_info next_frag = {}; ++ struct mlx5e_wqe_frag_info *prev = NULL; + int i; + + next_frag.di = &rq->wqe.di[0]; +- next_frag.offset = 0; +- prev = NULL; + + for (i = 0; i < mlx5_wq_cyc_get_size(&rq->wqe.wq); i++) { + struct mlx5e_rq_frag_info *frag_info = &rq->wqe.info.arr[0]; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index e40c60d1631f..ee95f96ead4e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -1210,13 +1210,13 @@ static struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow) + void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) + { + struct mlx5e_neigh *m_neigh = &nhe->m_neigh; +- u64 bytes, packets, lastuse = 0; + struct mlx5e_tc_flow *flow; + struct mlx5e_encap_entry *e; + struct mlx5_fc *counter; + struct neigh_table *tbl; + bool neigh_used = false; + struct neighbour *n; ++ u64 lastuse; + + if (m_neigh->family == AF_INET) + tbl = &arp_tbl; +@@ -1236,7 +1236,7 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) + encaps[efi->index]); + if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) { + counter = mlx5e_tc_get_counter(flow); +- mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse); ++ lastuse = mlx5_fc_query_lastuse(counter); + if (time_after((unsigned long)lastuse, nhe->reported_lastuse)) { + neigh_used = true; + break; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +index a08c3d09a50f..2664a05eee00 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +@@ -68,7 +68,7 @@ enum fs_flow_table_type { + FS_FT_SNIFFER_RX = 0X5, + FS_FT_SNIFFER_TX = 0X6, + FS_FT_RDMA_RX = 0X7, +- FS_FT_MAX_TYPE = FS_FT_SNIFFER_TX, ++ FS_FT_MAX_TYPE = FS_FT_RDMA_RX, + }; + + enum fs_flow_table_op_mod { +@@ -274,7 +274,8 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev); + (type == FS_FT_FDB) ? MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, cap) : \ + (type == FS_FT_SNIFFER_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) : \ + (type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(mdev, cap) : \ +- (BUILD_BUG_ON_ZERO(FS_FT_SNIFFER_TX != FS_FT_MAX_TYPE))\ ++ (type == FS_FT_RDMA_RX) ? MLX5_CAP_FLOWTABLE_RDMA_RX(mdev, cap) : \ ++ (BUILD_BUG_ON_ZERO(FS_FT_RDMA_RX != FS_FT_MAX_TYPE))\ + ) + + #endif +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +index c6c28f56aa29..add9db67028f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +@@ -367,6 +367,11 @@ int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter, + } + EXPORT_SYMBOL(mlx5_fc_query); + ++u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter) ++{ ++ return counter->cache.lastuse; ++} ++ + void mlx5_fc_query_cached(struct mlx5_fc *counter, + u64 *bytes, u64 *packets, u64 *lastuse) + { +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +index 23204356ad88..d51442e63aba 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +@@ -5989,7 +5989,7 @@ static int __init mlxsw_sp_module_init(void) + return 0; + + err_sp2_pci_driver_register: +- mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver); ++ mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver); + err_sp1_pci_driver_register: + mlxsw_core_driver_unregister(&mlxsw_sp2_driver); + err_sp2_core_driver_register: +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +index 1537f70bc26d..888ba4300bcc 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +@@ -437,8 +437,8 @@ static const struct mlxsw_sp_sb_pr mlxsw_sp1_sb_prs[] = { + MLXSW_SP1_SB_PR_CPU_SIZE, true, false), + }; + +-#define MLXSW_SP2_SB_PR_INGRESS_SIZE 38128752 +-#define MLXSW_SP2_SB_PR_EGRESS_SIZE 38128752 ++#define MLXSW_SP2_SB_PR_INGRESS_SIZE 35297568 ++#define MLXSW_SP2_SB_PR_EGRESS_SIZE 35297568 + #define MLXSW_SP2_SB_PR_CPU_SIZE (256 * 1000) + + /* Order according to mlxsw_sp2_sb_pool_dess */ +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index 02ad11e0b0d8..58e76e7cb0d6 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -1797,6 +1797,7 @@ EXPORT_SYMBOL(ocelot_init); + + void ocelot_deinit(struct ocelot *ocelot) + { ++ cancel_delayed_work(&ocelot->stats_work); + destroy_workqueue(ocelot->stats_queue); + mutex_destroy(&ocelot->stats_lock); + } +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +index 4bf20d0651c4..90ad5694e2af 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +@@ -51,7 +51,7 @@ struct rmnet_map_dl_csum_trailer { + struct rmnet_map_ul_csum_header { + __be16 csum_start_offset; + u16 csum_insert_offset:14; +- u16 udp_ip4_ind:1; ++ u16 udp_ind:1; + u16 csum_enabled:1; + } __aligned(1); + +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +index 60189923737a..21d38167f961 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +@@ -206,9 +206,9 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr, + ul_header->csum_insert_offset = skb->csum_offset; + ul_header->csum_enabled = 1; + if (ip4h->protocol == IPPROTO_UDP) +- ul_header->udp_ip4_ind = 1; ++ ul_header->udp_ind = 1; + else +- ul_header->udp_ip4_ind = 0; ++ ul_header->udp_ind = 0; + + /* Changing remaining fields to network order */ + hdr++; +@@ -239,6 +239,7 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr, + struct rmnet_map_ul_csum_header *ul_header, + struct sk_buff *skb) + { ++ struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr; + __be16 *hdr = (__be16 *)ul_header, offset; + + offset = htons((__force u16)(skb_transport_header(skb) - +@@ -246,7 +247,11 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr, + ul_header->csum_start_offset = offset; + ul_header->csum_insert_offset = skb->csum_offset; + ul_header->csum_enabled = 1; +- ul_header->udp_ip4_ind = 0; ++ ++ if (ip6h->nexthdr == IPPROTO_UDP) ++ ul_header->udp_ind = 1; ++ else ++ ul_header->udp_ind = 0; + + /* Changing remaining fields to network order */ + hdr++; +@@ -419,7 +424,7 @@ sw_csum: + ul_header->csum_start_offset = 0; + ul_header->csum_insert_offset = 0; + ul_header->csum_enabled = 0; +- ul_header->udp_ip4_ind = 0; ++ ul_header->udp_ind = 0; + + priv->stats.csum_sw++; + } +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index 96637fcbe65d..36261b2959b4 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -7050,13 +7050,18 @@ static int rtl_alloc_irq(struct rtl8169_private *tp) + { + unsigned int flags; + +- if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { ++ switch (tp->mac_version) { ++ case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: + rtl_unlock_config_regs(tp); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); + rtl_lock_config_regs(tp); ++ /* fall through */ ++ case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_24: + flags = PCI_IRQ_LEGACY; +- } else { ++ break; ++ default: + flags = PCI_IRQ_ALL_TYPES; ++ break; + } + + return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags); +diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c +index 3e5bc1fc3c46..c245a0f15066 100644 +--- a/drivers/net/ethernet/rocker/rocker_main.c ++++ b/drivers/net/ethernet/rocker/rocker_main.c +@@ -2208,6 +2208,7 @@ static int rocker_router_fib_event(struct notifier_block *nb, + + if (fen_info->fi->fib_nh_is_v6) { + NL_SET_ERR_MSG_MOD(info->extack, "IPv6 gateway with IPv4 route is not supported"); ++ kfree(fib_work); + return notifier_from_errno(-EINVAL); + } + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 932e54e25b71..b14f46a57154 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4374,8 +4374,9 @@ int stmmac_dvr_probe(struct device *device, + NAPI_POLL_WEIGHT); + } + if (queue < priv->plat->tx_queues_to_use) { +- netif_napi_add(ndev, &ch->tx_napi, stmmac_napi_poll_tx, +- NAPI_POLL_WEIGHT); ++ netif_tx_napi_add(ndev, &ch->tx_napi, ++ stmmac_napi_poll_tx, ++ NAPI_POLL_WEIGHT); + } + } + +diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c +index 3ffe46df249e..7c5265fd2b94 100644 +--- a/drivers/net/phy/fixed_phy.c ++++ b/drivers/net/phy/fixed_phy.c +@@ -216,8 +216,10 @@ static struct gpio_desc *fixed_phy_get_gpiod(struct device_node *np) + if (IS_ERR(gpiod)) { + if (PTR_ERR(gpiod) == -EPROBE_DEFER) + return gpiod; +- pr_err("error getting GPIO for fixed link %pOF, proceed without\n", +- fixed_link_node); ++ ++ if (PTR_ERR(gpiod) != -ENOENT) ++ pr_err("error getting GPIO for fixed link %pOF, proceed without\n", ++ fixed_link_node); + gpiod = NULL; + } + +diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c +index 28676af97b42..645d354ffb48 100644 +--- a/drivers/net/phy/mscc.c ++++ b/drivers/net/phy/mscc.c +@@ -2226,8 +2226,8 @@ static int vsc8514_probe(struct phy_device *phydev) + vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; + vsc8531->hw_stats = vsc85xx_hw_stats; + vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); +- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, +- sizeof(u64), GFP_KERNEL); ++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, ++ sizeof(u64), GFP_KERNEL); + if (!vsc8531->stats) + return -ENOMEM; + +@@ -2251,8 +2251,8 @@ static int vsc8574_probe(struct phy_device *phydev) + vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; + vsc8531->hw_stats = vsc8584_hw_stats; + vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); +- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, +- sizeof(u64), GFP_KERNEL); ++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, ++ sizeof(u64), GFP_KERNEL); + if (!vsc8531->stats) + return -ENOMEM; + +@@ -2281,8 +2281,8 @@ static int vsc8584_probe(struct phy_device *phydev) + vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; + vsc8531->hw_stats = vsc8584_hw_stats; + vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); +- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, +- sizeof(u64), GFP_KERNEL); ++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, ++ sizeof(u64), GFP_KERNEL); + if (!vsc8531->stats) + return -ENOMEM; + +@@ -2311,8 +2311,8 @@ static int vsc85xx_probe(struct phy_device *phydev) + vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; + vsc8531->hw_stats = vsc85xx_hw_stats; + vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); +- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, +- sizeof(u64), GFP_KERNEL); ++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, ++ sizeof(u64), GFP_KERNEL); + if (!vsc8531->stats) + return -ENOMEM; + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index a3f8740c6163..ffa402732aea 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1730,6 +1730,12 @@ done: + phydev->link = status & BMSR_LSTATUS ? 1 : 0; + phydev->autoneg_complete = status & BMSR_ANEGCOMPLETE ? 1 : 0; + ++ /* Consider the case that autoneg was started and "aneg complete" ++ * bit has been reset, but "link up" bit not yet. ++ */ ++ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) ++ phydev->link = 0; ++ + return 0; + } + EXPORT_SYMBOL(genphy_update_link); +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index 4c0616ba314d..c45ee6e3fe01 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -195,6 +195,8 @@ static int phylink_parse_fixedlink(struct phylink *pl, + pl->supported, true); + linkmode_zero(pl->supported); + phylink_set(pl->supported, MII); ++ phylink_set(pl->supported, Pause); ++ phylink_set(pl->supported, Asym_Pause); + if (s) { + __set_bit(s->bit, pl->supported); + } else { +@@ -912,10 +914,10 @@ void phylink_start(struct phylink *pl) + + if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) + mod_timer(&pl->link_poll, jiffies + HZ); +- if (pl->sfp_bus) +- sfp_upstream_start(pl->sfp_bus); + if (pl->phydev) + phy_start(pl->phydev); ++ if (pl->sfp_bus) ++ sfp_upstream_start(pl->sfp_bus); + } + EXPORT_SYMBOL_GPL(phylink_start); + +@@ -932,10 +934,10 @@ void phylink_stop(struct phylink *pl) + { + ASSERT_RTNL(); + +- if (pl->phydev) +- phy_stop(pl->phydev); + if (pl->sfp_bus) + sfp_upstream_stop(pl->sfp_bus); ++ if (pl->phydev) ++ phy_stop(pl->phydev); + if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) + del_timer_sync(&pl->link_poll); + +diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c +index 1d902ecb4aa8..a44dd3c8af63 100644 +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -1115,6 +1115,9 @@ static const struct proto_ops pppoe_ops = { + .recvmsg = pppoe_recvmsg, + .mmap = sock_no_mmap, + .ioctl = pppox_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = pppox_compat_ioctl, ++#endif + }; + + static const struct pppox_proto pppoe_proto = { +diff --git a/drivers/net/ppp/pppox.c b/drivers/net/ppp/pppox.c +index 5ef422a43d70..08364f10a43f 100644 +--- a/drivers/net/ppp/pppox.c ++++ b/drivers/net/ppp/pppox.c +@@ -17,6 +17,7 @@ + #include <linux/string.h> + #include <linux/module.h> + #include <linux/kernel.h> ++#include <linux/compat.h> + #include <linux/errno.h> + #include <linux/netdevice.h> + #include <linux/net.h> +@@ -98,6 +99,18 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + + EXPORT_SYMBOL(pppox_ioctl); + ++#ifdef CONFIG_COMPAT ++int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ++{ ++ if (cmd == PPPOEIOCSFWD32) ++ cmd = PPPOEIOCSFWD; ++ ++ return pppox_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); ++} ++ ++EXPORT_SYMBOL(pppox_compat_ioctl); ++#endif ++ + static int pppox_create(struct net *net, struct socket *sock, int protocol, + int kern) + { +diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c +index a8e52c8e4128..734de7de03f7 100644 +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -623,6 +623,9 @@ static const struct proto_ops pptp_ops = { + .recvmsg = sock_no_recvmsg, + .mmap = sock_no_mmap, + .ioctl = pppox_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = pppox_compat_ioctl, ++#endif + }; + + static const struct pppox_proto pppox_pptp_proto = { +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index d7c55e0fa8f4..192ac47fd055 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1600,7 +1600,8 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, + return true; + } + +-static struct sk_buff *__tun_build_skb(struct page_frag *alloc_frag, char *buf, ++static struct sk_buff *__tun_build_skb(struct tun_file *tfile, ++ struct page_frag *alloc_frag, char *buf, + int buflen, int len, int pad) + { + struct sk_buff *skb = build_skb(buf, buflen); +@@ -1610,6 +1611,7 @@ static struct sk_buff *__tun_build_skb(struct page_frag *alloc_frag, char *buf, + + skb_reserve(skb, pad); + skb_put(skb, len); ++ skb_set_owner_w(skb, tfile->socket.sk); + + get_page(alloc_frag->page); + alloc_frag->offset += buflen; +@@ -1687,7 +1689,8 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, + */ + if (hdr->gso_type || !xdp_prog) { + *skb_xdp = 1; +- return __tun_build_skb(alloc_frag, buf, buflen, len, pad); ++ return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, ++ pad); + } + + *skb_xdp = 0; +@@ -1724,7 +1727,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, + rcu_read_unlock(); + local_bh_enable(); + +- return __tun_build_skb(alloc_frag, buf, buflen, len, pad); ++ return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, pad); + + err_xdp: + put_page(alloc_frag->page); +diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c +index e65d027b91fa..529be35ac178 100644 +--- a/drivers/nfc/nfcmrvl/main.c ++++ b/drivers/nfc/nfcmrvl/main.c +@@ -244,7 +244,7 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv) + /* Reset possible fault of previous session */ + clear_bit(NFCMRVL_PHY_ERROR, &priv->flags); + +- if (priv->config.reset_n_io) { ++ if (gpio_is_valid(priv->config.reset_n_io)) { + nfc_info(priv->dev, "reset the chip\n"); + gpio_set_value(priv->config.reset_n_io, 0); + usleep_range(5000, 10000); +@@ -255,7 +255,7 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv) + + void nfcmrvl_chip_halt(struct nfcmrvl_private *priv) + { +- if (priv->config.reset_n_io) ++ if (gpio_is_valid(priv->config.reset_n_io)) + gpio_set_value(priv->config.reset_n_io, 0); + } + +diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c +index 9a22056e8d9e..e5a622ce4b95 100644 +--- a/drivers/nfc/nfcmrvl/uart.c ++++ b/drivers/nfc/nfcmrvl/uart.c +@@ -26,7 +26,7 @@ + static unsigned int hci_muxed; + static unsigned int flow_control; + static unsigned int break_control; +-static unsigned int reset_n_io; ++static int reset_n_io = -EINVAL; + + /* + ** NFCMRVL NCI OPS +@@ -231,5 +231,5 @@ MODULE_PARM_DESC(break_control, "Tell if UART driver must drive break signal."); + module_param(hci_muxed, uint, 0); + MODULE_PARM_DESC(hci_muxed, "Tell if transport is muxed in HCI one."); + +-module_param(reset_n_io, uint, 0); ++module_param(reset_n_io, int, 0); + MODULE_PARM_DESC(reset_n_io, "GPIO that is wired to RESET_N signal."); +diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c +index 945cc903d8f1..888e298f610b 100644 +--- a/drivers/nfc/nfcmrvl/usb.c ++++ b/drivers/nfc/nfcmrvl/usb.c +@@ -305,6 +305,7 @@ static int nfcmrvl_probe(struct usb_interface *intf, + + /* No configuration for USB */ + memset(&config, 0, sizeof(config)); ++ config.reset_n_io = -EINVAL; + + nfc_info(&udev->dev, "intf %p id %p\n", intf, id); + +diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c +index dfb93228d6a7..df41f3571dc9 100644 +--- a/drivers/nvdimm/bus.c ++++ b/drivers/nvdimm/bus.c +@@ -887,10 +887,12 @@ void wait_nvdimm_bus_probe_idle(struct device *dev) + do { + if (nvdimm_bus->probe_active == 0) + break; +- nvdimm_bus_unlock(&nvdimm_bus->dev); ++ nvdimm_bus_unlock(dev); ++ device_unlock(dev); + wait_event(nvdimm_bus->wait, + nvdimm_bus->probe_active == 0); +- nvdimm_bus_lock(&nvdimm_bus->dev); ++ device_lock(dev); ++ nvdimm_bus_lock(dev); + } while (true); + } + +@@ -973,20 +975,19 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + int read_only, unsigned int ioctl_cmd, unsigned long arg) + { + struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; +- static char out_env[ND_CMD_MAX_ENVELOPE]; +- static char in_env[ND_CMD_MAX_ENVELOPE]; + const struct nd_cmd_desc *desc = NULL; + unsigned int cmd = _IOC_NR(ioctl_cmd); + struct device *dev = &nvdimm_bus->dev; + void __user *p = (void __user *) arg; ++ char *out_env = NULL, *in_env = NULL; + const char *cmd_name, *dimm_name; + u32 in_len = 0, out_len = 0; + unsigned int func = cmd; + unsigned long cmd_mask; + struct nd_cmd_pkg pkg; + int rc, i, cmd_rc; ++ void *buf = NULL; + u64 buf_len = 0; +- void *buf; + + if (nvdimm) { + desc = nd_cmd_dimm_desc(cmd); +@@ -1017,7 +1018,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + case ND_CMD_ARS_START: + case ND_CMD_CLEAR_ERROR: + case ND_CMD_CALL: +- dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n", ++ dev_dbg(dev, "'%s' command while read-only.\n", + nvdimm ? nvdimm_cmd_name(cmd) + : nvdimm_bus_cmd_name(cmd)); + return -EPERM; +@@ -1026,6 +1027,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + } + + /* process an input envelope */ ++ in_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); ++ if (!in_env) ++ return -ENOMEM; + for (i = 0; i < desc->in_num; i++) { + u32 in_size, copy; + +@@ -1033,14 +1037,17 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + if (in_size == UINT_MAX) { + dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n", + __func__, dimm_name, cmd_name, i); +- return -ENXIO; ++ rc = -ENXIO; ++ goto out; + } +- if (in_len < sizeof(in_env)) +- copy = min_t(u32, sizeof(in_env) - in_len, in_size); ++ if (in_len < ND_CMD_MAX_ENVELOPE) ++ copy = min_t(u32, ND_CMD_MAX_ENVELOPE - in_len, in_size); + else + copy = 0; +- if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) +- return -EFAULT; ++ if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) { ++ rc = -EFAULT; ++ goto out; ++ } + in_len += in_size; + } + +@@ -1052,6 +1059,12 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + } + + /* process an output envelope */ ++ out_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); ++ if (!out_env) { ++ rc = -ENOMEM; ++ goto out; ++ } ++ + for (i = 0; i < desc->out_num; i++) { + u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, + (u32 *) in_env, (u32 *) out_env, 0); +@@ -1060,15 +1073,18 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + if (out_size == UINT_MAX) { + dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n", + dimm_name, cmd_name, i); +- return -EFAULT; ++ rc = -EFAULT; ++ goto out; + } +- if (out_len < sizeof(out_env)) +- copy = min_t(u32, sizeof(out_env) - out_len, out_size); ++ if (out_len < ND_CMD_MAX_ENVELOPE) ++ copy = min_t(u32, ND_CMD_MAX_ENVELOPE - out_len, out_size); + else + copy = 0; + if (copy && copy_from_user(&out_env[out_len], +- p + in_len + out_len, copy)) +- return -EFAULT; ++ p + in_len + out_len, copy)) { ++ rc = -EFAULT; ++ goto out; ++ } + out_len += out_size; + } + +@@ -1076,19 +1092,23 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + if (buf_len > ND_IOCTL_MAX_BUFLEN) { + dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name, + cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN); +- return -EINVAL; ++ rc = -EINVAL; ++ goto out; + } + + buf = vmalloc(buf_len); +- if (!buf) +- return -ENOMEM; ++ if (!buf) { ++ rc = -ENOMEM; ++ goto out; ++ } + + if (copy_from_user(buf, p, buf_len)) { + rc = -EFAULT; + goto out; + } + +- nvdimm_bus_lock(&nvdimm_bus->dev); ++ device_lock(dev); ++ nvdimm_bus_lock(dev); + rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); + if (rc) + goto out_unlock; +@@ -1103,17 +1123,16 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + nvdimm_account_cleared_poison(nvdimm_bus, clear_err->address, + clear_err->cleared); + } +- nvdimm_bus_unlock(&nvdimm_bus->dev); + + if (copy_to_user(p, buf, buf_len)) + rc = -EFAULT; + +- vfree(buf); +- return rc; +- +- out_unlock: +- nvdimm_bus_unlock(&nvdimm_bus->dev); +- out: ++out_unlock: ++ nvdimm_bus_unlock(dev); ++ device_unlock(dev); ++out: ++ kfree(in_env); ++ kfree(out_env); + vfree(buf); + return rc; + } +diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c +index 4fed9ce9c2fe..a15276cdec7d 100644 +--- a/drivers/nvdimm/region_devs.c ++++ b/drivers/nvdimm/region_devs.c +@@ -422,10 +422,12 @@ static ssize_t available_size_show(struct device *dev, + * memory nvdimm_bus_lock() is dropped, but that's userspace's + * problem to not race itself. + */ ++ device_lock(dev); + nvdimm_bus_lock(dev); + wait_nvdimm_bus_probe_idle(dev); + available = nd_region_available_dpa(nd_region); + nvdimm_bus_unlock(dev); ++ device_unlock(dev); + + return sprintf(buf, "%llu\n", available); + } +@@ -437,10 +439,12 @@ static ssize_t max_available_extent_show(struct device *dev, + struct nd_region *nd_region = to_nd_region(dev); + unsigned long long available = 0; + ++ device_lock(dev); + nvdimm_bus_lock(dev); + wait_nvdimm_bus_probe_idle(dev); + available = nd_region_allocatable_dpa(nd_region); + nvdimm_bus_unlock(dev); ++ device_unlock(dev); + + return sprintf(buf, "%llu\n", available); + } +diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c +index 590ec8009f52..9e444b1846ce 100644 +--- a/drivers/scsi/fcoe/fcoe_ctlr.c ++++ b/drivers/scsi/fcoe/fcoe_ctlr.c +@@ -2005,7 +2005,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); + */ + static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) + { +- return (struct fcoe_rport *)(rdata + 1); ++ return container_of(rdata, struct fcoe_rport, rdata); + } + + /** +@@ -2269,7 +2269,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) + */ + static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, + struct sk_buff *skb, +- struct fc_rport_priv *rdata) ++ struct fcoe_rport *frport) + { + struct fip_header *fiph; + struct fip_desc *desc = NULL; +@@ -2277,16 +2277,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, + struct fip_wwn_desc *wwn = NULL; + struct fip_vn_desc *vn = NULL; + struct fip_size_desc *size = NULL; +- struct fcoe_rport *frport; + size_t rlen; + size_t dlen; + u32 desc_mask = 0; + u32 dtype; + u8 sub; + +- memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); +- frport = fcoe_ctlr_rport(rdata); +- + fiph = (struct fip_header *)skb->data; + frport->flags = ntohs(fiph->fip_flags); + +@@ -2349,15 +2345,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, + if (dlen != sizeof(struct fip_wwn_desc)) + goto len_err; + wwn = (struct fip_wwn_desc *)desc; +- rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); ++ frport->rdata.ids.node_name = ++ get_unaligned_be64(&wwn->fd_wwn); + break; + case FIP_DT_VN_ID: + if (dlen != sizeof(struct fip_vn_desc)) + goto len_err; + vn = (struct fip_vn_desc *)desc; + memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN); +- rdata->ids.port_id = ntoh24(vn->fd_fc_id); +- rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn); ++ frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id); ++ frport->rdata.ids.port_name = ++ get_unaligned_be64(&vn->fd_wwpn); + break; + case FIP_DT_FC4F: + if (dlen != sizeof(struct fip_fc4_feat)) +@@ -2738,10 +2736,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) + { + struct fip_header *fiph; + enum fip_vn2vn_subcode sub; +- struct { +- struct fc_rport_priv rdata; +- struct fcoe_rport frport; +- } buf; ++ struct fcoe_rport frport = { }; + int rc, vlan_id = 0; + + fiph = (struct fip_header *)skb->data; +@@ -2757,7 +2752,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) + goto drop; + } + +- rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata); ++ rc = fcoe_ctlr_vn_parse(fip, skb, &frport); + if (rc) { + LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc); + goto drop; +@@ -2766,19 +2761,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) + mutex_lock(&fip->ctlr_mutex); + switch (sub) { + case FIP_SC_VN_PROBE_REQ: +- fcoe_ctlr_vn_probe_req(fip, &buf.rdata); ++ fcoe_ctlr_vn_probe_req(fip, &frport.rdata); + break; + case FIP_SC_VN_PROBE_REP: +- fcoe_ctlr_vn_probe_reply(fip, &buf.rdata); ++ fcoe_ctlr_vn_probe_reply(fip, &frport.rdata); + break; + case FIP_SC_VN_CLAIM_NOTIFY: +- fcoe_ctlr_vn_claim_notify(fip, &buf.rdata); ++ fcoe_ctlr_vn_claim_notify(fip, &frport.rdata); + break; + case FIP_SC_VN_CLAIM_REP: +- fcoe_ctlr_vn_claim_resp(fip, &buf.rdata); ++ fcoe_ctlr_vn_claim_resp(fip, &frport.rdata); + break; + case FIP_SC_VN_BEACON: +- fcoe_ctlr_vn_beacon(fip, &buf.rdata); ++ fcoe_ctlr_vn_beacon(fip, &frport.rdata); + break; + default: + LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub); +@@ -2802,22 +2797,18 @@ drop: + */ + static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, + struct sk_buff *skb, +- struct fc_rport_priv *rdata) ++ struct fcoe_rport *frport) + { + struct fip_header *fiph; + struct fip_desc *desc = NULL; + struct fip_mac_desc *macd = NULL; + struct fip_wwn_desc *wwn = NULL; +- struct fcoe_rport *frport; + size_t rlen; + size_t dlen; + u32 desc_mask = 0; + u32 dtype; + u8 sub; + +- memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); +- frport = fcoe_ctlr_rport(rdata); +- + fiph = (struct fip_header *)skb->data; + frport->flags = ntohs(fiph->fip_flags); + +@@ -2871,7 +2862,8 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, + if (dlen != sizeof(struct fip_wwn_desc)) + goto len_err; + wwn = (struct fip_wwn_desc *)desc; +- rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); ++ frport->rdata.ids.node_name = ++ get_unaligned_be64(&wwn->fd_wwn); + break; + default: + LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x " +@@ -2982,22 +2974,19 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) + { + struct fip_header *fiph; + enum fip_vlan_subcode sub; +- struct { +- struct fc_rport_priv rdata; +- struct fcoe_rport frport; +- } buf; ++ struct fcoe_rport frport = { }; + int rc; + + fiph = (struct fip_header *)skb->data; + sub = fiph->fip_subcode; +- rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata); ++ rc = fcoe_ctlr_vlan_parse(fip, skb, &frport); + if (rc) { + LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc); + goto drop; + } + mutex_lock(&fip->ctlr_mutex); + if (sub == FIP_SC_VL_REQ) +- fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata); ++ fcoe_ctlr_vlan_disc_reply(fip, &frport.rdata); + mutex_unlock(&fip->ctlr_mutex); + + drop: +diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c +index e0f3852fdad1..da6e97d8dc3b 100644 +--- a/drivers/scsi/libfc/fc_rport.c ++++ b/drivers/scsi/libfc/fc_rport.c +@@ -128,6 +128,7 @@ EXPORT_SYMBOL(fc_rport_lookup); + struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) + { + struct fc_rport_priv *rdata; ++ size_t rport_priv_size = sizeof(*rdata); + + lockdep_assert_held(&lport->disc.disc_mutex); + +@@ -135,7 +136,9 @@ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) + if (rdata) + return rdata; + +- rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL); ++ if (lport->rport_priv_size > 0) ++ rport_priv_size = lport->rport_priv_size; ++ rdata = kzalloc(rport_priv_size, GFP_KERNEL); + if (!rdata) + return NULL; + +diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c +index 402c1efcd762..6435b8652159 100644 +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -764,7 +764,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, + bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); + + /* handle all the 3-wire mode */ +- if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) ++ if (spi->mode & SPI_3WIRE && tfr->rx_buf && ++ tfr->rx_buf != master->dummy_rx) + cs |= BCM2835_SPI_CS_REN; + else + cs &= ~BCM2835_SPI_CS_REN; +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index 6e30949d9f77..a7ec2d3dff92 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -638,9 +638,6 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN) + COMPATIBLE_IOCTL(PPPIOCATTCHAN) + COMPATIBLE_IOCTL(PPPIOCGCHAN) + COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS) +-/* PPPOX */ +-COMPATIBLE_IOCTL(PPPOEIOCSFWD) +-COMPATIBLE_IOCTL(PPPOEIOCDFWD) + /* Big A */ + /* sparc only */ + /* Big Q for sound/OSS */ +diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h +index 8b728750a625..69e813bcb947 100644 +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -80,6 +80,9 @@ extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp); + extern void unregister_pppox_proto(int proto_num); + extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ + extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); ++extern int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); ++ ++#define PPPOEIOCSFWD32 _IOW(0xB1 ,0, compat_size_t) + + /* PPPoX socket states */ + enum { +diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h +index e690ba0f965c..70185079f83e 100644 +--- a/include/linux/mlx5/fs.h ++++ b/include/linux/mlx5/fs.h +@@ -211,6 +211,7 @@ int mlx5_modify_rule_destination(struct mlx5_flow_handle *handler, + + struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging); + void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter); ++u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter); + void mlx5_fc_query_cached(struct mlx5_fc *counter, + u64 *bytes, u64 *packets, u64 *lastuse); + int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter, +diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h +index 7e42efa143a0..29b55f8cd7b3 100644 +--- a/include/linux/mlx5/mlx5_ifc.h ++++ b/include/linux/mlx5/mlx5_ifc.h +@@ -5865,10 +5865,12 @@ struct mlx5_ifc_modify_cq_in_bits { + + struct mlx5_ifc_cqc_bits cq_context; + +- u8 reserved_at_280[0x40]; ++ u8 reserved_at_280[0x60]; + + u8 cq_umem_valid[0x1]; +- u8 reserved_at_2c1[0x5bf]; ++ u8 reserved_at_2e1[0x1f]; ++ ++ u8 reserved_at_300[0x580]; + + u8 pas[0][0x40]; + }; +diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h +index c50fb297e265..e89a922ee849 100644 +--- a/include/scsi/libfcoe.h ++++ b/include/scsi/libfcoe.h +@@ -229,6 +229,7 @@ struct fcoe_fcf { + * @vn_mac: VN_Node assigned MAC address for data + */ + struct fcoe_rport { ++ struct fc_rport_priv rdata; + unsigned long time; + u16 fcoe_len; + u16 flags; +diff --git a/net/bridge/br.c b/net/bridge/br.c +index d164f63a4345..8a8f9e5f264f 100644 +--- a/net/bridge/br.c ++++ b/net/bridge/br.c +@@ -37,12 +37,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v + int err; + + if (dev->priv_flags & IFF_EBRIDGE) { ++ err = br_vlan_bridge_event(dev, event, ptr); ++ if (err) ++ return notifier_from_errno(err); ++ + if (event == NETDEV_REGISTER) { + /* register of bridge completed, add sysfs entries */ + br_sysfs_addbr(dev); + return NOTIFY_DONE; + } +- br_vlan_bridge_event(dev, event, ptr); + } + + /* not a port of a bridge */ +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 3d8deac2353d..f8cac3702712 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1388,6 +1388,9 @@ br_multicast_leave_group(struct net_bridge *br, + if (!br_port_group_equal(p, port, src)) + continue; + ++ if (p->flags & MDB_PG_FLAGS_PERMANENT) ++ break; ++ + rcu_assign_pointer(*pp, p->next); + hlist_del_init(&p->mglist); + del_timer(&p->timer); +diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h +index 159a0e2cb0f6..9564a953bdf9 100644 +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -893,8 +893,8 @@ int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask); + void br_vlan_get_stats(const struct net_bridge_vlan *v, + struct br_vlan_stats *stats); + void br_vlan_port_event(struct net_bridge_port *p, unsigned long event); +-void br_vlan_bridge_event(struct net_device *dev, unsigned long event, +- void *ptr); ++int br_vlan_bridge_event(struct net_device *dev, unsigned long event, ++ void *ptr); + + static inline struct net_bridge_vlan_group *br_vlan_group( + const struct net_bridge *br) +@@ -1084,9 +1084,10 @@ static inline void br_vlan_port_event(struct net_bridge_port *p, + { + } + +-static inline void br_vlan_bridge_event(struct net_device *dev, +- unsigned long event, void *ptr) ++static inline int br_vlan_bridge_event(struct net_device *dev, ++ unsigned long event, void *ptr) + { ++ return 0; + } + #endif + +diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c +index f47f526b4f19..6b2c48b07e04 100644 +--- a/net/bridge/br_vlan.c ++++ b/net/bridge/br_vlan.c +@@ -1043,7 +1043,6 @@ int br_vlan_init(struct net_bridge *br) + { + struct net_bridge_vlan_group *vg; + int ret = -ENOMEM; +- bool changed; + + vg = kzalloc(sizeof(*vg), GFP_KERNEL); + if (!vg) +@@ -1058,17 +1057,10 @@ int br_vlan_init(struct net_bridge *br) + br->vlan_proto = htons(ETH_P_8021Q); + br->default_pvid = 1; + rcu_assign_pointer(br->vlgrp, vg); +- ret = br_vlan_add(br, 1, +- BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED | +- BRIDGE_VLAN_INFO_BRENTRY, &changed, NULL); +- if (ret) +- goto err_vlan_add; + + out: + return ret; + +-err_vlan_add: +- vlan_tunnel_deinit(vg); + err_tunnel_init: + rhashtable_destroy(&vg->vlan_hash); + err_rhtbl: +@@ -1443,13 +1435,23 @@ static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid) + } + + /* Must be protected by RTNL. */ +-void br_vlan_bridge_event(struct net_device *dev, unsigned long event, +- void *ptr) ++int br_vlan_bridge_event(struct net_device *dev, unsigned long event, void *ptr) + { + struct netdev_notifier_changeupper_info *info; +- struct net_bridge *br; ++ struct net_bridge *br = netdev_priv(dev); ++ bool changed; ++ int ret = 0; + + switch (event) { ++ case NETDEV_REGISTER: ++ ret = br_vlan_add(br, br->default_pvid, ++ BRIDGE_VLAN_INFO_PVID | ++ BRIDGE_VLAN_INFO_UNTAGGED | ++ BRIDGE_VLAN_INFO_BRENTRY, &changed, NULL); ++ break; ++ case NETDEV_UNREGISTER: ++ br_vlan_delete(br, br->default_pvid); ++ break; + case NETDEV_CHANGEUPPER: + info = ptr; + br_vlan_upper_change(dev, info->upper_dev, info->linking); +@@ -1457,12 +1459,13 @@ void br_vlan_bridge_event(struct net_device *dev, unsigned long event, + + case NETDEV_CHANGE: + case NETDEV_UP: +- br = netdev_priv(dev); + if (!br_opt_get(br, BROPT_VLAN_BRIDGE_BINDING)) +- return; ++ break; + br_vlan_link_state_change(dev, br); + break; + } ++ ++ return ret; + } + + /* Must be protected by RTNL. */ +diff --git a/net/core/dev.c b/net/core/dev.c +index d6edd218babd..29fcff2c3d51 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4382,12 +4382,17 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, + + act = bpf_prog_run_xdp(xdp_prog, xdp); + ++ /* check if bpf_xdp_adjust_head was used */ + off = xdp->data - orig_data; +- if (off > 0) +- __skb_pull(skb, off); +- else if (off < 0) +- __skb_push(skb, -off); +- skb->mac_header += off; ++ if (off) { ++ if (off > 0) ++ __skb_pull(skb, off); ++ else if (off < 0) ++ __skb_push(skb, -off); ++ ++ skb->mac_header += off; ++ skb_reset_network_header(skb); ++ } + + /* check if bpf_xdp_adjust_tail was used. it can only "shrink" + * pckt. +@@ -9711,6 +9716,8 @@ static void __net_exit default_device_exit(struct net *net) + + /* Push remaining network devices to init_net */ + snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex); ++ if (__dev_get_by_name(&init_net, fb_name)) ++ snprintf(fb_name, IFNAMSIZ, "dev%%d"); + err = dev_change_net_namespace(dev, &init_net, fb_name); + if (err) { + pr_emerg("%s: failed to move %s to init_net: %d\n", +diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c +index 43adfc1641ba..2f01cf6fa0de 100644 +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -275,6 +275,9 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, + const struct iphdr *tiph = &tunnel->parms.iph; + u8 ipproto; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_error; ++ + switch (skb->protocol) { + case htons(ETH_P_IP): + ipproto = IPPROTO_IPIP; +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index c2049c72f3e5..dd2d0b963260 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -660,12 +660,13 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *skb, + struct flowi6 *fl6, __u8 *dsfield, + int *encap_limit) + { +- struct ipv6hdr *ipv6h = ipv6_hdr(skb); ++ struct ipv6hdr *ipv6h; + struct ip6_tnl *t = netdev_priv(dev); + __u16 offset; + + offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); + /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ ++ ipv6h = ipv6_hdr(skb); + + if (offset > 0) { + struct ipv6_tlv_tnl_enc_lim *tel; +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index b80fde1bc005..d10a9e40729f 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1278,12 +1278,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) + } + + fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); ++ dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); + + if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) + return -1; + +- dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); +- + skb_set_inner_ipproto(skb, IPPROTO_IPIP); + + err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, +@@ -1367,12 +1366,11 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) + } + + fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); ++ dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h)); + + if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) + return -1; + +- dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h)); +- + skb_set_inner_ipproto(skb, IPPROTO_IPV6); + + err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 1d0e5904dedf..c54cb59593ef 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1681,6 +1681,9 @@ static const struct proto_ops pppol2tp_ops = { + .recvmsg = pppol2tp_recvmsg, + .mmap = sock_no_mmap, + .ioctl = pppox_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = pppox_compat_ioctl, ++#endif + }; + + static const struct pppox_proto pppol2tp_proto = { +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index 06aac0aaae64..8dc6580e1787 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1222,7 +1222,6 @@ static void ieee80211_if_setup(struct net_device *dev) + static void ieee80211_if_setup_no_queue(struct net_device *dev) + { + ieee80211_if_setup(dev); +- dev->features |= NETIF_F_LLTX; + dev->priv_flags |= IFF_NO_QUEUE; + } + +diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c +index 8126b26f125e..fd1f7e799e23 100644 +--- a/net/sched/act_bpf.c ++++ b/net/sched/act_bpf.c +@@ -285,6 +285,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, + struct tcf_bpf *prog; + bool is_bpf, is_ebpf; + int ret, res = 0; ++ u32 index; + + if (!nla) + return -EINVAL; +@@ -298,13 +299,13 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, + return -EINVAL; + + parm = nla_data(tb[TCA_ACT_BPF_PARMS]); +- +- ret = tcf_idr_check_alloc(tn, &parm->index, act, bind); ++ index = parm->index; ++ ret = tcf_idr_check_alloc(tn, &index, act, bind); + if (!ret) { +- ret = tcf_idr_create(tn, parm->index, est, act, ++ ret = tcf_idr_create(tn, index, est, act, + &act_bpf_ops, bind, true); + if (ret < 0) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c +index ce36b0f7e1dc..32ac04d77a45 100644 +--- a/net/sched/act_connmark.c ++++ b/net/sched/act_connmark.c +@@ -103,6 +103,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, + struct tcf_connmark_info *ci; + struct tc_connmark *parm; + int ret = 0, err; ++ u32 index; + + if (!nla) + return -EINVAL; +@@ -116,13 +117,13 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, + return -EINVAL; + + parm = nla_data(tb[TCA_CONNMARK_PARMS]); +- +- ret = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ ret = tcf_idr_check_alloc(tn, &index, a, bind); + if (!ret) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_connmark_ops, bind, false); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c +index 621fb22ce2a9..9b9288267a54 100644 +--- a/net/sched/act_csum.c ++++ b/net/sched/act_csum.c +@@ -52,6 +52,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, + struct tc_csum *parm; + struct tcf_csum *p; + int ret = 0, err; ++ u32 index; + + if (nla == NULL) + return -EINVAL; +@@ -64,13 +65,13 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, + if (tb[TCA_CSUM_PARMS] == NULL) + return -EINVAL; + parm = nla_data(tb[TCA_CSUM_PARMS]); +- +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (!err) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_csum_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c +index b2380c5284e6..8f0140c6ca58 100644 +--- a/net/sched/act_gact.c ++++ b/net/sched/act_gact.c +@@ -61,6 +61,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, + struct tc_gact *parm; + struct tcf_gact *gact; + int ret = 0; ++ u32 index; + int err; + #ifdef CONFIG_GACT_PROB + struct tc_gact_p *p_parm = NULL; +@@ -77,6 +78,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, + if (tb[TCA_GACT_PARMS] == NULL) + return -EINVAL; + parm = nla_data(tb[TCA_GACT_PARMS]); ++ index = parm->index; + + #ifndef CONFIG_GACT_PROB + if (tb[TCA_GACT_PROB] != NULL) +@@ -94,12 +96,12 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, + } + #endif + +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (!err) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_gact_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c +index 41d5398dd2f2..92ee853d43e6 100644 +--- a/net/sched/act_ife.c ++++ b/net/sched/act_ife.c +@@ -479,8 +479,14 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, + u8 *saddr = NULL; + bool exists = false; + int ret = 0; ++ u32 index; + int err; + ++ if (!nla) { ++ NL_SET_ERR_MSG_MOD(extack, "IFE requires attributes to be passed"); ++ return -EINVAL; ++ } ++ + err = nla_parse_nested_deprecated(tb, TCA_IFE_MAX, nla, ife_policy, + NULL); + if (err < 0) +@@ -502,7 +508,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, + if (!p) + return -ENOMEM; + +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) { + kfree(p); + return err; +@@ -514,10 +521,10 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, + } + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, &act_ife_ops, ++ ret = tcf_idr_create(tn, index, est, a, &act_ife_ops, + bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + kfree(p); + return ret; + } +diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c +index 58e7573dded4..d10dca7a13e1 100644 +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -101,6 +101,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, + struct net_device *dev; + bool exists = false; + int ret, err; ++ u32 index; + + if (!nla) { + NL_SET_ERR_MSG_MOD(extack, "Mirred requires attributes to be passed"); +@@ -115,8 +116,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, + return -EINVAL; + } + parm = nla_data(tb[TCA_MIRRED_PARMS]); +- +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -133,21 +134,21 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + NL_SET_ERR_MSG_MOD(extack, "Unknown mirred option"); + return -EINVAL; + } + + if (!exists) { + if (!parm->ifindex) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + NL_SET_ERR_MSG_MOD(extack, "Specified device does not exist"); + return -EINVAL; + } +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_mirred_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c +index 45923ebb7a4f..7b858c11b1b5 100644 +--- a/net/sched/act_nat.c ++++ b/net/sched/act_nat.c +@@ -44,6 +44,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, + struct tc_nat *parm; + int ret = 0, err; + struct tcf_nat *p; ++ u32 index; + + if (nla == NULL) + return -EINVAL; +@@ -56,13 +57,13 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, + if (tb[TCA_NAT_PARMS] == NULL) + return -EINVAL; + parm = nla_data(tb[TCA_NAT_PARMS]); +- +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (!err) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_nat_ops, bind, false); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c +index 45e9d6bfddb3..17360c6faeaa 100644 +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -149,6 +149,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, + struct tcf_pedit *p; + int ret = 0, err; + int ksize; ++ u32 index; + + if (!nla) { + NL_SET_ERR_MSG_MOD(extack, "Pedit requires attributes to be passed"); +@@ -179,18 +180,19 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, + if (IS_ERR(keys_ex)) + return PTR_ERR(keys_ex); + +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (!err) { + if (!parm->nkeys) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed"); + ret = -EINVAL; + goto out_free; + } +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_pedit_ops, bind, false); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + goto out_free; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_police.c b/net/sched/act_police.c +index a065f62fa79c..49cec3e64a4d 100644 +--- a/net/sched/act_police.c ++++ b/net/sched/act_police.c +@@ -57,6 +57,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, + struct tc_action_net *tn = net_generic(net, police_net_id); + struct tcf_police_params *new; + bool exists = false; ++ u32 index; + + if (nla == NULL) + return -EINVAL; +@@ -73,7 +74,8 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, + return -EINVAL; + + parm = nla_data(tb[TCA_POLICE_TBF]); +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -81,10 +83,10 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, + return 0; + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, NULL, a, ++ ret = tcf_idr_create(tn, index, NULL, a, + &act_police_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c +index 274d7a0c0e25..595308d60133 100644 +--- a/net/sched/act_sample.c ++++ b/net/sched/act_sample.c +@@ -41,8 +41,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, + struct tc_action_net *tn = net_generic(net, sample_net_id); + struct nlattr *tb[TCA_SAMPLE_MAX + 1]; + struct psample_group *psample_group; ++ u32 psample_group_num, rate, index; + struct tcf_chain *goto_ch = NULL; +- u32 psample_group_num, rate; + struct tc_sample *parm; + struct tcf_sample *s; + bool exists = false; +@@ -59,8 +59,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, + return -EINVAL; + + parm = nla_data(tb[TCA_SAMPLE_PARMS]); +- +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -68,10 +68,10 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, + return 0; + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_sample_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + ret = ACT_P_CREATED; +diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c +index f28ddbabff76..33aefa25b545 100644 +--- a/net/sched/act_simple.c ++++ b/net/sched/act_simple.c +@@ -95,6 +95,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, + struct tcf_defact *d; + bool exists = false; + int ret = 0, err; ++ u32 index; + + if (nla == NULL) + return -EINVAL; +@@ -108,7 +109,8 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, + return -EINVAL; + + parm = nla_data(tb[TCA_DEF_PARMS]); +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -119,15 +121,15 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -EINVAL; + } + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_simp_ops, bind, false); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c +index 215a06705cef..b100870f02a6 100644 +--- a/net/sched/act_skbedit.c ++++ b/net/sched/act_skbedit.c +@@ -99,6 +99,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, + u16 *queue_mapping = NULL, *ptype = NULL; + bool exists = false; + int ret = 0, err; ++ u32 index; + + if (nla == NULL) + return -EINVAL; +@@ -146,8 +147,8 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, + } + + parm = nla_data(tb[TCA_SKBEDIT_PARMS]); +- +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -158,15 +159,15 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -EINVAL; + } + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_skbedit_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c +index 4f07706eff07..7da3518e18ef 100644 +--- a/net/sched/act_skbmod.c ++++ b/net/sched/act_skbmod.c +@@ -87,12 +87,12 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, + struct tcf_skbmod_params *p, *p_old; + struct tcf_chain *goto_ch = NULL; + struct tc_skbmod *parm; ++ u32 lflags = 0, index; + struct tcf_skbmod *d; + bool exists = false; + u8 *daddr = NULL; + u8 *saddr = NULL; + u16 eth_type = 0; +- u32 lflags = 0; + int ret = 0, err; + + if (!nla) +@@ -122,10 +122,11 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, + } + + parm = nla_data(tb[TCA_SKBMOD_PARMS]); ++ index = parm->index; + if (parm->flags & SKBMOD_F_SWAPMAC) + lflags = SKBMOD_F_SWAPMAC; + +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -136,15 +137,15 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -EINVAL; + } + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_skbmod_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c +index 10dffda1d5cc..6d0debdc9b97 100644 +--- a/net/sched/act_tunnel_key.c ++++ b/net/sched/act_tunnel_key.c +@@ -225,6 +225,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, + __be16 flags = 0; + u8 tos, ttl; + int ret = 0; ++ u32 index; + int err; + + if (!nla) { +@@ -245,7 +246,8 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, + } + + parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]); +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -345,7 +347,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, + } + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_tunnel_key_ops, bind, true); + if (ret) { + NL_SET_ERR_MSG(extack, "Cannot create TC IDR"); +@@ -403,7 +405,7 @@ err_out: + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c +index 9269d350fb8a..a3c9eea1ee8a 100644 +--- a/net/sched/act_vlan.c ++++ b/net/sched/act_vlan.c +@@ -116,6 +116,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, + u8 push_prio = 0; + bool exists = false; + int ret = 0, err; ++ u32 index; + + if (!nla) + return -EINVAL; +@@ -128,7 +129,8 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, + if (!tb[TCA_VLAN_PARMS]) + return -EINVAL; + parm = nla_data(tb[TCA_VLAN_PARMS]); +- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); ++ index = parm->index; ++ err = tcf_idr_check_alloc(tn, &index, a, bind); + if (err < 0) + return err; + exists = err; +@@ -144,7 +146,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -EINVAL; + } + push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]); +@@ -152,7 +154,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -ERANGE; + } + +@@ -166,7 +168,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -EPROTONOSUPPORT; + } + } else { +@@ -180,16 +182,16 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, + if (exists) + tcf_idr_release(*a, bind); + else +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return -EINVAL; + } + action = parm->v_action; + + if (!exists) { +- ret = tcf_idr_create(tn, parm->index, est, a, ++ ret = tcf_idr_create(tn, index, est, a, + &act_vlan_ops, bind, true); + if (ret) { +- tcf_idr_cleanup(tn, parm->index); ++ tcf_idr_cleanup(tn, index); + return ret; + } + +@@ -306,6 +308,14 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index) + return tcf_idr_search(tn, a, index); + } + ++static size_t tcf_vlan_get_fill_size(const struct tc_action *act) ++{ ++ return nla_total_size(sizeof(struct tc_vlan)) ++ + nla_total_size(sizeof(u16)) /* TCA_VLAN_PUSH_VLAN_ID */ ++ + nla_total_size(sizeof(u16)) /* TCA_VLAN_PUSH_VLAN_PROTOCOL */ ++ + nla_total_size(sizeof(u8)); /* TCA_VLAN_PUSH_VLAN_PRIORITY */ ++} ++ + static struct tc_action_ops act_vlan_ops = { + .kind = "vlan", + .id = TCA_ID_VLAN, +@@ -315,6 +325,7 @@ static struct tc_action_ops act_vlan_ops = { + .init = tcf_vlan_init, + .cleanup = tcf_vlan_cleanup, + .walk = tcf_vlan_walker, ++ .get_fill_size = tcf_vlan_get_fill_size, + .lookup = tcf_vlan_search, + .size = sizeof(struct tcf_vlan), + }; +diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c +index 25ef172c23df..30169b3adbbb 100644 +--- a/net/sched/sch_codel.c ++++ b/net/sched/sch_codel.c +@@ -71,10 +71,10 @@ static struct sk_buff *dequeue_func(struct codel_vars *vars, void *ctx) + struct Qdisc *sch = ctx; + struct sk_buff *skb = __qdisc_dequeue_head(&sch->q); + +- if (skb) ++ if (skb) { + sch->qstats.backlog -= qdisc_pkt_len(skb); +- +- prefetch(&skb->end); /* we'll need skb_shinfo() */ ++ prefetch(&skb->end); /* we'll need skb_shinfo() */ ++ } + return skb; + } + +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 7621ec2f539c..a3cc879d2589 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -253,7 +253,7 @@ static int smc_bind(struct socket *sock, struct sockaddr *uaddr, + + /* Check if socket is already active */ + rc = -EINVAL; +- if (sk->sk_state != SMC_INIT) ++ if (sk->sk_state != SMC_INIT || smc->connect_nonblock) + goto out_rel; + + smc->clcsock->sk->sk_reuse = sk->sk_reuse; +@@ -1399,7 +1399,8 @@ static int smc_listen(struct socket *sock, int backlog) + lock_sock(sk); + + rc = -EINVAL; +- if ((sk->sk_state != SMC_INIT) && (sk->sk_state != SMC_LISTEN)) ++ if ((sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) || ++ smc->connect_nonblock) + goto out; + + rc = 0; +@@ -1527,7 +1528,7 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + goto out; + + if (msg->msg_flags & MSG_FASTOPEN) { +- if (sk->sk_state == SMC_INIT) { ++ if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) { + smc_switch_to_fallback(smc); + smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; + } else { +@@ -1741,14 +1742,18 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, + } + break; + case TCP_NODELAY: +- if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) { ++ if (sk->sk_state != SMC_INIT && ++ sk->sk_state != SMC_LISTEN && ++ sk->sk_state != SMC_CLOSED) { + if (val && !smc->use_fallback) + mod_delayed_work(system_wq, &smc->conn.tx_work, + 0); + } + break; + case TCP_CORK: +- if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) { ++ if (sk->sk_state != SMC_INIT && ++ sk->sk_state != SMC_LISTEN && ++ sk->sk_state != SMC_CLOSED) { + if (!val && !smc->use_fallback) + mod_delayed_work(system_wq, &smc->conn.tx_work, + 0); +diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c +index cf155061c472..acd8a72169c1 100644 +--- a/net/tipc/netlink_compat.c ++++ b/net/tipc/netlink_compat.c +@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg { + int rep_type; + int rep_size; + int req_type; ++ int req_size; + struct net *net; + struct sk_buff *rep; + struct tlv_desc *req; +@@ -257,7 +258,8 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, + int err; + struct sk_buff *arg; + +- if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) ++ if (msg->req_type && (!msg->req_size || ++ !TLV_CHECK_TYPE(msg->req, msg->req_type))) + return -EINVAL; + + msg->rep = tipc_tlv_alloc(msg->rep_size); +@@ -354,7 +356,8 @@ static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, + { + int err; + +- if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) ++ if (msg->req_type && (!msg->req_size || ++ !TLV_CHECK_TYPE(msg->req, msg->req_type))) + return -EINVAL; + + err = __tipc_nl_compat_doit(cmd, msg); +@@ -1288,8 +1291,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) + goto send; + } + +- len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); +- if (!len || !TLV_OK(msg.req, len)) { ++ msg.req_size = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); ++ if (msg.req_size && !TLV_OK(msg.req, msg.req_size)) { + msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); + err = -EOPNOTSUPP; + goto send; +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index dd8537f988c4..83ae41d7e554 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -485,9 +485,8 @@ static int tipc_sk_create(struct net *net, struct socket *sock, + tsk_set_unreturnable(tsk, true); + if (sock->type == SOCK_DGRAM) + tsk_set_unreliable(tsk, true); +- __skb_queue_head_init(&tsk->mc_method.deferredq); + } +- ++ __skb_queue_head_init(&tsk->mc_method.deferredq); + trace_tipc_sk_create(sk, NULL, TIPC_DUMP_NONE, " "); + return 0; + } +diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c +index 62dcdf082349..6c81a911fc02 100644 +--- a/net/vmw_vsock/hyperv_transport.c ++++ b/net/vmw_vsock/hyperv_transport.c +@@ -311,6 +311,11 @@ static void hvs_close_connection(struct vmbus_channel *chan) + lock_sock(sk); + hvs_do_close_lock_held(vsock_sk(sk), true); + release_sock(sk); ++ ++ /* Release the refcnt for the channel that's opened in ++ * hvs_open_connection(). ++ */ ++ sock_put(sk); + } + + static void hvs_open_connection(struct vmbus_channel *chan) +@@ -378,6 +383,9 @@ static void hvs_open_connection(struct vmbus_channel *chan) + } + + set_per_channel_state(chan, conn_from_host ? new : sk); ++ ++ /* This reference will be dropped by hvs_close_connection(). */ ++ sock_hold(conn_from_host ? new : sk); + vmbus_set_chn_rescind_callback(chan, hvs_close_connection); + + /* Set the pending send size to max packet size to always get +diff --git a/sound/usb/helper.c b/sound/usb/helper.c +index 84aa265dd802..4c12cc5b53fd 100644 +--- a/sound/usb/helper.c ++++ b/sound/usb/helper.c +@@ -63,6 +63,20 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype + return NULL; + } + ++/* check the validity of pipe and EP types */ ++int snd_usb_pipe_sanity_check(struct usb_device *dev, unsigned int pipe) ++{ ++ static const int pipetypes[4] = { ++ PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT ++ }; ++ struct usb_host_endpoint *ep; ++ ++ ep = usb_pipe_endpoint(dev, pipe); ++ if (!ep || usb_pipetype(pipe) != pipetypes[usb_endpoint_type(&ep->desc)]) ++ return -EINVAL; ++ return 0; ++} ++ + /* + * Wrapper for usb_control_msg(). + * Allocates a temp buffer to prevent dmaing from/to the stack. +@@ -75,6 +89,9 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, + void *buf = NULL; + int timeout; + ++ if (snd_usb_pipe_sanity_check(dev, pipe)) ++ return -EINVAL; ++ + if (size > 0) { + buf = kmemdup(data, size, GFP_KERNEL); + if (!buf) +diff --git a/sound/usb/helper.h b/sound/usb/helper.h +index d338bd0e0ca6..6afb70156ec4 100644 +--- a/sound/usb/helper.h ++++ b/sound/usb/helper.h +@@ -7,6 +7,7 @@ unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size); + void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype); + void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype); + ++int snd_usb_pipe_sanity_check(struct usb_device *dev, unsigned int pipe); + int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, + __u8 request, __u8 requesttype, __u16 value, __u16 index, + void *data, __u16 size); +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index cf5cff10c08e..78858918cbc1 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -828,11 +828,13 @@ static int snd_usb_novation_boot_quirk(struct usb_device *dev) + static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev) + { + int err, actual_length; +- + /* "midi send" enable */ + static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 }; ++ void *buf; + +- void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL); ++ if (snd_usb_pipe_sanity_check(dev, usb_sndintpipe(dev, 0x05))) ++ return -EINVAL; ++ buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL); + if (!buf) + return -ENOMEM; + err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf, +@@ -857,7 +859,11 @@ static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev) + + static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) + { +- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ++ int ret; ++ ++ if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0))) ++ return -EINVAL; ++ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 0, NULL, 0, 1000); + +@@ -964,6 +970,8 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev) + + dev_dbg(&dev->dev, "Waiting for Axe-Fx III to boot up...\n"); + ++ if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0))) ++ return -EINVAL; + /* If the Axe-Fx III has not fully booted, it will timeout when trying + * to enable the audio streaming interface. A more generous timeout is + * used here to detect when the Axe-Fx III has finished booting as the +@@ -996,6 +1004,8 @@ static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf, + { + int err, actual_length; + ++ if (snd_usb_pipe_sanity_check(dev, usb_sndintpipe(dev, 0x01))) ++ return -EINVAL; + err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x01), buf, *length, + &actual_length, 1000); + if (err < 0) +@@ -1006,6 +1016,8 @@ static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf, + + memset(buf, 0, buf_size); + ++ if (snd_usb_pipe_sanity_check(dev, usb_rcvintpipe(dev, 0x82))) ++ return -EINVAL; + err = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x82), buf, buf_size, + &actual_length, 1000); + if (err < 0) +diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile +index f1573a11d3e4..b9e88ccc289b 100644 +--- a/tools/testing/selftests/bpf/Makefile ++++ b/tools/testing/selftests/bpf/Makefile +@@ -51,7 +51,8 @@ TEST_PROGS := test_kmod.sh \ + test_lirc_mode2.sh \ + test_skb_cgroup_id.sh \ + test_flow_dissector.sh \ +- test_xdp_vlan.sh \ ++ test_xdp_vlan_mode_generic.sh \ ++ test_xdp_vlan_mode_native.sh \ + test_lwt_ip_encap.sh \ + test_tcp_check_syncookie.sh \ + test_tc_tunnel.sh \ +diff --git a/tools/testing/selftests/bpf/test_xdp_vlan.sh b/tools/testing/selftests/bpf/test_xdp_vlan.sh +index 51a3a31d1aac..bb8b0da91686 100755 +--- a/tools/testing/selftests/bpf/test_xdp_vlan.sh ++++ b/tools/testing/selftests/bpf/test_xdp_vlan.sh +@@ -1,6 +1,14 @@ + #!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++# Author: Jesper Dangaard Brouer <h...@kernel.org> + +-TESTNAME=xdp_vlan ++# Allow wrapper scripts to name test ++if [ -z "$TESTNAME" ]; then ++ TESTNAME=xdp_vlan ++fi ++ ++# Default XDP mode ++XDP_MODE=xdpgeneric + + usage() { + echo "Testing XDP + TC eBPF VLAN manipulations: $TESTNAME" +@@ -9,9 +17,23 @@ usage() { + echo " -v | --verbose : Verbose" + echo " --flush : Flush before starting (e.g. after --interactive)" + echo " --interactive : Keep netns setup running after test-run" ++ echo " --mode=XXX : Choose XDP mode (xdp | xdpgeneric | xdpdrv)" + echo "" + } + ++valid_xdp_mode() ++{ ++ local mode=$1 ++ ++ case "$mode" in ++ xdpgeneric | xdpdrv | xdp) ++ return 0 ++ ;; ++ *) ++ return 1 ++ esac ++} ++ + cleanup() + { + local status=$? +@@ -37,7 +59,7 @@ cleanup() + + # Using external program "getopt" to get --long-options + OPTIONS=$(getopt -o hvfi: \ +- --long verbose,flush,help,interactive,debug -- "$@") ++ --long verbose,flush,help,interactive,debug,mode: -- "$@") + if (( $? != 0 )); then + usage + echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?" +@@ -60,6 +82,11 @@ while true; do + cleanup + shift + ;; ++ --mode ) ++ shift ++ XDP_MODE=$1 ++ shift ++ ;; + -- ) + shift + break +@@ -81,8 +108,14 @@ if [ "$EUID" -ne 0 ]; then + exit 1 + fi + +-ip link set dev lo xdp off 2>/dev/null > /dev/null +-if [ $? -ne 0 ];then ++valid_xdp_mode $XDP_MODE ++if [ $? -ne 0 ]; then ++ echo "selftests: $TESTNAME [FAILED] unknown XDP mode ($XDP_MODE)" ++ exit 1 ++fi ++ ++ip link set dev lo xdpgeneric off 2>/dev/null > /dev/null ++if [ $? -ne 0 ]; then + echo "selftests: $TESTNAME [SKIP] need ip xdp support" + exit 0 + fi +@@ -155,7 +188,7 @@ ip netns exec ns2 ip link set lo up + # At this point, the hosts cannot reach each-other, + # because ns2 are using VLAN tags on the packets. + +-ip netns exec ns2 sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Okay ping fails"' ++ip netns exec ns2 sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Success: First ping must fail"' + + + # Now we can use the test_xdp_vlan.c program to pop/push these VLAN tags +@@ -166,7 +199,7 @@ export FILE=test_xdp_vlan.o + + # First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change" + export XDP_PROG=xdp_vlan_change +-ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG ++ip netns exec ns1 ip link set $DEVNS1 $XDP_MODE object $FILE section $XDP_PROG + + # In ns1: egress use TC to add back VLAN tag 4011 + # (del cmd) +@@ -177,8 +210,8 @@ ip netns exec ns1 tc filter add dev $DEVNS1 egress \ + prio 1 handle 1 bpf da obj $FILE sec tc_vlan_push + + # Now the namespaces can reach each-other, test with ping: +-ip netns exec ns2 ping -W 2 -c 3 $IPADDR1 +-ip netns exec ns1 ping -W 2 -c 3 $IPADDR2 ++ip netns exec ns2 ping -i 0.2 -W 2 -c 2 $IPADDR1 ++ip netns exec ns1 ping -i 0.2 -W 2 -c 2 $IPADDR2 + + # Second test: Replace xdp prog, that fully remove vlan header + # +@@ -187,9 +220,9 @@ ip netns exec ns1 ping -W 2 -c 3 $IPADDR2 + # ETH_P_8021Q indication, and this cause overwriting of our changes. + # + export XDP_PROG=xdp_vlan_remove_outer2 +-ip netns exec ns1 ip link set $DEVNS1 xdp off +-ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG ++ip netns exec ns1 ip link set $DEVNS1 $XDP_MODE off ++ip netns exec ns1 ip link set $DEVNS1 $XDP_MODE object $FILE section $XDP_PROG + + # Now the namespaces should still be able reach each-other, test with ping: +-ip netns exec ns2 ping -W 2 -c 3 $IPADDR1 +-ip netns exec ns1 ping -W 2 -c 3 $IPADDR2 ++ip netns exec ns2 ping -i 0.2 -W 2 -c 2 $IPADDR1 ++ip netns exec ns1 ping -i 0.2 -W 2 -c 2 $IPADDR2 +diff --git a/tools/testing/selftests/bpf/test_xdp_vlan_mode_generic.sh b/tools/testing/selftests/bpf/test_xdp_vlan_mode_generic.sh +new file mode 100644 +index 000000000000..c515326d6d59 +--- /dev/null ++++ b/tools/testing/selftests/bpf/test_xdp_vlan_mode_generic.sh +@@ -0,0 +1,9 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++ ++# Exit on failure ++set -e ++ ++# Wrapper script to test generic-XDP ++export TESTNAME=xdp_vlan_mode_generic ++./test_xdp_vlan.sh --mode=xdpgeneric +diff --git a/tools/testing/selftests/bpf/test_xdp_vlan_mode_native.sh b/tools/testing/selftests/bpf/test_xdp_vlan_mode_native.sh +new file mode 100644 +index 000000000000..5cf7ce1f16c1 +--- /dev/null ++++ b/tools/testing/selftests/bpf/test_xdp_vlan_mode_native.sh +@@ -0,0 +1,9 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++ ++# Exit on failure ++set -e ++ ++# Wrapper script to test native-XDP ++export TESTNAME=xdp_vlan_mode_native ++./test_xdp_vlan.sh --mode=xdpdrv