mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
serial: qcom-geni: Drop unsafe rx_buf realloc from setup_fifos()
The RX buffer is allocated once during probe using a fixed DMA_RX_BUF_SIZE and is DMA-mapped for the lifetime of the port. However, setup_fifos() attempts to reallocate rx_buf whenever the reported RX FIFO depth changes. Since the DMA mapping is not re-established after reallocation, the buffer pointer may change while the DMA engine continues using the stale DMA address. This can result in RX DMA targeting memory that no longer corresponds to the active buffer, leading to invalid DMA accesses and potential memory corruption. The RX FIFO depth is unrelated to the size of rx_buf. The buffer is allocated independently using DMA_RX_BUF_SIZE and all RX DMA paths consume it at that fixed size. As such, resizing the buffer based on FIFO depth changes provides no functional benefit. Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com> Link: https://patch.msgid.link/20260824-drop-unsafe-rx-buf-realloc-from-setup-fifos-v1-1-52d231c840e1@oss.qualcomm.com Link: https://patch.msgid.link/20260824-drop-unsafe-rx-buf-realloc-from-setup-fifos-v2-1-9a1c8f711e98@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
22a4e56a37
commit
16ccb505ff
|
|
@ -1291,7 +1291,6 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
|
|||
static int setup_fifos(struct qcom_geni_serial_port *port)
|
||||
{
|
||||
struct uart_port *uport;
|
||||
u32 old_rx_fifo_depth = port->rx_fifo_depth;
|
||||
|
||||
uport = &port->uport;
|
||||
port->tx_fifo_depth = geni_se_get_tx_fifo_depth(&port->se);
|
||||
|
|
@ -1300,19 +1299,6 @@ static int setup_fifos(struct qcom_geni_serial_port *port)
|
|||
uport->fifosize =
|
||||
(port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE;
|
||||
|
||||
if (port->rx_buf && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) {
|
||||
/*
|
||||
* Use krealloc rather than krealloc_array because rx_buf is
|
||||
* accessed as 1 byte entries as well as 4 byte entries so it's
|
||||
* not necessarily an array.
|
||||
*/
|
||||
port->rx_buf = devm_krealloc(uport->dev, port->rx_buf,
|
||||
port->rx_fifo_depth * sizeof(u32),
|
||||
GFP_KERNEL);
|
||||
if (!port->rx_buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user