summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-11 10:17:49 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-11 10:17:49 -0700
commit22e2036479cb77df6281ebbd376ae6c330774790 (patch)
treed872b0d89bf987fe6abf5897d6034baea0b5608f /drivers
parent79f2670da86722d075633d20fa57418994ee6940 (diff)
parent7360b96099806396f4ce15233f6dddcb69248d34 (diff)
Merge tag 'net-7.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni: "Including fixes from IPsec and netfilter. This is relatively small, mostly because we are a bit behind our PW queue. I'm not aware of any pending regression. Current release - regressions: - netfilter: nf_tables_offload: drop device refcount on error Previous releases - regressions: - core: add pskb_may_pull() to skb_gro_receive_list() - xfrm: iptfs: preserve shared-frag marker in iptfs_consume_frags() - ipv6: fix a potential NPD in cleanup_prefix_route() - ipv4: fix use-after-free caused by the fqdir_pre_exit() flush - eth: - bnxt_en: fix NULL pointer dereference - emac: fix use-after-free during device removal - octeontx2-af: fix memory leak in rvu_setup_hw_resources() - tun: zero the whole vnet header in tun_put_user() - sit: reload inner IPv6 header after GSO offloads Previous releases - always broken: - core: fix double-free in netdev_nl_bind_rx_doit() - netfilter: nf_log: validate MAC header was set before dumping it - xfrm: iptfs: fix ABBA deadlock in iptfs_destroy_state() - tcp: restrict SO_ATTACH_FILTER to priv users - mctp: usb: fix race between urb completion and rx_retry cancellation - eth: - mlx5: fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list - mvpp2: sync RX data at the hardware packet offset" * tag 'net-7.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (64 commits) octeontx2-af: fix IP fragment flag corruption on custom KPU profile load ipv6: Fix a potential NPD in cleanup_prefix_route() net: txgbe: initialize PHY interface to 0 net: txgbe: distinguish module types by checking identifier net: txgbe: initialize module info buffer net: mvpp2: build skb from XDP-adjusted data on XDP_PASS net: mvpp2: refill RX buffers before XDP or skb use net: mvpp2: limit XDP frame size to the RX buffer net: mvpp2: sync RX data at the hardware packet offset netfilter: nft_meta_bridge: fix stale stack leak via IIFHWADDR register netfilter: nft_fib: fix stale stack leak via the OIFNAME register netfilter: nft_exthdr: fix register tracking for F_PRESENT flag netfilter: nf_log: validate MAC header was set before dumping it netfilter: x_tables: avoid leaking percpu counter pointers netfilter: nf_conntrack: destroy stale expectfn expectations on unregister netfilter: nf_tables_offload: drop device refcount on error netfilter: revalidate bridge ports rds: mark snapshot pages dirty in rds_info_getsockopt() ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup() ptp: ocp: fix resource freeing order ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.c3
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_com.c5
-rw-r--r--drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c14
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c2
-rw-r--r--drivers/net/ethernet/ibm/emac/core.c9
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dpll.c2
-rw-r--r--drivers/net/ethernet/intel/idpf/idpf_ptp.c2
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c2
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c67
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c72
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/vport.c72
-rw-r--r--drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c24
-rw-r--r--drivers/net/ethernet/wangxun/txgbe/txgbe_type.h3
-rw-r--r--drivers/net/hyperv/netvsc.c19
-rw-r--r--drivers/net/mctp/mctp-usb.c28
-rw-r--r--drivers/net/phy/phy_device.c24
-rw-r--r--drivers/net/tun.c1
-rw-r--r--drivers/net/usb/r8152.c7
-rw-r--r--drivers/ptp/ptp_ocp.c24
24 files changed, 278 insertions, 141 deletions
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index eab6a98d62b9..31cdb11cd78d 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1153,6 +1153,9 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
rmem = of_reserved_mem_lookup(np);
of_node_put(np);
+ if (!rmem)
+ return -ENODEV;
+
dma_addr = rmem->base;
/* Compute the number of hw descriptors according to the
* reserved memory size and the payload buffer size
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
index 8c86789d867a..297fb36ab8c1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -1880,6 +1880,11 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp)
continue;
}
+ /* Ensure PHC payload (timestamp, error_flags) is read
+ * after req_id update is observed
+ */
+ dma_rmb();
+
/* req_id was updated by the device which indicates that
* PHC timestamp and error_flags are updated too,
* checking errors before retrieving timestamp
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
index eb11800f5573..1c9cfec1b633 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
@@ -277,7 +277,7 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
struct hwrm_func_backing_store_qcaps_v2_output *resp;
struct hwrm_func_backing_store_qcaps_v2_input *req;
struct bnge_ctx_mem_info *ctx;
- u16 type;
+ u16 type, next_type;
int rc;
if (bd->ctx)
@@ -294,8 +294,8 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
resp = bnge_hwrm_req_hold(bd, req);
- for (type = 0; type < BNGE_CTX_V2_MAX; ) {
- struct bnge_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
+ for (type = 0; type < BNGE_CTX_INV; type = next_type) {
+ struct bnge_ctx_mem_type *ctxm;
u8 init_val, init_off, i;
__le32 *p;
u32 flags;
@@ -304,8 +304,14 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
rc = bnge_hwrm_req_send(bd, req);
if (rc)
goto ctx_done;
+
+ next_type = le16_to_cpu(resp->next_valid_type);
+ if (type >= BNGE_CTX_V2_MAX)
+ continue;
+
+ ctxm = &ctx->ctx_arr[type];
flags = le32_to_cpu(resp->flags);
- type = le16_to_cpu(resp->next_valid_type);
+
if (!(flags &
FUNC_BACKING_STORE_QCAPS_V2_RESP_FLAGS_TYPE_VALID))
continue;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 35e1f8f663c7..c999f9733326 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5748,7 +5748,7 @@ static void bnxt_disable_int_sync(struct bnxt *bp)
{
int i;
- if (!bp->irq_tbl)
+ if (!bp->irq_tbl || !bp->bnapi)
return;
atomic_inc(&bp->intr_sem);
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 417dfa18daae..4e503b3d0d2d 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -3144,7 +3144,7 @@ static int emac_probe(struct platform_device *ofdev)
netif_carrier_off(ndev);
- err = devm_register_netdev(&ofdev->dev, ndev);
+ err = register_netdev(ndev);
if (err) {
printk(KERN_ERR "%pOF: failed to register net device (%d)!\n",
np, err);
@@ -3197,6 +3197,13 @@ static void emac_remove(struct platform_device *ofdev)
DBG(dev, "remove" NL);
+ /* Unregister network device before tearing down hardware
+ * to prevent use-after-free during deferred cleanup. This ensures
+ * the network stack stops all operations before hardware resources
+ * are released.
+ */
+ unregister_netdev(dev->ndev);
+
cancel_work_sync(&dev->reset_work);
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 892bc7c2e28b..0704e92ab043 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -2633,6 +2633,8 @@ static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
.state_on_dpll_set = ice_dpll_ufl_pin_state_set,
.state_on_dpll_get = ice_dpll_sw_pin_state_get,
.direction_get = ice_dpll_pin_sw_direction_get,
+ .prio_get = ice_dpll_sw_input_prio_get,
+ .prio_set = ice_dpll_sw_input_prio_set,
.frequency_get = ice_dpll_sw_pin_frequency_get,
.frequency_set = ice_dpll_sw_pin_frequency_set,
.esync_set = ice_dpll_sw_esync_set,
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index 4a51d2727547..71fe8b2a8b4e 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -51,7 +51,7 @@ void idpf_ptp_get_features_access(const struct idpf_adapter *adapter)
/* Set the device clock time */
direct = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
- mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
+ mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB;
ptp->set_dev_clk_time_access = idpf_ptp_get_access(adapter,
direct,
mailbox);
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index f9055b3d6fb1..1881583be5ce 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2780,7 +2780,7 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
goto put_err;
}
ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- ppdev->dev.of_node = pnp;
+ ppdev->dev.of_node = of_node_get(pnp);
ret = platform_device_add_resources(ppdev, &res, 1);
if (ret)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index f442b874bb59..ccc24a1301f2 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -3917,10 +3917,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
struct mvpp2_bm_pool *bm_pool;
struct page_pool *pp = NULL;
struct sk_buff *skb;
- unsigned int frag_size;
+ unsigned int frag_size, rx_sync_size;
dma_addr_t dma_addr;
phys_addr_t phys_addr;
- int pool, rx_bytes, err, ret;
+ int pool, rx_bytes, rx_offset, err, ret;
struct page *page;
void *data;
@@ -3933,6 +3933,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
rx_bytes -= MVPP2_MH_SIZE;
+ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
+ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
@@ -3946,9 +3948,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
dma_dir = DMA_FROM_DEVICE;
}
- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
- rx_bytes + MVPP2_MH_SIZE,
- dma_dir);
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+ rx_sync_size,
+ dma_dir);
/* Buffer header not supported */
if (rx_status & MVPP2_RXD_BUF_HDR)
@@ -3970,6 +3973,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
else
frag_size = bm_pool->frag_size;
+ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+ if (err) {
+ netdev_err(port->dev, "failed to refill BM pools\n");
+ goto err_drop_frame;
+ }
+
if (xdp_prog) {
struct xdp_rxq_info *xdp_rxq;
@@ -3978,7 +3987,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
else
xdp_rxq = &rxq->xdp_rxq_long;
- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
+ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
xdp_prepare_buff(&xdp, data,
MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
rx_bytes, true);
@@ -3987,17 +3996,19 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
if (ret) {
xdp_ret |= ret;
- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
- if (err) {
- netdev_err(port->dev, "failed to refill BM pools\n");
- goto err_drop_frame;
- }
-
ps.rx_packets++;
ps.rx_bytes += rx_bytes;
continue;
}
+ rx_sync_size = max_t(unsigned int, rx_sync_size,
+ xdp.data_end - xdp.data_hard_start -
+ MVPP2_SKB_HEADROOM);
+
+ /* Update offset and length to reflect any XDP adjustments. */
+ rx_offset = xdp.data - data;
+ rx_bytes = xdp.data_end - xdp.data;
+
metasize = xdp.data - xdp.data_meta;
}
@@ -4007,8 +4018,20 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
skb = slab_build_skb(data);
if (!skb) {
netdev_warn(port->dev, "skb build failed\n");
- goto err_drop_frame;
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+ DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+ mvpp2_frag_free(bm_pool, pp, data);
+ }
+ goto err_drop_frame_retired;
}
+ if (pp)
+ skb_mark_for_recycle(skb);
/* If we have RX hardware timestamping enabled, grab the
* timestamp from the queue and convert.
@@ -4019,16 +4042,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
skb_hwtstamps(skb));
}
- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
- if (err) {
- netdev_err(port->dev, "failed to refill BM pools\n");
- dev_kfree_skb_any(skb);
- goto err_drop_frame;
- }
-
- if (pp)
- skb_mark_for_recycle(skb);
- else
+ if (!pp)
dma_unmap_single_attrs(dev->dev.parent, dma_addr,
bm_pool->buf_size, DMA_FROM_DEVICE,
DMA_ATTR_SKIP_CPU_SYNC);
@@ -4036,7 +4050,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
ps.rx_packets++;
ps.rx_bytes += rx_bytes;
- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
+ skb_reserve(skb, rx_offset);
skb_put(skb, rx_bytes);
if (metasize)
skb_metadata_set(skb, metasize);
@@ -4047,13 +4061,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
continue;
err_drop_frame:
- dev->stats.rx_errors++;
- mvpp2_rx_error(port, rx_desc);
/* Return the buffer to the pool */
if (rx_status & MVPP2_RXD_BUF_HDR)
mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
else
mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
+err_drop_frame_retired:
+ dev->stats.rx_errors++;
+ mvpp2_rx_error(port, rx_desc);
}
if (xdp_ret & MVPP2_XDP_REDIR)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 6b3f453fd500..fe8c4ffcd8f7 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -1571,53 +1571,49 @@ static u8 npc_map2cn20k_flag(u8 flag)
return 0xff;
}
+static void npc_cn20k_translate_action_flags(struct npc_kpu_profile_action *act)
+{
+ u8 ltype, val;
+
+ if (act->lid != NPC_LID_LC)
+ return;
+
+ ltype = act->ltype;
+ if (ltype != NPC_LT_LC_IP &&
+ ltype != NPC_LT_LC_IP6 &&
+ ltype != NPC_LT_LC_IP_OPT &&
+ ltype != NPC_LT_LC_IP6_EXT)
+ return;
+
+ switch (act->flags) {
+ case NPC_F_LC_U_IP_FRAG:
+ case NPC_F_LC_U_IP6_FRAG:
+ case NPC_F_LC_L_6TO4:
+ case NPC_F_LC_L_MPLS_IN_IP:
+ case NPC_F_LC_L_IP6_TUN_IP6:
+ case NPC_F_LC_L_IP6_MPLS_IN_IP:
+ val = npc_map2cn20k_flag(act->flags);
+ if (val != 0xFF)
+ act->flags = val;
+ break;
+ default:
+ break;
+ }
+}
+
void
npc_cn20k_update_action_entries_n_flags(struct rvu *rvu,
struct npc_kpu_profile_adapter *pfl)
{
struct npc_kpu_profile_action *action;
- int entries, ltype;
- u8 flags, val;
+ int entries;
for (int i = 0; i < pfl->kpus; i++) {
action = pfl->kpu[i].action;
entries = pfl->kpu[i].action_entries;
- for (int j = 0; j < entries; j++) {
- if (action[j].lid != NPC_LID_LC)
- continue;
-
- ltype = action[j].ltype;
-
- if (ltype != NPC_LT_LC_IP &&
- ltype != NPC_LT_LC_IP6 &&
- ltype != NPC_LT_LC_IP_OPT &&
- ltype != NPC_LT_LC_IP6_EXT)
- continue;
-
- flags = action[j].flags;
-
- switch (flags) {
- case NPC_F_LC_U_IP_FRAG:
- case NPC_F_LC_U_IP6_FRAG:
- case NPC_F_LC_L_6TO4:
- case NPC_F_LC_L_MPLS_IN_IP:
- case NPC_F_LC_L_IP6_TUN_IP6:
- case NPC_F_LC_L_IP6_MPLS_IN_IP:
- val = npc_map2cn20k_flag(flags);
- if (val == 0xFF) {
- dev_err(rvu->dev,
- "%s: Error to get flag value\n",
- __func__);
- return;
- }
-
- action[j].flags = val;
- break;
- default:
- break;
- }
- }
+ for (int j = 0; j < entries; j++)
+ npc_cn20k_translate_action_flags(&action[j]);
}
}
@@ -1709,9 +1705,9 @@ int npc_cn20k_apply_custom_kpu(struct rvu *rvu,
for (entry = 0; entry < entries; entry++) {
profile->kpu[kpu].cam[entry] = cam[entry];
profile->kpu[kpu].action[entry] = action[entry];
+ npc_cn20k_translate_action_flags(&profile->kpu[kpu].action[entry]);
}
}
- npc_cn20k_update_action_entries_n_flags(rvu, profile);
return 0;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index 3cf131508ecf..6e907ee19164 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -1160,7 +1160,7 @@ cpt:
err = rvu_npc_exact_init(rvu);
if (err) {
dev_err(rvu->dev, "failed to initialize exact match table\n");
- return err;
+ goto cgx_err;
}
/* Assign MACs for CGX mapped functions */
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index e130e7259275..5c55971abbf0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -290,6 +290,7 @@ static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
{
int entries_per_copy = PAGE_SIZE / cqe_size;
+ size_t copy_bytes;
void *init_ents;
int err = 0;
int i;
@@ -314,8 +315,14 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
buf += PAGE_SIZE;
}
} else {
+ copy_bytes = array_size(entries, cqe_size);
+ if (WARN_ON_ONCE(copy_bytes > PAGE_SIZE)) {
+ err = -EINVAL;
+ goto out;
+ }
+
err = copy_to_user((void __user *)buf, init_ents,
- array_size(entries, cqe_size)) ?
+ copy_bytes) ?
-EFAULT : 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
index d3bab198c99c..d8c7cb8837d7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
@@ -103,9 +103,15 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
xdptxd->dma_addr = dma_addr;
- if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
- mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL)))
+ if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame,
+ mlx5e_xmit_xdp_frame_mpwqe,
+ mlx5e_xmit_xdp_frame,
+ sq, xdptxd, 0, NULL))) {
+ dma_unmap_single(sq->pdev, dma_addr, xdptxd->len,
+ DMA_TO_DEVICE);
+ xdp_return_frame(xdpf);
return false;
+ }
/* xmit_mode == MLX5E_XDP_XMIT_MODE_FRAME */
mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 7c8311f41232..236f89a6483a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -533,23 +533,16 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
struct mlx5_vport *vport, int list_type)
{
bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
- u8 (*mac_list)[ETH_ALEN];
+ u8 (*mac_list)[ETH_ALEN] = NULL;
struct l2addr_node *node;
struct vport_addr *addr;
struct hlist_head *hash;
struct hlist_node *tmp;
- int size;
+ int size = 0;
int err;
int hi;
int i;
- size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
- MLX5_MAX_MC_PER_VPORT(esw->dev);
-
- mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
- if (!mac_list)
- return;
-
hash = is_uc ? vport->uc_list : vport->mc_list;
for_each_l2hash_node(node, tmp, hash, hi) {
@@ -561,7 +554,7 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
goto out;
err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type,
- mac_list, &size);
+ &mac_list, &size);
if (err)
goto out;
esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
index 994fe83da4be..a0bb8ee44e35 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
@@ -105,9 +105,12 @@ irq_pool_find_least_loaded(struct mlx5_irq_pool *pool, const struct cpumask *req
lockdep_assert_held(&pool->lock);
xa_for_each_range(&pool->irqs, index, iter, start, end) {
- struct cpumask *iter_mask = mlx5_irq_get_affinity_mask(iter);
int iter_refcount = mlx5_irq_read_locked(iter);
+ const struct cpumask *iter_mask;
+ iter_mask = irq_get_effective_affinity_mask(mlx5_irq_get_irq(iter));
+ if (!iter_mask)
+ continue;
if (!cpumask_subset(iter_mask, req_mask))
/* skip IRQs with a mask which is not subset of req_mask */
continue;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
index 4effe37fd455..d63b0e8806b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -324,35 +324,63 @@ int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
}
EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
+static int mlx5_vport_max_mac_list_size(struct mlx5_core_dev *dev, u16 vport,
+ enum mlx5_list_type list_type)
+{
+ void *query_ctx, *hca_caps;
+ int ret = 0;
+
+ if (!vport && !mlx5_core_is_ecpf(dev))
+ return list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+ 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+ 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
+
+ query_ctx = kzalloc(MLX5_ST_SZ_BYTES(query_hca_cap_out), GFP_KERNEL);
+ if (!query_ctx)
+ return -ENOMEM;
+
+ ret = mlx5_vport_get_other_func_general_cap(dev, vport, query_ctx);
+ if (ret)
+ goto out;
+
+ hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
+ ret = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_uc_list) :
+ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_mc_list);
+
+out:
+ kfree(query_ctx);
+
+ return ret;
+}
+
int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
u16 vport,
enum mlx5_list_type list_type,
- u8 addr_list[][ETH_ALEN],
- int *list_size)
+ u8 (**addr_list)[ETH_ALEN],
+ int *addr_list_size)
{
u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
+ int allowed_list_size;
void *nic_vport_ctx;
int max_list_size;
- int req_list_size;
int out_sz;
void *out;
int err;
int i;
- req_list_size = *list_size;
+ if (!addr_list || !addr_list_size)
+ return -EINVAL;
- max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
- 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
- 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
+ *addr_list = NULL;
+ *addr_list_size = 0;
- if (req_list_size > max_list_size) {
- mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
- req_list_size, max_list_size);
- req_list_size = max_list_size;
- }
+ max_list_size = mlx5_vport_max_mac_list_size(dev, vport, list_type);
+ if (max_list_size < 0)
+ return max_list_size;
out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) +
- req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+ max_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
out = kvzalloc(out_sz, GFP_KERNEL);
if (!out)
@@ -371,16 +399,24 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
nic_vport_context);
- req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
- allowed_list_size);
+ allowed_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+ allowed_list_size);
+ if (!allowed_list_size)
+ goto out;
+
+ *addr_list = kcalloc(allowed_list_size, ETH_ALEN, GFP_KERNEL);
+ if (!*addr_list) {
+ err = -ENOMEM;
+ goto out;
+ }
- *list_size = req_list_size;
- for (i = 0; i < req_list_size; i++) {
+ for (i = 0; i < allowed_list_size; i++) {
u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
nic_vport_ctx,
current_uc_mac_address[i]) + 2;
- ether_addr_copy(addr_list[i], mac_addr);
+ ether_addr_copy((*addr_list)[i], mac_addr);
}
+ *addr_list_size = allowed_list_size;
out:
kvfree(out);
return err;
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
index f0514251d4f3..8fc32df8e49a 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
@@ -204,7 +204,7 @@ int txgbe_set_phy_link(struct wx *wx)
static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
- DECLARE_PHY_INTERFACE_MASK(interfaces);
+ DECLARE_PHY_INTERFACE_MASK_ZERO(interfaces);
struct txgbe *txgbe = wx->priv;
if (id->cable_tech & TXGBE_SFF_DA_PASSIVE_CABLE) {
@@ -271,7 +271,7 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
static int txgbe_qsfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
- DECLARE_PHY_INTERFACE_MASK(interfaces);
+ DECLARE_PHY_INTERFACE_MASK_ZERO(interfaces);
struct txgbe *txgbe = wx->priv;
if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_CR4) {
@@ -335,7 +335,7 @@ static int txgbe_qsfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
int txgbe_identify_module(struct wx *wx)
{
- struct txgbe_hic_get_module_info buffer;
+ struct txgbe_hic_get_module_info buffer = { 0 };
struct txgbe_sff_id *id;
int err = 0;
u32 mod_abs;
@@ -357,18 +357,16 @@ int txgbe_identify_module(struct wx *wx)
}
id = &buffer.id;
- if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP &&
- id->identifier != TXGBE_SFF_IDENTIFIER_QSFP &&
- id->identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS &&
- id->identifier != TXGBE_SFF_IDENTIFIER_QSFP28) {
- wx_err(wx, "Invalid module\n");
- return -ENODEV;
- }
-
- if (id->transceiver_type == 0xFF)
+ if (id->identifier == TXGBE_SFF_IDENTIFIER_SFP)
return txgbe_sfp_to_linkmodes(wx, id);
- return txgbe_qsfp_to_linkmodes(wx, id);
+ if (id->identifier == TXGBE_SFF_IDENTIFIER_QSFP ||
+ id->identifier == TXGBE_SFF_IDENTIFIER_QSFP_PLUS ||
+ id->identifier == TXGBE_SFF_IDENTIFIER_QSFP28)
+ return txgbe_qsfp_to_linkmodes(wx, id);
+
+ wx_err(wx, "Invalid module\n");
+ return -EINVAL;
}
void txgbe_setup_link(struct wx *wx)
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
index 6b05f32b4a01..877234e3fdc2 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
@@ -315,6 +315,9 @@ void txgbe_up(struct wx *wx);
int txgbe_setup_tc(struct net_device *dev, u8 tc);
void txgbe_do_reset(struct net_device *netdev);
+#define DECLARE_PHY_INTERFACE_MASK_ZERO(name) \
+ unsigned long name[PHY_INTERFACE_MODE_MAX] = { 0, }
+
#define TXGBE_LINK_SPEED_UNKNOWN 0
#define TXGBE_LINK_SPEED_10GB_FULL 4
#define TXGBE_LINK_SPEED_25GB_FULL 0x10
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 59e95341f9b1..4d319c50955e 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/slab.h>
@@ -965,12 +966,22 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device,
}
for (i = 0; i < page_count; i++) {
- char *src = phys_to_virt(pb[i].pfn << HV_HYP_PAGE_SHIFT);
- u32 offset = pb[i].offset;
+ phys_addr_t paddr = (pb[i].pfn << HV_HYP_PAGE_SHIFT) +
+ pb[i].offset;
u32 len = pb[i].len;
- memcpy(dest, (src + offset), len);
- dest += len;
+ while (len) {
+ struct page *page = phys_to_page(paddr);
+ u32 off = offset_in_page(paddr);
+ u32 chunk = min_t(u32, len, PAGE_SIZE - off);
+ char *src = kmap_local_page(page);
+
+ memcpy(dest, src + off, chunk);
+ kunmap_local(src);
+ dest += chunk;
+ paddr += chunk;
+ len -= chunk;
+ }
}
if (padding)
diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
index 3b5dff144177..fade65f2f269 100644
--- a/drivers/net/mctp/mctp-usb.c
+++ b/drivers/net/mctp/mctp-usb.c
@@ -22,7 +22,6 @@
struct mctp_usb {
struct usb_device *usbdev;
struct usb_interface *intf;
- bool stopped;
struct net_device *netdev;
@@ -32,6 +31,9 @@ struct mctp_usb {
struct urb *tx_urb;
struct urb *rx_urb;
+ /* enforces atomic access to rx_stopped and requeuing the retry work */
+ spinlock_t rx_lock;
+ bool rx_stopped;
struct delayed_work rx_retry_work;
};
@@ -122,6 +124,7 @@ static const unsigned long RX_RETRY_DELAY = HZ / 4;
static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
{
+ unsigned long flags;
struct sk_buff *skb;
int rc;
@@ -147,8 +150,11 @@ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
return rc;
err_retry:
- schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
- return rc;
+ spin_lock_irqsave(&mctp_usb->rx_lock, flags);
+ if (!mctp_usb->rx_stopped)
+ schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
+ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
+ return 0;
}
static void mctp_usb_in_complete(struct urb *urb)
@@ -248,9 +254,6 @@ static void mctp_usb_rx_retry_work(struct work_struct *work)
struct mctp_usb *mctp_usb = container_of(work, struct mctp_usb,
rx_retry_work.work);
- if (READ_ONCE(mctp_usb->stopped))
- return;
-
mctp_usb_rx_queue(mctp_usb, GFP_KERNEL);
}
@@ -258,7 +261,7 @@ static int mctp_usb_open(struct net_device *dev)
{
struct mctp_usb *mctp_usb = netdev_priv(dev);
- WRITE_ONCE(mctp_usb->stopped, false);
+ WRITE_ONCE(mctp_usb->rx_stopped, false);
netif_start_queue(dev);
@@ -268,17 +271,21 @@ static int mctp_usb_open(struct net_device *dev)
static int mctp_usb_stop(struct net_device *dev)
{
struct mctp_usb *mctp_usb = netdev_priv(dev);
+ unsigned long flags;
netif_stop_queue(dev);
/* prevent RX submission retry */
- WRITE_ONCE(mctp_usb->stopped, true);
+ spin_lock_irqsave(&mctp_usb->rx_lock, flags);
+ mctp_usb->rx_stopped = true;
+ cancel_delayed_work(&mctp_usb->rx_retry_work);
+ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
+
+ flush_delayed_work(&mctp_usb->rx_retry_work);
usb_kill_urb(mctp_usb->rx_urb);
usb_kill_urb(mctp_usb->tx_urb);
- cancel_delayed_work_sync(&mctp_usb->rx_retry_work);
-
return 0;
}
@@ -331,6 +338,7 @@ static int mctp_usb_probe(struct usb_interface *intf,
dev->netdev = netdev;
dev->usbdev = interface_to_usbdev(intf);
dev->intf = intf;
+ spin_lock_init(&dev->rx_lock);
usb_set_intfdata(intf, dev);
dev->ep_in = ep_in->bEndpointAddress;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3370eb822017..1511385b9b36 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1718,6 +1718,9 @@ static int phy_sfp_probe(struct phy_device *phydev)
ret = sfp_bus_add_upstream(bus, phydev, &sfp_phydev_ops);
sfp_bus_put(bus);
+
+ if (ret)
+ phydev->sfp_bus = NULL;
}
if (!ret && phydev->sfp_bus)
@@ -3509,9 +3512,15 @@ static int phy_setup_ports(struct phy_device *phydev)
if (ret)
return ret;
- ret = phy_sfp_probe(phydev);
- if (ret)
- goto out;
+ /* We don't support SFP with genphy drivers. Also, genphy driver
+ * binding occurs with RTNL help, which will deadlock the call to
+ * sfp_bus_add_upstream().
+ */
+ if (!phydev->is_genphy_driven) {
+ ret = phy_sfp_probe(phydev);
+ if (ret)
+ goto out;
+ }
if (phydev->n_ports < phydev->max_n_ports) {
ret = phy_default_setup_single_port(phydev);
@@ -3775,6 +3784,11 @@ static int phy_probe(struct device *dev)
return 0;
out:
+ sfp_bus_del_upstream(phydev->sfp_bus);
+ phydev->sfp_bus = NULL;
+
+ phy_cleanup_ports(phydev);
+
if (!phydev->is_on_sfp_module)
phy_led_triggers_unregister(phydev);
@@ -3798,11 +3812,11 @@ static int phy_remove(struct device *dev)
phydev->state = PHY_DOWN;
- phy_cleanup_ports(phydev);
-
sfp_bus_del_upstream(phydev->sfp_bus);
phydev->sfp_bus = NULL;
+ phy_cleanup_ports(phydev);
+
if (phydev->drv && phydev->drv->remove)
phydev->drv->remove(phydev);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 9e7744eb57a3..fed9dfdfcc3b 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2070,6 +2070,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
struct virtio_net_hdr_v1_hash_tunnel hdr;
struct virtio_net_hdr *gso;
+ memset(&hdr, 0, sizeof(hdr));
ret = tun_vnet_hdr_tnl_from_skb(tun->flags, tun->dev, skb,
&hdr);
if (ret)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 1ace1d2398c9..b1268553cd70 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -9851,7 +9851,12 @@ static int rtl8152_probe_once(struct usb_interface *intf,
struct net_device *netdev;
int ret;
- usb_reset_device(udev);
+ ret = usb_reset_device(udev);
+ if (ret < 0) {
+ dev_err(&intf->dev, "USB reset failed, errno=%d\n", ret);
+ return ret;
+ }
+
netdev = alloc_etherdev(sizeof(struct r8152));
if (!netdev) {
dev_err(&intf->dev, "Out of memory\n");
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index beacc2ffb166..735385539b9f 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -2479,8 +2479,13 @@ ptp_ocp_ts_enable(void *priv, u32 req, bool enable)
iowrite32(1, &reg->intr_mask);
iowrite32(1, &reg->intr);
} else {
+ int irq_vec = pci_irq_vector(bp->pdev, ext->irq_vec);
+
iowrite32(0, &reg->intr_mask);
iowrite32(0, &reg->enable);
+ ioread32(&reg->intr_mask);
+ if (irq_vec > 0)
+ synchronize_irq(irq_vec);
}
return 0;
@@ -4867,6 +4872,22 @@ ptp_ocp_detach(struct ptp_ocp *bp)
ptp_ocp_detach_sysfs(bp);
ptp_ocp_attr_group_del(bp);
timer_delete_sync(&bp->watchdog);
+ /* Disable interrupts on all timestampers */
+ if (bp->ts0)
+ ptp_ocp_ts_enable(bp->ts0, 0, false);
+ if (bp->ts1)
+ ptp_ocp_ts_enable(bp->ts1, 0, false);
+ if (bp->ts2)
+ ptp_ocp_ts_enable(bp->ts2, 0, false);
+ if (bp->ts3)
+ ptp_ocp_ts_enable(bp->ts3, 0, false);
+ if (bp->ts4)
+ ptp_ocp_ts_enable(bp->ts4, 0, false);
+ if (bp->pps)
+ ptp_ocp_ts_enable(bp->pps, ~0, false);
+ if (bp->ptp)
+ ptp_clock_unregister(bp->ptp);
+ kfree(bp->ptp_info.pin_config);
ptp_ocp_unregister_ext(bp->ts0);
ptp_ocp_unregister_ext(bp->ts1);
ptp_ocp_unregister_ext(bp->ts2);
@@ -4884,9 +4905,6 @@ ptp_ocp_detach(struct ptp_ocp *bp)
clk_hw_unregister_fixed_rate(bp->i2c_clk);
if (bp->n_irqs)
pci_free_irq_vectors(bp->pdev);
- if (bp->ptp)
- ptp_clock_unregister(bp->ptp);
- kfree(bp->ptp_info.pin_config);
device_unregister(&bp->dev);
}