| From 11ccb2b93320436010e2269175eeae2c1ae011a0 Mon Sep 17 00:00:00 2001 |
| From: Vishal Kulkarni <vishal@chelsio.com> |
| Date: Wed, 30 Oct 2019 20:17:57 +0530 |
| Subject: [PATCH] cxgb4: fix panic when attaching to ULD fail |
| |
| commit fc89cc358fb64e2429aeae0f37906126636507ec upstream. |
| |
| Release resources when attaching to ULD fail. Otherwise, data |
| mismatch is seen between LLD and ULD later on, which lead to |
| kernel panic when accessing resources that should not even |
| exist in the first place. |
| |
| Fixes: 94cdb8bb993a ("cxgb4: Add support for dynamic allocation of resources for ULD") |
| Signed-off-by: Shahjada Abul Husain <shahjada@chelsio.com> |
| Signed-off-by: Vishal Kulkarni <vishal@chelsio.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c |
| index bf17cf3ef613..96d2b7806e28 100644 |
| --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c |
| +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c |
| @@ -686,10 +686,10 @@ static void uld_init(struct adapter *adap, struct cxgb4_lld_info *lld) |
| lld->write_cmpl_support = adap->params.write_cmpl_support; |
| } |
| |
| -static void uld_attach(struct adapter *adap, unsigned int uld) |
| +static int uld_attach(struct adapter *adap, unsigned int uld) |
| { |
| - void *handle; |
| struct cxgb4_lld_info lli; |
| + void *handle; |
| |
| uld_init(adap, &lli); |
| uld_queue_init(adap, uld, &lli); |
| @@ -699,7 +699,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld) |
| dev_warn(adap->pdev_dev, |
| "could not attach to the %s driver, error %ld\n", |
| adap->uld[uld].name, PTR_ERR(handle)); |
| - return; |
| + return PTR_ERR(handle); |
| } |
| |
| adap->uld[uld].handle = handle; |
| @@ -707,22 +707,22 @@ static void uld_attach(struct adapter *adap, unsigned int uld) |
| |
| if (adap->flags & CXGB4_FULL_INIT_DONE) |
| adap->uld[uld].state_change(handle, CXGB4_STATE_UP); |
| + |
| + return 0; |
| } |
| |
| -/** |
| - * cxgb4_register_uld - register an upper-layer driver |
| - * @type: the ULD type |
| - * @p: the ULD methods |
| +/* cxgb4_register_uld - register an upper-layer driver |
| + * @type: the ULD type |
| + * @p: the ULD methods |
| * |
| - * Registers an upper-layer driver with this driver and notifies the ULD |
| - * about any presently available devices that support its type. Returns |
| - * %-EBUSY if a ULD of the same type is already registered. |
| + * Registers an upper-layer driver with this driver and notifies the ULD |
| + * about any presently available devices that support its type. |
| */ |
| void cxgb4_register_uld(enum cxgb4_uld type, |
| const struct cxgb4_uld_info *p) |
| { |
| - int ret = 0; |
| struct adapter *adap; |
| + int ret = 0; |
| |
| if (type >= CXGB4_ULD_MAX) |
| return; |
| @@ -754,8 +754,12 @@ void cxgb4_register_uld(enum cxgb4_uld type, |
| if (ret) |
| goto free_irq; |
| adap->uld[type] = *p; |
| - uld_attach(adap, type); |
| + ret = uld_attach(adap, type); |
| + if (ret) |
| + goto free_txq; |
| continue; |
| +free_txq: |
| + release_sge_txq_uld(adap, type); |
| free_irq: |
| if (adap->flags & CXGB4_FULL_INIT_DONE) |
| quiesce_rx_uld(adap, type); |
| -- |
| 2.7.4 |
| |