Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90ff030c authored by Xiongfeng Wang's avatar Xiongfeng Wang Committed by Greg Kroah-Hartman
Browse files

serial: pch: Fix PCI device refcount leak in pch_request_dma()



[ Upstream commit 8be3a7bf773700534a6e8f87f6ed2ed111254be5 ]

As comment of pci_get_slot() says, it returns a pci_device with its
refcount increased. The caller must decrement the reference count by
calling pci_dev_put().

Since 'dma_dev' is only used to filter the channel in filter(), we can
call pci_dev_put() before exiting from pch_request_dma(). Add the
missing pci_dev_put() for the normal and error path.

Fixes: 3c6a4832 ("Serial: EG20T: add PCH_UART driver")
Signed-off-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Link: https://lore.kernel.org/r/20221122114559.27692-1-wangxiongfeng2@huawei.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 1c5f0d3f
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -753,6 +753,7 @@ static void pch_request_dma(struct uart_port *port)
	if (!chan) {
	if (!chan) {
		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
			__func__);
			__func__);
		pci_dev_put(dma_dev);
		return;
		return;
	}
	}
	priv->chan_tx = chan;
	priv->chan_tx = chan;
@@ -769,6 +770,7 @@ static void pch_request_dma(struct uart_port *port)
			__func__);
			__func__);
		dma_release_channel(priv->chan_tx);
		dma_release_channel(priv->chan_tx);
		priv->chan_tx = NULL;
		priv->chan_tx = NULL;
		pci_dev_put(dma_dev);
		return;
		return;
	}
	}


@@ -776,6 +778,8 @@ static void pch_request_dma(struct uart_port *port)
	priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
	priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
				    &priv->rx_buf_dma, GFP_KERNEL);
				    &priv->rx_buf_dma, GFP_KERNEL);
	priv->chan_rx = chan;
	priv->chan_rx = chan;

	pci_dev_put(dma_dev);
}
}


static void pch_dma_rx_complete(void *arg)
static void pch_dma_rx_complete(void *arg)