net: liquidio: Add missing null pointer checks
The functions send_rx_ctrl_cmd() in both liquidio/lio_main.c and liquidio/lio_vf_main.c do not check if the call to octeon_alloc_soft_command() fails and returns a null pointer. Both functions also return void so errors are not propagated back to the caller. Fix these issues by updating both instances of send_rx_ctrl_cmd() to return an integer rather than void, and have them return -ENOMEM if an allocation failure occurs. Also update all callers of send_rx_ctrl_cmd() so that they now check the return value. Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Tom Seewald <tseewald@gmail.com> Link: https://lore.kernel.org/r/20210503115736.2104747-66-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4fd798a5a8
commit
dbc97bfd39
2 changed files with 40 additions and 15 deletions
|
@ -1153,7 +1153,7 @@ static void octeon_destroy_resources(struct octeon_device *oct)
|
||||||
* @lio: per-network private data
|
* @lio: per-network private data
|
||||||
* @start_stop: whether to start or stop
|
* @start_stop: whether to start or stop
|
||||||
*/
|
*/
|
||||||
static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
static int send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
||||||
{
|
{
|
||||||
struct octeon_soft_command *sc;
|
struct octeon_soft_command *sc;
|
||||||
union octnet_cmd *ncmd;
|
union octnet_cmd *ncmd;
|
||||||
|
@ -1161,11 +1161,16 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (oct->props[lio->ifidx].rx_on == start_stop)
|
if (oct->props[lio->ifidx].rx_on == start_stop)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
sc = (struct octeon_soft_command *)
|
sc = (struct octeon_soft_command *)
|
||||||
octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE,
|
octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE,
|
||||||
16, 0);
|
16, 0);
|
||||||
|
if (!sc) {
|
||||||
|
netif_info(lio, rx_err, lio->netdev,
|
||||||
|
"Failed to allocate octeon_soft_command struct\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
ncmd = (union octnet_cmd *)sc->virtdptr;
|
ncmd = (union octnet_cmd *)sc->virtdptr;
|
||||||
|
|
||||||
|
@ -1187,18 +1192,19 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
||||||
if (retval == IQ_SEND_FAILED) {
|
if (retval == IQ_SEND_FAILED) {
|
||||||
netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n");
|
netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n");
|
||||||
octeon_free_soft_command(oct, sc);
|
octeon_free_soft_command(oct, sc);
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
/* Sleep on a wait queue till the cond flag indicates that the
|
/* Sleep on a wait queue till the cond flag indicates that the
|
||||||
* response arrived or timed-out.
|
* response arrived or timed-out.
|
||||||
*/
|
*/
|
||||||
retval = wait_for_sc_completion_timeout(oct, sc, 0);
|
retval = wait_for_sc_completion_timeout(oct, sc, 0);
|
||||||
if (retval)
|
if (retval)
|
||||||
return;
|
return retval;
|
||||||
|
|
||||||
oct->props[lio->ifidx].rx_on = start_stop;
|
oct->props[lio->ifidx].rx_on = start_stop;
|
||||||
WRITE_ONCE(sc->caller_is_done, true);
|
WRITE_ONCE(sc->caller_is_done, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1773,6 +1779,7 @@ static int liquidio_open(struct net_device *netdev)
|
||||||
struct octeon_device_priv *oct_priv =
|
struct octeon_device_priv *oct_priv =
|
||||||
(struct octeon_device_priv *)oct->priv;
|
(struct octeon_device_priv *)oct->priv;
|
||||||
struct napi_struct *napi, *n;
|
struct napi_struct *napi, *n;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (oct->props[lio->ifidx].napi_enabled == 0) {
|
if (oct->props[lio->ifidx].napi_enabled == 0) {
|
||||||
tasklet_disable(&oct_priv->droq_tasklet);
|
tasklet_disable(&oct_priv->droq_tasklet);
|
||||||
|
@ -1808,7 +1815,9 @@ static int liquidio_open(struct net_device *netdev)
|
||||||
netif_info(lio, ifup, lio->netdev, "Interface Open, ready for traffic\n");
|
netif_info(lio, ifup, lio->netdev, "Interface Open, ready for traffic\n");
|
||||||
|
|
||||||
/* tell Octeon to start forwarding packets to host */
|
/* tell Octeon to start forwarding packets to host */
|
||||||
send_rx_ctrl_cmd(lio, 1);
|
ret = send_rx_ctrl_cmd(lio, 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* start periodical statistics fetch */
|
/* start periodical statistics fetch */
|
||||||
INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats);
|
INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats);
|
||||||
|
@ -1819,7 +1828,7 @@ static int liquidio_open(struct net_device *netdev)
|
||||||
dev_info(&oct->pci_dev->dev, "%s interface is opened\n",
|
dev_info(&oct->pci_dev->dev, "%s interface is opened\n",
|
||||||
netdev->name);
|
netdev->name);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1833,6 +1842,7 @@ static int liquidio_stop(struct net_device *netdev)
|
||||||
struct octeon_device_priv *oct_priv =
|
struct octeon_device_priv *oct_priv =
|
||||||
(struct octeon_device_priv *)oct->priv;
|
(struct octeon_device_priv *)oct->priv;
|
||||||
struct napi_struct *napi, *n;
|
struct napi_struct *napi, *n;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
ifstate_reset(lio, LIO_IFSTATE_RUNNING);
|
ifstate_reset(lio, LIO_IFSTATE_RUNNING);
|
||||||
|
|
||||||
|
@ -1849,7 +1859,9 @@ static int liquidio_stop(struct net_device *netdev)
|
||||||
lio->link_changes++;
|
lio->link_changes++;
|
||||||
|
|
||||||
/* Tell Octeon that nic interface is down. */
|
/* Tell Octeon that nic interface is down. */
|
||||||
send_rx_ctrl_cmd(lio, 0);
|
ret = send_rx_ctrl_cmd(lio, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (OCTEON_CN23XX_PF(oct)) {
|
if (OCTEON_CN23XX_PF(oct)) {
|
||||||
if (!oct->msix_on)
|
if (!oct->msix_on)
|
||||||
|
@ -1884,7 +1896,7 @@ static int liquidio_stop(struct net_device *netdev)
|
||||||
|
|
||||||
dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name);
|
dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -595,7 +595,7 @@ static void octeon_destroy_resources(struct octeon_device *oct)
|
||||||
* @lio: per-network private data
|
* @lio: per-network private data
|
||||||
* @start_stop: whether to start or stop
|
* @start_stop: whether to start or stop
|
||||||
*/
|
*/
|
||||||
static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
static int send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
||||||
{
|
{
|
||||||
struct octeon_device *oct = (struct octeon_device *)lio->oct_dev;
|
struct octeon_device *oct = (struct octeon_device *)lio->oct_dev;
|
||||||
struct octeon_soft_command *sc;
|
struct octeon_soft_command *sc;
|
||||||
|
@ -603,11 +603,16 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (oct->props[lio->ifidx].rx_on == start_stop)
|
if (oct->props[lio->ifidx].rx_on == start_stop)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
sc = (struct octeon_soft_command *)
|
sc = (struct octeon_soft_command *)
|
||||||
octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE,
|
octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE,
|
||||||
16, 0);
|
16, 0);
|
||||||
|
if (!sc) {
|
||||||
|
netif_info(lio, rx_err, lio->netdev,
|
||||||
|
"Failed to allocate octeon_soft_command struct\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
ncmd = (union octnet_cmd *)sc->virtdptr;
|
ncmd = (union octnet_cmd *)sc->virtdptr;
|
||||||
|
|
||||||
|
@ -635,11 +640,13 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
||||||
*/
|
*/
|
||||||
retval = wait_for_sc_completion_timeout(oct, sc, 0);
|
retval = wait_for_sc_completion_timeout(oct, sc, 0);
|
||||||
if (retval)
|
if (retval)
|
||||||
return;
|
return retval;
|
||||||
|
|
||||||
oct->props[lio->ifidx].rx_on = start_stop;
|
oct->props[lio->ifidx].rx_on = start_stop;
|
||||||
WRITE_ONCE(sc->caller_is_done, true);
|
WRITE_ONCE(sc->caller_is_done, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -906,6 +913,7 @@ static int liquidio_open(struct net_device *netdev)
|
||||||
struct octeon_device_priv *oct_priv =
|
struct octeon_device_priv *oct_priv =
|
||||||
(struct octeon_device_priv *)oct->priv;
|
(struct octeon_device_priv *)oct->priv;
|
||||||
struct napi_struct *napi, *n;
|
struct napi_struct *napi, *n;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!oct->props[lio->ifidx].napi_enabled) {
|
if (!oct->props[lio->ifidx].napi_enabled) {
|
||||||
tasklet_disable(&oct_priv->droq_tasklet);
|
tasklet_disable(&oct_priv->droq_tasklet);
|
||||||
|
@ -932,11 +940,13 @@ static int liquidio_open(struct net_device *netdev)
|
||||||
(LIQUIDIO_NDEV_STATS_POLL_TIME_MS));
|
(LIQUIDIO_NDEV_STATS_POLL_TIME_MS));
|
||||||
|
|
||||||
/* tell Octeon to start forwarding packets to host */
|
/* tell Octeon to start forwarding packets to host */
|
||||||
send_rx_ctrl_cmd(lio, 1);
|
ret = send_rx_ctrl_cmd(lio, 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
dev_info(&oct->pci_dev->dev, "%s interface is opened\n", netdev->name);
|
dev_info(&oct->pci_dev->dev, "%s interface is opened\n", netdev->name);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -950,9 +960,12 @@ static int liquidio_stop(struct net_device *netdev)
|
||||||
struct octeon_device_priv *oct_priv =
|
struct octeon_device_priv *oct_priv =
|
||||||
(struct octeon_device_priv *)oct->priv;
|
(struct octeon_device_priv *)oct->priv;
|
||||||
struct napi_struct *napi, *n;
|
struct napi_struct *napi, *n;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/* tell Octeon to stop forwarding packets to host */
|
/* tell Octeon to stop forwarding packets to host */
|
||||||
send_rx_ctrl_cmd(lio, 0);
|
ret = send_rx_ctrl_cmd(lio, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n");
|
netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n");
|
||||||
/* Inform that netif carrier is down */
|
/* Inform that netif carrier is down */
|
||||||
|
@ -986,7 +999,7 @@ static int liquidio_stop(struct net_device *netdev)
|
||||||
|
|
||||||
dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name);
|
dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue