]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
riscv: kexec: Avoid deadlock in kexec crash path
authorSong Shuai <songshuaishuai@tinylab.org>
Wed, 26 Jun 2024 02:33:16 +0000 (10:33 +0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Wed, 3 Jul 2024 20:11:30 +0000 (13:11 -0700)
If the kexec crash code is called in the interrupt context, the
machine_kexec_mask_interrupts() function will trigger a deadlock while
trying to acquire the irqdesc spinlock and then deactivate irqchip in
irq_set_irqchip_state() function.

Unlike arm64, riscv only requires irq_eoi handler to complete EOI and
keeping irq_set_irqchip_state() will only leave this possible deadlock
without any use. So we simply remove it.

Link: https://lore.kernel.org/linux-riscv/20231208111015.173237-1-songshuaishuai@tinylab.org/
Fixes: b17d19a5314a ("riscv: kexec: Fixup irq controller broken in kexec crash path")
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
Reviewed-by: Ryo Takakura <takakura@valinux.co.jp>
Link: https://lore.kernel.org/r/20240626023316.539971-1-songshuaishuai@tinylab.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/kernel/machine_kexec.c

index ed9cad20c039d9ebdd4f1a8f92074d8bd348590e..3c830a6f7ef464ba2e10e3ffad6c53d0bae3c4ce 100644 (file)
@@ -121,20 +121,12 @@ static void machine_kexec_mask_interrupts(void)
 
        for_each_irq_desc(i, desc) {
                struct irq_chip *chip;
-               int ret;
 
                chip = irq_desc_get_chip(desc);
                if (!chip)
                        continue;
 
-               /*
-                * First try to remove the active state. If this
-                * fails, try to EOI the interrupt.
-                */
-               ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
-               if (ret && irqd_irq_inprogress(&desc->irq_data) &&
-                   chip->irq_eoi)
+               if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
                        chip->irq_eoi(&desc->irq_data);
 
                if (chip->irq_mask)