{
int k;
for (k = 0; k < N_EXCEPTION_STACKS; k++) {
- unsigned long end = init_tss[cpu].ist[k] + EXCEPTION_STKSZ;
+ struct tss_struct *tss = &per_cpu(init_tss, cpu);
+ unsigned long end = tss->ist[k] + EXCEPTION_STKSZ;
- if (stack >= init_tss[cpu].ist[k] && stack <= end)
+ if (stack >= tss->ist[k] && stack <= end)
return (unsigned long *)end;
}
- return 0;
+ return NULL;
}
/*
if (estack_end) {
while (stack < estack_end) {
addr = *stack++;
- if (kernel_text_address(addr)) {
+ if (__kernel_text_address(addr)) {
i += printk_address(addr);
i += printk(" ");
if (i > 50) {
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
- if (kernel_text_address(addr)) {
+ if (__kernel_text_address(addr)) {
i += printk_address(addr);
i += printk(" ");
if (i > 50) {
while (((long) stack & (THREAD_SIZE-1)) != 0) {
addr = *stack++;
- if (kernel_text_address(addr)) {
+ if (__kernel_text_address(addr)) {
i += printk_address(addr);
i += printk(" ");
if (i > 50) {
#ifdef CONFIG_DEBUG_PAGEALLOC
printk("DEBUG_PAGEALLOC");
#endif
- printk("\n");
+ printk("\n");
notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
show_registers(regs);
/* Executive summary in case the oops scrolled away */
#define DO_ERROR(trapnr, signr, str, name) \
asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
{ \
- if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \
+ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
+ == NOTIFY_STOP) \
return; \
do_trap(trapnr, signr, str, regs, error_code, NULL); \
}
info.si_signo = signr; \
info.si_errno = 0; \
info.si_code = sicode; \
- info.si_addr = (void *)siaddr; \
- if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \
+ info.si_addr = (void __user *)siaddr; \
+ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
+ == NOTIFY_STOP) \
return; \
do_trap(trapnr, signr, str, regs, error_code, &info); \
}
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
-DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
+DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
DO_ERROR(18, SIGSEGV, "reserved", reserved)
#define DO_ERROR_STACK(trapnr, signr, str, name) \
asmlinkage void *do_##name(struct pt_regs * regs, long error_code) \
{ \
struct pt_regs *pr = ((struct pt_regs *)(current->thread.rsp0))-1; \
- if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \
+ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
+ == NOTIFY_STOP) \
return regs; \
if (regs->cs & 3) { \
memcpy(pr, regs, sizeof(struct pt_regs)); \
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 13;
force_sig(SIGSEGV, tsk);
- return;
+ return;
}
/* kernel gp */
unsigned char reason = inb(0x61);
if (!(reason & 0xc0)) {
- if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) == NOTIFY_BAD)
+ if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
+ == NOTIFY_STOP)
return;
#ifdef CONFIG_X86_LOCAL_APIC
/*
unknown_nmi_error(reason, regs);
return;
}
- if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_BAD)
+ if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP)
return;
if (reason & 0x80)
mem_parity_error(reason, regs);
if ((regs->cs & 3) == 0)
goto clear_dr7;
- info.si_addr = (void *)regs->rip;
+ info.si_addr = (void __user *)regs->rip;
force_sig_info(SIGTRAP, &info, tsk);
clear_dr7:
asm volatile("movq %0,%%db7"::"r"(0UL));
return regs;
clear_TF_reenable:
- printk("clear_tf_reenable\n");
set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
clear_TF:
/* RED-PEN could cause spurious errors */
if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP)
- != NOTIFY_BAD)
+ != NOTIFY_STOP)
regs->eflags &= ~TF_MASK;
return regs;
}
+static int kernel_math_error(struct pt_regs *regs, char *str)
+{
+ const struct exception_table_entry *fixup;
+ fixup = search_exception_tables(regs->rip);
+ if (fixup) {
+ regs->rip = fixup->fixup;
+ return 1;
+ }
+ notify_die(DIE_GPF, str, regs, 0, 16, SIGFPE);
+#if 0
+ /* This should be a die, but warn only for now */
+ die(str, regs, 0);
+#else
+ printk(KERN_DEBUG "%s: %s at ", current->comm, str);
+ printk_address(regs->rip);
+ printk("\n");
+#endif
+ return 0;
+}
+
/*
* Note that we play around with the 'TS' bit in an attempt to get
* the correct behaviour even in the presence of the asynchronous
* IRQ13 behaviour
*/
-void math_error(void *rip)
+asmlinkage void do_coprocessor_error(struct pt_regs *regs)
{
+ void __user *rip = (void __user *)(regs->rip);
struct task_struct * task;
siginfo_t info;
unsigned short cwd, swd;
+
+ conditional_sti(regs);
+ if ((regs->cs & 3) == 0 &&
+ kernel_math_error(regs, "kernel x87 math error"))
+ return;
+
/*
* Save the info for the exception handler and clear the error.
*/
force_sig_info(SIGFPE, &info, task);
}
-asmlinkage void do_coprocessor_error(struct pt_regs * regs)
-{
- conditional_sti(regs);
- math_error((void *)regs->rip);
-}
-
asmlinkage void bad_intr(void)
{
printk("bad interrupt");
}
-static inline void simd_math_error(void *rip)
+asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
{
+ void __user *rip = (void __user *)(regs->rip);
struct task_struct * task;
siginfo_t info;
unsigned short mxcsr;
+ conditional_sti(regs);
+ if ((regs->cs & 3) == 0 &&
+ kernel_math_error(regs, "simd math error"))
+ return;
+
/*
* Save the info for the exception handler and clear the error.
*/
force_sig_info(SIGFPE, &info, task);
}
-asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs)
-{
- conditional_sti(regs);
- simd_math_error((void *)regs->rip);
-}
-
asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
{
}