| From 89efbe70b27dd325d8a8c177743a26b885f7faec Mon Sep 17 00:00:00 2001 |
| From: Lukas Wunner <lukas@wunner.de> |
| Date: Thu, 13 Aug 2020 12:59:54 +0200 |
| Subject: serial: pl011: Don't leak amba_ports entry on driver register error |
| |
| From: Lukas Wunner <lukas@wunner.de> |
| |
| commit 89efbe70b27dd325d8a8c177743a26b885f7faec upstream. |
| |
| pl011_probe() calls pl011_setup_port() to reserve an amba_ports[] entry, |
| then calls pl011_register_port() to register the uart driver with the |
| tty layer. |
| |
| If registration of the uart driver fails, the amba_ports[] entry is not |
| released. If this happens 14 times (value of UART_NR macro), then all |
| amba_ports[] entries will have been leaked and driver probing is no |
| longer possible. (To be fair, that can only happen if the DeviceTree |
| doesn't contain alias IDs since they cause the same entry to be used for |
| a given port.) Fix it. |
| |
| Fixes: ef2889f7ffee ("serial: pl011: Move uart_register_driver call to device") |
| Signed-off-by: Lukas Wunner <lukas@wunner.de> |
| Cc: stable@vger.kernel.org # v3.15+ |
| Cc: Tushar Behera <tushar.behera@linaro.org> |
| Link: https://lore.kernel.org/r/138f8c15afb2f184d8102583f8301575566064a6.1597316167.git.lukas@wunner.de |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/tty/serial/amba-pl011.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/tty/serial/amba-pl011.c |
| +++ b/drivers/tty/serial/amba-pl011.c |
| @@ -2532,7 +2532,7 @@ static int pl011_setup_port(struct devic |
| |
| static int pl011_register_port(struct uart_amba_port *uap) |
| { |
| - int ret; |
| + int ret, i; |
| |
| /* Ensure interrupts from this UART are masked and cleared */ |
| pl011_write(0, uap, REG_IMSC); |
| @@ -2543,6 +2543,9 @@ static int pl011_register_port(struct ua |
| if (ret < 0) { |
| dev_err(uap->port.dev, |
| "Failed to register AMBA-PL011 driver\n"); |
| + for (i = 0; i < ARRAY_SIZE(amba_ports); i++) |
| + if (amba_ports[i] == uap) |
| + amba_ports[i] = NULL; |
| return ret; |
| } |
| } |