| From 8af14754e6a5c28020436456a65f8ab839316b94 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 9 Sep 2022 17:07:55 -0300 |
| Subject: firmware: google: Test spinlock on panic path to avoid lockups |
| |
| From: Guilherme G. Piccoli <gpiccoli@igalia.com> |
| |
| [ Upstream commit 3e081438b8e639cc76ef1a5ce0c1bd8a154082c7 ] |
| |
| Currently the gsmi driver registers a panic notifier as well as |
| reboot and die notifiers. The callbacks registered are called in |
| atomic and very limited context - for instance, panic disables |
| preemption and local IRQs, also all secondary CPUs (not executing |
| the panic path) are shutdown. |
| |
| With that said, taking a spinlock in this scenario is a dangerous |
| invitation for lockup scenarios. So, fix that by checking if the |
| spinlock is free to acquire in the panic notifier callback - if not, |
| bail-out and avoid a potential hang. |
| |
| Fixes: 74c5b31c6618 ("driver: Google EFI SMI") |
| Cc: Andrew Morton <akpm@linux-foundation.org> |
| Cc: Ard Biesheuvel <ardb@kernel.org> |
| Cc: David Gow <davidgow@google.com> |
| Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: Julius Werner <jwerner@chromium.org> |
| Cc: Petr Mladek <pmladek@suse.com> |
| Reviewed-by: Evan Green <evgreen@chromium.org> |
| Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com> |
| Link: https://lore.kernel.org/r/20220909200755.189679-1-gpiccoli@igalia.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/firmware/google/gsmi.c | 9 +++++++++ |
| 1 file changed, 9 insertions(+) |
| |
| diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c |
| index edaa4e5d84ad..517fb57d07d2 100644 |
| --- a/drivers/firmware/google/gsmi.c |
| +++ b/drivers/firmware/google/gsmi.c |
| @@ -679,6 +679,15 @@ static struct notifier_block gsmi_die_notifier = { |
| static int gsmi_panic_callback(struct notifier_block *nb, |
| unsigned long reason, void *arg) |
| { |
| + |
| + /* |
| + * Panic callbacks are executed with all other CPUs stopped, |
| + * so we must not attempt to spin waiting for gsmi_dev.lock |
| + * to be released. |
| + */ |
| + if (spin_is_locked(&gsmi_dev.lock)) |
| + return NOTIFY_DONE; |
| + |
| gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC); |
| return NOTIFY_DONE; |
| } |
| -- |
| 2.35.1 |
| |