From: Leonid Yegoshin <Leonid.Yegoshin@xxxxxxxxxx> When a breakpoint or trap happens when operating in kernel mode but on users behalf (eg syscall) it is necessary to change the address limit to KERNEL_DS so any address checking can be bypassed and print the correct stack trace. Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@xxxxxxxxxx> Signed-off-by: Markos Chandras <markos.chandras@xxxxxxxxxx> --- arch/mips/kernel/traps.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 3e5e700..a5a74d6 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -862,6 +862,11 @@ asmlinkage void do_bp(struct pt_regs *regs) enum ctx_state prev_state; unsigned long epc; u16 instr[2]; + mm_segment_t seg; + + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); prev_state = exception_enter(); if (get_isa16_mode(regs->cp0_epc)) { @@ -921,6 +926,7 @@ asmlinkage void do_bp(struct pt_regs *regs) do_trap_or_bp(regs, bcode, "Break"); out: + set_fs(seg); exception_exit(prev_state); return; @@ -934,8 +940,13 @@ asmlinkage void do_tr(struct pt_regs *regs) u32 opcode, tcode = 0; enum ctx_state prev_state; u16 instr[2]; + mm_segment_t seg; unsigned long epc = msk_isa16_mode(exception_epc(regs)); + seg = get_fs(); + if (!user_mode(regs)) + set_fs(get_ds()); + prev_state = exception_enter(); if (get_isa16_mode(regs->cp0_epc)) { if (__get_user(instr[0], (u16 __user *)(epc + 0)) || @@ -956,6 +967,7 @@ asmlinkage void do_tr(struct pt_regs *regs) do_trap_or_bp(regs, tcode, "Trap"); out: + set_fs(seg); exception_exit(prev_state); return; -- 1.8.5.3