summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/entry.S
diff options
context:
space:
mode:
authorJames Morse <james.morse@arm.com>2015-12-15 12:21:25 +0100
committerWill Deacon <will.deacon@arm.com>2015-12-15 18:09:08 +0100
commit971c67ce37cfeeaf560e792a2c3bc21d8b67163a (patch)
treedabce8d15638e66a8c351454e78e3f5bac6f6c2f /arch/arm64/kernel/entry.S
parentMerge branch 'aarch64/efi' into aarch64/for-next/core (diff)
downloadlinux-971c67ce37cfeeaf560e792a2c3bc21d8b67163a.tar.xz
linux-971c67ce37cfeeaf560e792a2c3bc21d8b67163a.zip
arm64: reduce stack use in irq_handler
The code for switching to irq_stack stores three pieces of information on the stack, fp+lr, as a fake stack frame (that lets us walk back onto the interrupted tasks stack frame), and the address of the struct pt_regs that contains the register values from kernel entry. (which dump_backtrace() will print in any stack trace). To reduce this, we store fp, and the pointer to the struct pt_regs. unwind_frame() can recognise this as the irq_stack dummy frame, (as it only appears at the top of the irq_stack), and use the struct pt_regs values to find the missing interrupted link-register. Suggested-by: Will Deacon <will.deacon@arm.com> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/entry.S')
-rw-r--r--arch/arm64/kernel/entry.S12
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 2284c296e3f7..0667fb7d8bb1 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -178,7 +178,7 @@ alternative_endif
mrs \rd, sp_el0
.endm
- .macro irq_stack_entry, dummy_lr
+ .macro irq_stack_entry
mov x19, sp // preserve the original sp
this_cpu_ptr irq_stack, x25, x26
@@ -196,10 +196,12 @@ alternative_endif
add x26, x25, x26
mov sp, x26
- /* Add a dummy stack frame */
- stp x29, \dummy_lr, [sp, #-16]! // dummy stack frame
+ /*
+ * Add a dummy stack frame, this non-standard format is fixed up
+ * by unwind_frame()
+ */
+ stp x29, x19, [sp, #-16]!
mov x29, sp
- stp x19, xzr, [sp, #-16]!
9998:
.endm
@@ -229,7 +231,7 @@ tsk .req x28 // current thread_info
.macro irq_handler
ldr_l x1, handle_arch_irq
mov x0, sp
- irq_stack_entry x22
+ irq_stack_entry
blr x1
irq_stack_exit
.endm