Re: [Crash-utility] [PATCH} crash 4.0-2.8 fixes to make it workonx86_64 for 2.6.14

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dave,

Here is the latest patch to make crash work on 2.6.14 kernel -
with fixes for 4-level pagetables also.

I changes & naming are kind of hacky (especially with naming) 
-- but to cleanup it completely and have backward compatibility 
needs more work. We should get rid of PML4 completely and
move to PGD/PUD/PMD/PTE.

Thanks,
Badari

elm3a242:~/crash-4.0-2.8 # ./crash

crash 4.0-2.8
Copyright (C) 2002, 2003, 2004, 2005  Red Hat, Inc.
Copyright (C) 2004, 2005  IBM Corporation
Copyright (C) 1999-2005  Hewlett-Packard Co
Copyright (C) 1999, 2002  Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public
License,
and you are welcome to change it and/or distribute copies of it under
certain conditions.  Enter "help copying" to see the conditions.
This program has absolutely no warranty.  Enter "help warranty" for
details.

GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "x86_64-unknown-linux-gnu"...

      KERNEL: /usr/src/linux-2.6.14.madv/vmlinux
    DUMPFILE: /dev/mem
        CPUS: 2
        DATE: Thu Nov  3 08:25:50 2005
      UPTIME: 07:12:24
LOAD AVERAGE: 0.60, 0.43, 0.18
       TASKS: 62
    NODENAME: elm3a242
     RELEASE: 2.6.14
     VERSION: #3 SMP PREEMPT Wed Nov 2 03:08:36 PST 2005
     MACHINE: x86_64  (3000 Mhz)
      MEMORY: 4.6 GB
         PID: 31320
     COMMAND: "crash"
        TASK: ffff810122f11860  [THREAD_INFO: ffff8100987f6000]
         CPU: 1
       STATE: TASK_RUNNING (ACTIVE)

crash> set
    PID: 31320
COMMAND: "crash"
   TASK: ffff810122f11860  [THREAD_INFO: ffff8100987f6000]
    CPU: 1
  STATE: TASK_RUNNING (ACTIVE)
crash> vm
PID: 31320  TASK: ffff810122f11860  CPU: 1   COMMAND: "crash"
       MM               PGD          RSS    TOTAL_VM
ffff810122e93700  ffff810099584000  148044k   86512k
      VMA           START       END     FLAGS FILE
ffff810122438cc0     400000     754000   1875 /root/crash-4.0-2.8/crash
ffff810122438590     853000     8b0000 101873 /root/crash-4.0-2.8/crash
ffff810122438d78     8b0000    1c2e000 100073
ffff810122438088 2aaaaaaab000 2aaaaaac0000    875 /lib64/ld-2.3.3.so
ffff8101224389e0 2aaaaaac0000 2aaaaaac2000 100073
ffff810123caa4d8 2aaaaaac2000 2aaaaaaf5000
71 /usr/lib/locale/en_US.utf8/LC_CTYPE
ffff810123caaee8 2aaaaaaf5000 2aaaaaafb000
d1 /usr/lib64/gconv/gconv-modules.cache
ffff8101136809e0 2aaaaaafb000 2aaaaaaff000 100073
ffff8101224387b8 2aaaaabc0000 2aaaaabc2000 100873 /lib64/ld-2.3.3.so
ffff810122438648 2aaaaabc2000 2aaaaac16000     75 /lib64/tls/libm.so.6
ffff810122438700 2aaaaac16000 2aaaaacc2000     70 /lib64/tls/libm.so.6
ffff8101276f4590 2aaaaacc2000 2aaaaad19000 100073 /lib64/tls/libm.so.6
ffff8101276f4a98 2aaaaad19000 2aaaaad1a000 100073
ffff810120ff1590 2aaaaad1a000 2aaaaad64000
75 /lib64/libncurses.so.5.4
ffff8101276f4b50 2aaaaad64000 2aaaaae1a000
70 /lib64/libncurses.so.5.4
ffff810120ff14d8 2aaaaae1a000 2aaaaae7a000
100073 /lib64/libncurses.so.5.4
ffff810120ff1140 2aaaaae7a000 2aaaaae7b000 100073

crash> rd -u 0x400000
          400000:  00010102464c457f                    .ELF....
crash> rd -u 2aaaaaaab000
    2aaaaaaab000:  00010102464c457f                    .ELF....

crash> mod
     MODULE       NAME          SIZE  OBJECT FILE
ffffffff88012600  dm_mod       70872  (not loaded)  [CONFIG_KALLSYMS]
ffffffff8805ef80  ipv6        312832  (not loaded)  [CONFIG_KALLSYMS]
ffffffff8806e200  parport      47244  (not loaded)  [CONFIG_KALLSYMS]
ffffffff88073800  lp           17232  (not loaded)  [CONFIG_KALLSYMS]
ffffffff8807fd00  parport_pc   33896  (not loaded)  [CONFIG_KALLSYMS]
ffffffff8808ab00  usbserial    39280  (not loaded)  [CONFIG_KALLSYMS]
ffffffff8808e900  hw_random     7968  (not loaded)  [CONFIG_KALLSYMS]
ffffffff88098f80  uhci_hcd     38304  (not loaded)  [CONFIG_KALLSYMS]
ffffffff880a4600  ehci_hcd     39944  (not loaded)  [CONFIG_KALLSYMS]
ffffffff880acd80  i2c_core     29568  (not loaded)  [CONFIG_KALLSYMS]
ffffffff880b1700  i2c_i801     11540  (not loaded)  [CONFIG_KALLSYMS]
ffffffff880b6000  joydev       13952  (not loaded)  [CONFIG_KALLSYMS]
ffffffff880bb000  edd          13984  (not loaded)  [CONFIG_KALLSYMS]

--- crash-4.0-2.8/defs.h	2005-10-21 11:36:32.000000000 -0700
+++ crash-4.0-2.8.working/defs.h	2005-11-03 11:05:55.128141480 -0800
@@ -652,9 +652,11 @@ struct machdep_table {
         	char *func;
         	char **file;
 	} *line_number_hooks;
+	char last_pml_read;
 	ulong last_pgd_read;
 	ulong last_pmd_read;
 	ulong last_ptbl_read;
+	char *pml;
 	char *pgd;
  	char *pmd;	
 	char *ptbl;
@@ -676,10 +678,18 @@ struct machdep_table {
 
 extern struct machdep_table *machdep;
 
+#define IS_LAST_PML_READ(pgd)     ((ulong)(pml) == machdep->last_pml_read)
 #define IS_LAST_PGD_READ(pgd)     ((ulong)(pgd) == machdep->last_pgd_read)
 #define IS_LAST_PMD_READ(pmd)     ((ulong)(pmd) == machdep->last_pmd_read)
 #define IS_LAST_PTBL_READ(ptbl)   ((ulong)(ptbl) == machdep->last_ptbl_read)
 
+#define FILL_UPML(PML, TYPE, SIZE) 					    \
+    if (!IS_LAST_PML_READ(PML)) {                                           \
+            readmem((ulonglong)((ulong)(PML)), TYPE, machdep->pml,          \
+                    SIZE, "pml page", FAULT_ON_ERROR);                      \
+            machdep->last_pml_read = (ulong)(PML);                          \
+    }								            
+
 #define FILL_PGD(PGD, TYPE, SIZE) 					    \
     if (!IS_LAST_PGD_READ(PGD)) {                                           \
             readmem((ulonglong)((ulong)(PGD)), TYPE, machdep->pgd,          \
@@ -1740,14 +1750,14 @@ struct load_module {
 #define _64BIT_
 #define MACHINE_TYPE       "X86_64"
 
-#define USERSPACE_TOP         0x0000008000000000
-#define __START_KERNEL_map    0xffffffff80000000
-#define PAGE_OFFSET           0x0000010000000000
+#define USERSPACE_TOP	(x86_64_userspace_top)
+#define PAGE_OFFSET	(x86_64_page_offset)
+#define VMALLOC_START	(x86_64_vmalloc_start_addr)
+#define VMALLOC_END	(x86_64_vmalloc_end)
+#define MODULES_VADDR	(x86_64_modules_vaddr) 
+#define MODULES_END	(x86_64_modules_end)
 
-#define VMALLOC_START   0xffffff0000000000
-#define VMALLOC_END     0xffffff7fffffffff
-#define MODULES_VADDR   0xffffffffa0000000
-#define MODULES_END     0xffffffffafffffff
+#define __START_KERNEL_map    0xffffffff80000000
 #define MODULES_LEN     (MODULES_END - MODULES_VADDR)
 
 #define PTOV(X)               ((unsigned long)(X)+(machdep->kvbase))
--- crash-4.0-2.8/x86_64.c	2005-10-21 11:36:32.000000000 -0700
+++ crash-4.0-2.8.working/x86_64.c	2005-11-03 11:26:31.793139824 -0800
@@ -19,6 +19,7 @@
 
 static int x86_64_kvtop(struct task_context *, ulong, physaddr_t *, int);
 static int x86_64_uvtop(struct task_context *, ulong, physaddr_t *, int);
+static int x86_64_uvtop_level4(struct task_context *, ulong, physaddr_t *, int);
 static ulong x86_64_vmalloc_start(void);
 static int x86_64_is_task_addr(ulong);
 static int x86_64_verify_symbol(const char *, ulong, char);
@@ -65,6 +66,12 @@ static void x86_64_cpu_pda_init(void);
 static void x86_64_ist_init(void);
 static void x86_64_post_init(void);
 
+ulong x86_64_userspace_top;
+ulong x86_64_page_offset;
+ulong x86_64_vmalloc_start_addr;
+ulong x86_64_vmalloc_end;
+ulong x86_64_modules_vaddr;
+ulong x86_64_modules_end;
 
 struct machine_specific x86_64_machine_specific = { 0 };
 
@@ -87,6 +94,8 @@ x86_64_init(int when)
                 machdep->pageoffset = machdep->pagesize - 1;
                 machdep->pagemask = ~((ulonglong)machdep->pageoffset);
 		machdep->stacksize = machdep->pagesize * 2;
+                if ((machdep->pml = (char *)malloc(PAGESIZE())) == NULL)
+                        error(FATAL, "cannot malloc pml space.");
                 if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL)
                         error(FATAL, "cannot malloc pgd space.");
                 if ((machdep->pmd = (char *)malloc(PAGESIZE())) == NULL)
@@ -96,6 +105,7 @@ x86_64_init(int when)
 		if ((machdep->machspec->pml4 = 
 			(char *)malloc(PAGESIZE())) == NULL)
                         error(FATAL, "cannot malloc pml4 space.");
+                machdep->last_pml_read = 0;
                 machdep->last_pgd_read = 0;
                 machdep->last_pmd_read = 0;
                 machdep->last_ptbl_read = 0;
@@ -105,6 +115,25 @@ x86_64_init(int when)
 		break;
 
 	case PRE_GDB:
+		if (symbol_exists("boot_vmalloc_pgt")) {
+			/* 2.4 & pre-2.6.11 layout */
+			x86_64_userspace_top = 0x0000008000000000;
+			x86_64_page_offset = 0x0000010000000000;
+			x86_64_vmalloc_start_addr = 0xffffff0000000000;
+			x86_64_vmalloc_end = 0xffffff7fffffffff;
+			x86_64_modules_vaddr = 0xffffffffa0000000;
+			x86_64_modules_end = 0xffffffffafffffff;
+	        	machdep->uvtop = x86_64_uvtop;
+		} else {
+			/* > 2.6.10 layout */
+			x86_64_userspace_top = 0x0000800000000000;
+			x86_64_page_offset = 0xffff810000000000;
+			x86_64_vmalloc_start_addr = 0xffffc20000000000;
+			x86_64_vmalloc_end = 0xffffe1ffffffffff;
+			x86_64_modules_vaddr = 0xffffffff88000000;
+			x86_64_modules_end = 0xfffffffffff00000;
+	        	machdep->uvtop = x86_64_uvtop_level4;
+		}
 	        machdep->kvbase = (ulong)PAGE_OFFSET;
 		machdep->identity_map_base = (ulong)PAGE_OFFSET;
                 machdep->is_kvaddr = x86_64_is_kvaddr;
@@ -112,7 +141,6 @@ x86_64_init(int when)
 	        machdep->eframe_search = x86_64_eframe_search;
 	        machdep->back_trace = x86_64_low_budget_back_trace_cmd;
 	        machdep->processor_speed = x86_64_processor_speed;
-	        machdep->uvtop = x86_64_uvtop;
 	        machdep->kvtop = x86_64_kvtop;
 	        machdep->get_task_pgd = x86_64_get_task_pgd;
 		machdep->get_stack_frame = x86_64_get_stack_frame;
@@ -329,9 +357,13 @@ x86_64_cpu_pda_init(void)
 	for (i = cpus = 0; i < nr_pda; i++) {
 		if (!CPU_PDA_READ(i, cpu_pda_buf))
 			break;
-		level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+		if (VALID_MEMBER(x8664_pda_level4_pgt)) {
+			level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+			if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+				break;
+		}
 		cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
-		if (!VALID_LEVEL4_PGT_ADDR(level4_pgt) || (cpunumber != cpus))
+		if (cpunumber != cpus)
 			break;
 		cpus++;
 
@@ -623,6 +655,114 @@ x86_64_is_uvaddr(ulong addr, struct task
  */
 
 static int
+x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose)
+{
+	ulong mm;
+	ulong *pml;
+	ulong pml_paddr;
+	ulong pml_pte;
+	ulong *pgd;
+	ulong pgd_paddr;
+	ulong pgd_pte;
+	ulong *pmd;
+	ulong pmd_paddr;
+	ulong pmd_pte;
+	ulong *ptep;
+	ulong pte_paddr;
+	ulong pte;
+	physaddr_t physpage;
+
+	if (!tc)
+		error(FATAL, "current context invalid\n");
+
+	*paddr = 0;
+
+	if (IS_KVADDR(uvaddr))
+		return x86_64_kvtop(tc, uvaddr, paddr, verbose);
+
+	if ((mm = task_mm(tc->task, TRUE)))
+		pml = ULONG_PTR(tt->mm_struct + OFFSET(mm_struct_pgd));
+	else
+		readmem(tc->mm_struct + OFFSET(mm_struct_pgd), KVADDR, &pml,
+			sizeof(long), "mm_struct pgd", FAULT_ON_ERROR);
+
+	pml_paddr = x86_64_VTOP((ulong)pml);
+	FILL_UPML(pml_paddr, PHYSADDR, PAGESIZE());
+	pml = ((ulong *)pml_paddr) + pml4_index(uvaddr); 
+	pml_pte = ULONG(machdep->pml + PAGEOFFSET(pml));
+	if (verbose) 
+		fprintf(fp, "   PML: %lx => %lx\n", (ulong)pml, pml_pte);
+	if (!(pml_pte & _PAGE_PRESENT))
+		goto no_upage;
+
+	pgd_paddr = pml_pte & PHYSICAL_PAGE_MASK;
+	FILL_PGD(pgd_paddr, PHYSADDR, PAGESIZE());
+	pgd = ((ulong *)pgd_paddr) + pgd_index(uvaddr); 
+	pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(pgd));
+	if (verbose) 
+                fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pgd, pgd_pte);
+	if (!(pgd_pte & _PAGE_PRESENT))
+		goto no_upage;
+
+	/*
+         *  pmd = pmd_offset(pgd, address);
+	 */
+	pmd_paddr = pgd_pte & PHYSICAL_PAGE_MASK;
+	FILL_PMD(pmd_paddr, PHYSADDR, PAGESIZE());
+	pmd = ((ulong *)pmd_paddr) + pmd_index(uvaddr);
+	pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(pmd));
+        if (verbose) 
+                fprintf(fp, "   PMD: %lx => %lx\n", (ulong)pmd, pmd_pte);
+	if (!(pmd_pte & _PAGE_PRESENT))
+		goto no_upage;
+        if (pmd_pte & _PAGE_PSE) {
+                if (verbose) {
+                        fprintf(fp, "  PAGE: %lx  (2MB)\n\n", 
+				PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK);
+                        x86_64_translate_pte(pmd_pte, 0, 0);
+                }
+
+                physpage = (PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK) + 
+			(uvaddr & ~_2MB_PAGE_MASK);
+                *paddr = physpage;
+                return TRUE;
+        }
+
+        /*
+	 *  ptep = pte_offset_map(pmd, address);
+	 *  pte = *ptep;
+	 */
+	pte_paddr = pmd_pte & PHYSICAL_PAGE_MASK;
+	FILL_PTBL(pte_paddr, PHYSADDR, PAGESIZE());
+	ptep = ((ulong *)pte_paddr) + pte_index(uvaddr);
+	pte = ULONG(machdep->ptbl + PAGEOFFSET(ptep));
+	if (verbose)
+		fprintf(fp, "   PTE: %lx => %lx\n", (ulong)ptep, pte);
+	if (!(pte & (_PAGE_PRESENT))) {
+		if (pte && verbose) {
+			fprintf(fp, "\n");
+			x86_64_translate_pte(pte, 0, 0);
+		}
+		goto no_upage;
+	}
+
+	*paddr = (PAGEBASE(pte) & PHYSICAL_PAGE_MASK) + PAGEOFFSET(uvaddr);
+
+	if (verbose) {
+		fprintf(fp, "  PAGE: %lx\n\n", 
+			PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK);
+		x86_64_translate_pte(pte, 0, 0);
+	}
+
+	return TRUE;
+
+no_upage:
+
+	return FALSE;
+}
+
+
+static int
 x86_64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose)
 {
        	ulong mm;
@@ -2500,10 +2640,15 @@ x86_64_get_smp_cpus(void)
 	for (i = cpus = 0; i < nr_pda; i++) {
 		if (!CPU_PDA_READ(i, cpu_pda_buf))
 			break;
-		level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+
+		if (VALID_MEMBER(x8664_pda_level4_pgt)) {
+			level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+			if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+				break;
+		}
 		cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
-                if (!VALID_LEVEL4_PGT_ADDR(level4_pgt) || (cpunumber != cpus))
-                        break;
+		if (cpunumber != cpus)
+			break;
                 cpus++;
 	}
 

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux