Merge tag 'irq_urgent_for_v5.13_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fix from Borislav Petkov:
"A single fix for GICv3 to not take an interrupt in an NMI context"

* tag 'irq_urgent_for_v5.13_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
irqchip/gic-v3: Workaround inconsistent PMR setting on NMI entry

+35 -1
+35 -1
drivers/irqchip/irq-gic-v3.c
··· 642 nmi_exit(); 643 } 644 645 static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) 646 { 647 u32 irqnr; 648 649 - irqnr = gic_read_iar(); 650 651 /* Check for special IDs first */ 652 if ((irqnr >= 1020 && irqnr <= 1023))
··· 642 nmi_exit(); 643 } 644 645 + static u32 do_read_iar(struct pt_regs *regs) 646 + { 647 + u32 iar; 648 + 649 + if (gic_supports_nmi() && unlikely(!interrupts_enabled(regs))) { 650 + u64 pmr; 651 + 652 + /* 653 + * We were in a context with IRQs disabled. However, the 654 + * entry code has set PMR to a value that allows any 655 + * interrupt to be acknowledged, and not just NMIs. This can 656 + * lead to surprising effects if the NMI has been retired in 657 + * the meantime, and that there is an IRQ pending. The IRQ 658 + * would then be taken in NMI context, something that nobody 659 + * wants to debug twice. 660 + * 661 + * Until we sort this, drop PMR again to a level that will 662 + * actually only allow NMIs before reading IAR, and then 663 + * restore it to what it was. 664 + */ 665 + pmr = gic_read_pmr(); 666 + gic_pmr_mask_irqs(); 667 + isb(); 668 + 669 + iar = gic_read_iar(); 670 + 671 + gic_write_pmr(pmr); 672 + } else { 673 + iar = gic_read_iar(); 674 + } 675 + 676 + return iar; 677 + } 678 + 679 static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) 680 { 681 u32 irqnr; 682 683 + irqnr = do_read_iar(regs); 684 685 /* Check for special IDs first */ 686 if ((irqnr >= 1020 && irqnr <= 1023))