mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
MIPS: Set trap_no field in thread_struct on exception.
This reverts commit 7281cd2297
and adds
actual functionality to use the field.
This commit is contained in:
parent
8c576912e4
commit
e3b28831c1
4 changed files with 21 additions and 18 deletions
|
@ -275,6 +275,7 @@ struct thread_struct {
|
||||||
unsigned long cp0_badvaddr; /* Last user fault */
|
unsigned long cp0_badvaddr; /* Last user fault */
|
||||||
unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
|
unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
|
||||||
unsigned long error_code;
|
unsigned long error_code;
|
||||||
|
unsigned long trap_nr;
|
||||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||||
struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
|
struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
|
||||||
struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
|
struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
|
||||||
|
@ -341,6 +342,7 @@ struct thread_struct {
|
||||||
.cp0_badvaddr = 0, \
|
.cp0_badvaddr = 0, \
|
||||||
.cp0_baduaddr = 0, \
|
.cp0_baduaddr = 0, \
|
||||||
.error_code = 0, \
|
.error_code = 0, \
|
||||||
|
.trap_nr = 0, \
|
||||||
/* \
|
/* \
|
||||||
* Platform specific cop2 registers(null if no COP2) \
|
* Platform specific cop2 registers(null if no COP2) \
|
||||||
*/ \
|
*/ \
|
||||||
|
|
|
@ -128,6 +128,7 @@ void output_thread_defines(void)
|
||||||
thread.cp0_baduaddr);
|
thread.cp0_baduaddr);
|
||||||
OFFSET(THREAD_ECODE, task_struct, \
|
OFFSET(THREAD_ECODE, task_struct, \
|
||||||
thread.error_code);
|
thread.error_code);
|
||||||
|
OFFSET(THREAD_TRAPNO, task_struct, thread.trap_nr);
|
||||||
BLANK();
|
BLANK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,11 +370,6 @@ void show_registers(struct pt_regs *regs)
|
||||||
set_fs(old_fs);
|
set_fs(old_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regs_to_trapnr(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return (regs->cp0_cause >> 2) & 0x1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEFINE_RAW_SPINLOCK(die_lock);
|
static DEFINE_RAW_SPINLOCK(die_lock);
|
||||||
|
|
||||||
void __noreturn die(const char *str, struct pt_regs *regs)
|
void __noreturn die(const char *str, struct pt_regs *regs)
|
||||||
|
@ -384,7 +379,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
|
||||||
|
|
||||||
oops_enter();
|
oops_enter();
|
||||||
|
|
||||||
if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs),
|
if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_nr,
|
||||||
SIGSEGV) == NOTIFY_STOP)
|
SIGSEGV) == NOTIFY_STOP)
|
||||||
sig = 0;
|
sig = 0;
|
||||||
|
|
||||||
|
@ -470,7 +465,7 @@ asmlinkage void do_be(struct pt_regs *regs)
|
||||||
printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
|
printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
|
||||||
data ? "Data" : "Instruction",
|
data ? "Data" : "Instruction",
|
||||||
field, regs->cp0_epc, field, regs->regs[31]);
|
field, regs->cp0_epc, field, regs->regs[31]);
|
||||||
if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs),
|
if (notify_die(DIE_OOPS, "bus error", regs, 0, current->thread.trap_nr,
|
||||||
SIGBUS) == NOTIFY_STOP)
|
SIGBUS) == NOTIFY_STOP)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -826,7 +821,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
prev_state = exception_enter();
|
prev_state = exception_enter();
|
||||||
if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
|
if (notify_die(DIE_FP, "FP exception", regs, 0, current->thread.trap_nr,
|
||||||
SIGFPE) == NOTIFY_STOP)
|
SIGFPE) == NOTIFY_STOP)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -882,11 +877,12 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
|
||||||
char b[40];
|
char b[40];
|
||||||
|
|
||||||
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
|
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
|
||||||
if (kgdb_ll_trap(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
if (kgdb_ll_trap(DIE_TRAP, str, regs, code, current->thread.trap_nr,
|
||||||
|
SIGTRAP) == NOTIFY_STOP)
|
||||||
return;
|
return;
|
||||||
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
|
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
|
||||||
|
|
||||||
if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs),
|
if (notify_die(DIE_TRAP, str, regs, code, current->thread.trap_nr,
|
||||||
SIGTRAP) == NOTIFY_STOP)
|
SIGTRAP) == NOTIFY_STOP)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -948,6 +944,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
|
||||||
set_fs(KERNEL_DS);
|
set_fs(KERNEL_DS);
|
||||||
|
|
||||||
prev_state = exception_enter();
|
prev_state = exception_enter();
|
||||||
|
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
|
||||||
if (get_isa16_mode(regs->cp0_epc)) {
|
if (get_isa16_mode(regs->cp0_epc)) {
|
||||||
u16 instr[2];
|
u16 instr[2];
|
||||||
|
|
||||||
|
@ -989,13 +986,13 @@ asmlinkage void do_bp(struct pt_regs *regs)
|
||||||
switch (bcode) {
|
switch (bcode) {
|
||||||
case BRK_KPROBE_BP:
|
case BRK_KPROBE_BP:
|
||||||
if (notify_die(DIE_BREAK, "debug", regs, bcode,
|
if (notify_die(DIE_BREAK, "debug", regs, bcode,
|
||||||
regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
|
||||||
goto out;
|
goto out;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
case BRK_KPROBE_SSTEPBP:
|
case BRK_KPROBE_SSTEPBP:
|
||||||
if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode,
|
if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode,
|
||||||
regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
|
||||||
goto out;
|
goto out;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -1028,6 +1025,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
|
||||||
set_fs(get_ds());
|
set_fs(get_ds());
|
||||||
|
|
||||||
prev_state = exception_enter();
|
prev_state = exception_enter();
|
||||||
|
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
|
||||||
if (get_isa16_mode(regs->cp0_epc)) {
|
if (get_isa16_mode(regs->cp0_epc)) {
|
||||||
if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
|
if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
|
||||||
__get_user(instr[1], (u16 __user *)(epc + 2)))
|
__get_user(instr[1], (u16 __user *)(epc + 2)))
|
||||||
|
@ -1094,8 +1092,9 @@ asmlinkage void do_ri(struct pt_regs *regs)
|
||||||
no_r2_instr:
|
no_r2_instr:
|
||||||
|
|
||||||
prev_state = exception_enter();
|
prev_state = exception_enter();
|
||||||
|
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
|
||||||
|
|
||||||
if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs),
|
if (notify_die(DIE_RI, "RI Fault", regs, 0, current->thread.trap_nr,
|
||||||
SIGILL) == NOTIFY_STOP)
|
SIGILL) == NOTIFY_STOP)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1444,8 +1443,9 @@ asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr)
|
||||||
enum ctx_state prev_state;
|
enum ctx_state prev_state;
|
||||||
|
|
||||||
prev_state = exception_enter();
|
prev_state = exception_enter();
|
||||||
|
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
|
||||||
if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,
|
if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,
|
||||||
regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP)
|
current->thread.trap_nr, SIGFPE) == NOTIFY_STOP)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Clear MSACSR.Cause before enabling interrupts */
|
/* Clear MSACSR.Cause before enabling interrupts */
|
||||||
|
|
|
@ -57,12 +57,10 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
|
||||||
|
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
/*
|
/*
|
||||||
* This is to notify the fault handler of the kprobes. The
|
* This is to notify the fault handler of the kprobes.
|
||||||
* exception code is redundant as it is also carried in REGS,
|
|
||||||
* but we pass it anyhow.
|
|
||||||
*/
|
*/
|
||||||
if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
|
if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
|
||||||
(regs->cp0_cause >> 2) & 0x1f, SIGSEGV) == NOTIFY_STOP)
|
current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -224,6 +222,7 @@ bad_area_nosemaphore:
|
||||||
print_vma_addr(" ", regs->regs[31]);
|
print_vma_addr(" ", regs->regs[31]);
|
||||||
pr_info("\n");
|
pr_info("\n");
|
||||||
}
|
}
|
||||||
|
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
|
||||||
info.si_signo = SIGSEGV;
|
info.si_signo = SIGSEGV;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
/* info.si_code has been set above */
|
/* info.si_code has been set above */
|
||||||
|
@ -282,6 +281,7 @@ do_sigbus:
|
||||||
field, (unsigned long) regs->cp0_epc,
|
field, (unsigned long) regs->cp0_epc,
|
||||||
field, (unsigned long) regs->regs[31]);
|
field, (unsigned long) regs->regs[31]);
|
||||||
#endif
|
#endif
|
||||||
|
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
|
||||||
tsk->thread.cp0_badvaddr = address;
|
tsk->thread.cp0_badvaddr = address;
|
||||||
info.si_signo = SIGBUS;
|
info.si_signo = SIGBUS;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue