patch-2.4.21 linux-2.4.21/arch/x86_64/mm/fault.c
Next file: linux-2.4.21/arch/x86_64/mm/init.c
Previous file: linux-2.4.21/arch/x86_64/lib/usercopy.c
Back to the patch index
Back to the overall index
- Lines: 142
- Date:
2003-06-13 07:51:32.000000000 -0700
- Orig file:
linux-2.4.20/arch/x86_64/mm/fault.c
- Orig date:
2002-11-28 15:53:12.000000000 -0800
diff -urN linux-2.4.20/arch/x86_64/mm/fault.c linux-2.4.21/arch/x86_64/mm/fault.c
@@ -30,9 +30,6 @@
#include <asm/proto.h>
#include <asm/kdebug.h>
-spinlock_t pcrash_lock;
-int crashing_cpu;
-
extern spinlock_t console_lock, timerlist_lock;
void bust_spinlocks(int yes)
@@ -60,29 +57,41 @@
}
}
+static int bad_address(void *p)
+{
+ unsigned long dummy;
+ return __get_user(dummy, (unsigned long *)p);
+}
+
void dump_pagetable(unsigned long address)
{
- static char *name[] = { "PML4", "PGD", "PDE", "PTE" };
- int i, shift;
- unsigned long page;
-
- shift = 9+9+9+12;
- address &= ~0xFFFF000000000000UL;
- asm("movq %%cr3,%0" : "=r" (page));
- for (i = 0; i < 4; i++) {
- unsigned long *padr = (unsigned long *) __va(page);
- padr += (address >> shift) & 0x1FFU;
- if (__get_user(page, padr)) {
- printk("%s: bad %p\n", name[i], padr);
- break;
- }
- printk("%s: %016lx ", name[i], page);
- if ((page & (1 | (1<<7))) != 1) /* Not present or 2MB page */
- break;
- page &= ~0xFFFUL;
- shift -= (i == 0) ? 12 : 9;
- }
+ pml4_t *pml4;
+ asm("movq %%cr3,%0" : "=r" (pml4));
+
+ pml4 = __va((unsigned long)pml4 & PHYSICAL_PAGE_MASK);
+ pml4 += pml4_index(address);
+ printk("PML4 %lx ", pml4_val(*pml4));
+ if (bad_address(pml4)) goto bad;
+ if (!pml4_present(*pml4)) goto ret;
+
+ pgd_t *pgd = __pgd_offset_k((pgd_t *)pml4_page(*pml4), address);
+ if (bad_address(pgd)) goto bad;
+ printk("PGD %lx ", pgd_val(*pgd));
+ if (!pgd_present(*pgd)) goto ret;
+
+ pmd_t *pmd = pmd_offset(pgd, address);
+ if (bad_address(pmd)) goto bad;
+ printk("PMD %lx ", pmd_val(*pmd));
+ if (!pmd_present(*pmd)) goto ret;
+
+ pte_t *pte = pte_offset(pmd, address);
+ if (bad_address(pte)) goto bad;
+ printk("PTE %lx", pte_val(*pte));
+ret:
printk("\n");
+ return;
+bad:
+ printk("BAD\n");
}
int page_fault_trace;
@@ -112,15 +121,18 @@
/* get the address */
__asm__("movq %%cr2,%0":"=r" (address));
+ if (regs->eflags & X86_EFLAGS_IF)
+ __sti();
+
#ifdef CONFIG_CHECKING
if (page_fault_trace)
- printk("pfault %d rip:%lx rsp:%lx cs:%lu ss:%lu addr %lx error %lx\n",
- stack_smp_processor_id(), regs->rip,regs->rsp,regs->cs,
- regs->ss,address,error_code);
+ printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
+ regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code);
+
{
unsigned long gs;
- struct x8664_pda *pda = cpu_pda + stack_smp_processor_id();
+ struct x8664_pda *pda = cpu_pda + safe_smp_processor_id();
rdmsrl(MSR_GS_BASE, gs);
if (gs != (unsigned long)pda) {
wrmsrl(MSR_GS_BASE, pda);
@@ -217,14 +229,11 @@
/* User mode accesses just cause a SIGSEGV */
if (error_code & 4) {
- if (exception_trace) {
-#if 1
- dump_pagetable(address);
-#endif
+ if (exception_trace)
printk("%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
current->comm, current->pid, address, regs->rip,
regs->rsp, error_code);
- }
+
tsk->thread.cr2 = address;
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 14;
@@ -256,14 +265,6 @@
console_verbose();
bust_spinlocks(1);
- if (!in_interrupt()) {
- if (!spin_trylock(&pcrash_lock)) {
- if (crashing_cpu != smp_processor_id())
- spin_lock(&pcrash_lock);
- }
- crashing_cpu = smp_processor_id();
- }
-
if (address < PAGE_SIZE)
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
else
@@ -272,14 +273,7 @@
printk(" printing rip:\n");
printk("%016lx\n", regs->rip);
dump_pagetable(address);
-
die("Oops", regs, error_code);
-
- if (!in_interrupt()) {
- crashing_cpu = -1; /* small harmless window */
- spin_unlock(&pcrash_lock);
- }
-
bust_spinlocks(0);
do_exit(SIGKILL);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)