···109109 * come via this function. Instead, they should provide their110110 * own 'handler'111111 */112112-asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)112112+asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)113113{114114 struct pt_regs *old_regs = set_irq_regs(regs);115115 struct irq_desc *desc = irq_desc + irq;
+16-2
arch/arm/kernel/traps.c
···4545__setup("user_debug=", user_debug_setup);4646#endif47474848-void dump_backtrace_entry(unsigned long where, unsigned long from)4848+static void dump_mem(const char *str, unsigned long bottom, unsigned long top);4949+5050+static inline int in_exception_text(unsigned long ptr)5151+{5252+ extern char __exception_text_start[];5353+ extern char __exception_text_end[];5454+5555+ return ptr >= (unsigned long)&__exception_text_start &&5656+ ptr < (unsigned long)&__exception_text_end;5757+}5858+5959+void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)4960{5061#ifdef CONFIG_KALLSYMS5162 printk("[<%08lx>] ", where);···6655#else6756 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);6857#endif5858+5959+ if (in_exception_text(where))6060+ dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));6961}70627163/*···280266 spin_unlock_irqrestore(&undef_lock, flags);281267}282268283283-asmlinkage void do_undefinstr(struct pt_regs *regs)269269+asmlinkage void __exception do_undefinstr(struct pt_regs *regs)284270{285271 unsigned int correction = thumb_mode(regs) ? 2 : 4;286272 unsigned int instr;
+3
arch/arm/kernel/vmlinux.lds.S
···83838484 .text : { /* Real text segment */8585 _text = .; /* Text and read-only data */8686+ __exception_text_start = .;8787+ *(.exception.text)8888+ __exception_text_end = .;8689 *(.text)8790 SCHED_TEXT8891 LOCK_TEXT
+77-80
arch/arm/lib/backtrace.S
···1717@ fp is 0 or stack frame18181919#define frame r42020-#define next r52121-#define save r62020+#define sv_fp r52121+#define sv_pc r62222#define mask r72323#define offset r82424···3131#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)3232 mov pc, lr3333#else3434-3534 stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...3636- tst r1, #0x10 @ 26 or 32-bit?3737- moveq mask, #0xfc0000033838- movne mask, #03939- tst mask, r04040- movne r0, #04141- movs frame, r04242-1: moveq r0, #-24343- ldmeqfd sp!, {r4 - r8, pc}3535+ movs frame, r0 @ if frame pointer is zero3636+ beq no_frame @ we have no stack frames44374545-2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction4646- ldr r0, [sp], #44747- adr r1, 2b - 43838+ tst r1, #0x10 @ 26 or 32-bit mode?3939+ moveq mask, #0xfc000003 @ mask for 26-bit4040+ movne mask, #0 @ mask for 32-bit4141+4242+1: stmfd sp!, {pc} @ calculate offset of PC stored4343+ ldr r0, [sp], #4 @ by stmfd for this CPU4444+ adr r1, 1b4845 sub offset, r0, r149465050-3: tst frame, mask @ Check for address exceptions...5151- bne 1b4747+/*4848+ * Stack frame layout:4949+ * optionally saved caller registers (r4 - r10)5050+ * saved fp5151+ * saved sp5252+ * saved lr5353+ * frame => saved pc5454+ * optionally saved arguments (r0 - r3)5555+ * saved sp => <next word>5656+ *5757+ * Functions start with the following code sequence:5858+ * mov ip, sp5959+ * stmfd sp!, {r0 - r3} (optional)6060+ * corrected pc => stmfd sp!, {..., fp, ip, lr, pc}6161+ */6262+for_each_frame: tst frame, mask @ Check for address exceptions6363+ bne no_frame52645353-1001: ldr next, [frame, #-12] @ get fp5454-1002: ldr r2, [frame, #-4] @ get lr5555-1003: ldr r3, [frame, #0] @ get pc5656- sub save, r3, offset @ Correct PC for prefetching5757- bic save, save, mask5858-1004: ldr r1, [save, #0] @ get instruction at function5959- mov r1, r1, lsr #106060- ldr r3, .Ldsi+46161- teq r1, r36262- subeq save, save, #46363- mov r0, save6464- bic r1, r2, mask6565+1001: ldr sv_pc, [frame, #0] @ get saved pc6666+1002: ldr sv_fp, [frame, #-12] @ get saved fp6767+6868+ sub sv_pc, sv_pc, offset @ Correct PC for prefetching6969+ bic sv_pc, sv_pc, mask @ mask PC/LR for the mode7070+7171+1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists,7272+ ldr r3, .Ldsi+4 @ adjust saved 'pc' back one7373+ teq r3, r2, lsr #10 @ instruction7474+ subne r0, sv_pc, #4 @ allow for mov7575+ subeq r0, sv_pc, #8 @ allow for mov + stmia7676+7777+ ldr r1, [frame, #-4] @ get saved lr7878+ mov r2, frame7979+ bic r1, r1, mask @ mask PC/LR for the mode6580 bl dump_backtrace_entry66816767- ldr r0, [frame, #-8] @ get sp6868- sub r0, r0, #46969-1005: ldr r1, [save, #4] @ get instruction at function+47070- mov r3, r1, lsr #107171- ldr r2, .Ldsi+47272- teq r3, r2 @ Check for stmia sp!, {args}7373- addeq save, save, #4 @ next instruction7474- bleq .Ldumpstm8282+ ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists,8383+ ldr r3, .Ldsi+48484+ teq r3, r1, lsr #108585+ ldreq r0, [frame, #-8] @ get sp8686+ subeq r0, r0, #4 @ point at the last arg8787+ bleq .Ldumpstm @ dump saved registers75887676- sub r0, frame, #167777-1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction7878- mov r3, r1, lsr #107979- ldr r2, .Ldsi8080- teq r3, r28181- bleq .Ldumpstm8989+1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc}9090+ ldr r3, .Ldsi @ instruction exists,9191+ teq r3, r1, lsr #109292+ subeq r0, frame, #169393+ bleq .Ldumpstm @ dump saved registers82948383- /*8484- * A zero next framepointer means we're done.8585- */8686- teq next, #08787- ldmeqfd sp!, {r4 - r8, pc}9595+ teq sv_fp, #0 @ zero saved fp means9696+ beq no_frame @ no further frames88978989- /*9090- * The next framepointer must be above the9191- * current framepointer.9292- */9393- cmp next, frame9494- mov frame, next9595- bhi 3b9696- b 1007f9898+ cmp sv_fp, frame @ next frame must be9999+ mov frame, sv_fp @ above the current frame100100+ bhi for_each_frame971019898-/*9999- * Fixup for LDMDB. Note that this must not be in the fixup section.100100- */101101-1007: ldr r0, =.Lbad102102+1006: adr r0, .Lbad102103 mov r1, frame103104 bl printk104104- ldmfd sp!, {r4 - r8, pc}105105- .ltorg105105+no_frame: ldmfd sp!, {r4 - r8, pc}106106107107 .section __ex_table,"a"108108 .align 3109109- .long 1001b, 1007b110110- .long 1002b, 1007b111111- .long 1003b, 1007b112112- .long 1004b, 1007b113113- .long 1005b, 1007b114114- .long 1006b, 1007b109109+ .long 1001b, 1006b110110+ .long 1002b, 1006b111111+ .long 1003b, 1006b112112+ .long 1004b, 1006b115113 .previous116114117115#define instr r4118116#define reg r5119117#define stack r6120118121121-.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr}119119+.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}122120 mov stack, r0123121 mov instr, r1124124- mov reg, #9122122+ mov reg, #10125123 mov r7, #01261241: mov r3, #1127125 tst instr, r3, lsl reg128126 beq 2f129127 add r7, r7, #1130130- teq r7, #4131131- moveq r7, #0132132- moveq r3, #'\n'133133- movne r3, #' '134134- ldr r2, [stack], #-4135135- mov r1, reg128128+ teq r7, #6129129+ moveq r7, #1130130+ moveq r1, #'\n'131131+ movne r1, #' '132132+ ldr r3, [stack], #-4133133+ mov r2, reg136134 adr r0, .Lfp137135 bl printk1381362: subs reg, reg, #1···138140 teq r7, #0139141 adrne r0, .Lcr140142 blne printk141141- mov r0, stack142142- ldmfd sp!, {instr, reg, stack, r7, r8, pc}143143+ ldmfd sp!, {instr, reg, stack, r7, pc}143144144144-.Lfp: .asciz " r%d = %08X%c"145145+.Lfp: .asciz "%cr%d:%08x"145146.Lcr: .asciz "\n"146147.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"147148 .align148148-.Ldsi: .word 0x00e92dd8 >> 2149149- .word 0x00e92d00 >> 2149149+.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc}150150+ .word 0xe92d0000 >> 10 @ stmfd sp!, {}150151151152#endif
+2-2
arch/arm/mm/fault.c
···438438/*439439 * Dispatch a data abort to the relevant handler.440440 */441441-asmlinkage void441441+asmlinkage void __exception442442do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)443443{444444 const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);···457457 notify_die("", regs, &info, fsr, 0);458458}459459460460-asmlinkage void460460+asmlinkage void __exception461461do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)462462{463463 do_translation_fault(addr, 0, regs);