diff options
author | James Morse <james.morse@arm.com> | 2015-12-04 06:02:27 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2015-12-08 06:42:51 -0500 |
commit | 8e23dacd12a48e58125b84c817da50850b73280a (patch) | |
tree | b920b408538982d88d9482fc2c28f1b361062648 /arch/arm64/kernel/entry.S | |
parent | 132cd887b5c54758d04bf25c52fa48f45e843a30 (diff) |
arm64: Add do_softirq_own_stack() and enable irq_stacks
entry.S is modified to switch to the per_cpu irq_stack during el{0,1}_irq.
irq_count is used to detect recursive interrupts on the irq_stack, it is
updated late by do_softirq_own_stack(), when called on the irq_stack, before
__do_softirq() re-enables interrupts to process softirqs.
do_softirq_own_stack() is added by this patch, but does not yet switch
stack.
This patch adds the dummy stack frame and data needed by the previous
stack tracing patches.
Reviewed-by: Catalin Marinas <catalin.marinas@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.S | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 245fa6837880..8f7e737949fe 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/cpufeature.h> | 27 | #include <asm/cpufeature.h> |
28 | #include <asm/errno.h> | 28 | #include <asm/errno.h> |
29 | #include <asm/esr.h> | 29 | #include <asm/esr.h> |
30 | #include <asm/irq.h> | ||
30 | #include <asm/thread_info.h> | 31 | #include <asm/thread_info.h> |
31 | #include <asm/unistd.h> | 32 | #include <asm/unistd.h> |
32 | 33 | ||
@@ -175,6 +176,42 @@ alternative_endif | |||
175 | mrs \rd, sp_el0 | 176 | mrs \rd, sp_el0 |
176 | .endm | 177 | .endm |
177 | 178 | ||
179 | .macro irq_stack_entry, dummy_lr | ||
180 | mov x19, sp // preserve the original sp | ||
181 | |||
182 | adr_l x25, irq_stack | ||
183 | mrs x26, tpidr_el1 | ||
184 | add x25, x25, x26 | ||
185 | |||
186 | /* | ||
187 | * Check the lowest address on irq_stack for the irq_count value, | ||
188 | * incremented by do_softirq_own_stack if we have re-enabled irqs | ||
189 | * while on the irq_stack. | ||
190 | */ | ||
191 | ldr x26, [x25] | ||
192 | cbnz x26, 9998f // recursive use? | ||
193 | |||
194 | /* switch to the irq stack */ | ||
195 | mov x26, #IRQ_STACK_START_SP | ||
196 | add x26, x25, x26 | ||
197 | mov sp, x26 | ||
198 | |||
199 | /* Add a dummy stack frame */ | ||
200 | stp x29, \dummy_lr, [sp, #-16]! // dummy stack frame | ||
201 | mov x29, sp | ||
202 | stp xzr, x19, [sp, #-16]! | ||
203 | |||
204 | 9998: | ||
205 | .endm | ||
206 | |||
207 | /* | ||
208 | * x19 should be preserved between irq_stack_entry and | ||
209 | * irq_stack_exit. | ||
210 | */ | ||
211 | .macro irq_stack_exit | ||
212 | mov sp, x19 | ||
213 | .endm | ||
214 | |||
178 | /* | 215 | /* |
179 | * These are the registers used in the syscall handler, and allow us to | 216 | * These are the registers used in the syscall handler, and allow us to |
180 | * have in theory up to 7 arguments to a function - x0 to x6. | 217 | * have in theory up to 7 arguments to a function - x0 to x6. |
@@ -190,10 +227,11 @@ tsk .req x28 // current thread_info | |||
190 | * Interrupt handling. | 227 | * Interrupt handling. |
191 | */ | 228 | */ |
192 | .macro irq_handler | 229 | .macro irq_handler |
193 | adrp x1, handle_arch_irq | 230 | ldr_l x1, handle_arch_irq |
194 | ldr x1, [x1, #:lo12:handle_arch_irq] | ||
195 | mov x0, sp | 231 | mov x0, sp |
232 | irq_stack_entry x22 | ||
196 | blr x1 | 233 | blr x1 |
234 | irq_stack_exit | ||
197 | .endm | 235 | .endm |
198 | 236 | ||
199 | .text | 237 | .text |