| From 8161e9626b50892eaedbd8070ecb1586ecedb109 Mon Sep 17 00:00:00 2001 |
| From: Serge Semin <Sergey.Semin@baikalelectronics.ru> |
| Date: Fri, 24 Jun 2022 17:34:15 +0300 |
| Subject: [PATCH] PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors |
| Git-commit: 8161e9626b50892eaedbd8070ecb1586ecedb109 |
| Patch-mainline: v6.0-rc1 |
| References: git-fixes |
| |
| If dw_pcie_ep_init() fails to perform any action after the EPC memory is |
| initialized and the MSI memory region is allocated, the latter parts won't |
| be undone thus causing a memory leak. Add a cleanup-on-error path to fix |
| these leaks. |
| |
| [bhelgaas: commit log] |
| Fixes: 2fd0c9d966cc ("PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init") |
| Link: https://lore.kernel.org/r/20220624143428.8334-6-Sergey.Semin@baikalelectronics.ru |
| Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> |
| Reviewed-by: Rob Herring <robh@kernel.org> |
| Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Acked-by: Takashi Iwai <tiwai@suse.de> |
| |
| |
| .../pci/controller/dwc/pcie-designware-ep.c | 18 ++++++++++++++++-- |
| 1 file changed, 16 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c |
| index 0eda8236c125..13c2e73f0eaf 100644 |
| |
| |
| @@ -780,8 +780,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) |
| ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, |
| epc->mem->window.page_size); |
| if (!ep->msi_mem) { |
| + ret = -ENOMEM; |
| dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n"); |
| - return -ENOMEM; |
| + goto err_exit_epc_mem; |
| } |
| |
| if (ep->ops->get_features) { |
| @@ -790,6 +791,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) |
| return 0; |
| } |
| |
| - return dw_pcie_ep_init_complete(ep); |
| + ret = dw_pcie_ep_init_complete(ep); |
| + if (ret) |
| + goto err_free_epc_mem; |
| + |
| + return 0; |
| + |
| +err_free_epc_mem: |
| + pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, |
| + epc->mem->window.page_size); |
| + |
| +err_exit_epc_mem: |
| + pci_epc_mem_exit(epc); |
| + |
| + return ret; |
| } |
| EXPORT_SYMBOL_GPL(dw_pcie_ep_init); |
| -- |
| 2.35.3 |
| |