lkml.org 
[lkml]   [2005]   [Jul]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch] compress the stack layout of do_page_fault(), x86

    this patch pushes the creation of a rare signal frame (SIGBUS or
    SIGSEGV) into a separate function, thus saving stackspace in the main
    do_page_fault() stackframe. The effect is 132 bytes less of stack used
    by the typical do_page_fault() invocation - resulting in a denser
    cache-layout.

    (another minor effect is that in case of kernel crashes that come from a
    pagefault, we add less space to the already existing frame, giving the
    crash functions a slightly higher chance to do their stuff without
    overflowing the stack.)

    (the changes also result in slightly cleaner code.)

    build and boot tested.

    Ingo

    Signed-off-by: Ingo Molnar <mingo@elte.hu>

    Index: linux/arch/i386/mm/fault.c
    ===================================================================
    --- linux.orig/arch/i386/mm/fault.c
    +++ linux/arch/i386/mm/fault.c
    @@ -201,6 +201,18 @@ static inline int is_prefetch(struct pt_
    return 0;
    }

    +static void force_sig_info_fault(int si_signo, int si_code,
    + unsigned long address, struct task_struct *tsk)
    +{
    + siginfo_t info;
    +
    + info.si_signo = SIGSEGV;
    + info.si_errno = 0;
    + info.si_code = si_code;
    + info.si_addr = (void __user *)address;
    + force_sig_info(SIGSEGV, &info, tsk);
    +}
    +
    fastcall void do_invalid_op(struct pt_regs *, unsigned long);

    /*
    @@ -220,9 +232,8 @@ fastcall notrace void do_page_fault(stru
    struct vm_area_struct * vma;
    unsigned long address;
    unsigned long page;
    - int write;
    - siginfo_t info;
    -
    + int write, si_code;
    +
    /* get the address */
    __asm__("movl %%cr2,%0":"=r" (address));
    trace_special(regs->eip, error_code, address);
    @@ -236,7 +247,7 @@ fastcall notrace void do_page_fault(stru

    tsk = current;

    - info.si_code = SEGV_MAPERR;
    + si_code = SEGV_MAPERR;

    /*
    * We fault-in kernel-space virtual memory on-demand. The
    @@ -316,7 +327,7 @@ fastcall notrace void do_page_fault(stru
    * we can handle it..
    */
    good_area:
    - info.si_code = SEGV_ACCERR;
    + si_code = SEGV_ACCERR;
    write = 0;
    switch (error_code & 3) {
    default: /* 3: write, present */
    @@ -390,11 +401,7 @@ bad_area_nosemaphore:
    /* Kernel addresses are always protection faults */
    tsk->thread.error_code = error_code | (address >= TASK_SIZE);
    tsk->thread.trap_no = 14;
    - info.si_signo = SIGSEGV;
    - info.si_errno = 0;
    - /* info.si_code has been set above */
    - info.si_addr = (void __user *)address;
    - force_sig_info(SIGSEGV, &info, tsk);
    + force_sig_info_fault(SIGSEGV, si_code, address, tsk);
    return;
    }

    @@ -500,11 +507,7 @@ do_sigbus:
    tsk->thread.cr2 = address;
    tsk->thread.error_code = error_code;
    tsk->thread.trap_no = 14;
    - info.si_signo = SIGBUS;
    - info.si_errno = 0;
    - info.si_code = BUS_ADRERR;
    - info.si_addr = (void __user *)address;
    - force_sig_info(SIGBUS, &info, tsk);
    + force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
    return;

    vmalloc_fault:
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-07-09 16:45    [W:0.028 / U:120.440 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site