lkml.org 
[lkml]   [2000]   [Jul]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [patch] 2.4.0-test2: %cr4 in a register dump
Brian Gerst wrote:
>
> Linus Torvalds wrote:
> >
> > On Wed, 5 Jul 2000, Brian Gerst wrote:
> >
> > > How about just trapping the illegal opcode exception then? (patch
> > > untested)
> >
> > Looks fine. Me likee, except for the fact that you should clear %0
> > (otherwise you'll have random crap in the "cr4" variable after a trap - I
> > realize that you zeroed the variable on a C source level, but gcc thinks
> > that your asm-statement will overwrite it, so ...)
> >
> > Linus
>
> Hmm, upon a closer look at the source, the illegal opcode trap isn't
> quite setup to handle kernel faults properly. I assumed it did since I
> got the idea from the 3DNow memcpy code, which uses the illegal opcode
> trap for the "prefetch" instruction. I am working on an updated patch.

As promised here is the updated patch. Previously, if an exception
(other than a general protection fault) occured in kernel mode, the trap
handlers would send a signal to userspace even if an exception handler
was found. Correct me if I'm wrong, but I don't think this should
happen.

--

Brian Gerstdiff -urN linux-2.4.0t3p3/arch/i386/kernel/process.c linux-cr4/arch/i386/kernel/process.c
--- linux-2.4.0t3p3/arch/i386/kernel/process.c Sat Jun 24 09:09:15 2000
+++ linux-cr4/arch/i386/kernel/process.c Wed Jul 5 20:20:59 2000
@@ -344,7 +344,7 @@

void show_regs(struct pt_regs * regs)
{
- long cr0 = 0L, cr2 = 0L, cr3 = 0L;
+ unsigned long cr0, cr2, cr3, cr4;

printk("\n");
printk("EIP: %04x:[<%08lx>]",0xffff & regs->xcs,regs->eip);
@@ -361,7 +361,18 @@
__asm__("movl %%cr0, %0": "=r" (cr0));
__asm__("movl %%cr2, %0": "=r" (cr2));
__asm__("movl %%cr3, %0": "=r" (cr3));
- printk("CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3);
+ /* This could fault if %cr4 does not exist */
+ __asm__("1: movl %%cr4, %0 \n"
+ "2: \n"
+ ".section .fixup,\"ax\" \n"
+ "3: xorl %0, %0 \n"
+ " jmp 2b \n"
+ ".previous \n"
+ ".section __ex_table,\"a\" \n"
+ ".long 1b,3b \n"
+ ".previous \n"
+ : "=r" (cr4));
+ printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
}

/*
diff -urN linux-2.4.0t3p3/arch/i386/kernel/traps.c linux-cr4/arch/i386/kernel/traps.c
--- linux-2.4.0t3p3/arch/i386/kernel/traps.c Sat Jun 24 09:09:16 2000
+++ linux-cr4/arch/i386/kernel/traps.c Wed Jul 5 21:50:20 2000
@@ -77,68 +77,6 @@
console_loglevel = 15;
}

-#define DO_ERROR(trapnr, signr, str, name, tsk) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-{ \
- tsk->thread.error_code = error_code; \
- tsk->thread.trap_no = trapnr; \
- die_if_no_fixup(str,regs,error_code); \
- force_sig(signr, tsk); \
-}
-
-#define DO_ERROR_INFO(trapnr, signr, str, name, tsk, sicode, siaddr) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-{ \
- siginfo_t info; \
- tsk->thread.error_code = error_code; \
- tsk->thread.trap_no = trapnr; \
- die_if_no_fixup(str,regs,error_code); \
- info.si_signo = signr; \
- info.si_errno = 0; \
- info.si_code = sicode; \
- info.si_addr = (void *)siaddr; \
- force_sig_info(signr, &info, tsk); \
-}
-
-#define DO_VM86_ERROR(trapnr, signr, str, name, tsk) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-{ \
- lock_kernel(); \
- if (regs->eflags & VM_MASK) { \
- if (!handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr)) \
- goto out; \
- /* else fall through */ \
- } \
- tsk->thread.error_code = error_code; \
- tsk->thread.trap_no = trapnr; \
- force_sig(signr, tsk); \
- die_if_kernel(str,regs,error_code); \
-out: \
- unlock_kernel(); \
-}
-
-#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, tsk, sicode, siaddr) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-{ \
- siginfo_t info; \
- lock_kernel(); \
- if (regs->eflags & VM_MASK) { \
- if (!handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr)) \
- goto out; \
- /* else fall through */ \
- } \
- tsk->thread.error_code = error_code; \
- tsk->thread.trap_no = trapnr; \
- info.si_signo = signr; \
- info.si_errno = 0; \
- info.si_code = sicode; \
- info.si_addr = (void *)siaddr; \
- force_sig_info(signr, &info, tsk); \
- die_if_kernel(str,regs,error_code); \
-out: \
- unlock_kernel(); \
-}
-
asmlinkage void divide_error(void);
asmlinkage void debug(void);
asmlinkage void nmi(void);
@@ -285,20 +223,6 @@
die(str, regs, err);
}

-static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
-{
- if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs))
- {
- unsigned long fixup;
- fixup = search_exception_table(regs->eip);
- if (fixup) {
- regs->eip = fixup;
- return;
- }
- die(str, regs, err);
- }
-}
-
static inline unsigned long get_cr2(void)
{
unsigned long address;
@@ -306,6 +230,76 @@
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
return address;
+}
+
+static void inline do_trap(int trapnr, int signr, char *str, struct task_struct *tsk, int vm86,
+ struct pt_regs * regs, long error_code, siginfo_t *info)
+{
+ unsigned long fixup;
+ int ret;
+
+ if (vm86 && regs->eflags & VM_MASK)
+ goto vm86_trap;
+ if (!(regs->xcs & 3))
+ goto kernel_trap;
+
+trap_signal:
+ tsk->thread.error_code = error_code;
+ tsk->thread.trap_no = trapnr;
+ if (info)
+ force_sig_info(signr, info, tsk);
+ else
+ force_sig(signr, tsk);
+ return;
+
+kernel_trap:
+ fixup = search_exception_table(regs->eip);
+ if (fixup)
+ regs->eip = fixup;
+ else
+ die(str, regs, error_code);
+ return;
+
+vm86_trap:
+ lock_kernel();
+ ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
+ unlock_kernel();
+ if (ret) goto trap_signal;
+ return;
+}
+
+#define DO_ERROR(trapnr, signr, str, name, tsk) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+{ \
+ do_trap(trapnr, signr, str, tsk, 0, regs, error_code, NULL); \
+}
+
+#define DO_ERROR_INFO(trapnr, signr, str, name, tsk, sicode, siaddr) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+{ \
+ siginfo_t info; \
+ info.si_signo = signr; \
+ info.si_errno = 0; \
+ info.si_code = sicode; \
+ info.si_addr = (void *)siaddr; \
+ do_trap(trapnr, signr, str, tsk, 0, regs, error_code, &info); \
+}
+
+#define DO_VM86_ERROR(trapnr, signr, str, name, tsk) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+{ \
+ do_trap(trapnr, signr, str, tsk, 1, regs, error_code, NULL); \
+}
+
+#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, tsk, sicode, siaddr) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+{ \
+ siginfo_t info; \
+ info.si_signo = signr; \
+ info.si_errno = 0; \
+ info.si_code = sicode; \
+ info.si_addr = (void *)siaddr; \
+ do_trap(trapnr, signr, str, tsk, 1, regs, error_code, &info); \
}

DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, current, FPE_INTDIV, regs->eip)
\
 
 \ /
  Last update: 2005-03-22 13:57    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site