X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fmm%2Ffault.c;h=a509237c4815ed6f8443e85b973dda2a0f2c0688;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=e929384767b9afadbbd809c518717120701c7236;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index e92938476..a509237c4 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -112,9 +112,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, } /* Decode the code segment base from the descriptor */ - base = (desc[0] >> 16) | - ((desc[1] & 0xff) << 16) | - (desc[1] & 0xff000000); + base = get_desc_base((unsigned long *)desc); if (seg & (1<<2)) { up(¤t->mm->context.sem); @@ -201,7 +199,7 @@ static inline int is_prefetch(struct pt_regs *regs, unsigned long addr, return 0; } -asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); +fastcall void do_invalid_op(struct pt_regs *, unsigned long); /* * This routine handles page faults. It determines the address, @@ -213,7 +211,7 @@ asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user-mode */ -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) +fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code) { struct task_struct *tsk; struct mm_struct *mm; @@ -518,6 +516,7 @@ vmalloc_fault: int index = pgd_index(address); unsigned long pgd_paddr; pgd_t *pgd, *pgd_k; + pud_t *pud, *pud_k; pmd_t *pmd, *pmd_k; pte_t *pte_k; @@ -530,11 +529,17 @@ vmalloc_fault: /* * set_pgd(pgd, *pgd_k); here would be useless on PAE - * and redundant with the set_pmd() on non-PAE. + * and redundant with the set_pmd() on non-PAE. As would + * set_pud. */ - pmd = pmd_offset(pgd, address); - pmd_k = pmd_offset(pgd_k, address); + pud = pud_offset(pgd, address); + pud_k = pud_offset(pgd_k, address); + if (!pud_present(*pud_k)) + goto no_context; + + pmd = pmd_offset(pud, address); + pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) goto no_context; set_pmd(pmd, *pmd_k);