[openwrt/openwrt] realtek: don't unmask non-maskable GPIO IRQs

LEDE Commits lede-commits at lists.infradead.org
Sun May 29 22:24:15 PDT 2022


svanheule pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/bde6311569ef25a00c3beaeabfd6b78b19651872

commit bde6311569ef25a00c3beaeabfd6b78b19651872
Author: Sander Vanheule <sander at svanheule.net>
AuthorDate: Sun May 29 19:38:09 2022 +0200

    realtek: don't unmask non-maskable GPIO IRQs
    
    On uniprocessor builds, for_each_cpu(cpu, mask) will assume 'mask'
    always contains exactly one CPU, and ignore the actual mask contents.
    This causes the loop to run, even when it shouldn't on an empty mask,
    and tries to access an uninitialised pointer.
    
    Fix this by wrapping the loop in a cpumask_empty() check, to ensure it
    will not run on uniprocessor builds if the CPU mask is empty.
    
    Fixes: af6cd37f42f3 ("realtek: replace RTL93xx GPIO patches")
    Reported-by: INAGAKI Hiroshi <musashino.open at gmail.com>
    Reported-by: Robert Marko <robimarko at gmail.com>
    Tested-by: Robert Marko <robimarko at gmail.com>
    Signed-off-by: Sander Vanheule <sander at svanheule.net>
---
 .../316-otto-gpio-uniprocessor-irq-mask.patch      | 29 ++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/target/linux/realtek/patches-5.10/316-otto-gpio-uniprocessor-irq-mask.patch b/target/linux/realtek/patches-5.10/316-otto-gpio-uniprocessor-irq-mask.patch
new file mode 100644
index 0000000000..a3241cadbd
--- /dev/null
+++ b/target/linux/realtek/patches-5.10/316-otto-gpio-uniprocessor-irq-mask.patch
@@ -0,0 +1,29 @@
+--- a/drivers/gpio/gpio-realtek-otto.c
++++ b/drivers/gpio/gpio-realtek-otto.c
+@@ -304,6 +304,7 @@ static int realtek_gpio_irq_set_affinity
+ static int realtek_gpio_irq_init(struct gpio_chip *gc)
+ {
+ 	struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
++	void __iomem *irq_cpu_mask;
+ 	unsigned int port;
+ 	int cpu;
+ 
+@@ -311,8 +312,16 @@ static int realtek_gpio_irq_init(struct
+ 		realtek_gpio_write_imr(ctrl, port, 0, 0);
+ 		realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
+ 
+-		for_each_cpu(cpu, &ctrl->cpu_irq_maskable)
+-			iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu));
++		/*
++		 * Uniprocessor builds assume a mask always contains one CPU,
++		 * so only start the loop if we have at least one maskable CPU.
++		 */
++		if(!cpumask_empty(&ctrl->cpu_irq_maskable)) {
++			for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
++				irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
++				iowrite8(GENMASK(7, 0), irq_cpu_mask);
++			}
++		}
+ 	}
+ 
+ 	return 0;




More information about the lede-commits mailing list