Commit dbc97bfd authored by Tom Seewald's avatar Tom Seewald Committed by Greg Kroah-Hartman

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: default avatarTom Seewald <tseewald@gmail.com>
Link: https://lore.kernel.org/r/20210503115736.2104747-66-gregkh@linuxfoundation.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4fd798a5
...@@ -1153,7 +1153,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment