Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: entry: factor irq triage logic into macros

In subsequent patches we'll allow an FIQ handler to be registered, and
FIQ exceptions will need to be triaged very similarly to IRQ exceptions.
So that we can reuse the existing logic, this patch factors the IRQ
triage logic out into macros that can be reused for FIQ.

The macros are named to follow the elX_foo_handler scheme used by the C
exception handlers. For consistency with other top-level exception
handlers, the kernel_entry/kernel_exit logic is not moved into the
macros. As FIQ will use a different C handler, this handler name is
provided as an argument to the macros.

There should be no functional change as a result of this patch.

Signed-off-by: Marc Zyngier <maz@kernel.org>
[Mark: rework macros, commit message, rebase before DAIF rework]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Hector Martin <marcan@marcan.st>
Cc: James Morse <james.morse@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20210315115629.57191-5-mark.rutland@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Marc Zyngier and committed by
Catalin Marinas
9eb563cd 8ff443ce

+43 -37
+43 -37
arch/arm64/kernel/entry.S
··· 491 491 /* 492 492 * Interrupt handling. 493 493 */ 494 - .macro irq_handler 495 - ldr_l x1, handle_arch_irq 494 + .macro irq_handler, handler:req 495 + ldr_l x1, \handler 496 496 mov x0, sp 497 497 irq_stack_entry 498 498 blr x1 ··· 529 529 msr_s SYS_ICC_PMR_EL1, \tmp 530 530 alternative_else_nop_endif 531 531 #endif 532 + .endm 533 + 534 + .macro el1_interrupt_handler, handler:req 535 + gic_prio_irq_setup pmr=x20, tmp=x1 536 + enable_da_f 537 + 538 + mov x0, sp 539 + bl enter_el1_irq_or_nmi 540 + 541 + irq_handler \handler 542 + 543 + #ifdef CONFIG_PREEMPTION 544 + ldr x24, [tsk, #TSK_TI_PREEMPT] // get preempt count 545 + alternative_if ARM64_HAS_IRQ_PRIO_MASKING 546 + /* 547 + * DA_F were cleared at start of handling. If anything is set in DAIF, 548 + * we come back from an NMI, so skip preemption 549 + */ 550 + mrs x0, daif 551 + orr x24, x24, x0 552 + alternative_else_nop_endif 553 + cbnz x24, 1f // preempt count != 0 || NMI return path 554 + bl arm64_preempt_schedule_irq // irq en/disable is done inside 555 + 1: 556 + #endif 557 + 558 + mov x0, sp 559 + bl exit_el1_irq_or_nmi 560 + .endm 561 + 562 + .macro el0_interrupt_handler, handler:req 563 + gic_prio_irq_setup pmr=x20, tmp=x0 564 + user_exit_irqoff 565 + enable_da_f 566 + 567 + tbz x22, #55, 1f 568 + bl do_el0_irq_bp_hardening 569 + 1: 570 + irq_handler \handler 532 571 .endm 533 572 534 573 .text ··· 699 660 .align 6 700 661 SYM_CODE_START_LOCAL_NOALIGN(el1_irq) 701 662 kernel_entry 1 702 - gic_prio_irq_setup pmr=x20, tmp=x1 703 - enable_da_f 704 - 705 - mov x0, sp 706 - bl enter_el1_irq_or_nmi 707 - 708 - irq_handler 709 - 710 - #ifdef CONFIG_PREEMPTION 711 - ldr x24, [tsk, #TSK_TI_PREEMPT] // get preempt count 712 - alternative_if ARM64_HAS_IRQ_PRIO_MASKING 713 - /* 714 - * DA_F were cleared at start of handling. If anything is set in DAIF, 715 - * we come back from an NMI, so skip preemption 716 - */ 717 - mrs x0, daif 718 - orr x24, x24, x0 719 - alternative_else_nop_endif 720 - cbnz x24, 1f // preempt count != 0 || NMI return path 721 - bl arm64_preempt_schedule_irq // irq en/disable is done inside 722 - 1: 723 - #endif 724 - 725 - mov x0, sp 726 - bl exit_el1_irq_or_nmi 727 - 663 + el1_interrupt_handler handle_arch_irq 728 664 kernel_exit 1 729 665 SYM_CODE_END(el1_irq) 730 666 ··· 739 725 SYM_CODE_START_LOCAL_NOALIGN(el0_irq) 740 726 kernel_entry 0 741 727 el0_irq_naked: 742 - gic_prio_irq_setup pmr=x20, tmp=x0 743 - user_exit_irqoff 744 - enable_da_f 745 - 746 - tbz x22, #55, 1f 747 - bl do_el0_irq_bp_hardening 748 - 1: 749 - irq_handler 750 - 728 + el0_interrupt_handler handle_arch_irq 751 729 b ret_to_user 752 730 SYM_CODE_END(el0_irq) 753 731