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    [W:0.031 / U:0.656 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site