diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-04-09 18:17:43 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-04-09 18:17:43 -1000 |
commit | fa3b895da8e06d6e3dcf3e6941a3fd428343e3d7 (patch) | |
tree | 251dbd45b10536a157ff75e3835733c47a939e19 /drivers | |
parent | e1f700ebd6bea293abe3c7e2807b252018efde01 (diff) | |
parent | 5467801f1fcbdc46bc7298a84dbf3ca1ff2a7320 (diff) | |
download | linux-stable-fa3b895da8e06d6e3dcf3e6941a3fd428343e3d7.tar.gz linux-stable-fa3b895da8e06d6e3dcf3e6941a3fd428343e3d7.tar.bz2 linux-stable-fa3b895da8e06d6e3dcf3e6941a3fd428343e3d7.zip |
Merge tag 'gpio-fixes-for-v5.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio fix from Bartosz Golaszewski:
- fix a race condition with consumers accessing the fields of GPIO IRQ
chips before they're fully initialized
* tag 'gpio-fixes-for-v5.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
gpio: Restrict usage of GPIO chip irq members before initialization
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/gpiolib.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e59884cc12a7..085348e08986 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1404,6 +1404,16 @@ static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset) { struct irq_domain *domain = gc->irq.domain; +#ifdef CONFIG_GPIOLIB_IRQCHIP + /* + * Avoid race condition with other code, which tries to lookup + * an IRQ before the irqchip has been properly registered, + * i.e. while gpiochip is still being brought up. + */ + if (!gc->irq.initialized) + return -EPROBE_DEFER; +#endif + if (!gpiochip_irqchip_irq_valid(gc, offset)) return -ENXIO; @@ -1593,6 +1603,15 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc, acpi_gpiochip_request_interrupts(gc); + /* + * Using barrier() here to prevent compiler from reordering + * gc->irq.initialized before initialization of above + * GPIO chip irq members. + */ + barrier(); + + gc->irq.initialized = true; + return 0; } |