From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: monok8s Date: Sun, 10 May 2026 00:00:00 +0000 Subject: [PATCH 2/4] cdx: harden FMAN port lookup The DPA userspace loader passes FMC-derived port metadata into the CDX ioctl. If an Ethernet netdev has a partially initialized DPAA private structure, find_osdev_by_fman_params() can dereference a missing mac_dev or FM wrapper pointer while trying to match the FMC port. Add lookup diagnostics and hard NULL guards so a mismatched board model returns -ENODEV instead of oopsing the kernel. --- cdx/devman.c | 85 +++++++++++++++++++++++++++++++++++++-------------- cdx/dpa_cfg.c | 18 ++++++++--- 2 files changed, 76 insertions(+), 27 deletions(-) diff -urN a/cdx/devman.c b/cdx/devman.c --- a/cdx/devman.c 2026-05-10 00:32:28.745375897 +0000 +++ b/cdx/devman.c 2026-05-10 00:32:29.834300280 +0000 @@ -396,39 +396,74 @@ uint32_t speed) { struct net_device *device; - struct dpa_priv_s *priv; - struct mac_device *macdev; + + DPA_INFO("%s::lookup fm %u port %u speed %uG\n", + __func__, fm_idx, port_idx, speed); device = first_net_device(&init_net); - while(1) { - if (!device) - break; - if (device->type == ARPHRD_ETHER) { - t_LnxWrpFmDev *p_LnxWrpFmDev; - priv = netdev_priv(device); - macdev = priv->mac_dev; - if (macdev) { - p_LnxWrpFmDev = (t_LnxWrpFmDev*)macdev->fm; - if (speed == 10) { - //10 gig interfaces upports only SUPPORTED_10000baseT_Full - /*DGW board has 2 fixed-link interfaces - 1 - (eth2)(xDSL)1G Fixed link interface linked to rgmii-txid - 2 - eth5(G.fast)- 1G Fixed link interface linked to sgmii and - connected to 10G link of the board. - sgmii - considered as 1000baseT_Full and this has cell_index = 0*/ - - if ( (!macdev->fixed_link) && (macdev->if_support != SUPPORTED_10000baseT_Full) ) - goto next_device; - } - if ((fm_idx == p_LnxWrpFmDev->id) && - (port_idx == macdev->cell_index)) - return device; - } + while (device) { + struct dpa_priv_s *priv; + struct mac_device *macdev; + t_LnxWrpFmDev *p_LnxWrpFmDev; + + if (device->type != ARPHRD_ETHER) + goto next_device; + + priv = netdev_priv(device); + if (!priv) { + DPA_INFO("%s::skip %s: null private data\n", + __func__, device->name); + goto next_device; + } + + macdev = priv->mac_dev; + if (!macdev) { + DPA_INFO("%s::skip %s: null mac_dev\n", + __func__, device->name); + goto next_device; + } + + if (!macdev->fm) { + DPA_INFO("%s::skip %s: null mac_dev->fm cell_index %u max_speed %u fixed_link %u if_support 0x%x\n", + __func__, device->name, macdev->cell_index, + macdev->max_speed, macdev->fixed_link, + macdev->if_support); + goto next_device; } + + p_LnxWrpFmDev = (t_LnxWrpFmDev *)macdev->fm; + DPA_INFO("%s::candidate %s fm %u cell_index %u max_speed %u fixed_link %u if_support 0x%x\n", + __func__, device->name, p_LnxWrpFmDev->id, + macdev->cell_index, macdev->max_speed, + macdev->fixed_link, macdev->if_support); + + if (speed == 10) { + //10 gig interfaces upports only SUPPORTED_10000baseT_Full + /*DGW board has 2 fixed-link interfaces + 1 - (eth2)(xDSL)1G Fixed link interface linked to rgmii-txid + 2 - eth5(G.fast)- 1G Fixed link interface linked to sgmii and + connected to 10G link of the board. + sgmii - considered as 1000baseT_Full and this has cell_index = 0*/ + + if ((!macdev->fixed_link) && + (macdev->if_support != SUPPORTED_10000baseT_Full)) + goto next_device; + } + + if ((fm_idx == p_LnxWrpFmDev->id) && + (port_idx == macdev->cell_index)) { + DPA_INFO("%s::matched %s for fm %u port %u speed %uG\n", + __func__, device->name, fm_idx, port_idx, speed); + return device; + } + next_device: device = next_net_device(device); } - return device; + + DPA_ERROR("%s::no OS device found for fm %u port %u speed %uG\n", + __func__, fm_idx, port_idx, speed); + return NULL; } diff -urN a/cdx/dpa_cfg.c b/cdx/dpa_cfg.c --- a/cdx/dpa_cfg.c 2026-05-10 00:32:28.757992164 +0000 +++ b/cdx/dpa_cfg.c 2026-05-10 00:32:51.954850425 +0000 @@ -301,15 +301,21 @@ struct net_device *dev; if (port_info->type) { + DPA_INFO("%s::mapping user port %s fm %u index %u portid %u type %uG\n", + __func__, port_info->name, port_info->fm_index, + port_info->index, port_info->portid, port_info->type); dev = find_osdev_by_fman_params(port_info->fm_index, port_info->index, port_info->type); if (!dev) { - DPA_ERROR("%s::could not map port %s\n", - __func__, port_info->name); - return -EIO; - } else { - strcpy(port_info->name, dev->name); + DPA_ERROR("%s::could not map port %s fm %u index %u portid %u type %uG\n", + __func__, port_info->name, + port_info->fm_index, port_info->index, + port_info->portid, port_info->type); + return -ENODEV; } + DPA_INFO("%s::mapped user port %s to netdev %s\n", + __func__, port_info->name, dev->name); + strscpy(port_info->name, dev->name, sizeof(port_info->name)); } #ifdef DPA_CFG_DEBUG DPA_INFO("%s::port %s, fmindex %d, port index %d, port id %d\n",