diff --git a/crash.patch b/crash.patch index b852d34..aeafd3f 100644 --- a/crash.patch +++ b/crash.patch @@ -1,4 +1,4 @@ ---- crash/extensions/Makefile.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/extensions/Makefile.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/extensions/Makefile 2005-11-08 11:38:21.000000000 -0500 @@ -0,0 +1,41 @@ +# @@ -42,8 +42,8 @@ +dminfo.so: ../defs.h dminfo.c + gcc -nostartfiles -shared -rdynamic -o dminfo.so dminfo.c -fPIC -D$(TARGET) + ---- crash/extensions/echo.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/extensions/echo.c 2005-11-10 16:12:50.000000000 -0500 +--- crash/extensions/echo.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/extensions/echo.c 2006-05-16 15:43:05.000000000 -0400 @@ -0,0 +1,105 @@ +/* echo.c - simple example of a crash extension + * @@ -150,8 +150,8 @@ +}; + + ---- crash/extensions/dminfo.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/extensions/dminfo.c 2005-11-10 16:12:50.000000000 -0500 +--- crash/extensions/dminfo.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/extensions/dminfo.c 2006-05-16 15:43:05.000000000 -0400 @@ -0,0 +1,1531 @@ +/* dminfo.c - crash extension module for device-mapper analysis + * @@ -1684,7 +1684,7 @@ +{ + return 0; +} ---- crash/gdb-6.1/gdb/ppc-linux-tdep.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/gdb-6.1/gdb/ppc-linux-tdep.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/gdb-6.1/gdb/ppc-linux-tdep.c 2005-11-04 17:37:54.000000000 -0500 @@ -0,0 +1,1116 @@ +/* Target-dependent code for GDB, the GNU debugger. @@ -2803,9 +2803,9 @@ + ppc_linux_init_abi); + add_core_fns (&ppc_linux_regset_core_fns); +} ---- crash/main.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/main.c 2006-04-26 15:41:04.000000000 -0400 -@@ -35,11 +35,13 @@ +--- crash/main.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/main.c 2006-08-03 16:58:32.000000000 -0400 +@@ -35,11 +35,15 @@ {"no_data_debug", 0, 0, 0}, {"no_crashrc", 0, 0, 0}, {"no_kmem_cache", 0, 0, 0}, @@ -2816,10 +2816,12 @@ {"version", 0, 0, 0}, {"buildinfo", 0, 0, 0}, + {"shadow_page_tables", 0, 0, 0}, ++ {"cpus", 1, 0, 0}, ++ {"no_ikconfig", 0, 0, 0}, {0, 0, 0, 0} }; -@@ -55,7 +57,7 @@ +@@ -55,7 +59,7 @@ */ opterr = 0; optind = 0; @@ -2828,7 +2830,18 @@ long_options, &option_index)) != -1) { switch (c) { -@@ -98,6 +100,10 @@ +@@ -77,6 +81,10 @@ + kt->flags |= NO_MODULE_ACCESS; + + if (STREQ(long_options[option_index].name, ++ "no_ikconfig")) ++ kt->flags |= NO_IKCONFIG; ++ ++ if (STREQ(long_options[option_index].name, + "no_namelist_gzip")) + pc->flags |= NAMELIST_NO_GZIP; + +@@ -98,6 +106,10 @@ vt->flags |= KMEM_CACHE_UNAVAIL; if (STREQ(long_options[option_index].name, @@ -2839,18 +2852,30 @@ "readnow")) pc->flags |= READNOW; -@@ -123,6 +129,10 @@ +@@ -123,6 +135,13 @@ clean_exit(0); } + if (STREQ(long_options[option_index].name, + "shadow_page_tables")) + kt->xen_flags |= SHADOW_PAGE_TABLES; ++ ++ if (STREQ(long_options[option_index].name, "cpus")) ++ kt->cpus_override = optarg; + break; case 'f': -@@ -193,6 +203,10 @@ +@@ -168,7 +187,7 @@ + case 's': + pc->flags |= SILENT; + pc->flags &= ~SCROLL; +- pc->scroll_command = SCROLL_NONE; ++// pc->scroll_command = SCROLL_NONE; (why?) + break; + + case 'L': +@@ -193,6 +212,10 @@ set_vas_debug(pc->debug); break; @@ -2861,7 +2886,7 @@ default: if (STREQ(argv[optind-1], "-h")) program_usage(LONG_FORM); -@@ -264,6 +278,28 @@ +@@ -264,6 +287,28 @@ pc->readmem = read_netdump; pc->writemem = write_netdump; @@ -2890,18 +2915,17 @@ } else if (is_diskdump(argv[optind])) { if (pc->flags & MEMORY_SOURCES) { error(INFO, -@@ -335,8 +371,8 @@ +@@ -335,8 +380,7 @@ machdep_init(PRE_SYMTAB); symtab_init(); machdep_init(PRE_GDB); - kernel_init(PRE_GDB); - verify_version(); -+// kernel_init(PRE_GDB); -+// verify_version(); ++ read_in_kernel_config(IKCFG_INIT); datatype_init(); /* -@@ -361,6 +397,8 @@ +@@ -361,6 +405,8 @@ { if (!(pc->flags & GDB_INIT)) { gdb_session_init(); @@ -2910,7 +2934,7 @@ kernel_init(POST_GDB); machdep_init(POST_GDB); vm_init(); -@@ -591,6 +629,8 @@ +@@ -591,6 +637,8 @@ int i; char *p1; char buf[BUFSIZE]; @@ -2919,7 +2943,7 @@ FILE *afp; char *program; -@@ -685,11 +725,11 @@ +@@ -685,11 +733,11 @@ pc->home = "(unknown)"; } else strcpy(pc->home, p1); @@ -2935,7 +2959,7 @@ else { while (fgets(buf, BUFSIZE, afp)) resolve_rc_cmd(buf, ALIAS_RCHOME); -@@ -698,11 +738,12 @@ +@@ -698,11 +746,12 @@ } } @@ -2952,7 +2976,7 @@ else { while (fgets(buf, BUFSIZE, afp)) resolve_rc_cmd(buf, ALIAS_RCLOCAL); -@@ -840,13 +881,22 @@ +@@ -840,13 +889,22 @@ if (pc->flags & REM_S390D) sprintf(&buf[strlen(buf)], "%sREM_S390D", others++ ? "|" : ""); @@ -2977,7 +3001,7 @@ sprintf(&buf[strlen(buf)], "%sDISKDUMP", others++ ? "|" : ""); if (pc->flags & SYSMAP) -@@ -855,21 +905,24 @@ +@@ -855,21 +913,24 @@ if (pc->flags & SYSMAP_ARG) sprintf(&buf[strlen(buf)], "%sSYSMAP_ARG", others++ ? "|" : ""); @@ -3007,26 +3031,42 @@ if (pc->flags) strcat(buf, ")"); -@@ -1051,6 +1104,8 @@ +@@ -1017,6 +1078,11 @@ + fprintf(fp, " cur_req: %lx\n", (ulong)pc->cur_req); + fprintf(fp, " cmdgencur: %ld\n", pc->cmdgencur); + fprintf(fp, " cmdgenspec: %ld\n", pc->cmdgenspec); ++ fprintf(fp, " curcmd_flags: %lx (", pc->curcmd_flags); ++ others = 0; ++ if (pc->curcmd_flags & XEN_MACHINE_ADDR) ++ fprintf(fp, "%sXEN_MACHINE_ADDR", others ? "|" : ""); ++ fprintf(fp, ")\n"); + fprintf(fp, " sigint_cnt: %d\n", pc->sigint_cnt); + fprintf(fp, " sigaction: %lx\n", (ulong)&pc->sigaction); + fprintf(fp, " gdb_sigaction: %lx\n", (ulong)&pc->gdb_sigaction); +@@ -1051,6 +1117,10 @@ fprintf(fp, " readmem: read_daemon()\n"); else if (pc->readmem == read_netdump) fprintf(fp, " readmem: read_netdump()\n"); ++ else if (pc->readmem == read_xendump) ++ fprintf(fp, " readmem: read_xendump()\n"); + else if (pc->readmem == read_kdump) + fprintf(fp, " readmem: read_kdump()\n"); else if (pc->readmem == read_memory_device) fprintf(fp, " readmem: read_memory_device()\n"); else -@@ -1065,6 +1120,8 @@ +@@ -1065,6 +1135,10 @@ fprintf(fp, " writemem: write_daemon()\n"); else if (pc->writemem == write_netdump) fprintf(fp, " writemem: write_netdump()\n"); ++ else if (pc->writemem == write_xendump) ++ fprintf(fp, " writemem: write_xendump()\n"); + else if (pc->writemem == write_kdump) + fprintf(fp, " writemem: write_kdump()\n"); else if (pc->writemem == write_memory_device) fprintf(fp, " writemem: write_memory_device()\n"); else ---- crash/tools.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/tools.c 2006-04-26 15:45:34.000000000 -0400 +--- crash/tools.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/tools.c 2006-07-06 16:21:55.000000000 -0400 @@ -2004,6 +2004,10 @@ pc->flags &= ~(DUMPFILE_TYPES); if (is_netdump(args[optind], NETDUMP_LOCAL)) @@ -3086,7 +3126,7 @@ total = (count)/(ulonglong)machdep->hz; days = total / SEC_DAYS; -@@ -4300,12 +4322,34 @@ +@@ -4300,12 +4322,54 @@ void command_not_supported() { @@ -3123,8 +3163,28 @@ + fprintf(fp, "\r \r"); + fflush(fp); +} ---- crash/memory.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/memory.c 2006-05-01 11:35:50.000000000 -0400 ++ ++/* ++ * Compare two pathnames. ++ */ ++int ++pathcmp(char *p1, char *p2) ++{ ++ char c1, c2; ++ ++ do { ++ if ((c1 = *p1++) == '/') ++ while (*p1 == '/') { p1++; } ++ if ((c2 = *p2++) == '/') ++ while (*p2 == '/') { p2++; } ++ if (c1 == '\0') ++ return ((c2 == '/') && (*p2 == '\0')) ? 0 : c1 - c2; ++ } while (c1 == c2); ++ ++ return ((c2 == '\0') && (c1 == '/') && (*p1 == '\0')) ? 0 : c1 - c2; ++} +--- crash/memory.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/memory.c 2006-08-02 10:32:08.000000000 -0400 @@ -45,6 +45,8 @@ ulong *addrlist; int *kmem_bufctl; @@ -3192,7 +3252,15 @@ /* * Memory display modes specific to this file. -@@ -182,6 +201,13 @@ +@@ -142,6 +161,7 @@ + #define DECIMAL (0x100) + #define UDECIMAL (0x200) + #define ASCII_ENDLINE (0x400) ++#define NO_ASCII (0x800) + + static ulong DISPLAY_DEFAULT; + +@@ -182,6 +202,13 @@ MEMBER_OFFSET_INIT(mm_struct_mmap, "mm_struct", "mmap"); MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd"); MEMBER_OFFSET_INIT(mm_struct_rss, "mm_struct", "rss"); @@ -3206,7 +3274,7 @@ MEMBER_OFFSET_INIT(mm_struct_total_vm, "mm_struct", "total_vm"); MEMBER_OFFSET_INIT(mm_struct_start_code, "mm_struct", "start_code"); MEMBER_OFFSET_INIT(vm_area_struct_vm_mm, "vm_area_struct", "vm_mm"); -@@ -270,6 +296,7 @@ +@@ -270,6 +297,7 @@ STRUCT_SIZE_INIT(kmem_slab_s, "kmem_slab_s"); STRUCT_SIZE_INIT(slab_s, "slab_s"); STRUCT_SIZE_INIT(slab, "slab"); @@ -3214,7 +3282,7 @@ STRUCT_SIZE_INIT(pgd_t, "pgd_t"); if (!VALID_STRUCT(kmem_slab_s) && VALID_STRUCT(slab_s)) { -@@ -310,17 +337,49 @@ +@@ -310,17 +338,49 @@ !VALID_STRUCT(slab_s) && VALID_STRUCT(slab)) { vt->flags |= PERCPU_KMALLOC_V2; @@ -3275,7 +3343,7 @@ MEMBER_OFFSET_INIT(slab_list, "slab", "list"); MEMBER_OFFSET_INIT(slab_s_mem, "slab", "s_mem"); MEMBER_OFFSET_INIT(slab_inuse, "slab", "inuse"); -@@ -330,10 +389,6 @@ +@@ -330,10 +390,6 @@ MEMBER_OFFSET_INIT(array_cache_limit, "array_cache", "limit"); STRUCT_SIZE_INIT(array_cache, "array_cache"); @@ -3286,7 +3354,27 @@ MEMBER_OFFSET_INIT(kmem_list3_slabs_partial, "kmem_list3", "slabs_partial"); MEMBER_OFFSET_INIT(kmem_list3_slabs_full, -@@ -415,10 +470,17 @@ +@@ -381,6 +437,19 @@ + "kmem_slab_s", "s_magic"); + } + ++ if (!kt->kernel_NR_CPUS) { ++ kt->kernel_NR_CPUS = ARRAY_LENGTH(kmem_cache_s_cpudata) ? ++ ARRAY_LENGTH(kmem_cache_s_cpudata) : ++ ARRAY_LENGTH(kmem_cache_s_array); ++ } ++ ++ if (kt->kernel_NR_CPUS > NR_CPUS) { ++ error(WARNING, ++ "kernel-configured NR_CPUS (%d) greater than compiled-in NR_CPUS (%d)\n", ++ kt->kernel_NR_CPUS, NR_CPUS); ++ error(FATAL, "recompile crash with larger NR_CPUS\n"); ++ } ++ + if (machdep->init_kernel_pgd) + machdep->init_kernel_pgd(); + else if (symbol_exists("swapper_pg_dir")) { +@@ -415,10 +484,17 @@ error(FATAL, "no swapper_pg_dir or cpu_pgd symbols exist?\n"); get_symbol_data("high_memory", sizeof(ulong), &vt->high_memory); @@ -3305,7 +3393,7 @@ vt->vmalloc_start = machdep->vmalloc_start(); if (IS_VMALLOC_ADDR(vt->mem_map)) vt->flags |= V_MEM_MAP; -@@ -478,7 +540,6 @@ +@@ -478,7 +554,6 @@ STRUCT_SIZE_INIT(free_area_struct, "free_area_struct"); STRUCT_SIZE_INIT(zone, "zone"); STRUCT_SIZE_INIT(zone_struct, "zone_struct"); @@ -3313,7 +3401,7 @@ STRUCT_SIZE_INIT(kmem_bufctl_t, "kmem_bufctl_t"); STRUCT_SIZE_INIT(swap_info_struct, "swap_info_struct"); STRUCT_SIZE_INIT(mm_struct, "mm_struct"); -@@ -524,6 +585,7 @@ +@@ -524,6 +599,7 @@ ARRAY_LENGTH_INIT(vt->nr_zones, pglist_data_node_zones, "pglist_data.node_zones", NULL, SIZE_OPTION(zone_struct, zone)); @@ -3321,7 +3409,7 @@ if (VALID_STRUCT(zone_struct)) { MEMBER_OFFSET_INIT(zone_struct_free_pages, -@@ -539,6 +601,8 @@ +@@ -539,6 +615,8 @@ if (INVALID_MEMBER(zone_struct_size)) MEMBER_OFFSET_INIT(zone_struct_memsize, "zone_struct", "memsize"); @@ -3330,7 +3418,7 @@ MEMBER_OFFSET_INIT(zone_struct_zone_start_paddr, "zone_struct", "zone_start_paddr"); MEMBER_OFFSET_INIT(zone_struct_zone_start_mapnr, -@@ -640,13 +704,7 @@ +@@ -640,13 +718,7 @@ kmem_cache_init(); PG_reserved_flag_init(); @@ -3345,7 +3433,76 @@ } /* -@@ -970,7 +1028,8 @@ +@@ -685,7 +757,7 @@ + memtype = KVADDR; + count = -1; + +- while ((c = getopt(argcnt, args, "e:pudDuso:81:3:6:")) != EOF) { ++ while ((c = getopt(argcnt, args, "xme:pudDuso:81:3:6:")) != EOF) { + switch(c) + { + case '8': +@@ -748,12 +820,12 @@ + break; + + case 'p': +- memtype &= ~(UVADDR|KVADDR); ++ memtype &= ~(UVADDR|KVADDR|XENMACHADDR); + memtype = PHYSADDR; + break; + + case 'u': +- memtype &= ~(KVADDR|PHYSADDR); ++ memtype &= ~(KVADDR|PHYSADDR|XENMACHADDR); + memtype = UVADDR; + break; + +@@ -767,6 +839,17 @@ + flag |= UDECIMAL; + break; + ++ case 'm': ++ if (!(kt->flags & ARCH_XEN)) ++ error(FATAL, "-m option only applies to xen architecture\n"); ++ memtype &= ~(UVADDR|KVADDR); ++ memtype = XENMACHADDR; ++ break; ++ ++ case 'x': ++ flag |= NO_ASCII; ++ break; ++ + default: + argerrs++; + break; +@@ -830,7 +913,7 @@ + error(WARNING, + "ending address ignored when count is specified\n"); + +- if ((flag & HEXADECIMAL) && !(flag & SYMBOLIC)) ++ if ((flag & HEXADECIMAL) && !(flag & SYMBOLIC) && !(flag & NO_ASCII)) + flag |= ASCII_ENDLINE; + + if (memtype == KVADDR) { +@@ -839,7 +922,6 @@ + } + + display_memory(addr, count, flag, memtype); +- + } + + /* +@@ -903,6 +985,9 @@ + case PHYSADDR: + addrtype = "PHYSADDR"; + break; ++ case XENMACHADDR: ++ addrtype = "XENMACHADDR"; ++ break; + } + + if (CRASHDEBUG(4)) +@@ -970,7 +1055,8 @@ case DISPLAY_64: if ((flag & (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) == (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) { @@ -3355,7 +3512,7 @@ fprintf(fp, "%-16s ", value_to_symstr(mem.u64, buf, 0)); linelen += strlen(buf)+1; -@@ -993,7 +1052,8 @@ +@@ -993,7 +1079,8 @@ case DISPLAY_32: if ((flag & (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) == (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) { @@ -3365,7 +3522,70 @@ fprintf(fp, INT_PRLEN == 16 ? "%-16s " : "%-8s ", value_to_symstr(mem.u32, -@@ -2113,6 +2173,8 @@ +@@ -1376,6 +1463,7 @@ + int fd; + long cnt; + physaddr_t paddr; ++ ulonglong pseudo; + char *bufptr; + + if (CRASHDEBUG(4)) +@@ -1424,6 +1512,7 @@ + break; + + case PHYSADDR: ++ case XENMACHADDR: + break; + } + +@@ -1449,6 +1538,17 @@ + case PHYSADDR: + paddr = addr; + break; ++ ++ case XENMACHADDR: ++ pseudo = xen_m2p(addr); ++ ++ if (pseudo == XEN_MACHADDR_NOT_FOUND) { ++ pc->curcmd_flags |= XEN_MACHINE_ADDR; ++ paddr = addr; ++ } else ++ paddr = pseudo | PAGEOFFSET(addr); ++ ++ break; + } + + /* +@@ -1460,7 +1560,7 @@ + cnt = size; + + switch (READMEM(fd, bufptr, cnt, +- memtype == PHYSADDR ? 0 : addr, paddr)) ++ (memtype == PHYSADDR) || (memtype == XENMACHADDR) ? 0 : addr, paddr)) + { + case SEEK_ERROR: + if (PRINT_ERROR_MESSAGE) +@@ -1610,6 +1710,9 @@ + int + read_memory_device(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr) + { ++ if (pc->curcmd_flags & XEN_MACHINE_ADDR) ++ return READ_ERROR; ++ + if (!machdep->verify_paddr(paddr)) { + if (CRASHDEBUG(1)) + error(INFO, "verify_paddr(%lx) failed\n", paddr); +@@ -1754,6 +1857,9 @@ + case PHYSADDR: + sprintf(membuf, debug ? "PHYSADDR" : "physical"); + break; ++ case XENMACHADDR: ++ sprintf(membuf, debug ? "XENMACHADDR" : "xen machine"); ++ break; + default: + if (debug) + sprintf(membuf, "0x%x (?)", memtype); +@@ -2113,6 +2219,8 @@ break; } @@ -3374,7 +3594,7 @@ switch (memtype) { case UVADDR: fprintf(fp, "%s %s\n", -@@ -2126,9 +2188,12 @@ +@@ -2126,9 +2234,12 @@ return; } if (!uvtop(tc, vaddr, &paddr, 0)) { @@ -3389,7 +3609,7 @@ page_exists = FALSE; } else { fprintf(fp, "%s %s\n\n", -@@ -2161,9 +2226,13 @@ +@@ -2161,9 +2272,13 @@ } if (vtop_flags & USE_USER_PGD) { if (!uvtop(tc, vaddr, &paddr, 0)) { @@ -3405,7 +3625,7 @@ page_exists = FALSE; } else { fprintf(fp, "%s %s\n\n", -@@ -2176,9 +2245,13 @@ +@@ -2176,9 +2291,13 @@ uvtop(tc, vaddr, &paddr, VERBOSE); } else { if (!kvtop(tc, vaddr, &paddr, 0)) { @@ -3421,7 +3641,7 @@ page_exists = FALSE; } else { fprintf(fp, "%s %s\n\n", -@@ -2980,6 +3053,8 @@ +@@ -2980,6 +3099,8 @@ return; tm->rss = ULONG(tt->mm_struct + OFFSET(mm_struct_rss)); @@ -3430,7 +3650,7 @@ tm->total_vm = ULONG(tt->mm_struct + OFFSET(mm_struct_total_vm)); tm->pgd_addr = ULONG(tt->mm_struct + OFFSET(mm_struct_pgd)); -@@ -3036,6 +3111,9 @@ +@@ -3036,6 +3157,9 @@ #define GET_INACTIVE_DIRTY (ADDRESS_SPECIFIED << 13) /* obsolete */ #define SLAB_GET_COUNTS (ADDRESS_SPECIFIED << 14) #define SLAB_WALKTHROUGH (ADDRESS_SPECIFIED << 15) @@ -3440,7 +3660,7 @@ #define GET_ALL \ (GET_SHARED_PAGES|GET_TOTALRAM_PAGES|GET_BUFFERS_PAGES|GET_SLAB_PAGES) -@@ -3159,7 +3237,7 @@ +@@ -3159,7 +3283,7 @@ cmd_usage(pc->curcmd, SYNOPSIS); } @@ -3449,7 +3669,7 @@ kmem_cache_init(); while (args[optind]) { -@@ -3373,12 +3451,13 @@ +@@ -3373,12 +3497,13 @@ buf = (char *)GETBUF(SIZE(page)); if (!readmem(pageptr, KVADDR, buf, SIZE(page), @@ -3465,7 +3685,7 @@ if (count_bits_long(flags) == 1) vt->PG_reserved = flags; else -@@ -3386,12 +3465,50 @@ +@@ -3386,12 +3511,50 @@ if (CRASHDEBUG(2)) fprintf(fp, @@ -3517,7 +3737,7 @@ /* * dump_mem_map() displays basic data about each entry in the mem_map[] * array, or if an address is specified, just the mem_map[] entry for that -@@ -3440,16 +3557,16 @@ +@@ -3440,16 +3603,16 @@ static void dump_mem_map(struct meminfo *mi) { @@ -3537,7 +3757,7 @@ uint count; int print_hdr, pg_spec, phys_spec, done; int v22; -@@ -3462,6 +3579,7 @@ +@@ -3462,6 +3625,7 @@ char buf4[BUFSIZE]; char *page_cache; char *pcache; @@ -3545,7 +3765,7 @@ v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */ -@@ -3549,22 +3667,67 @@ +@@ -3549,22 +3713,67 @@ done = FALSE; total_pages = 0; @@ -3624,7 +3844,7 @@ i++, pp += SIZE(page), phys += PAGESIZE()) { if ((i % PGMM_CACHED) == 0) { -@@ -3653,11 +3816,12 @@ +@@ -3653,11 +3862,12 @@ } continue; } @@ -3638,7 +3858,7 @@ mapping = ULONG(pcache + OFFSET(page_mapping)); index = ULONG(pcache + OFFSET(page_index)); -@@ -3700,6 +3864,20 @@ +@@ -3700,6 +3910,20 @@ space(MINSPACE), mkstring(buf4, 8, CENTER|RJUST, " "), " "); @@ -3659,7 +3879,7 @@ else fprintf(fp, "%s%s%s%s%s%s%8ld %2d ", mkstring(buf0, VADDR_PRLEN, -@@ -3827,6 +4005,11 @@ +@@ -3827,6 +4051,11 @@ if (done) break; @@ -3671,7 +3891,7 @@ } switch (mi->flags) -@@ -4520,13 +4703,6 @@ +@@ -4520,13 +4749,6 @@ */ static char *zone_hdr = "ZONE NAME SIZE FREE"; @@ -3685,7 +3905,7 @@ static void dump_free_pages_zones_v1(struct meminfo *fi) { -@@ -4610,7 +4786,7 @@ +@@ -4610,7 +4832,7 @@ } if (fi->flags == GET_FREE_HIGHMEM_PAGES) { @@ -3694,7 +3914,7 @@ readmem(node_zones+ OFFSET(zone_struct_free_pages), KVADDR, &value, sizeof(ulong), -@@ -4702,7 +4878,7 @@ +@@ -4702,7 +4924,7 @@ hq_close(); @@ -3703,7 +3923,7 @@ fi->retval = sum; return; } -@@ -4899,7 +5075,7 @@ +@@ -4899,7 +5121,7 @@ } if (fi->flags == GET_FREE_HIGHMEM_PAGES) { @@ -3712,7 +3932,7 @@ readmem(node_zones+ OFFSET(zone_free_pages), KVADDR, &value, sizeof(ulong), -@@ -4997,7 +5173,7 @@ +@@ -4997,7 +5219,7 @@ hq_close(); @@ -3721,7 +3941,31 @@ fi->retval = sum; return; } -@@ -5575,15 +5751,17 @@ +@@ -5519,17 +5741,18 @@ + ulong nrpages; + char *block_device_buf, *inode_buf, *address_space_buf; + +- block_device_buf = GETBUF(SIZE(block_device)); +- inode_buf = GETBUF(SIZE(inode)); +- address_space_buf = GETBUF(SIZE(address_space)); +- + ld = &list_data; + BZERO(ld, sizeof(struct list_data)); +- + get_symbol_data("all_bdevs", sizeof(void *), &ld->start); ++ if (empty_list(ld->start)) ++ return 0; + ld->end = symbol_value("all_bdevs"); + ld->list_head_offset = OFFSET(block_device_bd_list); + ++ block_device_buf = GETBUF(SIZE(block_device)); ++ inode_buf = GETBUF(SIZE(inode)); ++ address_space_buf = GETBUF(SIZE(address_space)); ++ + hq_open(); + bdevcnt = do_list(ld); + bdevlist = (ulong *)GETBUF(bdevcnt * sizeof(ulong)); +@@ -5575,15 +5798,17 @@ char buf1[BUFSIZE]; char buf2[BUFSIZE]; ulong vmlist; @@ -3741,7 +3985,7 @@ fprintf(fp, "%s ", mkstring(buf, MAX(strlen("VM_STRUCT"), VADDR_PRLEN), CENTER|LJUST, "VM_STRUCT")); -@@ -5599,6 +5777,20 @@ +@@ -5599,6 +5824,20 @@ &size, sizeof(ulong), "vmlist size", FAULT_ON_ERROR); @@ -3762,7 +4006,7 @@ if (!(vi->flags & ADDRESS_SPECIFIED) || ((vi->memtype == KVADDR) && ((vi->spec_addr >= addr) && (vi->spec_addr < (addr+size))))) -@@ -5639,7 +5831,7 @@ +@@ -5639,7 +5878,7 @@ } } @@ -3771,7 +4015,7 @@ readmem(next+OFFSET(vm_struct_next), KVADDR, &next, sizeof(void *), "vmlist next", FAULT_ON_ERROR); -@@ -5647,6 +5839,9 @@ +@@ -5647,6 +5886,9 @@ if (vi->flags & GET_HIGHEST) vi->retval = addr+size; @@ -3781,7 +4025,7 @@ } /* -@@ -6136,9 +6331,14 @@ +@@ -6136,9 +6378,14 @@ if (vt->flags & KMEM_CACHE_UNAVAIL) return; @@ -3796,7 +4040,7 @@ if (!strlen(slab_hdr)) sprintf(slab_hdr, "SLAB%sMEMORY%sTOTAL ALLOCATED FREE\n", -@@ -6177,9 +6377,11 @@ +@@ -6177,9 +6424,11 @@ if (!readmem(cache, KVADDR, cache_buf, SIZE(kmem_cache_s), "kmem_cache_s buffer", RETURN_ON_ERROR)) { @@ -3809,7 +4053,7 @@ return; } -@@ -6190,6 +6392,13 @@ +@@ -6190,6 +6439,13 @@ if ((tmp = max_cpudata_limit(cache, &tmp2)) > max_limit) max_limit = tmp; @@ -3823,7 +4067,7 @@ if (tmp2 > max_cpus) max_cpus = tmp2; -@@ -6237,6 +6446,8 @@ +@@ -6237,6 +6493,8 @@ NULL, 0); } @@ -3832,7 +4076,7 @@ vt->flags |= KMEM_CACHE_INIT; } -@@ -6250,25 +6461,32 @@ +@@ -6250,25 +6508,32 @@ ulong cpudata[NR_CPUS]; int limit; ulong max_limit; @@ -3878,7 +4122,7 @@ if (limit > max_limit) max_limit = limit; } -@@ -6279,22 +6497,89 @@ +@@ -6279,22 +6544,89 @@ kmem_cache_s_array: @@ -3890,6 +4134,42 @@ + KVADDR, &cpudata[0], + sizeof(ulong) * ARRAY_LENGTH(kmem_cache_s_array), + "array cache array", RETURN_ON_ERROR)) ++ goto bail_out; ++ ++ for (i = max_limit = 0; (i < ARRAY_LENGTH(kmem_cache_s_array)) && ++ cpudata[i]; i++) { ++ if (!readmem(cpudata[i]+OFFSET(array_cache_limit), ++ KVADDR, &limit, sizeof(int), ++ "array cache limit", RETURN_ON_ERROR)) ++ goto bail_out; ++ if (limit > max_limit) ++ max_limit = limit; ++ } ++ ++ /* ++ * If the shared list can be accessed, check its size as well. ++ */ ++ if (VALID_MEMBER(kmem_list3_shared) && ++ VALID_MEMBER(kmem_cache_s_lists) && ++ readmem(cache+OFFSET(kmem_cache_s_lists)+OFFSET(kmem_list3_shared), ++ KVADDR, &shared, sizeof(void *), "kmem_list3 shared", ++ RETURN_ON_ERROR|QUIET) && ++ readmem(shared+OFFSET(array_cache_limit), ++ KVADDR, &limit, sizeof(int), "shared array_cache limit", ++ RETURN_ON_ERROR|QUIET)) { ++ if (limit > max_limit) ++ max_limit = limit; ++ } ++ ++ *cpus = i; ++ return max_limit; ++ ++kmem_cache_s_array_nodes: ++ ++ if (!readmem(cache+OFFSET(kmem_cache_s_array), ++ KVADDR, &cpudata[0], ++ sizeof(ulong) * ARRAY_LENGTH(kmem_cache_s_array), ++ "array cache array", RETURN_ON_ERROR)) + goto bail_out; for (i = max_limit = 0; (i < ARRAY_LENGTH(kmem_cache_s_array)) && @@ -3905,43 +4185,7 @@ max_limit = limit; } -+ /* -+ * If the shared list can be accessed, check its size as well. -+ */ -+ if (VALID_MEMBER(kmem_list3_shared) && -+ VALID_MEMBER(kmem_cache_s_lists) && -+ readmem(cache+OFFSET(kmem_cache_s_lists)+OFFSET(kmem_list3_shared), -+ KVADDR, &shared, sizeof(void *), "kmem_list3 shared", -+ RETURN_ON_ERROR|QUIET) && -+ readmem(shared+OFFSET(array_cache_limit), -+ KVADDR, &limit, sizeof(int), "shared array_cache limit", -+ RETURN_ON_ERROR|QUIET)) { -+ if (limit > max_limit) -+ max_limit = limit; -+ } -+ *cpus = i; - return max_limit; -+ -+kmem_cache_s_array_nodes: -+ -+ if (!readmem(cache+OFFSET(kmem_cache_s_array), -+ KVADDR, &cpudata[0], -+ sizeof(ulong) * ARRAY_LENGTH(kmem_cache_s_array), -+ "array cache array", RETURN_ON_ERROR)) -+ goto bail_out; -+ -+ for (i = max_limit = 0; (i < ARRAY_LENGTH(kmem_cache_s_array)) && -+ cpudata[i]; i++) { -+ if (!readmem(cpudata[i]+OFFSET(array_cache_limit), -+ KVADDR, &limit, sizeof(int), -+ "array cache limit", RETURN_ON_ERROR)) -+ goto bail_out; -+ if (limit > max_limit) -+ max_limit = limit; -+ } -+ -+ *cpus = i; + + /* + * Check the shared list of all the nodes. @@ -3965,7 +4209,7 @@ + } + } + FREEBUF(start_address); -+ return max_limit; + return max_limit; + +bail_out: + vt->flags |= KMEM_CACHE_UNAVAIL; @@ -3975,7 +4219,7 @@ } /* -@@ -6353,6 +6638,7 @@ +@@ -6353,6 +6685,7 @@ #define KMEM_OBJECT_ADDR_INUSE (4) #define KMEM_OBJECT_ADDR_CACHED (5) #define KMEM_ON_SLAB (6) @@ -3983,7 +4227,7 @@ #define DUMP_KMEM_CACHE_INFO_V1() \ { \ -@@ -6408,7 +6694,7 @@ +@@ -6408,7 +6741,7 @@ { \ char b1[BUFSIZE], b2[BUFSIZE]; \ ulong allocated, freeobjs; \ @@ -3992,7 +4236,7 @@ allocated = si->s_inuse - si->cpucached_slab; \ freeobjs = si->c_num - allocated - si->cpucached_slab; \ } else { \ -@@ -6419,8 +6705,8 @@ +@@ -6419,8 +6752,8 @@ mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->slab)), \ mkstring(b2, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->s_mem)), \ si->c_num, allocated, \ @@ -4003,7 +4247,7 @@ } static void -@@ -6857,6 +7143,13 @@ +@@ -6857,6 +7190,13 @@ for (i = 0; i < vt->kmem_max_cpus; i++) si->cpudata[i] = (ulong *) GETBUF(vt->kmem_max_limit * sizeof(ulong)); @@ -4017,7 +4261,7 @@ cnt = 0; -@@ -6939,7 +7232,10 @@ +@@ -6939,7 +7279,10 @@ "kmem_cache_s num", FAULT_ON_ERROR); si->c_num = (ulong)tmp_val; @@ -4029,7 +4273,7 @@ if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) { DUMP_KMEM_CACHE_INFO_V2(); -@@ -6953,12 +7249,16 @@ +@@ -6953,12 +7296,16 @@ if (si->flags & (VERBOSE|ADDRESS_SPECIFIED)) { @@ -4048,7 +4292,7 @@ if (si->found) { fprintf(fp, kmem_cache_hdr); -@@ -7005,7 +7305,14 @@ +@@ -7005,7 +7352,14 @@ " %lx (cpu %d cache)\n", (ulong)si->spec_addr, si->cpu); break; @@ -4064,7 +4308,7 @@ break; } -@@ -7033,6 +7340,7 @@ +@@ -7033,6 +7387,7 @@ FREEBUF(si->kmem_bufctl); for (i = 0; i < vt->kmem_max_cpus; i++) FREEBUF(si->cpudata[i]); @@ -4072,10 +4316,15 @@ } -@@ -7638,6 +7946,231 @@ +@@ -7638,68 +7993,293 @@ } } +-/* +- * Try to preclude any attempt to translate a bogus slab structure. +- */ +-static int +-verify_slab_v2(struct meminfo *si, ulong last, int s) + +/* +* Added To Traverse the Nodelists @@ -4083,7 +4332,13 @@ + +static void +do_slab_chain_percpu_v2_nodes(long cmd, struct meminfo *si) -+{ + { +- char slab_buf[BUFSIZE]; +- struct kernel_list_head *list_head; +- unsigned int inuse; +- ulong s_mem; +- char *list; +- int errcnt; + int i, tmp, s; + int list_borked; + char *slab_buf; @@ -4092,17 +4347,25 @@ + ulong slab_chains[SLAB_CHAINS]; + ulong *start_address; + int index; -+ + +- list = slab_chain_name_v2[s]; + list_borked = 0; + si->slabsize = (power(2, si->order) * PAGESIZE()); + si->cpucached_slab = 0; + start_address = (ulong *)GETBUF(sizeof(ulong) * vt->kmem_cache_len_nodes); -+ + +- errcnt = 0; + if (!readmem(si->cache+OFFSET(kmem_cache_s_lists), KVADDR, + &start_address[0], sizeof(ulong) * vt->kmem_cache_len_nodes, + "array nodelist array", RETURN_ON_ERROR)) + error(INFO, "cannot read kmem_cache nodelists array"); -+ + +- if (!readmem(si->slab, KVADDR, slab_buf, +- SIZE(slab), "slab buffer", QUIET|RETURN_ON_ERROR)) { +- error(INFO, "%s: %s list: bad slab pointer: %lx\n", +- si->curname, list, si->slab); +- return FALSE; +- } + switch (cmd) + { + case SLAB_GET_COUNTS: @@ -4124,7 +4387,15 @@ + fprintf(fp, "partial: %lx full: %lx free: %lx ]\n", + slab_chains[0], slab_chains[1], slab_chains[2]); + } -+ + +- list_head = (struct kernel_list_head *)(slab_buf + OFFSET(slab_list)); +- if (!IS_KVADDR((ulong)list_head->next) || +- !accessible((ulong)list_head->next)) { +- error(INFO, "%s: %s list: slab: %lx bad next pointer: %lx\n", +- si->curname, list, si->slab, +- (ulong)list_head->next); +- errcnt++; +- } + for (s = 0; s < SLAB_CHAINS; s++) { + if (!slab_chains[s]) + continue; @@ -4151,14 +4422,26 @@ + continue; + + last = slab_chains[s]; -+ + +- if (last && (last != (ulong)list_head->prev)) { +- error(INFO, "%s: %s list: slab: %lx bad prev pointer: %lx\n", +- si->curname, list, si->slab, +- (ulong)list_head->prev); +- errcnt++; +- } + do { + if (received_SIGINT()) { + FREEBUF(slab_buf); + FREEBUF(start_address); + restart(0); + } -+ + +- inuse = UINT(slab_buf + OFFSET(slab_inuse)); +- if (inuse > si->c_num) { +- error(INFO, "%s: %s list: slab: %lx bad inuse counter: %ld\n", +- si->curname, list, si->slab, inuse); +- errcnt++; +- } + if (!verify_slab_v2(si, last, s)) { + list_borked = 1; + continue; @@ -4174,7 +4457,9 @@ + + if (ACTIVE()) + gather_cpudata_list_v2_nodes(si, index); -+ + +- if (!last) +- goto no_inuse_check_v2; + si->s_mem = ULONG(slab_buf + + OFFSET(slab_s_mem)); + gather_slab_cached_count(si); @@ -4184,7 +4469,15 @@ + si->slab = ULONG(slab_buf + + OFFSET(slab_list)); + si->slab -= OFFSET(slab_list); -+ + +- switch (s) +- { +- case 0: /* partial */ +- if ((inuse == 0) || (inuse == si->c_num)) { +- error(INFO, +- "%s: %s list: slab: %lx bad inuse counter: %ld\n", +- si->curname, list, si->slab, inuse); +- errcnt++; + /* + * Check for slab transition. (Tony Dziedzic) + */ @@ -4201,8 +4494,10 @@ + + } while (si->slab != slab_chains[s] && !list_borked); + } -+ } -+ + } +- break; + +- case 1: /* full */ + if (!list_borked) + save_slab_data(si); + break; @@ -4301,10 +4596,72 @@ + FREEBUF(start_address); +} + - /* - * Try to preclude any attempt to translate a bogus slab structure. - */ -@@ -7750,6 +8283,11 @@ ++/* ++ * Try to preclude any attempt to translate a bogus slab structure. ++ */ ++static int ++verify_slab_v2(struct meminfo *si, ulong last, int s) ++{ ++ char slab_buf[BUFSIZE]; ++ struct kernel_list_head *list_head; ++ unsigned int inuse; ++ ulong s_mem; ++ char *list; ++ int errcnt; ++ ++ list = slab_chain_name_v2[s]; ++ ++ errcnt = 0; ++ ++ if (!readmem(si->slab, KVADDR, slab_buf, ++ SIZE(slab), "slab buffer", QUIET|RETURN_ON_ERROR)) { ++ error(INFO, "%s: %s list: bad slab pointer: %lx\n", ++ si->curname, list, si->slab); ++ return FALSE; ++ } ++ ++ list_head = (struct kernel_list_head *)(slab_buf + OFFSET(slab_list)); ++ if (!IS_KVADDR((ulong)list_head->next) || ++ !accessible((ulong)list_head->next)) { ++ error(INFO, "%s: %s list: slab: %lx bad next pointer: %lx\n", ++ si->curname, list, si->slab, ++ (ulong)list_head->next); ++ errcnt++; ++ } ++ ++ if (last && (last != (ulong)list_head->prev)) { ++ error(INFO, "%s: %s list: slab: %lx bad prev pointer: %lx\n", ++ si->curname, list, si->slab, ++ (ulong)list_head->prev); ++ errcnt++; ++ } ++ ++ inuse = UINT(slab_buf + OFFSET(slab_inuse)); ++ if (inuse > si->c_num) { ++ error(INFO, "%s: %s list: slab: %lx bad inuse counter: %ld\n", ++ si->curname, list, si->slab, inuse); ++ errcnt++; ++ } ++ ++ if (!last) ++ goto no_inuse_check_v2; ++ ++ switch (s) ++ { ++ case 0: /* partial */ ++ if ((inuse == 0) || (inuse == si->c_num)) { ++ error(INFO, ++ "%s: %s list: slab: %lx bad inuse counter: %ld\n", ++ si->curname, list, si->slab, inuse); ++ errcnt++; ++ } ++ break; ++ ++ case 1: /* full */ + if (inuse != si->c_num) { + error(INFO, + "%s: %s list: slab: %lx bad inuse counter: %ld\n", +@@ -7750,6 +8330,11 @@ { int i; @@ -4316,7 +4673,7 @@ if (ACTIVE()) return; -@@ -7840,7 +8378,7 @@ +@@ -7840,7 +8425,7 @@ if (si->flags & ADDRESS_SPECIFIED) { if (INSLAB(si->slab, si) && (si->spec_addr >= si->slab) && @@ -4325,7 +4682,7 @@ si->found = KMEM_SLAB_ADDR; return; } -@@ -8213,7 +8751,7 @@ +@@ -8213,7 +8798,7 @@ */ if (si->c_flags & SLAB_CFLGS_BUFCTL) { @@ -4334,7 +4691,7 @@ obj = si->s_mem + ((next - si->s_index) * si->c_offset); DUMP_SLAB_OBJECT(); -@@ -8263,7 +8801,7 @@ +@@ -8263,7 +8848,7 @@ dump_slab_objects_percpu(struct meminfo *si) { int i, j; @@ -4343,7 +4700,7 @@ ulong cnt, expected; ulong obj; -@@ -8285,6 +8823,7 @@ +@@ -8285,6 +8870,7 @@ for (i = 0, obj = si->s_mem; i < si->c_num; i++, obj += si->size) { on_free_list = FALSE; on_cpudata_list = FALSE; @@ -4351,7 +4708,7 @@ for (j = 0; j < si->c_num; j++) { if (obj == si->addrlist[j]) { -@@ -8294,13 +8833,26 @@ +@@ -8294,13 +8880,26 @@ } on_cpudata_list = check_cpudata_list(si, obj); @@ -4379,7 +4736,7 @@ if (on_free_list) { if (!(si->flags & ADDRESS_SPECIFIED)) -@@ -8324,6 +8876,17 @@ +@@ -8324,6 +8923,17 @@ return; } } @@ -4397,7 +4754,7 @@ } else { if (!(si->flags & ADDRESS_SPECIFIED)) fprintf(fp, " [%lx]\n", obj); -@@ -8349,7 +8912,10 @@ +@@ -8349,7 +8959,10 @@ /* * Determine how many of the "inuse" slab objects are actually cached * in the kmem_cache_s header. Set the per-slab count and update the @@ -4409,7 +4766,7 @@ */ static void -@@ -8357,16 +8923,35 @@ +@@ -8357,16 +8970,35 @@ { int i; ulong obj; @@ -4445,7 +4802,7 @@ } } -@@ -8423,7 +9008,8 @@ +@@ -8423,7 +9055,8 @@ } /* @@ -4455,7 +4812,7 @@ */ static void gather_cpudata_list_v2(struct meminfo *si) -@@ -8431,6 +9017,7 @@ +@@ -8431,6 +9064,7 @@ int i, j; int avail; ulong cpudata[NR_CPUS]; @@ -4463,7 +4820,7 @@ readmem(si->cache+OFFSET(kmem_cache_s_array), KVADDR, &cpudata[0], -@@ -8466,8 +9053,152 @@ +@@ -8466,8 +9100,152 @@ if (CRASHDEBUG(2)) for (j = 0; j < avail; j++) @@ -4617,7 +4974,7 @@ } /* -@@ -8491,6 +9222,27 @@ +@@ -8491,6 +9269,27 @@ return FALSE; } @@ -4645,7 +5002,7 @@ /* * Search the various memory subsystems for instances of this address. -@@ -8690,6 +9442,16 @@ +@@ -8690,6 +9489,16 @@ physaddr_t pstart, pend; ulong node_size; @@ -4662,7 +5019,7 @@ for (n = 0; n < vt->numnodes; n++) { nt = &vt->node_table[n]; if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1)) -@@ -8797,6 +9559,17 @@ +@@ -8797,6 +9606,17 @@ fprintf(fp, "%sKMEM_CACHE_UNAVAIL", others++ ? "|" : ""); if (vt->flags & DISCONTIGMEM) fprintf(fp, "%sDISCONTIGMEM", others++ ? "|" : ""); @@ -4680,7 +5037,7 @@ fprintf(fp, ")\n"); if (vt->kernel_pgd[0] == vt->kernel_pgd[1]) fprintf(fp, " kernel_pgd[NR_CPUS]: %lx ...\n", -@@ -8825,6 +9598,7 @@ +@@ -8825,6 +9645,7 @@ fprintf(fp, " kmem_max_cpus: %ld\n", vt->kmem_max_cpus); fprintf(fp, " kmem_cache_count: %ld\n", vt->kmem_cache_count); fprintf(fp, " kmem_cache_namelen: %d\n", vt->kmem_cache_namelen); @@ -4688,7 +5045,7 @@ fprintf(fp, " PG_reserved: %lx\n", vt->PG_reserved); fprintf(fp, " PG_slab: %ld\n", vt->PG_slab); fprintf(fp, " paddr_prlen: %d\n", vt->paddr_prlen); -@@ -8869,6 +9643,8 @@ +@@ -8869,6 +9690,8 @@ fprintf(fp, " nr_swapfiles: %d\n", vt->nr_swapfiles); fprintf(fp, " last_swap_read: %lx\n", vt->last_swap_read); fprintf(fp, " swap_info_struct: %lx\n", (ulong)vt->swap_info_struct); @@ -4697,7 +5054,7 @@ dump_vma_cache(VERBOSE); } -@@ -9321,6 +10097,43 @@ +@@ -9321,6 +10144,43 @@ } /* @@ -4741,7 +5098,7 @@ * Return the next kernel virtual address page that comes after * the passed-in address. */ -@@ -9348,6 +10161,8 @@ +@@ -9348,6 +10208,8 @@ if (IS_VMALLOC_ADDR(vaddr_orig)) { if (IS_VMALLOC_ADDR(vaddr) && (vaddr < vmalloc_limit)) { @@ -4750,7 +5107,7 @@ *nextvaddr = vaddr; return TRUE; } -@@ -9377,6 +10192,7 @@ +@@ -9377,6 +10239,7 @@ /* * We're in the physical range. */ @@ -4758,7 +5115,7 @@ return TRUE; } -@@ -9446,7 +10262,7 @@ +@@ -9446,7 +10309,7 @@ totalswap = totalused = 0; for (i = 0; i < vt->nr_swapfiles; i++, @@ -4767,7 +5124,7 @@ fill_swap_info(swap_info); flags = INT(vt->swap_info_struct + -@@ -9471,8 +10287,12 @@ +@@ -9471,8 +10334,12 @@ prio = INT(vt->swap_info_struct + OFFSET(swap_info_struct_prio)); @@ -4782,7 +5139,16 @@ swap_map = ULONG(vt->swap_info_struct + OFFSET(swap_info_struct_swap_map)); -@@ -9741,13 +10561,13 @@ +@@ -9486,7 +10353,7 @@ + } else if (VALID_MEMBER + (swap_info_struct_old_block_size)) { + get_pathname(file_to_dentry(swap_file), +- buf, BUFSIZE, 1, 0); ++ buf, BUFSIZE, 1, file_to_vfsmnt(swap_file)); + } else { + get_pathname(swap_file, buf, BUFSIZE, 1, 0); + } +@@ -9741,13 +10608,13 @@ dump_memory_nodes(int initialize) { int i, j; @@ -4798,7 +5164,7 @@ ulong zone_start_paddr, zone_start_mapnr, zone_mem_map; ulong zone_start_pfn; ulong bdata; -@@ -9761,23 +10581,23 @@ +@@ -9761,23 +10628,23 @@ char buf5[BUFSIZE]; struct node_table *nt; @@ -4839,7 +5205,7 @@ } if (initialize) -@@ -9785,7 +10605,7 @@ +@@ -9785,7 +10652,7 @@ else pgdat = vt->node_table[0].pgdat; @@ -4848,7 +5214,7 @@ if (n >= vt->numnodes) error(FATAL, "numnodes out of sync with pgdat_list?\n"); -@@ -9794,9 +10614,14 @@ +@@ -9794,9 +10661,14 @@ readmem(pgdat+OFFSET(pglist_data_node_id), KVADDR, &id, sizeof(int), "pglist node_id", FAULT_ON_ERROR); @@ -4866,7 +5232,7 @@ if (VALID_MEMBER(pglist_data_node_start_paddr)) readmem(pgdat+OFFSET(pglist_data_node_start_paddr), -@@ -9896,6 +10721,7 @@ +@@ -9896,6 +10768,7 @@ } node_zones = pgdat + OFFSET(pglist_data_node_zones); @@ -4874,7 +5240,7 @@ for (i = 0; i < vt->nr_zones; i++) { if (CRASHDEBUG(7)) fprintf(fp, "zone at %lx\n", node_zones); -@@ -9926,12 +10752,24 @@ +@@ -9926,12 +10799,24 @@ if (!read_string(value, buf1, BUFSIZE-1)) sprintf(buf1, "(unknown) "); if (VALID_STRUCT(zone_struct)) { @@ -4905,7 +5271,7 @@ readmem(node_zones+ OFFSET(zone_struct_zone_start_mapnr), KVADDR, &zone_start_mapnr, -@@ -9946,7 +10784,14 @@ +@@ -9946,7 +10831,14 @@ "node_zones zone_start_pfn", FAULT_ON_ERROR); zone_start_paddr = PTOB(zone_start_pfn); @@ -4921,7 +5287,7 @@ OFFSET(zone_zone_mem_map), KVADDR, &zone_mem_map, sizeof(ulong), -@@ -9959,15 +10804,27 @@ +@@ -9959,15 +10851,27 @@ else zone_start_mapnr = 0; } @@ -4954,7 +5320,7 @@ fprintf(fp, "%s %s %s\n", mkstring(buf1, VADDR_PRLEN, RJUST|LONG_HEX,MKSTR(zone_mem_map)), -@@ -10011,19 +10868,21 @@ +@@ -10011,19 +10915,21 @@ * Override numnodes -- some kernels may leave it at 1 on a system * with multiple memory nodes. */ @@ -4989,7 +5355,7 @@ } if (!(vt->node_table = (struct node_table *) -@@ -10072,6 +10931,9 @@ +@@ -10072,6 +10978,9 @@ { uint psz; @@ -4999,7 +5365,7 @@ if (REMOTE_MEMSRC()) return remote_page_size(); -@@ -10081,6 +10943,14 @@ +@@ -10081,6 +10990,14 @@ psz = diskdump_page_size(); break; @@ -5014,7 +5380,7 @@ case NETDUMP: psz = netdump_page_size(); break; -@@ -10115,6 +10985,48 @@ +@@ -10115,6 +11032,48 @@ } /* @@ -5063,7 +5429,17 @@ * Return the vmalloc address referenced by the first vm_struct * on the vmlist. This can normally be used by the machine-specific * xxx_vmalloc_start() routines. -@@ -10186,6 +11098,10 @@ +@@ -10127,6 +11086,9 @@ + + get_symbol_data("vmlist", sizeof(void *), &vmlist); + ++ if (!vmlist) ++ return 0; ++ + if (!readmem(vmlist+OFFSET(vm_struct_addr), KVADDR, &addr, + sizeof(void *), "first vmlist addr", RETURN_ON_ERROR)) + non_matching_kernel(); +@@ -10186,6 +11148,10 @@ retval = remote_memory_used(); else if (pc->flags & NETDUMP) retval = netdump_memory_used(); @@ -5074,7 +5450,7 @@ else if (pc->flags & DISKDUMP) retval = diskdump_memory_used(); else if (pc->flags & LKCD) -@@ -10201,6 +11117,10 @@ +@@ -10201,6 +11167,10 @@ retval = remote_free_memory(); else if (pc->flags & NETDUMP) retval = netdump_free_memory(); @@ -5085,7 +5461,7 @@ else if (pc->flags & DISKDUMP) retval = diskdump_free_memory(); else if (pc->flags & LKCD) -@@ -10216,6 +11136,10 @@ +@@ -10216,6 +11186,10 @@ retval = remote_memory_dump(0); else if (pc->flags & NETDUMP) retval = netdump_memory_dump(fp); @@ -5096,7 +5472,7 @@ else if (pc->flags & DISKDUMP) retval = diskdump_memory_dump(fp); else if (pc->flags & LKCD) -@@ -10238,3 +11162,197 @@ +@@ -10238,3 +11212,197 @@ return retval; } @@ -5294,8 +5670,8 @@ + } + } +} ---- crash/filesys.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/filesys.c 2006-04-28 11:24:32.000000000 -0400 +--- crash/filesys.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/filesys.c 2006-07-06 16:40:52.000000000 -0400 @@ -1,8 +1,8 @@ /* filesys.c - core analysis suite * @@ -5337,7 +5713,36 @@ pc->flags |= SYSMAP; } -@@ -1706,12 +1718,20 @@ +@@ -1131,6 +1143,7 @@ + char *arglist[MAXARGS*2]; + ulong vfsmount = 0; + int flags = 0; ++ int mh_flag = 1; + int save_next; + + while ((c = getopt(argcnt, args, "if")) != EOF) { +@@ -1181,7 +1194,7 @@ + continue; + + for (i = 0; i < c; i++) { +- if (STREQ(arglist[i], spec_string)) ++ if (PATHEQ(arglist[i], spec_string)) + found = TRUE; + } + if (found) { +@@ -1190,7 +1203,10 @@ + sscanf(buf2,"%lx",&vfsmount); + show_mounts(vfsmount, flags); + } else { +- fprintf(fp, mount_hdr); ++ if (mh_flag) { ++ fprintf(fp, mount_hdr); ++ mh_flag = 0; ++ } + fprintf(fp, buf2); + } + found = FALSE; +@@ -1706,12 +1722,20 @@ MEMBER_OFFSET_INIT(fs_struct_pwd, "fs_struct", "pwd"); MEMBER_OFFSET_INIT(fs_struct_rootmnt, "fs_struct", "rootmnt"); MEMBER_OFFSET_INIT(fs_struct_pwdmnt, "fs_struct", "pwdmnt"); @@ -5362,7 +5767,7 @@ MEMBER_OFFSET_INIT(file_f_dentry, "file", "f_dentry"); MEMBER_OFFSET_INIT(file_f_vfsmnt, "file", "f_vfsmnt"); MEMBER_OFFSET_INIT(file_f_count, "file", "f_count"); -@@ -1762,6 +1782,8 @@ +@@ -1762,6 +1786,8 @@ STRUCT_SIZE_INIT(umode_t, "umode_t"); STRUCT_SIZE_INIT(dentry, "dentry"); STRUCT_SIZE_INIT(files_struct, "files_struct"); @@ -5371,7 +5776,7 @@ STRUCT_SIZE_INIT(file, "file"); STRUCT_SIZE_INIT(inode, "inode"); STRUCT_SIZE_INIT(vfsmount, "vfsmount"); -@@ -1998,8 +2020,9 @@ +@@ -1998,8 +2024,9 @@ open_files_dump(ulong task, int flags, struct reference *ref) { struct task_context *tc; @@ -5383,7 +5788,7 @@ ulong fs_struct_addr; char *dentry_buf, *fs_struct_buf; ulong root_dentry, pwd_dentry; -@@ -2027,6 +2050,8 @@ +@@ -2027,6 +2054,8 @@ BZERO(root_pathname, BUFSIZE); BZERO(pwd_pathname, BUFSIZE); files_struct_buf = GETBUF(SIZE(files_struct)); @@ -5392,7 +5797,7 @@ fill_task_struct(task); sprintf(files_header, " FD%s%s%s%s%s%s%sTYPE%sPATH\n", -@@ -2107,24 +2132,42 @@ +@@ -2107,24 +2136,42 @@ files_struct_addr = ULONG(tt->task_struct + OFFSET(task_struct_files)); @@ -5445,7 +5850,7 @@ FREEBUF(files_struct_buf); return; } -@@ -2146,8 +2189,12 @@ +@@ -2146,8 +2193,12 @@ } } @@ -5460,7 +5865,7 @@ if (open_fds_addr) { if (VALID_MEMBER(files_struct_open_fds_init) && -@@ -2157,16 +2204,21 @@ +@@ -2157,16 +2208,21 @@ OFFSET(files_struct_open_fds_init), &open_fds, sizeof(fd_set)); else @@ -5485,7 +5890,7 @@ FREEBUF(files_struct_buf); return; } -@@ -2220,6 +2272,8 @@ +@@ -2220,6 +2276,8 @@ if (ref && (ref->cmdflags & FILES_REF_FOUND)) fprintf(fp, "\n"); @@ -5494,8 +5899,29 @@ FREEBUF(files_struct_buf); } ---- crash/help.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/help.c 2006-03-23 14:25:56.000000000 -0500 +@@ -2494,6 +2552,20 @@ + } + + /* ++ * Get the vfsmnt associated with a file. ++ */ ++ulong ++file_to_vfsmnt(ulong file) ++{ ++ char *file_buf; ++ ulong vfsmnt; ++ ++ file_buf = fill_file_cache(file); ++ vfsmnt = ULONG(file_buf + OFFSET(file_f_vfsmnt)); ++ return vfsmnt; ++} ++ ++/* + * get_pathname() fills in a pathname string for an ending dentry + * See __d_path() in the kernel for help fixing problems. + */ +--- crash/help.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/help.c 2006-08-03 16:59:00.000000000 -0400 @@ -1,8 +1,8 @@ /* help.c - core analysis suite * @@ -5563,7 +5989,28 @@ " flag Pass this optional flag to the command selected.", " argument Pass this argument to the command selected.", " ", -@@ -1155,7 +1160,7 @@ +@@ -1037,7 +1042,7 @@ + char *help_rd[] = { + "rd", + "read memory", +-"[-dDsup][-8|-16|-32|-64][-o offs][-e addr] [address|symbol] [count]", ++"[-dDsupxm][-8|-16|-32|-64][-o offs][-e addr] [address|symbol] [count]", + " This command displays the contents of memory, with the output formatted", + " in several different manners. The starting address may be entered either", + " symbolically or by address. The default output size is the size of a long", +@@ -1046,9 +1051,11 @@ + " -p address argument is a physical address.", + " -u address argument is a user virtual address; only required on", + " processors with common user and kernel virtual address spaces.", ++" -m address argument is a xen host machine address.", + " -d display output in signed decimal format (default is hexadecimal).", + " -D display output in unsigned decimal format (default is hexadecimal).", + " -s displays output symbolically when appropriate.", ++" -x do not display ASCII translation at end of each line.", + #ifdef NOTDEF + " -o Shows offset value from the starting address.", + #endif +@@ -1155,7 +1162,7 @@ "bt", "backtrace", #if defined(GDB_6_0) || defined(GDB_6_1) @@ -5572,7 +6019,7 @@ #else "[-a|-r|-t|-l|-e|-f|-g] [-R ref] [ -I ip ] [-S sp] [pid | taskp]", #endif -@@ -1167,6 +1172,9 @@ +@@ -1167,6 +1174,9 @@ " pages of memory containing the task_union structure.", " -t display all text symbols found from the last known stack location", " to the top of the stack. (helpful if the back trace fails)", @@ -5582,7 +6029,7 @@ " -l show file and line number of each stack trace text location.", " -e search the stack for possible kernel and user mode exception frames.", " -E search the IRQ stacks (x86, x86_64 and PPC64), and the exception", -@@ -1175,6 +1183,11 @@ +@@ -1175,6 +1185,11 @@ " -f display all stack data contained in a frame; this option can be", " used to determine the arguments passed to each function (x86 only);", " on IA64, the argument register contents are dumped.", @@ -5594,7 +6041,7 @@ #if !defined(GDB_6_0) && !defined(GDB_6_1) " -g use gdb stack trace code. (alpha only)", #endif -@@ -1439,12 +1452,13 @@ +@@ -1439,12 +1454,13 @@ " called \"echo\", which simply echoes back all arguments passed to it.", " Note the comments contained within it for further details. To build it,", " cut and paste the following output into a file, and call it, for example,", @@ -5612,7 +6059,53 @@ " located in the current directory, or in the user's $HOME directory.", " ", "---------------------------------- cut here ----------------------------------", -@@ -3324,7 +3338,8 @@ +@@ -2013,7 +2029,7 @@ + char *help_sys[] = { + "sys", + "system data", +-"[-c [name|number]] ", ++"[-c [name|number]] config", + " This command displays system-specific data. If no arguments are entered,\n" + " the same system data shown during %s invocation is shown.\n", + " -c [name|number] If no name or number argument is entered, dump all", +@@ -2023,6 +2039,8 @@ + " that number is displayed. If the current output radix", + " has been set to 16, the system call numbers will be ", + " displayed in hexadecimal.", ++" config If the kernel was configured with CONFIG_IKCONFIG, then", ++" dump the in-kernel configuration data.", + " -panic Panic a live system. Requires write permission to", + " /dev/mem. Results in the %s context causing an", + " \"Attempted to kill the idle task!\" panic. (The dump", +@@ -2043,6 +2061,27 @@ + " VERSION: #24 SMP Mon Oct 11 17:41:40 CDT 1999", + " MACHINE: i686 (500 MHz)", + " MEMORY: 1 GB", ++"\n Dump the system configuration data (if CONFIG_IKCONFIG):\n", ++" %s> sys config", ++" #", ++" # Automatically generated make config: don't edit", ++" # Linux kernel version: 2.6.16", ++" # Mon Apr 10 07:58:06 2006", ++" #", ++" CONFIG_X86_64=y", ++" CONFIG_64BIT=y", ++" CONFIG_X86=y", ++" CONFIG_SEMAPHORE_SLEEPERS=y", ++" CONFIG_MMU=y", ++" CONFIG_RWSEM_GENERIC_SPINLOCK=y", ++" CONFIG_GENERIC_CALIBRATE_DELAY=y", ++" CONFIG_X86_CMPXCHG=y", ++" CONFIG_EARLY_PRINTK=y", ++" CONFIG_GENERIC_ISA_DMA=y", ++" CONFIG_GENERIC_IOMAP=y", ++" CONFIG_ARCH_MAY_HAVE_PC_FDC=y", ++" CONFIG_DMI=y", ++" ...", + "\n Dump the system call table:\n", + " %s> sys -c", + " NUM SYSTEM CALL FILE AND LINE NUMBER", +@@ -3324,7 +3363,8 @@ "linked list", "[[-o] offset] [-e end] [-s struct[.member]] [-H] start", " This command dumps the contents of a linked list. The entries in a linked", @@ -5622,7 +6115,7 @@ " ", " 1. A starting address points to a data structure; that structure contains", " a member that is a pointer to the next structure, and so on. The list", -@@ -3335,7 +3350,7 @@ +@@ -3335,7 +3375,7 @@ " c. a pointer to the first item pointed to by the start address.", " d. a pointer to its containing structure.", " ", @@ -5631,7 +6124,7 @@ " within the data structures in the list. The linked list is headed by an", " external LIST_HEAD, which is simply a list_head structure initialized to", " point to itself, signifying that the list is empty:", -@@ -3377,8 +3392,9 @@ +@@ -3377,8 +3417,9 @@ " is pre-pended or not:", " ", " start The address of the first structure in the list.", @@ -5643,7 +6136,7 @@ "\nEXAMPLES", " Note that each task_struct is linked to its parent's task_struct via the", " p_pptr member:", -@@ -4419,10 +4435,11 @@ +@@ -4419,10 +4460,11 @@ " Display various network related data:\n", " -a display the ARP cache.", " -s display open network socket/sock addresses, their family and type,", @@ -5657,7 +6150,7 @@ " value into a standard numbers-and-dots notation.", " -R ref socket or sock address, or file descriptor.", " pid a process PID.", -@@ -4450,8 +4467,8 @@ +@@ -4450,8 +4492,8 @@ " Display the sockets for PID 2517, using both -s and -S output formats:\n", " %s> net -s 2517", " PID: 2517 TASK: c1598000 CPU: 1 COMMAND: \"rlogin\"", @@ -5668,7 +6161,7 @@ " ", " %s> net -S 2517", " PID: 2517 TASK: c1598000 CPU: 1 COMMAND: \"rlogin\"", -@@ -4497,52 +4514,52 @@ +@@ -4497,52 +4539,52 @@ " From \"foreach\", find all tasks with references to socket c08ea3cc:\n", " %s> foreach net -s -R c08ea3cc", " PID: 2184 TASK: c7026000 CPU: 1 COMMAND: \"klines.kss\"", @@ -5745,7 +6238,7 @@ " ", NULL }; -@@ -4854,9 +4871,11 @@ +@@ -4854,9 +4896,11 @@ static char *version_info[] = { @@ -5760,8 +6253,8 @@ "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,", ---- crash/task.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/task.c 2006-04-28 11:25:53.000000000 -0400 +--- crash/task.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/task.c 2006-06-26 09:13:03.000000000 -0400 @@ -27,6 +27,7 @@ static void refresh_pidhash_task_table(void); static void refresh_pid_hash_task_table(void); @@ -6144,7 +6637,7 @@ + if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) { + wrapped = (start_time & 0xffffffff00000000ULL); + if (wrapped) { -+ wrapped -= 0x100000000; ++ wrapped -= 0x100000000ULL; + start_time &= 0x00000000ffffffffULL; + start_time |= wrapped; + start_time += (ulonglong)(300*machdep->hz); @@ -6262,13 +6755,13 @@ + while (!msg_found && fgets(buf, BUFSIZE, pc->tmpfile)) { + if (strstr(buf, "Kernel panic: ")) + msg_found = TRUE; -+ } + } + rewind(pc->tmpfile); + while (!msg_found && fgets(buf, BUFSIZE, pc->tmpfile)) { + if (strstr(buf, "Oops: ") || + strstr(buf, "kernel BUG at")) + msg_found = TRUE; - } ++ } + rewind(pc->tmpfile); + while (!msg_found && fgets(buf, BUFSIZE, pc->tmpfile)) { + if (strstr(buf, "SysRq : Netdump") || @@ -6421,6 +6914,15 @@ tt->panic_threads[0] = get_dumpfile_panic_task(); } +@@ -4331,7 +4621,7 @@ + void + dump_task_table(int verbose) + { +- int i; ++ int i, nr_cpus; + struct task_context *tc; + char buf[BUFSIZE]; + int others, wrap, flen; @@ -4363,6 +4653,8 @@ fprintf(fp, "refresh_pid_hash_task_table()\n"); else if (tt->refresh_task_table == refresh_hlist_task_table) @@ -6430,7 +6932,81 @@ else fprintf(fp, "%lx\n", (ulong)tt->refresh_task_table); -@@ -4799,23 +5091,47 @@ +@@ -4443,7 +4735,9 @@ + wrap = sizeof(void *) == SIZEOF_32BIT ? 8 : 4; + flen = sizeof(void *) == SIZEOF_32BIT ? 8 : 16; + +- for (i = 0; i < NR_CPUS; i++) { ++ nr_cpus = kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : nr_cpus; ++ ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->panic_threads[i]); +@@ -4451,7 +4745,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " panic_ksp:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->panic_ksp[i]); +@@ -4459,7 +4753,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " hardirq_ctx:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->hardirq_ctx[i]); +@@ -4467,7 +4761,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " hardirq_tasks:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->hardirq_tasks[i]); +@@ -4475,7 +4769,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " softirq_ctx:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->softirq_ctx[i]); +@@ -4483,7 +4777,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " softirq_tasks:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->softirq_tasks[i]); +@@ -4491,7 +4785,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " idle_threads:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->idle_threads[i]); +@@ -4499,7 +4793,7 @@ + fprintf(fp, "\n"); + + fprintf(fp, " active_set:"); +- for (i = 0; i < NR_CPUS; i++) { ++ for (i = 0; i < nr_cpus; i++) { + if ((i % wrap) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%.*lx ", flen, tt->active_set[i]); +@@ -4799,23 +5093,47 @@ tt->flags &= ~ACTIVE_SET; } @@ -6493,7 +7069,7 @@ while (fgets(buf, BUFSIZE, pc->tmpfile)) { \ if (strstr(buf, " die+")) { \ switch (die_task) \ -@@ -4833,12 +5149,23 @@ +@@ -4833,12 +5151,23 @@ { \ case NO_TASK: \ panic_task = task; \ @@ -6517,7 +7093,7 @@ } /* -@@ -4850,11 +5177,12 @@ +@@ -4850,11 +5179,12 @@ int i, j, found; ulong task; char buf[BUFSIZE]; @@ -6532,7 +7108,7 @@ for (i = 0; i < NR_CPUS; i++) { if (!(task = tt->active_set[i])) -@@ -4875,7 +5203,7 @@ +@@ -4875,7 +5205,7 @@ raw_stack_dump(GET_STACKBASE(task), STACKSIZE()); rewind(pc->tmpfile); @@ -6541,7 +7117,7 @@ close_tmpfile(); } -@@ -4903,7 +5231,7 @@ +@@ -4903,7 +5233,7 @@ raw_stack_dump(tt->hardirq_ctx[i], SIZE(thread_union)); rewind(pc->tmpfile); @@ -6550,7 +7126,7 @@ close_tmpfile(); } -@@ -4930,7 +5258,7 @@ +@@ -4930,7 +5260,7 @@ raw_stack_dump(tt->softirq_ctx[i], SIZE(thread_union)); rewind(pc->tmpfile); @@ -6559,7 +7135,7 @@ close_tmpfile(); } -@@ -4938,6 +5266,20 @@ +@@ -4938,6 +5268,20 @@ RESOLVE_PANIC_AND_DIE_CALLERS(); } @@ -6580,7 +7156,7 @@ return NO_TASK; } -@@ -5416,6 +5758,15 @@ +@@ -5416,6 +5760,15 @@ char buf3[BUFSIZE]; char buf4[BUFSIZE]; @@ -6596,8 +7172,8 @@ sigset = task_signal(tc->task); if (!tt->last_task_read) return; ---- crash/kernel.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/kernel.c 2006-04-26 16:42:12.000000000 -0400 +--- crash/kernel.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/kernel.c 2006-08-03 17:25:27.000000000 -0400 @@ -20,7 +20,7 @@ static void do_module_cmd(ulong, char *, ulong, char *, char *); @@ -6607,16 +7183,29 @@ static char *get_loadavg(char *); static void get_lkcd_regs(struct bt_info *, ulong *, ulong *); static void dump_sys_call_table(char *, int); -@@ -51,7 +51,7 @@ +@@ -42,6 +42,8 @@ + static void verify_namelist(void); + static char *debug_kernel_version(char *); + static int restore_stack(struct bt_info *); ++static ulong __xen_m2p(ulonglong, ulong); ++static void read_in_kernel_config_err(int, char *); + + + /* +@@ -50,9 +52,10 @@ + void kernel_init(int when) { - int i; +- int i; - char *p1, *p2, buf[BUFSIZE];; ++ int i, c; + char *p1, *p2, buf[BUFSIZE]; struct syment *sp1, *sp2; ++ char *rqstruct; if (pc->flags & KERNEL_DEBUG_QUERY) -@@ -69,6 +69,26 @@ + return; +@@ -69,6 +72,26 @@ } kt->end = symbol_value("_end"); @@ -6633,17 +7222,38 @@ + get_symbol_data("phys_to_machine_mapping", sizeof(ulong), + &kt->phys_to_machine_mapping); + if (machine_type("X86")) -+ get_symbol_data("max_pfn", sizeof(ulong), &kt->ptm_table_size); ++ get_symbol_data("max_pfn", sizeof(ulong), &kt->p2m_table_size); + if (machine_type("X86_64")) -+ get_symbol_data("end_pfn", sizeof(ulong), &kt->ptm_table_size); -+ if ((kt->machine_to_pseudo = (char *)malloc(PAGESIZE())) == NULL) -+ error(FATAL, "cannot malloc machine_to_pseudo space."); ++ get_symbol_data("end_pfn", sizeof(ulong), &kt->p2m_table_size); ++ if ((kt->m2p_page = (char *)malloc(PAGESIZE())) == NULL) ++ error(FATAL, "cannot malloc m2p page."); + } + if (symbol_exists("smp_num_cpus")) { kt->flags |= SMP; get_symbol_data("smp_num_cpus", sizeof(int), &kt->cpus); -@@ -117,6 +137,7 @@ +@@ -96,9 +119,17 @@ + clean_exit(0); + } + +- readmem(symbol_value("system_utsname"), KVADDR, &kt->utsname, +- sizeof(struct new_utsname), "system_utsname", +- FAULT_ON_ERROR); ++ if (symbol_exists("system_utsname")) ++ readmem(symbol_value("system_utsname"), KVADDR, &kt->utsname, ++ sizeof(struct new_utsname), "system_utsname", ++ RETURN_ON_ERROR); ++ else if (symbol_exists("init_uts_ns")) ++ readmem(symbol_value("init_uts_ns") + sizeof(int), ++ KVADDR, &kt->utsname, sizeof(struct new_utsname), ++ "init_uts_ns", RETURN_ON_ERROR); ++ else ++ error(INFO, "cannot access utsname information\n\n"); ++ + strncpy(buf, kt->utsname.release, MIN(strlen(kt->utsname.release), 65)); + if (ascii_string(kt->utsname.release)) { + p1 = p2 = buf; +@@ -117,6 +148,7 @@ *p2 = NULLCHAR; kt->kernel_version[2] = atoi(p1); } @@ -6651,25 +7261,71 @@ break; case POST_GDB: -@@ -128,7 +149,8 @@ +@@ -127,8 +159,17 @@ + &kt->__per_cpu_offset[0]); kt->flags |= PER_CPU_OFF; } - MEMBER_OFFSET_INIT(runqueue_cpu, "runqueue", "cpu"); +- MEMBER_OFFSET_INIT(runqueue_cpu, "runqueue", "cpu"); - if (VALID_MEMBER(runqueue_cpu)) { ++ if (STRUCT_EXISTS("runqueue")) ++ rqstruct = "runqueue"; ++ else if (STRUCT_EXISTS("rq")) ++ rqstruct = "rq"; ++ ++ MEMBER_OFFSET_INIT(runqueue_cpu, rqstruct, "cpu"); ++ /* ++ * 'cpu' does not exist in 'struct rq'. ++ */ + if (VALID_MEMBER(runqueue_cpu) && + (get_array_length("runqueue.cpu", NULL, 0) > 0)) { MEMBER_OFFSET_INIT(cpu_s_curr, "cpu_s", "curr"); MEMBER_OFFSET_INIT(cpu_s_idle, "cpu_s", "idle"); STRUCT_SIZE_INIT(cpu_s, "cpu_s"); -@@ -153,6 +175,7 @@ +@@ -151,16 +192,17 @@ + "runq_siblings: %d: __cpu_idx and __rq_idx arrays don't exist?\n", + kt->runq_siblings); } else { - MEMBER_OFFSET_INIT(runqueue_idle, "runqueue", "idle"); - MEMBER_OFFSET_INIT(runqueue_curr, "runqueue", "curr"); +- MEMBER_OFFSET_INIT(runqueue_idle, "runqueue", "idle"); +- MEMBER_OFFSET_INIT(runqueue_curr, "runqueue", "curr"); +- } +- MEMBER_OFFSET_INIT(runqueue_active, "runqueue", "active"); +- MEMBER_OFFSET_INIT(runqueue_expired, "runqueue", "expired"); +- MEMBER_OFFSET_INIT(runqueue_arrays, "runqueue", "arrays"); ++ MEMBER_OFFSET_INIT(runqueue_idle, rqstruct, "idle"); ++ MEMBER_OFFSET_INIT(runqueue_curr, rqstruct, "curr"); + ASSIGN_OFFSET(runqueue_cpu) = INVALID_OFFSET; ++ } ++ MEMBER_OFFSET_INIT(runqueue_active, rqstruct, "active"); ++ MEMBER_OFFSET_INIT(runqueue_expired, rqstruct, "expired"); ++ MEMBER_OFFSET_INIT(runqueue_arrays, rqstruct, "arrays"); + MEMBER_OFFSET_INIT(prio_array_queue, "prio_array", "queue"); + MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", + "nr_active"); +- STRUCT_SIZE_INIT(runqueue, "runqueue"); ++ STRUCT_SIZE_INIT(runqueue, rqstruct); + STRUCT_SIZE_INIT(prio_array, "prio_array"); + + /* +@@ -197,10 +239,16 @@ + (kt->flags & PER_CPU_OFF)) + kt->cpus = machdep->get_smp_cpus(); + ++ if (kt->cpus_override && (c = atoi(kt->cpus_override))) { ++ error(WARNING, "forcing cpu count to: %d\n\n", c); ++ kt->cpus = c; ++ } ++ + if (kt->cpus > NR_CPUS) { + error(WARNING, +- "calculated number of cpus (%d) greater than compiled-in NR_CPUS (%d)\n", +- kt->cpus, NR_CPUS); ++ "%s number of cpus (%d) greater than compiled-in NR_CPUS (%d)\n", ++ kt->cpus_override && atoi(kt->cpus_override) ? ++ "configured" : "calculated", kt->cpus, NR_CPUS); + error(FATAL, "recompile crash with larger NR_CPUS\n"); } - MEMBER_OFFSET_INIT(runqueue_active, "runqueue", "active"); - MEMBER_OFFSET_INIT(runqueue_expired, "runqueue", "expired"); -@@ -471,6 +494,9 @@ + +@@ -471,6 +519,9 @@ } } @@ -6679,7 +7335,7 @@ return; bad_match: -@@ -1140,7 +1166,10 @@ +@@ -1140,7 +1191,10 @@ bt = &bt_info; BZERO(bt, sizeof(struct bt_info)); @@ -6691,7 +7347,7 @@ switch(c) { case 'f': -@@ -1151,6 +1180,28 @@ +@@ -1151,6 +1205,28 @@ bt->flags |= BT_OLD_BACK_TRACE; break; @@ -6720,7 +7376,7 @@ case 'R': if (refptr) error(INFO, "only one -R option allowed\n"); -@@ -1241,6 +1292,8 @@ +@@ -1241,6 +1317,8 @@ bt->flags |= BT_SYMBOLIC_ARGS; break; @@ -6729,7 +7385,7 @@ case 't': bt->flags |= BT_TEXT_SYMBOLS; break; -@@ -1350,9 +1403,10 @@ +@@ -1350,9 +1428,10 @@ char buf[BUFSIZE]; if (bt->flags & BT_TEXT_SYMBOLS) { @@ -6743,7 +7399,7 @@ } if (bt->hp) -@@ -1435,6 +1489,9 @@ +@@ -1435,6 +1514,9 @@ i < LONGS_PER_STACK; i++, up++) { if (is_kernel_text(*up)) fprintf(fp, "%lx: %s\n", @@ -6753,7 +7409,7 @@ bt->task + (i * sizeof(long)), value_to_symstr(*up, buf, 0)); } -@@ -1461,8 +1518,8 @@ +@@ -1461,8 +1543,8 @@ if (bt->hp) { if (bt->hp->esp && !INSTACK(bt->hp->esp, bt)) error(INFO, @@ -6764,7 +7420,7 @@ eip = bt->hp->eip; esp = bt->hp->esp; -@@ -1471,10 +1528,14 @@ +@@ -1471,10 +1553,14 @@ } else if (NETDUMP_DUMPFILE()) get_netdump_regs(bt, &eip, &esp); @@ -6779,7 +7435,7 @@ else machdep->get_stack_frame(bt, &eip, &esp); -@@ -1486,6 +1547,13 @@ +@@ -1486,6 +1572,13 @@ if (bt->flags & (BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)) { @@ -6793,7 +7449,7 @@ if (machdep->flags & MACHDEP_BT_TEXT) { bt->instptr = eip; bt->stkptr = esp; -@@ -1721,6 +1789,13 @@ +@@ -1721,6 +1814,13 @@ *esp = *(up-1); return; } @@ -6807,7 +7463,7 @@ if (STREQ(sym, "smp_stop_cpu_interrupt")) { *eip = *up; *esp = bt->task + -@@ -1873,6 +1948,8 @@ +@@ -1873,6 +1973,8 @@ kallsymsbuf = kt->flags & KALLSYMS_V1 ? GETBUF(SIZE(kallsyms_header)) : NULL; @@ -6816,7 +7472,7 @@ for (mod = kt->module_list; mod != kt->kernel_module; mod = mod_next) { if (CRASHDEBUG(7)) fprintf(fp, "module: %lx\n", mod); -@@ -1880,7 +1957,8 @@ +@@ -1880,7 +1982,8 @@ if (!readmem(mod, KVADDR, modbuf, SIZE(module), "module struct", RETURN_ON_ERROR|QUIET)) { error(WARNING, @@ -6826,7 +7482,7 @@ kt->mods_installed = 0; kt->flags |= NO_MODULE_ACCESS; FREEBUF(modbuf); -@@ -1914,7 +1992,8 @@ +@@ -1914,7 +2017,8 @@ kallsymsbuf, SIZE(kallsyms_header), "kallsyms_header", RETURN_ON_ERROR|QUIET)) { error(WARNING, @@ -6836,7 +7492,7 @@ } else { nsyms = UINT(kallsymsbuf + OFFSET(kallsyms_header_symbols)); -@@ -1947,6 +2026,8 @@ +@@ -1947,6 +2051,8 @@ store_module_symbols_v2(total, kt->mods_installed); break; } @@ -6845,7 +7501,7 @@ } -@@ -2459,7 +2540,7 @@ +@@ -2459,7 +2565,7 @@ static char * @@ -6854,7 +7510,7 @@ { char buf[BUFSIZE]; char file[BUFSIZE]; -@@ -2592,6 +2673,32 @@ +@@ -2592,6 +2698,32 @@ return retbuf; } @@ -6887,7 +7543,16 @@ /* * Unlink any temporary remote module object files. -@@ -2876,7 +2983,7 @@ +@@ -2787,6 +2919,8 @@ + do { + if (sflag) + dump_sys_call_table(args[optind], cnt++); ++ else if (STREQ(args[optind], "config")) ++ read_in_kernel_config(IKCFG_READ); + else + cmd_usage(args[optind], COMPLETE_HELP); + optind++; +@@ -2876,7 +3010,7 @@ get_symbol_data("xtime", sizeof(struct timespec), &kt->date); fprintf(fp, " DATE: %s\n", strip_linefeeds(ctime(&kt->date.tv_sec))); @@ -6896,7 +7561,7 @@ fprintf(fp, "LOAD AVERAGE: %s\n", get_loadavg(buf)); fprintf(fp, " TASKS: %ld\n", RUNNING_TASKS()); fprintf(fp, " NODENAME: %s\n", uts->nodename); -@@ -2891,6 +2998,9 @@ +@@ -2891,6 +3025,9 @@ #ifdef WHO_CARES fprintf(fp, " DOMAINNAME: %s\n", uts->domainname); #endif @@ -6906,7 +7571,7 @@ if (DUMPFILE()) { fprintf(fp, " PANIC: "); if (machdep->flags & HWRESET) -@@ -2952,28 +3062,42 @@ +@@ -2952,28 +3089,42 @@ /* * Calculate and return the uptime. */ @@ -6936,7 +7601,7 @@ + if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) { + wrapped = (jiffies_64 & 0xffffffff00000000ULL); + if (wrapped) { -+ wrapped -= 0x100000000; ++ wrapped -= 0x100000000ULL; + jiffies_64 &= 0x00000000ffffffffULL; + jiffies_64 |= wrapped; + jiffies_64 += (ulonglong)(300*machdep->hz); @@ -6965,16 +7630,19 @@ #define FSHIFT 11 /* nr of bits of precision */ #define FIXED_1 (1<> FSHIFT) -@@ -3181,7 +3305,7 @@ +@@ -3181,9 +3332,9 @@ * "help -k" output */ void -dump_kernel_table(void) +dump_kernel_table(int verbose) { - int i; +- int i; ++ int i, nr_cpus; struct new_utsname *uts; -@@ -3225,6 +3349,10 @@ + int others; + +@@ -3225,6 +3376,12 @@ fprintf(fp, "%sKMOD_V2", others++ ? "|" : ""); if (kt->flags & KALLSYMS_V2) fprintf(fp, "%sKALLSYMS_V2", others++ ? "|" : ""); @@ -6982,12 +7650,42 @@ + fprintf(fp, "%sUSE_OLD_BT", others++ ? "|" : ""); + if (kt->flags & ARCH_XEN) + fprintf(fp, "%sARCH_XEN", others++ ? "|" : ""); ++ if (kt->flags & NO_IKCONFIG) ++ fprintf(fp, "%sNO_IKCONFIG", others++ ? "|" : ""); fprintf(fp, ")\n"); fprintf(fp, " stext: %lx\n", kt->stext); fprintf(fp, " etext: %lx\n", kt->etext); -@@ -3277,7 +3405,37 @@ +@@ -3234,8 +3391,10 @@ + fprintf(fp, " init_end: %lx\n", kt->init_end); + fprintf(fp, " end: %lx\n", kt->end); + fprintf(fp, " cpus: %d\n", kt->cpus); ++ fprintf(fp, " cpus_override: %s\n", kt->cpus_override); + fprintf(fp, " NR_CPUS: %d (compiled-in to this version of %s)\n", + NR_CPUS, pc->program_name); ++ fprintf(fp, "kernel_NR_CPUS: %d\n", kt->kernel_NR_CPUS); + if (kt->display_bh == display_bh_1) + fprintf(fp, " display_bh: display_bh_1()\n"); + else if (kt->display_bh == display_bh_2) +@@ -3265,19 +3424,50 @@ + kt->gcc_version[1], kt->gcc_version[2]); + fprintf(fp, " runq_siblings: %d\n", kt->runq_siblings); + fprintf(fp, " __rq_idx[NR_CPUS]: "); +- for (i = 0; i < NR_CPUS; i++) ++ nr_cpus = kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS; ++ for (i = 0; i < nr_cpus; i++) + fprintf(fp, "%ld ", kt->__rq_idx[i]); + fprintf(fp, "\n __cpu_idx[NR_CPUS]: "); +- for (i = 0; i < NR_CPUS; i++) ++ for (i = 0; i < nr_cpus; i++) + fprintf(fp, "%ld ", kt->__cpu_idx[i]); + fprintf(fp, "\n __per_cpu_offset[NR_CPUS]:"); +- for (i = 0; i < NR_CPUS; i++) ++ for (i = 0; i < nr_cpus; i++) + fprintf(fp, "%s%.*lx ", (i % 4) == 0 ? "\n " : "", + LONG_PRLEN, kt->__per_cpu_offset[i]); fprintf(fp, "\n cpu_flags[NR_CPUS]:"); - for (i = 0; i < NR_CPUS; i++) +- for (i = 0; i < NR_CPUS; i++) ++ for (i = 0; i < nr_cpus; i++) fprintf(fp, "%lx ", kt->cpu_flags[i]); - fprintf(fp, "\n"); + others = 0; @@ -7001,30 +7699,30 @@ + if (kt->xen_flags & XEN_SUSPEND) + fprintf(fp, "%sXEN_SUSPEND", others++ ? "|" : ""); + fprintf(fp, ")\n"); -+ fprintf(fp, " machine_to_pseudo: %lx\n", (ulong)kt->machine_to_pseudo); ++ fprintf(fp, " m2p_page: %lx\n", (ulong)kt->m2p_page); + fprintf(fp, "phys_to_machine_mapping: %lx\n", kt->phys_to_machine_mapping); -+ fprintf(fp, " ptm_table_size: %ld\n", kt->ptm_table_size); -+ fprintf(fp, " ptm_mapping_cache[%d]: %s\n", PTM_MAPPING_CACHE, ++ fprintf(fp, " p2m_table_size: %ld\n", kt->p2m_table_size); ++ fprintf(fp, " p2m_mapping_cache[%d]: %s\n", P2M_MAPPING_CACHE, + verbose ? "" : "(use \"help -K\" to view cache contents)"); -+ for (i = 0; verbose && (i < PTM_MAPPING_CACHE); i++) { -+ if (!kt->ptm_mapping_cache[i].mapping) ++ for (i = 0; verbose && (i < P2M_MAPPING_CACHE); i++) { ++ if (!kt->p2m_mapping_cache[i].mapping) + continue; + fprintf(fp, " [%d] mapping: %lx mfn: %lx\n", -+ i, kt->ptm_mapping_cache[i].mapping, -+ kt->ptm_mapping_cache[i].mfn); ++ i, kt->p2m_mapping_cache[i].mapping, ++ kt->p2m_mapping_cache[i].mfn); + } + fprintf(fp, " last_mapping_read: %lx\n", kt->last_mapping_read); -+ fprintf(fp, " ptm_cache_index: %ld\n", kt->ptm_cache_index); -+ fprintf(fp, " ptm_pages_searched: %ld\n", kt->ptm_pages_searched); -+ fprintf(fp, " ptm_cache_hits: %ld ", kt->ptm_cache_hits); -+ if (kt->ptm_pages_searched) -+ fprintf(fp, "(%ld%%)\n", kt->ptm_cache_hits * 100 / kt->ptm_pages_searched); ++ fprintf(fp, " p2m_cache_index: %ld\n", kt->p2m_cache_index); ++ fprintf(fp, " p2m_pages_searched: %ld\n", kt->p2m_pages_searched); ++ fprintf(fp, " p2m_cache_hits: %ld ", kt->p2m_cache_hits); ++ if (kt->p2m_pages_searched) ++ fprintf(fp, "(%ld%%)\n", kt->p2m_cache_hits * 100 / kt->p2m_pages_searched); + else + fprintf(fp, "\n"); } /* -@@ -4475,9 +4633,16 @@ +@@ -4475,9 +4665,16 @@ ld->start = vec[i]; ld->list_head_offset = offset; ld->end = vec_kvaddr; @@ -7042,7 +7740,7 @@ if (!timer_cnt) continue; timer_list = (ulong *)GETBUF(timer_cnt * sizeof(ulong)); -@@ -4708,6 +4873,8 @@ +@@ -4708,21 +4905,412 @@ machdep->last_pgd_read = 0; machdep->last_pmd_read = 0; machdep->last_ptbl_read = 0; @@ -7051,61 +7749,114 @@ } } -@@ -4726,3 +4893,104 @@ + /* +- * For kernels containing cpu_online_map, count the bits. ++ * For kernels containing at least the cpu_online_map, use it ++ * to determine the cpu count. + */ + int + get_cpus_online() + { +- ulong cpu_online_map; ++ int i, len, online; ++ struct gnu_request req; ++ char *buf; ++ ulong *maskptr; - return count_bits_long(cpu_online_map); - } + if (!symbol_exists("cpu_online_map")) + return 0; + +- get_symbol_data("cpu_online_map", sizeof(ulong), &cpu_online_map); ++ len = get_symbol_type("cpu_online_map", NULL, &req) == TYPE_CODE_UNDEF ? ++ sizeof(ulong) : req.length; ++ buf = GETBUF(len); + ++ online = 0; ++ ++ if (readmem(symbol_value("cpu_online_map"), KVADDR, buf, len, ++ "cpu_online_map", RETURN_ON_ERROR)) { ++ ++ maskptr = (ulong *)buf; ++ for (i = 0; i < (len/sizeof(ulong)); i++, maskptr++) ++ online += count_bits_long(*maskptr); ++ ++ FREEBUF(buf); ++ if (CRASHDEBUG(1)) ++ error(INFO, "get_cpus_online: online: %d\n", online); ++ } ++ ++ return online; ++} + +- return count_bits_long(cpu_online_map); +/* -+ * Generic xen machine-address to pseudo-physical-address translator. ++ * Xen machine-address to pseudo-physical-page translator. + */ -+ulong -+xen_machine_to_pseudo(ulong machine) ++ulonglong ++xen_m2p(ulonglong machine) +{ -+ ulong mapping, mfn, kmfn, pfn, p, i, c; -+ ulong *mp; ++ ulong mfn, pfn; + + mfn = XEN_MACHINE_TO_MFN(machine); -+ mp = (ulong *)kt->machine_to_pseudo; ++ pfn = __xen_m2p(machine, mfn); ++ ++ if (pfn == XEN_MFN_NOT_FOUND) { ++ if (CRASHDEBUG(1)) ++ error(INFO, ++ "xen_machine_to_pseudo_PAE: machine address %lx not found\n", ++ machine); ++ return XEN_MACHADDR_NOT_FOUND; ++ } ++ ++ return XEN_PFN_TO_PSEUDO(pfn); ++} ++ ++static ulong ++__xen_m2p(ulonglong machine, ulong mfn) ++{ ++ ulong mapping, kmfn, pfn, p, i, c; ++ ulong *mp; ++ ++ mp = (ulong *)kt->m2p_page; + mapping = kt->phys_to_machine_mapping; + + /* + * Check the FIFO cache first. + */ -+ for (c = 0; c < PTM_MAPPING_CACHE; c++) { -+ if (kt->ptm_mapping_cache[c].mapping && -+ (kt->ptm_mapping_cache[c].mfn == mfn)) { ++ for (c = 0; c < P2M_MAPPING_CACHE; c++) { ++ if (kt->p2m_mapping_cache[c].mapping && ++ (kt->p2m_mapping_cache[c].mfn == mfn)) { + -+ if (kt->ptm_mapping_cache[c].mapping != kt->last_mapping_read) { -+ if (!readmem(kt->ptm_mapping_cache[c].mapping, KVADDR, ++ if (kt->p2m_mapping_cache[c].mapping != kt->last_mapping_read) { ++ if (!readmem(kt->p2m_mapping_cache[c].mapping, KVADDR, + mp, PAGESIZE(), "phys_to_machine_mapping page (cached)", + RETURN_ON_ERROR)) + error(FATAL, "cannot access " + "phys_to_machine_mapping page\n"); + else -+ kt->last_mapping_read = kt->ptm_mapping_cache[c].mapping; ++ kt->last_mapping_read = kt->p2m_mapping_cache[c].mapping; + } + + for (i = 0; i < XEN_PFNS_PER_PAGE; i++) { + kmfn = (*(mp+i)) & ~XEN_FOREIGN_FRAME; + if (kmfn == mfn) { -+ p = PTM_MAPPING_TO_PAGE_INDEX(c); ++ p = P2M_MAPPING_TO_PAGE_INDEX(c); + pfn = p + i; + + if (CRASHDEBUG(1)) -+ console("(cached) mfn: %lx (%lx) p: %ld" -+ " i: %ld pfn: %lx (%lx)\n", ++ console("(cached) mfn: %lx (%llx) p: %ld" ++ " i: %ld pfn: %lx (%llx)\n", + mfn, machine, p, + i, pfn, XEN_PFN_TO_PSEUDO(pfn)); -+ kt->ptm_cache_hits++; ++ kt->p2m_cache_hits++; + -+ return(XEN_PFN_TO_PSEUDO(pfn)); ++ return pfn; + } + } + /* + * Stale entry -- clear it out. + */ -+ kt->ptm_mapping_cache[c].mapping = 0; ++ kt->p2m_mapping_cache[c].mapping = 0; + } + } + @@ -7114,7 +7865,7 @@ + * beginning of the phys_to_machine_mapping array, caching + * only the found machine address. + */ -+ for (p = 0; p < kt->ptm_table_size; p += XEN_PFNS_PER_PAGE) ++ for (p = 0; p < kt->p2m_table_size; p += XEN_PFNS_PER_PAGE) + { + if (mapping != kt->last_mapping_read) { + if (!readmem(mapping, KVADDR, mp, PAGESIZE(), @@ -7125,7 +7876,7 @@ + kt->last_mapping_read = mapping; + } + -+ kt->ptm_pages_searched++; ++ kt->p2m_pages_searched++; + + for (i = 0; i < XEN_PFNS_PER_PAGE; i++) + { @@ -7133,17 +7884,17 @@ + if (kmfn == mfn) { + pfn = p + i; + if (CRASHDEBUG(1)) -+ console("pages: %d mfn: %lx (%lx) p: %ld" -+ " i: %ld pfn: %lx (%lx)\n", ++ console("pages: %d mfn: %lx (%llx) p: %ld" ++ " i: %ld pfn: %lx (%llx)\n", + (p/XEN_PFNS_PER_PAGE)+1, mfn, machine, + p, i, pfn, XEN_PFN_TO_PSEUDO(pfn)); + -+ c = kt->ptm_cache_index; -+ kt->ptm_mapping_cache[c].mfn = mfn; -+ kt->ptm_mapping_cache[c].mapping = mapping; -+ kt->ptm_cache_index = (c+1) % PTM_MAPPING_CACHE; ++ c = kt->p2m_cache_index; ++ kt->p2m_mapping_cache[c].mfn = mfn; ++ kt->p2m_mapping_cache[c].mapping = mapping; ++ kt->p2m_cache_index = (c+1) % P2M_MAPPING_CACHE; + -+ return(XEN_PFN_TO_PSEUDO(pfn)); ++ return pfn; + } + } + @@ -7151,12 +7902,262 @@ + } + + if (CRASHDEBUG(1)) -+ console("machine address %lx not found\n", machine); ++ console("machine address %llx not found\n", machine); + -+ return(XEN_MFN_NOT_FOUND); ++ return (XEN_MFN_NOT_FOUND); +} + ---- crash/gdb_interface.c.orig 2006-05-15 17:21:18.000000000 -0400 ++ ++/* ++ * Read the relevant IKCONFIG (In Kernel Config) data if available. ++ */ ++ ++static char *ikconfig[] = { ++ "CONFIG_NR_CPUS", ++ "CONFIG_PGTABLE_4", ++ "CONFIG_HZ", ++ NULL, ++}; ++ ++void ++read_in_kernel_config(int command) ++{ ++ struct syment *sp; ++ int ii, jj, ret, end, found=0; ++ unsigned long size, bufsz; ++ char *pos, *ln, *buf, *head, *tail, *val, *uncomp; ++ char line[512]; ++ z_stream stream; ++ ++ if ((kt->flags & NO_IKCONFIG) && !(pc->flags & RUNTIME)) ++ return; ++ ++ if ((sp = symbol_search("kernel_config_data")) == NULL) { ++ if (command == IKCFG_READ) ++ error(FATAL, ++ "kernel_config_data does not exist in this kernel\n"); ++ return; ++ } ++ ++ /* We don't know how large IKCONFIG is, so we start with ++ * 32k, if we can't find MAGIC_END assume we didn't read ++ * enough, double it and try again. ++ */ ++ ii = 32; ++ ++again: ++ size = ii * 1024; ++ ++ if ((buf = (char *)malloc(size)) == NULL) { ++ error(WARNING, "cannot malloc IKCONFIG input buffer\n"); ++ return; ++ } ++ ++ if (!readmem(sp->value, KVADDR, buf, size, ++ "kernel_config_data", RETURN_ON_ERROR)) { ++ error(WARNING, "cannot read kernel_config_data\n"); ++ goto out2; ++ } ++ ++ /* Find the start */ ++ if (strstr(buf, MAGIC_START)) ++ head = buf + MAGIC_SIZE + 10; /* skip past MAGIC_START and gzip header */ ++ else { ++ error(WARNING, "could not find MAGIC_START!\n"); ++ goto out2; ++ } ++ ++ tail = head; ++ ++ end = strlen(MAGIC_END); ++ ++ /* Find the end*/ ++ while (tail < (buf + (size - 1))) { ++ ++ if (strncmp(tail, MAGIC_END, end)==0) { ++ found = 1; ++ break; ++ } ++ tail++; ++ } ++ ++ if (found) { ++ bufsz = tail - head; ++ size = 10 * bufsz; ++ if ((uncomp = (char *)malloc(size)) == NULL) { ++ error(WARNING, "cannot malloc IKCONFIG output buffer\n"); ++ goto out2; ++ } ++ } else { ++ if (ii > 512) { ++ error(WARNING, "could not find MAGIC_END!\n"); ++ goto out2; ++ } else { ++ free(buf); ++ ii *= 2; ++ goto again; ++ } ++ } ++ ++ ++ /* initialize zlib */ ++ stream.next_in = (Bytef *)head; ++ stream.avail_in = (uInt)bufsz; ++ ++ stream.next_out = uncomp; ++ stream.avail_out = (uInt)size; ++ ++ stream.zalloc = NULL; ++ stream.zfree = NULL; ++ stream.opaque = NULL; ++ ++ ret = inflateInit2(&stream, -MAX_WBITS); ++ if (ret != Z_OK) { ++ read_in_kernel_config_err(ret, "initialize"); ++ goto out1; ++ } ++ ++ ret = inflate(&stream, Z_FINISH); ++ ++ if (ret != Z_STREAM_END) { ++ inflateEnd(&stream); ++ if (ret == Z_NEED_DICT || ++ (ret == Z_BUF_ERROR && stream.avail_in == 0)) { ++ read_in_kernel_config_err(Z_DATA_ERROR, "uncompress"); ++ goto out1; ++ } ++ read_in_kernel_config_err(ret, "uncompress"); ++ goto out1; ++ } ++ size = stream.total_out; ++ ++ ret = inflateEnd(&stream); ++ ++ pos = uncomp; ++ ++ do { ++ ret = sscanf(pos, "%511[^\n]\n%n", line, &ii); ++ if (ret > 0) { ++ if ((command == IKCFG_READ) || CRASHDEBUG(8)) ++ fprintf(fp, "%s\n", line); ++ ++ pos += ii; ++ ++ ln = line; ++ ++ /* skip leading whitespace */ ++ while (whitespace(*ln)) ++ ln++; ++ ++ /* skip comments */ ++ if (*ln == '#') ++ continue; ++ ++ /* Find '=' */ ++ if ((head = strchr(ln, '=')) != NULL) { ++ *head = '\0'; ++ val = head + 1; ++ ++ head--; ++ ++ /* skip trailing whitespace */ ++ while (whitespace(*head)) { ++ *head = '\0'; ++ head--; ++ } ++ ++ /* skip whitespace */ ++ while (whitespace(*val)) ++ val++; ++ ++ } else /* Bad line, skip it */ ++ continue; ++ ++ if (command != IKCFG_INIT) ++ continue; ++ ++ for (jj = 0; ikconfig[jj]; jj++) { ++ if (STREQ(ln, ikconfig[jj])) { ++ ++ if (STREQ(ln, "CONFIG_NR_CPUS")) { ++ kt->kernel_NR_CPUS = atoi(val); ++ if (CRASHDEBUG(1)) ++ error(INFO, ++ "CONFIG_NR_CPUS: %d\n", ++ kt->kernel_NR_CPUS); ++ ++ } else if (STREQ(ln, "CONFIG_PGTABLE_4")) { ++ machdep->flags |= VM_4_LEVEL; ++ if (CRASHDEBUG(1)) ++ error(INFO, "CONFIG_PGTABLE_4\n"); ++ ++ } else if (STREQ(ln, "CONFIG_HZ")) { ++ machdep->hz = atoi(val); ++ if (CRASHDEBUG(1)) ++ error(INFO, ++ "CONFIG_HZ: %d\n", ++ machdep->hz); ++ } ++ } ++ } ++ } ++ } while (ret > 0); ++ ++out1: ++ free(uncomp); ++out2: ++ free(buf); ++ ++ return; ++} ++ ++static void ++read_in_kernel_config_err(int e, char *msg) ++{ ++ error(WARNING, "zlib could not %s\n", msg); ++ switch (e) { ++ case Z_OK: ++ fprintf(fp, "Z_OK\n"); ++ break; ++ ++ case Z_STREAM_END: ++ fprintf(fp, "Z_STREAM_END\n"); ++ break; ++ ++ case Z_NEED_DICT: ++ fprintf(fp, "Z_NEED_DICT\n"); ++ break; ++ ++ case Z_ERRNO: ++ fprintf(fp, "Z_ERNO\n"); ++ break; ++ ++ case Z_STREAM_ERROR: ++ fprintf(fp, "Z_STREAM\n"); ++ break; ++ ++ case Z_DATA_ERROR: ++ fprintf(fp, "Z_DATA_ERROR\n"); ++ break; ++ ++ case Z_MEM_ERROR: /* out of memory */ ++ fprintf(fp, "Z_MEM_ERROR\n"); ++ break; ++ ++ case Z_BUF_ERROR: /* not enough room in output buf */ ++ fprintf(fp, "Z_BUF_ERROR\n"); ++ break; ++ ++ case Z_VERSION_ERROR: ++ fprintf(fp, "Z_VERSION_ERROR\n"); ++ break; ++ ++ default: ++ fprintf(fp, "UNKNOWN ERROR: %d\n", e); ++ break; ++ } + } +--- crash/gdb_interface.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/gdb_interface.c 2006-04-11 17:25:48.000000000 -0400 @@ -31,9 +31,6 @@ { @@ -7188,7 +8189,7 @@ gdb_interface(req); if (!(req->flags & GNU_COMMAND_FAILED)) goto retry; ---- crash/configure.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/configure.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/configure.c 2006-03-23 15:44:46.000000000 -0500 @@ -1128,7 +1128,7 @@ printf("License: GPL\n"); @@ -7199,7 +8200,7 @@ printf("Distribution: Linux 2.2 or greater\n"); printf("Vendor: Red Hat, Inc.\n"); printf("Packager: Dave Anderson \n"); ---- crash/net.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/net.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/net.c 2006-05-11 11:17:01.000000000 -0400 @@ -50,6 +50,7 @@ #define STRUCT_NET_DEVICE (0x4) @@ -7556,7 +8557,7 @@ break; } break; ---- crash/dev.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/dev.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/dev.c 2005-11-23 11:09:08.000000000 -0500 @@ -91,13 +91,13 @@ switch(c) @@ -7574,9 +8575,19 @@ option_not_supported(c); do_pci(); return; ---- crash/alpha.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/alpha.c 2005-11-04 17:37:53.000000000 -0500 -@@ -1858,8 +1858,6 @@ +--- crash/alpha.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/alpha.c 2006-08-02 10:30:58.000000000 -0400 +@@ -186,7 +186,8 @@ + "irq_desc", NULL, 0); + else + machdep->nr_irqs = 0; +- machdep->hz = HZ; ++ if (!machdep->hz) ++ machdep->hz = HZ; + break; + + case POST_INIT: +@@ -1858,8 +1859,6 @@ fprintf(fp, " flags: %lx (", machdep->flags); if (machdep->flags & HWRESET) fprintf(fp, "%sHWRESET", others++ ? "|" : ""); @@ -7585,9 +8596,26 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base); ---- crash/x86.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/x86.c 2006-04-26 15:53:35.000000000 -0400 -@@ -685,6 +685,7 @@ +--- crash/x86.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/x86.c 2006-08-03 11:15:55.000000000 -0400 +@@ -176,6 +176,7 @@ + static void db_symbol_values(db_sym_t, char **, db_expr_t *); + static int db_sym_numargs(db_sym_t, int *, char **); + static void x86_dump_line_number(ulong); ++static void x86_clear_machdep_cache(void); + + static ulong mach_debug = 0; + +@@ -215,7 +216,7 @@ + + argp = (int *)db_get_value((int)&fp->f_retaddr, 4, FALSE, bt); + /* +- * XXX etext is wrong for LKMs. We should attempt to interpret ++ * etext is wrong for LKMs. We should attempt to interpret + * the instruction at the return address in all cases. This + * may require better fault handling. + */ +@@ -685,6 +686,7 @@ bt->debug || (bt->flags & BT_FRAMESIZE_DEBUG) || !(bt->flags & BT_OLD_BACK_TRACE)) { @@ -7595,23 +8623,33 @@ lkcd_x86_back_trace(bt, 0, fp); return; } -@@ -964,6 +965,10 @@ +@@ -962,8 +964,12 @@ + */ + static int x86_uvtop(struct task_context *, ulong, physaddr_t *, int); static int x86_kvtop(struct task_context *, ulong, physaddr_t *, int); - static int x86_uvtop_pae(struct task_context *, ulong, physaddr_t *, int); - static int x86_kvtop_pae(struct task_context *, ulong, physaddr_t *, int); +-static int x86_uvtop_pae(struct task_context *, ulong, physaddr_t *, int); +-static int x86_kvtop_pae(struct task_context *, ulong, physaddr_t *, int); ++static int x86_uvtop_PAE(struct task_context *, ulong, physaddr_t *, int); ++static int x86_kvtop_PAE(struct task_context *, ulong, physaddr_t *, int); +static int x86_uvtop_xen_wpt(struct task_context *, ulong, physaddr_t *, int); +static int x86_kvtop_xen_wpt(struct task_context *, ulong, physaddr_t *, int); -+static int x86_uvtop_pae_xen_wpt(struct task_context *, ulong, physaddr_t *, int); -+static int x86_kvtop_pae_xen_wpt(struct task_context *, ulong, physaddr_t *, int); ++static int x86_uvtop_xen_wpt_PAE(struct task_context *, ulong, physaddr_t *, int); ++static int x86_kvtop_xen_wpt_PAE(struct task_context *, ulong, physaddr_t *, int); static ulong x86_get_task_pgd(ulong); static ulong x86_processor_speed(void); static ulong x86_get_pc(struct bt_info *); -@@ -983,6 +988,14 @@ +@@ -983,6 +989,20 @@ static int x86_dis_filter(ulong, char *); static struct line_number_hook x86_line_number_hooks[]; static int x86_is_uvaddr(ulong, struct task_context *); +static void x86_init_kernel_pgd(void); -+static int x86_xendump_ptm_create(struct xendump_data *); ++static ulong xen_m2p_nonPAE(ulong); ++static int x86_xendump_p2m_create(struct xendump_data *); ++static int x86_xen_kdump_p2m_create(struct xen_kdump_data *); ++static char *x86_xen_kdump_load_page(ulong, char *); ++static char *x86_xen_kdump_load_page_PAE(ulong, char *); ++static ulong x86_xen_kdump_page_mfn(ulong); ++static ulong x86_xen_kdump_page_mfn_PAE(ulong); +static ulong x86_xendump_panic_task(struct xendump_data *); +static void x86_get_xendump_regs(struct xendump_data *, struct bt_info *, ulong *, ulong *); +static char *x86_xendump_load_page(ulong, char *); @@ -7621,7 +8659,7 @@ #define INT_EFRAME_SS (14) -@@ -1420,6 +1433,17 @@ +@@ -1420,6 +1440,17 @@ break; } @@ -7639,7 +8677,7 @@ /* check for user exception frame */ if (((short)pt->reg_value[INT_EFRAME_CS] == 0x23) && -@@ -1441,6 +1465,20 @@ +@@ -1441,6 +1472,20 @@ rv = bt->stackbase + sizeof(ulong) * (first - stack); break; } @@ -7660,7 +8698,7 @@ } return(rv); } -@@ -1536,6 +1574,8 @@ +@@ -1536,6 +1581,8 @@ mode = "USER-MODE"; } else if ((cs == 0x10) || (cs == 0x60)) { mode = "KERNEL-MODE"; @@ -7669,7 +8707,7 @@ } else { mode = "UNKNOWN-MODE"; } -@@ -1639,7 +1679,7 @@ +@@ -1639,7 +1686,7 @@ machdep->stacksize = machdep->pagesize * 2; if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc pgd space."); @@ -7678,7 +8716,18 @@ error(FATAL, "cannot malloc pmd space."); if ((machdep->ptbl = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc ptbl space."); -@@ -1696,14 +1736,17 @@ +@@ -1659,8 +1706,8 @@ + PGDIR_SHIFT = PGDIR_SHIFT_3LEVEL; + PTRS_PER_PTE = PTRS_PER_PTE_3LEVEL; + PTRS_PER_PGD = PTRS_PER_PGD_3LEVEL; +- machdep->uvtop = x86_uvtop_pae; +- machdep->kvtop = x86_kvtop_pae; ++ machdep->uvtop = x86_uvtop_PAE; ++ machdep->kvtop = x86_kvtop_PAE; + } else { + PGDIR_SHIFT = PGDIR_SHIFT_2LEVEL; + PTRS_PER_PTE = PTRS_PER_PTE_2LEVEL; +@@ -1696,14 +1743,19 @@ machdep->cmd_mach = x86_cmd_mach; machdep->get_smp_cpus = x86_get_smp_cpus; machdep->line_number_hooks = x86_line_number_hooks; @@ -7688,9 +8737,11 @@ machdep->value_to_symbol = generic_machdep_value_to_symbol; - machdep->init_kernel_pgd = NULL; + machdep->init_kernel_pgd = x86_init_kernel_pgd; -+ machdep->xendump_ptm_create = x86_xendump_ptm_create; ++ machdep->xendump_p2m_create = x86_xendump_p2m_create; ++ machdep->xen_kdump_p2m_create = x86_xen_kdump_p2m_create; + machdep->xendump_panic_task = x86_xendump_panic_task; + machdep->get_xendump_regs = x86_get_xendump_regs; ++ machdep->clear_machdep_cache = x86_clear_machdep_cache; break; case POST_GDB: @@ -7699,10 +8750,18 @@ STRUCT_SIZE_INIT(user_regs_struct, "user_regs_struct"); MEMBER_OFFSET_INIT(user_regs_struct_ebp, "user_regs_struct", "ebp"); -@@ -1726,6 +1769,31 @@ - machdep->hz = HZ; - if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) - machdep->hz = 1000; +@@ -1723,9 +1775,36 @@ + "irq_desc", NULL, 0); + else + machdep->nr_irqs = 224; /* NR_IRQS */ +- machdep->hz = HZ; +- if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) +- machdep->hz = 1000; ++ if (!machdep->hz) { ++ machdep->hz = HZ; ++ if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) ++ machdep->hz = 1000; ++ } + + if (machdep->flags & PAE){ + machdep->section_size_bits = _SECTION_SIZE_BITS_PAE; @@ -7714,7 +8773,7 @@ + + if (XEN() && (kt->xen_flags & WRITABLE_PAGE_TABLES)) { + if (machdep->flags & PAE) -+ machdep->uvtop = x86_uvtop_pae_xen_wpt; ++ machdep->uvtop = x86_uvtop_xen_wpt_PAE; + else + machdep->uvtop = x86_uvtop_xen_wpt; + } @@ -7731,7 +8790,7 @@ break; case POST_INIT: -@@ -1825,7 +1893,7 @@ +@@ -1825,7 +1904,7 @@ fprintf(fp, " PAGE: %s (4MB)\n\n", mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, MKSTR(NONPAE_PAGEBASE(pgd_pte)))); @@ -7740,10 +8799,11 @@ } *paddr = NONPAE_PAGEBASE(pgd_pte) + (vaddr & ~_4MB_PAGE_MASK); -@@ -1892,6 +1960,169 @@ +@@ -1892,7 +1971,170 @@ } static int +-x86_uvtop_pae(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) +x86_uvtop_xen_wpt(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) +{ + ulong mm, active_mm; @@ -7813,7 +8873,7 @@ + mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, + MKSTR(NONPAE_PAGEBASE(pgd_pte)))); + -+ pseudo_pgd_pte = xen_machine_to_pseudo(NONPAE_PAGEBASE(pgd_pte)); ++ pseudo_pgd_pte = xen_m2p_nonPAE(NONPAE_PAGEBASE(pgd_pte)); + + if (pseudo_pgd_pte == XEN_MFN_NOT_FOUND) { + if (verbose) @@ -7856,7 +8916,7 @@ + ((vaddr>>10) & ((PTRS_PER_PTE-1)<<2))); + + pseudo_page_table = (ulong *) -+ xen_machine_to_pseudo(NONPAE_PAGEBASE(machine_page_table)); ++ xen_m2p_nonPAE(NONPAE_PAGEBASE(machine_page_table)); + + FILL_PTBL(NONPAE_PAGEBASE(pseudo_page_table), PHYSADDR, PAGESIZE()); + machine_pte = ULONG(machdep->ptbl + PAGEOFFSET(machine_page_table)); @@ -7883,7 +8943,7 @@ + goto no_upage; + } + -+ pseudo_pte = xen_machine_to_pseudo(NONPAE_PAGEBASE(machine_pte)); ++ pseudo_pte = xen_m2p_nonPAE(NONPAE_PAGEBASE(machine_pte)); + pseudo_pte |= PAGEOFFSET(machine_pte); + + *paddr = NONPAE_PAGEBASE(pseudo_pte) + PAGEOFFSET(vaddr); @@ -7907,42 +8967,342 @@ +} + +static int - x86_uvtop_pae(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) ++x86_uvtop_PAE(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) { ulong mm, active_mm; -@@ -2040,6 +2271,12 @@ + ulonglong *pgd; +@@ -1962,7 +2204,7 @@ + + page_middle = PAE_PAGEBASE(page_dir_entry); + +- FILL_PMD(page_middle, PHYSADDR, PAGESIZE()); ++ FILL_PMD_PAE(page_middle, PHYSADDR, PAGESIZE()); + + offset = ((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)) * sizeof(ulonglong); + +@@ -1998,7 +2240,7 @@ + + page_table = PAE_PAGEBASE(page_middle_entry); + +- FILL_PTBL(page_table, PHYSADDR, PAGESIZE()); ++ FILL_PTBL_PAE(page_table, PHYSADDR, PAGESIZE()); + + offset = ((vaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)) * + sizeof(ulonglong); +@@ -2028,9 +2270,10 @@ + *paddr = physpage; + + if (verbose) { +- fprintf(fp, " PAGE: %s\n\n", +- mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, +- MKSTR(&physpage))); ++ ull = PAE_PAGEBASE(page_table_entry); ++ fprintf(fp, " PAGE: %s\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull))); + x86_translate_pte(0, 0, page_table_entry); + } + +@@ -2040,67 +2283,256 @@ return FALSE; } -+static int -+x86_uvtop_pae_xen_wpt(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) -+{ -+ return(error(FATAL, "x86_uvtop_pae_xen_wpt: TBD\n")); +-/* +- * Translates a kernel virtual address to its physical address. cmd_vtop() +- * sets the verbose flag so that the pte translation gets displayed; all +- * other callers quietly accept the translation. +- */ +- + static int +-x86_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) ++x86_uvtop_xen_wpt_PAE(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) + { +- ulong *pgd; +- ulong *page_dir; +- ulong *page_middle; +- ulong *page_table; +- ulong pgd_pte; +- ulong pmd_pte; +- ulong pte; ++ ulong mm, active_mm; ++ ulonglong *pgd; ++ ulonglong page_dir_entry; ++ ulonglong page_middle, pseudo_page_middle; ++ ulonglong page_middle_entry; ++ ulonglong page_table, pseudo_page_table; ++ ulonglong page_table_entry; ++ ulonglong physpage, pseudo_physpage; ++ ulonglong ull; ++ ulong offset; + char buf[BUFSIZE]; + +- if (!IS_KVADDR(kvaddr)) +- return FALSE; ++ if (!tc) ++ error(FATAL, "current context invalid\n"); + +- if (!vt->vmalloc_start) { +- *paddr = VTOP(kvaddr); +- return TRUE; +- } ++ *paddr = 0; + +- if (!IS_VMALLOC_ADDR(kvaddr)) { +- *paddr = VTOP(kvaddr); +- if (!verbose) +- return TRUE; +- } ++ if (is_kernel_thread(tc->task) && IS_KVADDR(vaddr)) { ++ if (VALID_MEMBER(thread_struct_cr3)) ++ pgd = (ulonglong *)machdep->get_task_pgd(tc->task); ++ else { ++ if (INVALID_MEMBER(task_struct_active_mm)) ++ error(FATAL, "no cr3 or active_mm?\n"); + +- pgd = (ulong *)vt->kernel_pgd[0]; ++ readmem(tc->task + OFFSET(task_struct_active_mm), ++ KVADDR, &active_mm, sizeof(void *), ++ "task active_mm contents", FAULT_ON_ERROR); ++ ++ if (!active_mm) ++ error(FATAL, ++ "no active_mm for this kernel thread\n"); ++ ++ readmem(active_mm + OFFSET(mm_struct_pgd), ++ KVADDR, &pgd, sizeof(long), ++ "mm_struct pgd", FAULT_ON_ERROR); ++ } ++ } else { ++ if ((mm = task_mm(tc->task, TRUE))) ++ pgd = (ulonglong *)(ULONG_PTR(tt->mm_struct + ++ OFFSET(mm_struct_pgd))); ++ else ++ readmem(tc->mm_struct + OFFSET(mm_struct_pgd), ++ KVADDR, &pgd, sizeof(long), "mm_struct pgd", ++ FAULT_ON_ERROR); ++ } + + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); + +- page_dir = pgd + (kvaddr >> PGDIR_SHIFT); ++ FILL_PGD(pgd, KVADDR, PTRS_PER_PGD * sizeof(ulonglong)); + +- FILL_PGD(NONPAE_PAGEBASE(pgd), KVADDR, PAGESIZE()); +- pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); ++ offset = ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) * ++ sizeof(ulonglong); ++ ++ page_dir_entry = *((ulonglong *)&machdep->pgd[offset]); + + if (verbose) +- fprintf(fp, " PGD: %s => %lx\n", ++ fprintf(fp, " PGD: %s => %llx [machine]\n", + mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, +- MKSTR((ulong)page_dir)), pgd_pte); ++ MKSTR((ulong)pgd + offset)), ++ page_dir_entry); + +- if (!pgd_pte) +- goto no_kpage; ++ if (!(page_dir_entry & _PAGE_PRESENT)) { ++ goto no_upage; ++ } + +- if (pgd_pte & _PAGE_4M) { +- if (verbose) { +- fprintf(fp, " PAGE: %s (4MB)\n\n", +- mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, +- MKSTR(NONPAE_PAGEBASE(pgd_pte)))); +- x86_translate_pte(0, 0, pgd_pte); +- } ++ page_middle = PAE_PAGEBASE(page_dir_entry); ++ pseudo_page_middle = xen_m2p(page_middle); + +- *paddr = NONPAE_PAGEBASE(pgd_pte) + (kvaddr & ~_4MB_PAGE_MASK); ++ if (verbose) ++ fprintf(fp, " PGD: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, ++ MKSTR((ulong)pgd + offset)), ++ pseudo_page_middle | PAGEOFFSET(page_dir_entry) | ++ (page_dir_entry & _PAGE_NX)); + +- return TRUE; ++ FILL_PMD_PAE(pseudo_page_middle, PHYSADDR, PAGESIZE()); ++ ++ offset = ((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)) * sizeof(ulonglong); ++ ++ page_middle_entry = *((ulonglong *)&machdep->pmd[offset]); ++ ++ if (verbose) { ++ ull = page_middle + offset; ++ fprintf(fp, " PMD: %s => %llx [machine]\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), ++ page_middle_entry); ++ } ++ ++ if (!(page_middle_entry & _PAGE_PRESENT)) { ++ goto no_upage; ++ } ++ ++ if (page_middle_entry & _PAGE_PSE) { ++ error(FATAL, "_PAGE_PSE in an mfn not supported\n"); /* XXX */ ++ if (verbose) { ++ ull = PAE_PAGEBASE(page_middle_entry); ++ fprintf(fp, " PAGE: %s (2MB)\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull))); ++ x86_translate_pte(0, 0, page_middle_entry); ++ } ++ ++ physpage = PAE_PAGEBASE(page_middle_entry) + ++ (vaddr & ~_2MB_PAGE_MASK); ++ *paddr = physpage; ++ ++ return TRUE; ++ } ++ ++ page_table = PAE_PAGEBASE(page_middle_entry); ++ pseudo_page_table = xen_m2p(page_table); ++ ++ if (verbose) { ++ ull = page_middle + offset; ++ fprintf(fp, " PMD: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), ++ pseudo_page_table | PAGEOFFSET(page_middle_entry) | ++ (page_middle_entry & _PAGE_NX)); ++ } ++ ++ FILL_PTBL_PAE(pseudo_page_table, PHYSADDR, PAGESIZE()); ++ ++ offset = ((vaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)) * ++ sizeof(ulonglong); ++ ++ page_table_entry = *((ulonglong *)&machdep->ptbl[offset]); ++ ++ if (verbose) { ++ ull = page_table + offset; ++ fprintf(fp, " PTE: %s => %llx [machine]\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), page_table_entry); ++ } ++ ++ if (!(page_table_entry & (_PAGE_PRESENT | _PAGE_PROTNONE))) { ++ *paddr = page_table_entry; ++ ++ if (page_table_entry && verbose) { ++ fprintf(fp, "\n"); ++ x86_translate_pte(0, 0, page_table_entry); ++ } ++ ++ goto no_upage; ++ } ++ ++ physpage = PAE_PAGEBASE(page_table_entry) + PAGEOFFSET(vaddr); ++ pseudo_physpage = xen_m2p(physpage); ++ ++ if (verbose) { ++ ull = page_table + offset; ++ fprintf(fp, " PTE: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), ++ pseudo_physpage | PAGEOFFSET(page_table_entry) | ++ (page_table_entry & _PAGE_NX)); ++ } ++ ++ *paddr = pseudo_physpage + PAGEOFFSET(vaddr); ++ ++ if (verbose) { ++ fprintf(fp, " PAGE: %s [machine]\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&physpage))); ++ ++ pseudo_physpage += (PAGEOFFSET(vaddr) | ++ (page_table_entry & _PAGE_NX)); ++ ++ fprintf(fp, " PAGE: %s\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&pseudo_physpage))); ++ ++ x86_translate_pte(0, 0, pseudo_physpage); ++ } ++ ++ return TRUE; ++ ++no_upage: ++ return FALSE; +} + - /* - * Translates a kernel virtual address to its physical address. cmd_vtop() - * sets the verbose flag so that the pte translation gets displayed; all -@@ -2072,6 +2309,9 @@ - return TRUE; - } - ++/* ++ * Translates a kernel virtual address to its physical address. cmd_vtop() ++ * sets the verbose flag so that the pte translation gets displayed; all ++ * other callers quietly accept the translation. ++ */ ++ ++static int ++x86_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) ++{ ++ ulong *pgd; ++ ulong *page_dir; ++ ulong *page_middle; ++ ulong *page_table; ++ ulong pgd_pte; ++ ulong pmd_pte; ++ ulong pte; ++ char buf[BUFSIZE]; ++ ++ if (!IS_KVADDR(kvaddr)) ++ return FALSE; ++ ++ if (!vt->vmalloc_start) { ++ *paddr = VTOP(kvaddr); ++ return TRUE; ++ } ++ ++ if (!IS_VMALLOC_ADDR(kvaddr)) { ++ *paddr = VTOP(kvaddr); ++ if (!verbose) ++ return TRUE; ++ } ++ + if (XEN() && (kt->xen_flags & WRITABLE_PAGE_TABLES)) + return (x86_kvtop_xen_wpt(tc, kvaddr, paddr, verbose)); + - pgd = (ulong *)vt->kernel_pgd[0]; - - if (verbose) -@@ -2095,7 +2335,7 @@ - fprintf(fp, " PAGE: %s (4MB)\n\n", - mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, - MKSTR(NONPAE_PAGEBASE(pgd_pte)))); -- x86_translate_pte(0, 0, pgd_pte); ++ pgd = (ulong *)vt->kernel_pgd[0]; ++ ++ if (verbose) ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); ++ ++ page_dir = pgd + (kvaddr >> PGDIR_SHIFT); ++ ++ FILL_PGD(NONPAE_PAGEBASE(pgd), KVADDR, PAGESIZE()); ++ pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); ++ ++ if (verbose) ++ fprintf(fp, " PGD: %s => %lx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, ++ MKSTR((ulong)page_dir)), pgd_pte); ++ ++ if (!pgd_pte) ++ goto no_kpage; ++ ++ if (pgd_pte & _PAGE_4M) { ++ if (verbose) { ++ fprintf(fp, " PAGE: %s (4MB)\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, ++ MKSTR(NONPAE_PAGEBASE(pgd_pte)))); + x86_translate_pte(pgd_pte, 0, 0); - } ++ } ++ ++ *paddr = NONPAE_PAGEBASE(pgd_pte) + (kvaddr & ~_4MB_PAGE_MASK); ++ ++ return TRUE; + } - *paddr = NONPAE_PAGEBASE(pgd_pte) + (kvaddr & ~_4MB_PAGE_MASK); -@@ -2158,6 +2398,131 @@ + page_middle = page_dir; +@@ -2158,9 +2590,134 @@ return FALSE; } @@ -7982,7 +9342,7 @@ + mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, + MKSTR(NONPAE_PAGEBASE(pgd_pte)))); + -+ pseudo_pgd_pte = xen_machine_to_pseudo(NONPAE_PAGEBASE(pgd_pte)); ++ pseudo_pgd_pte = xen_m2p_nonPAE(NONPAE_PAGEBASE(pgd_pte)); + + if (pseudo_pgd_pte == XEN_MFN_NOT_FOUND) { + if (verbose) @@ -8024,7 +9384,7 @@ + ((kvaddr>>10) & ((PTRS_PER_PTE-1)<<2))); + + pseudo_page_table = (ulong *) -+ xen_machine_to_pseudo(NONPAE_PAGEBASE(machine_page_table)); ++ xen_m2p_nonPAE(NONPAE_PAGEBASE(machine_page_table)); + + FILL_PTBL(NONPAE_PAGEBASE(pseudo_page_table), PHYSADDR, PAGESIZE()); + machine_pte = ULONG(machdep->ptbl + PAGEOFFSET(machine_page_table)); @@ -8048,7 +9408,7 @@ + goto no_kpage; + } + -+ pseudo_pte = xen_machine_to_pseudo(NONPAE_PAGEBASE(machine_pte)); ++ pseudo_pte = xen_m2p_nonPAE(NONPAE_PAGEBASE(machine_pte)); + pseudo_pte |= PAGEOFFSET(machine_pte); + + if (verbose) { @@ -8073,31 +9433,238 @@ + static int - x86_kvtop_pae(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) -@@ -2188,6 +2553,9 @@ +-x86_kvtop_pae(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) ++x86_kvtop_PAE(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) + { + ulonglong *pgd; + ulonglong page_dir_entry; +@@ -2188,6 +2745,9 @@ return TRUE; } + if (XEN() && (kt->xen_flags & WRITABLE_PAGE_TABLES)) -+ return (x86_kvtop_pae_xen_wpt(tc, kvaddr, paddr, verbose)); ++ return (x86_kvtop_xen_wpt_PAE(tc, kvaddr, paddr, verbose)); + pgd = (ulonglong *)vt->kernel_pgd[0]; if (verbose) -@@ -2289,6 +2657,12 @@ +@@ -2212,7 +2772,7 @@ + + page_middle = PAE_PAGEBASE(page_dir_entry); + +- FILL_PMD(page_middle, PHYSADDR, PAGESIZE()); ++ FILL_PMD_PAE(page_middle, PHYSADDR, PAGESIZE()); + + offset = ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)) * sizeof(ulonglong); + +@@ -2247,9 +2807,144 @@ + return TRUE; + } + +- page_table = PAE_PAGEBASE(page_middle_entry); +- +- FILL_PTBL(page_table, PHYSADDR, PAGESIZE()); ++ page_table = PAE_PAGEBASE(page_middle_entry); ++ ++ FILL_PTBL_PAE(page_table, PHYSADDR, PAGESIZE()); ++ ++ offset = ((kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)) * ++ sizeof(ulonglong); ++ ++ page_table_entry = *((ulonglong *)&machdep->ptbl[offset]); ++ ++ if (verbose) { ++ ull = page_table + offset; ++ fprintf(fp, " PTE: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), page_table_entry); ++ } ++ ++ if (!(page_table_entry & (_PAGE_PRESENT | _PAGE_PROTNONE))) { ++ if (page_table_entry && verbose) { ++ fprintf(fp, "\n"); ++ x86_translate_pte(0, 0, page_table_entry); ++ } ++ ++ goto no_kpage; ++ } ++ ++ physpage = PAE_PAGEBASE(page_table_entry) + PAGEOFFSET(kvaddr); ++ ++ *paddr = physpage; ++ ++ if (verbose) { ++ ull = PAE_PAGEBASE(page_table_entry); ++ fprintf(fp, " PAGE: %s\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull))); ++ x86_translate_pte(0, 0, page_table_entry); ++ } ++ ++ return TRUE; ++ ++no_kpage: ++ return FALSE; ++} ++ ++static int ++x86_kvtop_xen_wpt_PAE(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) ++{ ++ ulonglong *pgd; ++ ulonglong page_dir_entry; ++ ulonglong page_middle, pseudo_page_middle; ++ ulonglong page_middle_entry; ++ ulonglong page_table, pseudo_page_table; ++ ulonglong page_table_entry; ++ ulonglong physpage, pseudo_physpage; ++ ulonglong ull; ++ ulong offset; ++ char buf[BUFSIZE]; ++ ++ pgd = (ulonglong *)vt->kernel_pgd[0]; ++ ++ if (verbose) ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); ++ ++ FILL_PGD(pgd, KVADDR, PTRS_PER_PGD * sizeof(ulonglong)); ++ ++ offset = ((kvaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) * ++ sizeof(ulonglong); ++ ++ page_dir_entry = *((ulonglong *)&machdep->pgd[offset]); ++ ++ if (verbose) ++ fprintf(fp, " PGD: %s => %llx [machine]\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, ++ MKSTR((ulong)pgd + offset)), ++ page_dir_entry); ++ ++ if (!(page_dir_entry & _PAGE_PRESENT)) { ++ goto no_kpage; ++ } ++ ++ page_middle = PAE_PAGEBASE(page_dir_entry); ++ pseudo_page_middle = xen_m2p(page_middle); ++ ++ if (verbose) ++ fprintf(fp, " PGD: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONG_HEX, ++ MKSTR((ulong)pgd + offset)), ++ pseudo_page_middle | PAGEOFFSET(page_dir_entry) | ++ (page_dir_entry & _PAGE_NX)); ++ ++ FILL_PMD_PAE(pseudo_page_middle, PHYSADDR, PAGESIZE()); ++ ++ offset = ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)) * sizeof(ulonglong); ++ ++ page_middle_entry = *((ulonglong *)&machdep->pmd[offset]); ++ ++ if (verbose) { ++ ull = page_middle + offset; ++ fprintf(fp, " PMD: %s => %llx [machine]\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), ++ page_middle_entry); ++ } ++ ++ if (!(page_middle_entry & _PAGE_PRESENT)) { ++ goto no_kpage; ++ } ++ ++ if (page_middle_entry & _PAGE_PSE) { ++ error(FATAL, "_PAGE_PSE in an mfn not supported\n"); /* XXX */ ++ if (verbose) { ++ ull = PAE_PAGEBASE(page_middle_entry); ++ fprintf(fp, " PAGE: %s (2MB)\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull))); ++ x86_translate_pte(0, 0, page_middle_entry); ++ } ++ ++ physpage = PAE_PAGEBASE(page_middle_entry) + ++ (kvaddr & ~_2MB_PAGE_MASK); ++ *paddr = physpage; ++ ++ ++ return TRUE; ++ } ++ ++ page_table = PAE_PAGEBASE(page_middle_entry); ++ pseudo_page_table = xen_m2p(page_table); ++ ++ if (verbose) { ++ ull = page_middle + offset; ++ fprintf(fp, " PMD: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), ++ pseudo_page_table | PAGEOFFSET(page_middle_entry) | ++ (page_middle_entry & _PAGE_NX)); ++ } ++ ++ FILL_PTBL_PAE(pseudo_page_table, PHYSADDR, PAGESIZE()); + + offset = ((kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)) * + sizeof(ulonglong); +@@ -2258,7 +2953,7 @@ + + if (verbose) { + ull = page_table + offset; +- fprintf(fp, " PTE: %s => %llx\n", ++ fprintf(fp, " PTE: %s => %llx [machine]\n", + mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, + MKSTR(&ull)), page_table_entry); + } +@@ -2273,14 +2968,32 @@ + } + + physpage = PAE_PAGEBASE(page_table_entry) + PAGEOFFSET(kvaddr); ++ pseudo_physpage = xen_m2p(physpage); + +- *paddr = physpage; ++ if (verbose) { ++ ull = page_table + offset; ++ fprintf(fp, " PTE: %s => %llx\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&ull)), ++ pseudo_physpage | PAGEOFFSET(page_table_entry) | ++ (page_table_entry & _PAGE_NX)); ++ } ++ ++ *paddr = pseudo_physpage + PAGEOFFSET(kvaddr); + + if (verbose) { +- fprintf(fp, " PAGE: %s\n\n", ++ fprintf(fp, " PAGE: %s [machine]\n", + mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, + MKSTR(&physpage))); +- x86_translate_pte(0, 0, page_table_entry); ++ ++ pseudo_physpage += (PAGEOFFSET(kvaddr) | ++ (page_table_entry & _PAGE_NX)); ++ ++ fprintf(fp, " PAGE: %s\n\n", ++ mkstring(buf, VADDR_PRLEN, RJUST|LONGLONG_HEX, ++ MKSTR(&pseudo_physpage))); ++ ++ x86_translate_pte(0, 0, pseudo_physpage); + } + + return TRUE; +@@ -2289,6 +3002,13 @@ return FALSE; } -+static int -+x86_kvtop_pae_xen_wpt(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) ++void ++x86_clear_machdep_cache(void) +{ -+ return (error(FATAL, "x86_kvtop_pae_xen_wpt: TBD\n")); ++ machdep->machspec->last_pmd_read_PAE = 0; ++ machdep->machspec->last_ptbl_read_PAE = 0; +} + /* * Get the relevant page directory pointer from a task structure. */ -@@ -2341,6 +2715,7 @@ +@@ -2341,6 +3061,7 @@ x86_dump_machdep_table(ulong arg) { int others; @@ -8105,7 +9672,7 @@ switch (arg) { default: -@@ -2355,8 +2730,6 @@ +@@ -2355,8 +3076,6 @@ fprintf(fp, "%sPAE", others++ ? "|" : ""); if (machdep->flags & OMIT_FRAME_PTR) fprintf(fp, "%sOMIT_FRAME_PTR", others++ ? "|" : ""); @@ -8114,7 +9681,7 @@ if (machdep->flags & FRAMESIZE_DEBUG) fprintf(fp, "%sFRAMESIZE_DEBUG", others++ ? "|" : ""); fprintf(fp, ")\n"); -@@ -2376,12 +2749,17 @@ +@@ -2376,12 +3095,17 @@ fprintf(fp, " eframe_search: x86_eframe_search()\n"); fprintf(fp, " back_trace: x86_back_trace_cmd()\n"); fprintf(fp, "get_processor_speed: x86_processor_speed()\n"); @@ -8123,9 +9690,9 @@ - fprintf(fp, " uvtop: x86_uvtop_pae()\n"); - fprintf(fp, " kvtop: x86_uvtop_pae()\n"); + fprintf(fp, " uvtop: %s()\n", -+ xen_wpt ? "x86_uvtop_pae_xen_wpt" : "x86_uvtop_pae"); -+ fprintf(fp, " kvtop: x86_kvtop_pae()%s\n", -+ xen_wpt ? " -> x86_kvtop_pae_xen_wpt()" : ""); ++ xen_wpt ? "x86_uvtop_xen_wpt_PAE" : "x86_uvtop_PAE"); ++ fprintf(fp, " kvtop: x86_kvtop_PAE()%s\n", ++ xen_wpt ? " -> x86_kvtop_xen_wpt_PAE()" : ""); } else { - fprintf(fp, " uvtop: x86_uvtop()\n"); - fprintf(fp, " kvtop: x86_uvtop()\n"); @@ -8136,7 +9703,7 @@ } fprintf(fp, " get_task_pgd: x86_get_task_pgd()\n"); fprintf(fp, " dump_irq: generic_dump_irq()\n"); -@@ -2399,7 +2777,7 @@ +@@ -2399,7 +3123,7 @@ fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n"); fprintf(fp, " is_uvaddr: generic_is_uvaddr()\n"); fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); @@ -8145,20 +9712,34 @@ fprintf(fp, " value_to_symbol: %s\n", machdep->value_to_symbol == generic_machdep_value_to_symbol ? "generic_machdep_value_to_symbol()" : -@@ -2412,6 +2790,12 @@ +@@ -2412,6 +3136,14 @@ fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); + fprintf(fp, " section_size_bits: %ld\n", machdep->section_size_bits); + fprintf(fp, " max_physmem_bits: %ld\n", machdep->max_physmem_bits); + fprintf(fp, " sections_per_root: %ld\n", machdep->sections_per_root); -+ fprintf(fp, " xendump_ptm_create: x86_xendump_ptm_create()\n"); ++ fprintf(fp, " xendump_p2m_create: x86_xendump_p2m_create()\n"); + fprintf(fp, " xendump_panic_task: x86_xendump_panic_task()\n"); + fprintf(fp, " get_xendump_regs: x86_get_xendump_regs()\n"); ++ fprintf(fp, "xen_kdump_p2m_create: x86_xen_kdump_p2m_create()\n"); ++ fprintf(fp, "clear_machdep_cache: x86_clear_machdep_cache()\n"); fprintf(fp, " machspec: x86_machine_specific\n"); fprintf(fp, " idt_table: %lx\n", (ulong)machdep->machspec->idt_table); -@@ -2732,6 +3116,9 @@ +@@ -2421,6 +3153,11 @@ + machdep->machspec->entry_tramp_end); + fprintf(fp, " entry_tramp_start_phys: %llx\n", + machdep->machspec->entry_tramp_start_phys); ++ fprintf(fp, " last_pmd_read_PAE: %llx\n", ++ machdep->machspec->last_pmd_read_PAE); ++ fprintf(fp, " last_ptbl_read_PAE: %llx\n", ++ machdep->machspec->last_ptbl_read_PAE); ++ + } + + /* +@@ -2732,6 +3469,9 @@ switch (flag) { case READ_IDT_INIT: @@ -8168,7 +9749,7 @@ if (!(idt = (ulong *)malloc(desc_struct_size))) { error(WARNING, "cannot malloc idt_table\n\n"); return NULL; -@@ -2779,6 +3166,10 @@ +@@ -2779,6 +3519,10 @@ break; case READ_IDT_RUNTIME: @@ -8179,7 +9760,7 @@ idt = (ulong *)GETBUF(desc_struct_size); readmem(symbol_value("idt_table"), KVADDR, idt, desc_struct_size, "idt_table", FAULT_ON_ERROR); -@@ -2969,6 +3360,16 @@ +@@ -2969,6 +3713,16 @@ } } @@ -8196,7 +9777,7 @@ return count; } -@@ -3092,31 +3493,31 @@ +@@ -3092,31 +3846,31 @@ * with the -fomit-frame-pointer flag. */ #define PUSH_BP_MOV_ESP_BP 0xe58955 @@ -8244,7 +9825,7 @@ } /* -@@ -3207,4 +3608,305 @@ +@@ -3207,4 +3961,717 @@ return ((sp = value_search(value, offset))); } @@ -8267,6 +9848,353 @@ + +} + ++static ulong ++xen_m2p_nonPAE(ulong machine) ++{ ++ ulonglong pseudo; ++ ++ pseudo = xen_m2p((ulonglong)machine); ++ ++ if (pseudo == XEN_MACHADDR_NOT_FOUND) ++ return XEN_MFN_NOT_FOUND; ++ ++ return ((ulong)pseudo); ++} ++ ++#include "netdump.h" ++ ++/* ++ * From the xen vmcore, create an index of mfns for each page that makes ++ * up the dom0 kernel's complete phys_to_machine_mapping[max_pfn] array. ++ */ ++ ++#define MAX_X86_FRAMES (16) ++#define MFNS_PER_FRAME (PAGESIZE()/sizeof(ulong)) ++ ++static int ++x86_xen_kdump_p2m_create(struct xen_kdump_data *xkd) ++{ ++ int i, j; ++ ulong kvaddr; ++ ulong *up; ++ ulonglong *ulp; ++ ulong frames; ++ ulong frame_mfn[MAX_X86_FRAMES] = { 0 }; ++ int mfns[MAX_X86_FRAMES] = { 0 }; ++ ++ /* ++ * Temporarily read physical (machine) addresses from vmcore by ++ * going directly to read_netdump() instead of via read_kdump(). ++ */ ++ pc->readmem = read_netdump; ++ ++ if (xkd->flags & KDUMP_CR3) ++ goto use_cr3; ++ ++ xkd->p2m_frames = 0; ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "x86_xen_kdump_p2m_create: p2m_mfn: %lx\n", ++ xkd->p2m_mfn); ++ ++ if (!readmem(PTOB(xkd->p2m_mfn), PHYSADDR, xkd->page, PAGESIZE(), ++ "xen kdump p2m mfn page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump p2m mfn page\n"); ++ ++ if (CRASHDEBUG(1)) { ++ up = (ulong *)xkd->page; ++ for (i = 0; i < 4; i++) { ++ fprintf(fp, "%08lx: %08lx %08lx %08lx %08lx\n", ++ (ulong)((i * 4) * sizeof(ulong)), ++ *up, *(up+1), *(up+2), *(up+3)); ++ up += 4; ++ } ++ fprintf(fp, "\n"); ++ } ++ ++ for (i = 0, up = (ulong *)xkd->page; i < MAX_X86_FRAMES; i++, up++) ++ frame_mfn[i] = *up; ++ ++ for (i = 0; i < MAX_X86_FRAMES; i++) { ++ if (!frame_mfn[i]) ++ break; ++ ++ if (!readmem(PTOB(frame_mfn[i]), PHYSADDR, xkd->page, ++ PAGESIZE(), "xen kdump p2m mfn list page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump p2m mfn list page\n"); ++ ++ for (j = 0, up = (ulong *)xkd->page; j < MFNS_PER_FRAME; j++, up++) ++ if (*up) ++ mfns[i]++; ++ ++ xkd->p2m_frames += mfns[i]; ++ ++ if (CRASHDEBUG(7)) { ++ up = (ulong *)xkd->page; ++ for (i = 0; i < 256; i++) { ++ fprintf(fp, "%08lx: %08lx %08lx %08lx %08lx\n", ++ (ulong)((i * 4) * sizeof(ulong)), ++ *up, *(up+1), *(up+2), *(up+3)); ++ up += 4; ++ } ++ } ++ } ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "p2m_frames: %d\n", xkd->p2m_frames); ++ ++ if ((xkd->p2m_mfn_frame_list = (ulong *) ++ malloc(xkd->p2m_frames * sizeof(ulong))) == NULL) ++ error(FATAL, "cannot malloc p2m_frame_index_list"); ++ ++ for (i = 0, frames = xkd->p2m_frames; frames; i++) { ++ if (!readmem(PTOB(frame_mfn[i]), PHYSADDR, ++ &xkd->p2m_mfn_frame_list[i * MFNS_PER_FRAME], ++ mfns[i] * sizeof(ulong), "xen kdump p2m mfn list page", ++ RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump p2m mfn list page\n"); ++ ++ frames -= mfns[i]; ++ } ++ ++ pc->readmem = read_kdump; ++ return TRUE; ++ ++use_cr3: ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "x86_xen_kdump_p2m_create: cr3: %lx\n", xkd->cr3); ++ ++ if (!readmem(PTOB(xkd->cr3), PHYSADDR, machdep->pgd, PAGESIZE(), ++ "xen kdump cr3 page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump cr3 page\n"); ++ ++ if (CRASHDEBUG(7)) { ++ fprintf(fp, "contents of page directory page:\n"); ++ ++ if (machdep->flags & PAE) { ++ ulp = (ulonglong *)machdep->pgd; ++ fprintf(fp, ++ "%016llx %016llx %016llx %016llx\n", ++ *ulp, *(ulp+1), *(ulp+2), *(ulp+3)); ++ } else { ++ up = (ulong *)machdep->pgd; ++ for (i = 0; i < 256; i++) { ++ fprintf(fp, ++ "%08lx: %08lx %08lx %08lx %08lx\n", ++ (ulong)((i * 4) * sizeof(ulong)), ++ *up, *(up+1), *(up+2), *(up+3)); ++ up += 4; ++ } ++ } ++ } ++ ++ kvaddr = symbol_value("max_pfn"); ++ if (!x86_xen_kdump_load_page(kvaddr, xkd->page)) ++ return FALSE; ++ up = (ulong *)(xkd->page + PAGEOFFSET(kvaddr)); ++ ++ xkd->p2m_frames = (*up/(PAGESIZE()/sizeof(ulong))) + ++ ((*up%(PAGESIZE()/sizeof(ulong))) ? 1 : 0); ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "max_pfn at %lx: %lx (%ld) -> %d p2m_frames\n", ++ kvaddr, *up, *up, xkd->p2m_frames); ++ ++ if ((xkd->p2m_mfn_frame_list = (ulong *) ++ malloc(xkd->p2m_frames * sizeof(ulong))) == NULL) ++ error(FATAL, "cannot malloc p2m_frame_index_list"); ++ ++ kvaddr = symbol_value("phys_to_machine_mapping"); ++ if (!x86_xen_kdump_load_page(kvaddr, xkd->page)) ++ return FALSE; ++ up = (ulong *)(xkd->page + PAGEOFFSET(kvaddr)); ++ kvaddr = *up; ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "phys_to_machine_mapping: %lx\n", kvaddr); ++ ++ if (CRASHDEBUG(7)) { ++ fprintf(fp, "contents of first phys_to_machine_mapping page:\n"); ++ if (!x86_xen_kdump_load_page(kvaddr, xkd->page)) ++ error(INFO, ++ "cannot read first phys_to_machine_mapping page\n"); ++ ++ up = (ulong *)xkd->page; ++ for (i = 0; i < 256; i++) { ++ fprintf(fp, "%08lx: %08lx %08lx %08lx %08lx\n", ++ (ulong)((i * 4) * sizeof(ulong)), ++ *up, *(up+1), *(up+2), *(up+3)); ++ up += 4; ++ } ++ } ++ ++ machdep->last_ptbl_read = BADADDR; ++ machdep->last_pmd_read = BADADDR; ++ ++ for (i = 0; i < xkd->p2m_frames; i++) { ++ xkd->p2m_mfn_frame_list[i] = x86_xen_kdump_page_mfn(kvaddr); ++ kvaddr += PAGESIZE(); ++ } ++ ++ if (CRASHDEBUG(1)) { ++ for (i = 0; i < xkd->p2m_frames; i++) ++ fprintf(fp, "%lx ", xkd->p2m_mfn_frame_list[i]); ++ fprintf(fp, "\n"); ++ } ++ ++ machdep->last_ptbl_read = 0; ++ machdep->last_pmd_read = 0; ++ pc->readmem = read_kdump; ++ ++ return TRUE; ++} ++ ++/* ++ * Find the page associate with the kvaddr, and read its contents ++ * into the passed-in buffer. ++ */ ++static char * ++x86_xen_kdump_load_page(ulong kvaddr, char *pgbuf) ++{ ++ ulong *entry; ++ ulong *up; ++ ulong mfn; ++ ++ if (machdep->flags & PAE) ++ return x86_xen_kdump_load_page_PAE(kvaddr, pgbuf); ++ ++ up = (ulong *)machdep->pgd; ++ entry = up + (kvaddr >> PGDIR_SHIFT); ++ mfn = (*entry) >> PAGESHIFT(); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, pgbuf, PAGESIZE(), ++ "xen kdump pgd entry", RETURN_ON_ERROR)) { ++ error(INFO, "cannot read/find pgd entry from cr3 page\n"); ++ return NULL; ++ } ++ ++ up = (ulong *)pgbuf; ++ entry = up + ((kvaddr >> 12) & (PTRS_PER_PTE-1)); ++ mfn = (*entry) >> PAGESHIFT(); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, pgbuf, PAGESIZE(), ++ "xen page table page", RETURN_ON_ERROR)) { ++ error(INFO, "cannot read/find page table page\n"); ++ return NULL; ++ } ++ ++ return pgbuf; ++} ++ ++static char * ++x86_xen_kdump_load_page_PAE(ulong kvaddr, char *pgbuf) ++{ ++ ulonglong *entry; ++ ulonglong *up; ++ ulong mfn; ++ ++ up = (ulonglong *)machdep->pgd; ++ entry = up + (kvaddr >> PGDIR_SHIFT); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, pgbuf, PAGESIZE(), ++ "xen kdump pgd entry", RETURN_ON_ERROR)) { ++ error(INFO, "cannot read/find pgd entry from cr3 page\n"); ++ return NULL; ++ } ++ ++ up = (ulonglong *)pgbuf; ++ entry = up + ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, pgbuf, PAGESIZE(), ++ "xen kdump pmd entry", RETURN_ON_ERROR)) { ++ error(INFO, "cannot read/find pmd entry from pgd\n"); ++ return NULL; ++ } ++ ++ up = (ulonglong *)pgbuf; ++ entry = up + ((kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, pgbuf, PAGESIZE(), ++ "xen kdump page table page", RETURN_ON_ERROR)) { ++ error(INFO, "cannot read/find page table page from pmd\n"); ++ return NULL; ++ } ++ ++ return pgbuf; ++} ++ ++/* ++ * Return the mfn value associated with a virtual address. ++ */ ++static ulong ++x86_xen_kdump_page_mfn(ulong kvaddr) ++{ ++ ulong *entry; ++ ulong *up; ++ ulong mfn; ++ ++ if (machdep->flags & PAE) ++ return x86_xen_kdump_page_mfn_PAE(kvaddr); ++ ++ up = (ulong *)machdep->pgd; ++ entry = up + (kvaddr >> PGDIR_SHIFT); ++ mfn = (*entry) >> PAGESHIFT(); ++ ++ if ((mfn != machdep->last_ptbl_read) && ++ !readmem(PTOB(mfn), PHYSADDR, machdep->ptbl, PAGESIZE(), ++ "xen kdump pgd entry", RETURN_ON_ERROR)) ++ error(FATAL, ++ "cannot read/find pgd entry from cr3 page (mfn: %lx)\n", ++ mfn); ++ machdep->last_ptbl_read = mfn; ++ ++ up = (ulong *)machdep->ptbl; ++ entry = up + ((kvaddr >> 12) & (PTRS_PER_PTE-1)); ++ mfn = (*entry) >> PAGESHIFT(); ++ ++ return mfn; ++} ++ ++static ulong ++x86_xen_kdump_page_mfn_PAE(ulong kvaddr) ++{ ++ ulonglong *entry; ++ ulonglong *up; ++ ulong mfn; ++ ++ up = (ulonglong *)machdep->pgd; ++ entry = up + (kvaddr >> PGDIR_SHIFT); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if ((mfn != machdep->last_pmd_read) && ++ !readmem(PTOB(mfn), PHYSADDR, machdep->pmd, PAGESIZE(), ++ "xen kdump pgd entry", RETURN_ON_ERROR)) ++ error(FATAL, ++ "cannot read/find pgd entry from cr3 page (mfn: %lx)\n", ++ mfn); ++ machdep->last_pmd_read = mfn; ++ ++ up = (ulonglong *)machdep->pmd; ++ entry = up + ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if ((mfn != machdep->last_ptbl_read) && ++ !readmem(PTOB(mfn), PHYSADDR, machdep->ptbl, PAGESIZE(), ++ "xen kdump pmd entry", RETURN_ON_ERROR)) ++ error(FATAL, ++ "cannot read/find pmd entry from pgd (mfn: %lx)\n", ++ mfn); ++ machdep->last_ptbl_read = mfn; ++ ++ up = (ulonglong *)machdep->ptbl; ++ entry = up + ((kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ return mfn; ++} ++ +#include "xendump.h" + +/* @@ -8274,11 +10202,12 @@ + * kernel's complete phys_to_machine_mapping[max_pfn] array. + */ +static int -+x86_xendump_ptm_create(struct xendump_data *xd) ++x86_xendump_p2m_create(struct xendump_data *xd) +{ + int i, idx; + ulong mfn, kvaddr, ctrlreg[8], ctrlreg_offset; + ulong *up; ++ ulonglong *ulp; + off_t offset; + + if ((ctrlreg_offset = MEMBER_OFFSET("vcpu_guest_context", "ctrlreg")) == @@ -8312,12 +10241,20 @@ + if (CRASHDEBUG(1)) { + fprintf(xd->ofp, "contents of page directory page:\n"); + -+ up = (ulong *)machdep->pgd; -+ for (i = 0; i < 256; i++) { -+ fprintf(xd->ofp, "%08lx: %08lx %08lx %08lx %08lx\n", -+ (ulong)((i * 4) * sizeof(ulong)), -+ *up, *(up+1), *(up+2), *(up+3)); -+ up += 4; ++ if (machdep->flags & PAE) { ++ ulp = (ulonglong *)machdep->pgd; ++ fprintf(xd->ofp, ++ "%016llx %016llx %016llx %016llx\n", ++ *ulp, *(ulp+1), *(ulp+2), *(ulp+3)); ++ } else { ++ up = (ulong *)machdep->pgd; ++ for (i = 0; i < 256; i++) { ++ fprintf(xd->ofp, ++ "%08lx: %08lx %08lx %08lx %08lx\n", ++ (ulong)((i * 4) * sizeof(ulong)), ++ *up, *(up+1), *(up+2), *(up+3)); ++ up += 4; ++ } + } + } + @@ -8328,11 +10265,12 @@ + if (CRASHDEBUG(1)) + fprintf(xd->ofp, "max_pfn: %lx\n", *up); + -+ xd->xc_core.ptm_frames = *up/(PAGESIZE()/sizeof(ulong)); ++ xd->xc_core.p2m_frames = (*up/(PAGESIZE()/sizeof(ulong))) + ++ ((*up%(PAGESIZE()/sizeof(ulong))) ? 1 : 0); + -+ if ((xd->xc_core.ptm_frame_index_list = (ulong *) -+ malloc(xd->xc_core.ptm_frames * sizeof(int))) == NULL) -+ error(FATAL, "cannot malloc ptm_mfn_frame_list"); ++ if ((xd->xc_core.p2m_frame_index_list = (ulong *) ++ malloc(xd->xc_core.p2m_frames * sizeof(int))) == NULL) ++ error(FATAL, "cannot malloc p2m_frame_index_list"); + + kvaddr = symbol_value("phys_to_machine_mapping"); + if (!x86_xendump_load_page(kvaddr, xd->page)) @@ -8343,15 +10281,17 @@ + + kvaddr = *up; + machdep->last_ptbl_read = BADADDR; ++ machdep->last_pmd_read = BADADDR; + -+ for (i = 0; i < xd->xc_core.ptm_frames; i++) { ++ for (i = 0; i < xd->xc_core.p2m_frames; i++) { + if ((idx = x86_xendump_page_index(kvaddr)) == MFN_NOT_FOUND) + return FALSE; -+ xd->xc_core.ptm_frame_index_list[i] = idx; ++ xd->xc_core.p2m_frame_index_list[i] = idx; + kvaddr += PAGESIZE(); + } + + machdep->last_ptbl_read = 0; ++ machdep->last_pmd_read = 0; + + return TRUE; +} @@ -8380,8 +10320,7 @@ + } + + up = (ulong *)pgbuf; -+ entry = up + ((kvaddr>>12) & (PTRS_PER_PTE-1)); -+ ++ entry = up + ((kvaddr >> 12) & (PTRS_PER_PTE-1)); + mfn = (*entry) >> PAGESHIFT(); + + if (!xc_core_mfn_to_page(mfn, pgbuf)) { @@ -8395,8 +10334,38 @@ +static char * +x86_xendump_load_page_PAE(ulong kvaddr, char *pgbuf) +{ -+ error(FATAL, "x86_xendump_load_page_PAE: TBD\n"); -+ return NULL; ++ ulonglong *entry; ++ ulonglong *up; ++ ulong mfn; ++ ++ up = (ulonglong *)machdep->pgd; ++ entry = up + (kvaddr >> PGDIR_SHIFT); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if (!xc_core_mfn_to_page(mfn, pgbuf)) { ++ error(INFO, "cannot read/find pgd entry from cr3 page\n"); ++ return NULL; ++ } ++ ++ up = (ulonglong *)pgbuf; ++ entry = up + ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if (!xc_core_mfn_to_page(mfn, pgbuf)) { ++ error(INFO, "cannot read/find pmd entry from pgd\n"); ++ return NULL; ++ } ++ ++ up = (ulonglong *)pgbuf; ++ entry = up + ((kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ ++ if (!xc_core_mfn_to_page(mfn, pgbuf)) { ++ error(INFO, "cannot read/find page table page from pmd\n"); ++ return NULL; ++ } ++ ++ return pgbuf; +} + +/* @@ -8409,9 +10378,6 @@ + ulong *entry; + ulong *up; + ulong mfn; -+ char *pgbuf; -+ -+ pgbuf = machdep->ptbl; + + if (machdep->flags & PAE) + return x86_xendump_page_index_PAE(kvaddr); @@ -8419,20 +10385,16 @@ + up = (ulong *)machdep->pgd; + entry = up + (kvaddr >> PGDIR_SHIFT); + mfn = (*entry) >> PAGESHIFT(); -+ + if ((mfn != machdep->last_ptbl_read) && -+ !xc_core_mfn_to_page(mfn, pgbuf)) { ++ !xc_core_mfn_to_page(mfn, machdep->ptbl)) { + error(INFO, "cannot read/find pgd entry from cr3 page\n"); + return MFN_NOT_FOUND; + } -+ + machdep->last_ptbl_read = mfn; + -+ up = (ulong *)pgbuf; ++ up = (ulong *)machdep->ptbl; + entry = up + ((kvaddr>>12) & (PTRS_PER_PTE-1)); -+ + mfn = (*entry) >> PAGESHIFT(); -+ + if ((idx = xc_core_mfn_to_page_index(mfn)) == MFN_NOT_FOUND) + error(INFO, "cannot determine page index for %lx\n", + kvaddr); @@ -8443,8 +10405,39 @@ +static int +x86_xendump_page_index_PAE(ulong kvaddr) +{ -+ error(FATAL, "x86_xendump_load_index_PAE: TBD\n"); -+ return -1; ++ int idx; ++ ulonglong *entry; ++ ulonglong *up; ++ ulong mfn; ++ ++ up = (ulonglong *)machdep->pgd; ++ entry = up + (kvaddr >> PGDIR_SHIFT); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ if ((mfn != machdep->last_pmd_read) && ++ !xc_core_mfn_to_page(mfn, machdep->pmd)) { ++ error(INFO, "cannot read/find pgd entry from cr3 page\n"); ++ return MFN_NOT_FOUND; ++ } ++ machdep->last_pmd_read = mfn; ++ ++ up = (ulonglong *)machdep->pmd; ++ entry = up + ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ if ((mfn != machdep->last_ptbl_read) && ++ !xc_core_mfn_to_page(mfn, machdep->ptbl)) { ++ error(INFO, "cannot read/find pmd entry from pgd\n"); ++ return MFN_NOT_FOUND; ++ } ++ machdep->last_ptbl_read = mfn; ++ ++ up = (ulonglong *)machdep->ptbl; ++ entry = up + ((kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE-1)); ++ mfn = (ulong)((*entry) >> PAGESHIFT()); ++ if ((idx = xc_core_mfn_to_page_index(mfn)) == MFN_NOT_FOUND) ++ error(INFO, "cannot determine page index for %lx\n", ++ kvaddr); ++ ++ return idx; +} + +/* @@ -8550,18 +10543,26 @@ + return machdep->get_stack_frame(bt, eip, esp); +} #endif /* X86 */ ---- crash/ppc.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/ppc.c 2006-04-11 15:22:52.000000000 -0400 -@@ -138,6 +138,8 @@ - machdep->hz = HZ; - if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) - machdep->hz = 1000; +--- crash/ppc.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/ppc.c 2006-08-02 10:31:13.000000000 -0400 +@@ -135,9 +135,13 @@ + "irq_desc", NULL, 0); + else + machdep->nr_irqs = 0; +- machdep->hz = HZ; +- if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) +- machdep->hz = 1000; ++ if (!machdep->hz) { ++ machdep->hz = HZ; ++ if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) ++ machdep->hz = 1000; ++ } + machdep->section_size_bits = _SECTION_SIZE_BITS; + machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; break; case POST_INIT: -@@ -154,8 +156,6 @@ +@@ -154,8 +158,6 @@ fprintf(fp, " flags: %lx (", machdep->flags); if (machdep->flags & KSYMS_START) fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); @@ -8570,7 +10571,7 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); -@@ -205,6 +205,9 @@ +@@ -205,6 +207,9 @@ fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); @@ -8580,8 +10581,8 @@ fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec); } ---- crash/ia64.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/ia64.c 2006-04-26 15:56:33.000000000 -0400 +--- crash/ia64.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/ia64.c 2006-08-03 14:28:37.000000000 -0400 @@ -1,8 +1,8 @@ /* ia64.c - core analysis suite * @@ -8593,7 +10594,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -@@ -92,6 +92,9 @@ +@@ -25,6 +25,8 @@ + static void try_old_unwind(struct bt_info *); + static void ia64_dump_irq(int); + static ulong ia64_processor_speed(void); ++static int ia64_vtop_4l(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr); ++static int ia64_vtop(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr); + static int ia64_uvtop(struct task_context *, ulong, physaddr_t *, int); + static int ia64_kvtop(struct task_context *, ulong, physaddr_t *, int); + static ulong ia64_get_task_pgd(ulong); +@@ -92,17 +94,23 @@ case 16384: machdep->stacksize = (power(2, 1) * PAGESIZE()); break; @@ -8603,7 +10613,84 @@ default: machdep->stacksize = 32*1024; break; -@@ -401,8 +404,6 @@ + } + if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc pgd space."); ++ if ((machdep->pud = (char *)malloc(PAGESIZE())) == NULL) ++ error(FATAL, "cannot malloc pud space."); + if ((machdep->pmd = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc pmd space."); + if ((machdep->ptbl = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc ptbl space."); + machdep->last_pgd_read = 0; ++ machdep->last_pud_read = 0; + machdep->last_pmd_read = 0; + machdep->last_ptbl_read = 0; + machdep->verify_paddr = ia64_verify_paddr; +@@ -115,14 +123,17 @@ + break; + + case PRE_GDB: ++ + if (pc->flags & KERNEL_DEBUG_QUERY) + return; ++ + /* + * Until the kernel core dump and va_server library code + * do the right thing with respect to the configured page size, + * try to recognize a fatal inequity between the compiled-in + * page size and the page size used by the kernel. + */ ++ + + if ((sp = symbol_search("empty_zero_page")) && + (spn = next_symbol(NULL, sp)) && +@@ -202,7 +213,8 @@ + else if (symbol_exists("_irq_desc")) + ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc, + "_irq_desc", NULL, 0); +- machdep->hz = 1024; ++ if (!machdep->hz) ++ machdep->hz = 1024; + ia64_create_memmap(); + break; + +@@ -284,11 +296,34 @@ + continue; + } + } ++ } else if (STRNEQ(arglist[i], "vm=")) { ++ p = arglist[i] + strlen("vm="); ++ if (strlen(p)) { ++ if (STREQ(p, "4l")) { ++ machdep->flags |= VM_4_LEVEL; ++ continue; ++ } ++ } + } + + error(WARNING, "ignoring --machdep option: %s\n", arglist[i]); + } + ++ switch (machdep->flags & (VM_4_LEVEL)) ++ { ++ case VM_4_LEVEL: ++ error(NOTE, "using 4-level pagetable\n"); ++ c++; ++ break; ++ ++ default: ++ error(WARNING, "Invalid vm= option\n"); ++ c++; ++ machdep->flags &= ~(VM_4_LEVEL); ++ break; ++ } ++ ++ + if (c) + fprintf(fp, "\n"); + } +@@ -401,12 +436,12 @@ fprintf(fp, "%sUNW_R0", others++ ? "|" : ""); if (machdep->flags & MEM_LIMIT) fprintf(fp, "%sMEM_LIMIT", others++ ? "|" : ""); @@ -8612,15 +10699,391 @@ if (machdep->flags & DEVMEMRD) fprintf(fp, "%sDEVMEMRD", others++ ? "|" : ""); if (machdep->flags & INIT) -@@ -445,6 +446,7 @@ + fprintf(fp, "%sINIT", others++ ? "|" : ""); ++ if (machdep->flags & VM_4_LEVEL) ++ fprintf(fp, "%sVM_4_LEVEL", others++ ? "|" : ""); + fprintf(fp, ")\n"); + fprintf(fp, " kvbase: %lx\n", machdep->kvbase); + fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base); +@@ -445,12 +480,16 @@ (machdep->verify_paddr == ia64_verify_paddr) ? "ia64_verify_paddr" : "generic_verify_paddr"); fprintf(fp, " init_kernel_pgd: NULL\n"); -+ fprintf(fp, " xendump_ptm_create: NULL\n"); ++ fprintf(fp, " xendump_p2m_create: NULL\n"); ++ fprintf(fp, "xen_kdump_p2m_create: NULL\n"); fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); fprintf(fp, " line_number_hooks: ia64_line_number_hooks\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); -@@ -2605,6 +2607,7 @@ ++ fprintf(fp, " last_pud_read: %lx\n", machdep->last_pud_read); + fprintf(fp, " last_pmd_read: %lx\n", machdep->last_pmd_read); + fprintf(fp, " last_ptbl_read: %lx\n", machdep->last_ptbl_read); + fprintf(fp, " pgd: %lx\n", (ulong)machdep->pgd); ++ fprintf(fp, " pud: %lx\n", (ulong)machdep->pud); + fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); + fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); + fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); +@@ -664,75 +703,152 @@ + + return (machdep->mhz = mhz); + } +- +- +-/* +- * Translates a user virtual address to its physical address. cmd_vtop() +- * sets the verbose flag so that the pte translation gets displayed; all +- * other callers quietly accept the translation. +- * +- * This routine can also take mapped kernel virtual addresses if the -u flag +- * was passed to cmd_vtop(). If so, it makes the translation using the +- * swapper_pg_dir, making it irrelevant in this processor's case. ++/* Generic abstraction to translate user or kernel virtual ++ * addresses to physical using a 4 level page table. + */ + static int +-ia64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose) ++ia64_vtop_4l(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr) + { +- ulong mm; +- ulong *pgd; + ulong *page_dir; ++ ulong *page_upper; + ulong *page_middle; + ulong *page_table; + ulong pgd_pte; ++ ulong pud_pte; + ulong pmd_pte; + ulong pte; + ulong region, offset; + +- if (!tc) +- error(FATAL, "current context invalid\n"); +- +- *paddr = 0; +- region = VADDR_REGION(uvaddr); ++ if(usr){ ++ region = VADDR_REGION(vaddr); ++ offset = (vaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); ++ offset |= (region << (PAGESHIFT() - 6)); ++ page_dir = pgd + offset; ++ }else{ ++ pgd = (ulong *)vt->kernel_pgd[0]; ++ page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); ++ } + +- if (IS_KVADDR(uvaddr)) +- return ia64_kvtop(tc, uvaddr, paddr, verbose); ++ if (verbose) ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); + +- if ((mm = task_mm(tc->task, TRUE))) +- pgd = ULONG_PTR(tt->mm_struct + OFFSET(mm_struct_pgd)); +- else +- readmem(tc->mm_struct + OFFSET(mm_struct_pgd), KVADDR, &pgd, +- sizeof(long), "mm_struct pgd", FAULT_ON_ERROR); ++ FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); ++ pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); ++ ++ if (verbose) ++ fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); + ++ if (!(pgd_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PUD_SHIFT) & (PTRS_PER_PUD - 1); ++ page_upper = (ulong *)(PTOV(pgd_pte & _PFN_MASK)) + offset; ++ ++ FILL_PUD(PAGEBASE(page_upper), KVADDR, PAGESIZE()); ++ pud_pte = ULONG(machdep->pud + PAGEOFFSET(page_upper)); ++ + if (verbose) ++ fprintf(fp, " PUD: %lx => %lx\n", (ulong)page_upper, pud_pte); ++ ++ if (!(pud_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1); ++ page_middle = (ulong *)(PTOV(pud_pte & _PFN_MASK)) + offset; ++ ++ FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); ++ pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); ++ ++ if (verbose) ++ fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); ++ ++ if (!(pmd_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); ++ page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; ++ ++ FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); ++ pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); ++ ++ if (verbose) ++ fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); ++ ++ if (!(pte & (_PAGE_P))) { ++ if(usr) ++ *paddr = pte; ++ if (pte && verbose) { ++ fprintf(fp, "\n"); ++ ia64_translate_pte(pte, 0, 0); ++ } ++ return FALSE; ++ } ++ ++ *paddr = (pte & _PFN_MASK) + PAGEOFFSET(vaddr); ++ ++ if (verbose) { ++ fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); ++ ia64_translate_pte(pte, 0, 0); ++ } ++ ++ return TRUE; ++ ++ ++ ++} ++ ++/* Generic abstraction to translate user or kernel virtual ++ * addresses to physical using a 3 level page table. ++ */ ++static int ++ia64_vtop(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr) ++{ ++ ulong *page_dir; ++ ulong *page_middle; ++ ulong *page_table; ++ ulong pgd_pte; ++ ulong pmd_pte; ++ ulong pte; ++ ulong region, offset; ++ ++ if(usr){ ++ region = VADDR_REGION(vaddr); ++ offset = (vaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); ++ offset |= (region << (PAGESHIFT() - 6)); ++ page_dir = pgd + offset; ++ }else{ ++ pgd = (ulong *)vt->kernel_pgd[0]; ++ page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); ++ } ++ ++ if (verbose) + fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); ++ + +- offset = (uvaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); +- offset |= (region << (PAGESHIFT() - 6)); +- page_dir = pgd + offset; + + FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); + pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); + +- if (verbose) { ++ if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); +- } ++ + + if (!(pgd_pte)) +- goto no_upage; ++ return FALSE; + +- offset = (uvaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1); ++ offset = (vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + page_middle = (ulong *)(PTOV(pgd_pte & _PFN_MASK)) + offset; + + FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); + pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); + + if (verbose) +- fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle,pmd_pte); ++ fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); + + if (!(pmd_pte)) +- goto no_upage; ++ return FALSE; + +- offset = (uvaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); ++ offset = (vaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); + page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; + + FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); +@@ -742,15 +858,16 @@ + fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); + + if (!(pte & (_PAGE_P))) { +- *paddr = pte; ++ if(usr) ++ *paddr = pte; + if (pte && verbose) { + fprintf(fp, "\n"); + ia64_translate_pte(pte, 0, 0); + } +- goto no_upage; ++ return FALSE; + } + +- *paddr = (pte & _PFN_MASK) + PAGEOFFSET(uvaddr); ++ *paddr = (pte & _PFN_MASK) + PAGEOFFSET(vaddr); + + if (verbose) { + fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); +@@ -759,9 +876,52 @@ + + return TRUE; + +-no_upage: ++} + +- return FALSE; ++ ++/* ++ * Translates a user virtual address to its physical address. cmd_vtop() ++ * sets the verbose flag so that the pte translation gets displayed; all ++ * other callers quietly accept the translation. ++ * ++ * This routine can also take mapped kernel virtual addresses if the -u flag ++ * was passed to cmd_vtop(). If so, it makes the translation using the ++ * swapper_pg_dir, making it irrelevant in this processor's case. ++ */ ++static int ++ia64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose) ++{ ++ ulong mm; ++ ulong *pgd; ++/** ++ ulong *page_dir; ++ ulong *page_middle; ++ ulong *page_table; ++ ulong pgd_pte; ++ ulong pmd_pte; ++ ulong pte; ++ ulong offset; ++**/ ++ ++ if (!tc) ++ error(FATAL, "current context invalid\n"); ++ ++ *paddr = 0; ++ ++ if (IS_KVADDR(uvaddr)) ++ return ia64_kvtop(tc, uvaddr, paddr, verbose); ++ ++ if ((mm = task_mm(tc->task, TRUE))) ++ pgd = ULONG_PTR(tt->mm_struct + OFFSET(mm_struct_pgd)); ++ else ++ readmem(tc->mm_struct + OFFSET(mm_struct_pgd), KVADDR, &pgd, ++ sizeof(long), "mm_struct pgd", FAULT_ON_ERROR); ++ ++ if (machdep->flags & VM_4_LEVEL) ++ return ia64_vtop_4l(uvaddr, paddr, pgd, verbose, 1); ++ else ++ return ia64_vtop(uvaddr, paddr, pgd, verbose, 1); ++ + } + + +@@ -774,6 +934,7 @@ + ia64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) + { + ulong *pgd; ++/** + ulong *page_dir; + ulong *page_middle; + ulong *page_table; +@@ -781,6 +942,7 @@ + ulong pmd_pte; + ulong pte; + ulong offset; ++**/ + + if (!IS_KVADDR(kvaddr)) + return FALSE; +@@ -815,64 +977,11 @@ + + pgd = (ulong *)vt->kernel_pgd[0]; + +- if (verbose) { +- fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); +- } +- +- page_dir = pgd + ((kvaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); +- +- FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); +- pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); +- +- if (verbose) { +- fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); +- } +- +- if (!(pgd_pte)) +- goto no_kpage; +- +- offset = (kvaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1); +- page_middle = (ulong *)(PTOV(pgd_pte & _PFN_MASK)) + offset; +- +- FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); +- pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); +- +- if (verbose) +- fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, +- pmd_pte); +- +- if (!(pmd_pte)) +- goto no_kpage; +- +- offset = (kvaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); +- page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; +- +- FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); +- pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); +- +- if (verbose) +- fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); +- +- if (!(pte & (_PAGE_P))) { +- if (pte && verbose) { +- fprintf(fp, "\n"); +- ia64_translate_pte(pte, 0, 0); +- } +- goto no_kpage; +- } +- +- *paddr = (pte & _PFN_MASK) + PAGEOFFSET(kvaddr); +- +- if (verbose) { +- fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); +- ia64_translate_pte(pte, 0, 0); +- } +- +- return TRUE; +- +-no_kpage: ++ if (machdep->flags & VM_4_LEVEL) ++ return ia64_vtop_4l(kvaddr, paddr, pgd, verbose, 0); ++ else ++ return ia64_vtop(kvaddr, paddr, pgd, verbose, 0); + +- return FALSE; + } + + /* +@@ -2391,9 +2500,10 @@ + + if ((ms->mem_limit && (efi_memmap >= ms->mem_limit)) || + !readmem(PTOV(efi_memmap), KVADDR, memmap, +- ms->efi_memmap_size, "efi_mmap contents", RETURN_ON_ERROR)) { ++ ms->efi_memmap_size, "efi_mmap contents", ++ QUIET|RETURN_ON_ERROR)) { + error(WARNING, "cannot read efi_mmap: " +- "memory verification will not be performed\n"); ++ "EFI memory verification will not be performed\n\n"); + free(memmap); + return; + } +@@ -2605,6 +2715,7 @@ ia64_post_init(void) { struct machine_specific *ms; @@ -8628,7 +11091,7 @@ ms = &ia64_machine_specific; -@@ -2677,9 +2680,10 @@ +@@ -2677,9 +2788,10 @@ } } @@ -8642,9 +11105,19 @@ if (DUMPFILE() && ia64_in_init_stack(SWITCH_STACK_ADDR(CURRENT_TASK()))) machdep->flags |= INIT; ---- crash/s390.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/s390.c 2005-11-04 17:37:53.000000000 -0500 -@@ -178,8 +178,6 @@ +--- crash/s390.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/s390.c 2006-08-02 10:31:22.000000000 -0400 +@@ -158,7 +158,8 @@ + machdep->nr_irqs = 0; /* TBD */ + machdep->vmalloc_start = s390_vmalloc_start; + machdep->dump_irq = s390_dump_irq; +- machdep->hz = HZ; ++ if (!machdep->hz) ++ machdep->hz = HZ; + break; + + case POST_INIT: +@@ -178,8 +179,6 @@ fprintf(fp, " flags: %lx (", machdep->flags); if (machdep->flags & KSYMS_START) fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); @@ -8653,9 +11126,30 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); ---- crash/s390x.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/s390x.c 2005-11-04 17:37:53.000000000 -0500 -@@ -193,8 +193,6 @@ +@@ -716,7 +715,9 @@ + frame_size = stack_base - old_backchain + + KERNEL_STACK_SIZE; + } else { +- frame_size = backchain - old_backchain; ++ frame_size = MIN((backchain - old_backchain), ++ (stack_base - old_backchain + ++ KERNEL_STACK_SIZE)); + } + for(j=0; j< frame_size; j+=4){ + if(j % 16 == 0){ +--- crash/s390x.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/s390x.c 2006-08-02 10:31:24.000000000 -0400 +@@ -173,7 +173,8 @@ + machdep->nr_irqs = 0; /* TBD */ + machdep->vmalloc_start = s390x_vmalloc_start; + machdep->dump_irq = s390x_dump_irq; +- machdep->hz = HZ; ++ if (!machdep->hz) ++ machdep->hz = HZ; + break; + + case POST_INIT: +@@ -193,8 +194,6 @@ fprintf(fp, " flags: %lx (", machdep->flags); if (machdep->flags & KSYMS_START) fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); @@ -8664,8 +11158,19 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); ---- crash/ppc64.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/ppc64.c 2006-04-26 15:57:36.000000000 -0400 +@@ -749,7 +748,9 @@ + frame_size = stack_base - old_backchain + + KERNEL_STACK_SIZE; + } else { +- frame_size = backchain - old_backchain; ++ frame_size = MIN((backchain - old_backchain), ++ (stack_base - old_backchain + ++ KERNEL_STACK_SIZE)); + } + for(j=0; j< frame_size; j+=4){ + if(j % 16 == 0){ +--- crash/ppc64.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/ppc64.c 2006-08-02 10:31:29.000000000 -0400 @@ -47,6 +47,9 @@ static char * ppc64_check_eframe(struct ppc64_pt_regs *); static void ppc64_print_eframe(char *, struct ppc64_pt_regs *, @@ -8752,7 +11257,22 @@ machdep->vmalloc_start = ppc64_vmalloc_start; MEMBER_OFFSET_INIT(thread_struct_pg_tables, "thread_struct", "pg_tables"); -@@ -229,10 +288,12 @@ +@@ -178,9 +237,11 @@ + */ + BZERO(&machdep->machspec->hwintrstack, + NR_CPUS*sizeof(ulong)); +- machdep->hz = HZ; +- if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) +- machdep->hz = 1000; ++ if (!machdep->hz) { ++ machdep->hz = HZ; ++ if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) ++ machdep->hz = 1000; ++ } + /* + * IRQ stacks are introduced in 2.6 and also configurable. + */ +@@ -229,10 +290,12 @@ fprintf(fp, " flags: %lx (", machdep->flags); if (machdep->flags & KSYMS_START) fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); @@ -8767,11 +11287,12 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); -@@ -269,15 +330,24 @@ +@@ -269,15 +332,25 @@ fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n"); fprintf(fp, " is_uvaddr: generic_is_uvaddr()\n"); fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); -+ fprintf(fp, " xendump_ptm_create: NULL\n"); ++ fprintf(fp, " xendump_p2m_create: NULL\n"); ++ fprintf(fp, "xen_kdump_p2m_create: NULL\n"); fprintf(fp, " line_number_hooks: ppc64_line_number_hooks\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); fprintf(fp, " last_pmd_read: %lx\n", machdep->last_pmd_read); @@ -8792,7 +11313,7 @@ } /* -@@ -342,7 +412,7 @@ +@@ -342,7 +415,7 @@ if (!(pte & _PAGE_PRESENT)) { if (pte && verbose) { fprintf(fp, "\n"); @@ -8801,7 +11322,7 @@ } return FALSE; } -@@ -354,7 +424,90 @@ +@@ -354,7 +427,90 @@ if (verbose) { fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); @@ -8893,7 +11414,7 @@ } return TRUE; -@@ -411,7 +564,10 @@ +@@ -411,7 +567,10 @@ FAULT_ON_ERROR); } @@ -8905,7 +11426,7 @@ } /* -@@ -436,7 +592,10 @@ +@@ -436,7 +595,10 @@ return TRUE; } @@ -8917,7 +11438,7 @@ } /* -@@ -657,7 +816,7 @@ +@@ -657,7 +819,7 @@ * If a physaddr pointer is passed in, don't print anything. */ static int @@ -8926,7 +11447,7 @@ { int c, len1, len2, len3, others, page_present; char buf[BUFSIZE]; -@@ -668,7 +827,7 @@ +@@ -668,7 +830,7 @@ char *arglist[MAXARGS]; ulong paddr; @@ -8935,7 +11456,7 @@ page_present = (pte & _PAGE_PRESENT); if (physaddr) { -@@ -1034,8 +1193,12 @@ +@@ -1034,8 +1196,12 @@ ms->hwstacksize + STACK_FRAME_OVERHEAD; bt->stackbuf = ms->hwstackbuf; alter_stackbuf(bt); @@ -8950,7 +11471,7 @@ } -@@ -1270,20 +1433,11 @@ +@@ -1270,20 +1436,11 @@ return NULL; } @@ -8972,7 +11493,7 @@ /* print out the gprs... */ for(i=0; i<32; i++) { if(!(i % 3)) -@@ -1315,9 +1469,78 @@ +@@ -1315,9 +1472,78 @@ fprintf(fp, "DAR: %016lx\n", regs->dar); fprintf(fp, " DSISR: %016lx ", regs->dsisr); fprintf(fp, " Syscall Result: %016lx\n", regs->result); @@ -9051,7 +11572,7 @@ /* * Get the starting point for the active cpus in a diskdump/netdump. -@@ -1335,12 +1558,18 @@ +@@ -1335,12 +1561,18 @@ ulong ur_ksp = 0; int check_hardirq, check_softirq; int check_intrstack = TRUE; @@ -9071,7 +11592,7 @@ panic_task = tt->panic_task == bt->task ? TRUE : FALSE; -@@ -1424,6 +1653,7 @@ +@@ -1424,6 +1656,7 @@ if (STREQ(sym, ".netconsole_netdump") || STREQ(sym, ".netpoll_start_netdump") || STREQ(sym, ".start_disk_dump") || @@ -9079,7 +11600,7 @@ STREQ(sym, ".disk_dump")) { *nip = *up; *ksp = bt->stackbase + -@@ -2000,4 +2230,145 @@ +@@ -2000,4 +2233,145 @@ ppc64_dump_line_number(0); } @@ -9225,8 +11746,8 @@ + machdep->machspec->last_level4_read = 0; +} #endif /* PPC64 */ ---- crash/x86_64.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/x86_64.c 2006-04-26 16:12:41.000000000 -0400 +--- crash/x86_64.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/x86_64.c 2006-08-02 10:31:34.000000000 -0400 @@ -18,7 +18,10 @@ #ifdef X86_64 @@ -9254,23 +11775,26 @@ static int x86_64_is_kvaddr(ulong); static int x86_64_is_uvaddr(ulong, struct task_context *); void x86_64_compiler_warning_stub(void); -@@ -63,7 +68,14 @@ +@@ -63,7 +68,17 @@ static void x86_64_cpu_pda_init(void); static void x86_64_ist_init(void); static void x86_64_post_init(void); - +static void parse_cmdline_arg(void); +static void x86_64_clear_machdep_cache(void); -+static int x86_64_xendump_ptm_create(struct xendump_data *); ++static int x86_64_xendump_p2m_create(struct xendump_data *); +static char *x86_64_xendump_load_page(ulong, struct xendump_data *); +static int x86_64_xendump_page_index(ulong, struct xendump_data *); ++static int x86_64_xen_kdump_p2m_create(struct xen_kdump_data *); ++static char *x86_64_xen_kdump_load_page(ulong, char *); ++static ulong x86_64_xen_kdump_page_mfn(ulong); +static void x86_64_debug_dump_page(FILE *, char *, char *); +static void x86_64_get_xendump_regs(struct xendump_data *, struct bt_info *, ulong *, ulong *); +static ulong x86_64_xendump_panic_task(struct xendump_data *); struct machine_specific x86_64_machine_specific = { 0 }; -@@ -86,6 +98,8 @@ +@@ -86,6 +101,8 @@ machdep->pageoffset = machdep->pagesize - 1; machdep->pagemask = ~((ulonglong)machdep->pageoffset); machdep->stacksize = machdep->pagesize * 2; @@ -9279,7 +11803,7 @@ if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc pgd space."); if ((machdep->pmd = (char *)malloc(PAGESIZE())) == NULL) -@@ -93,17 +107,69 @@ +@@ -93,17 +110,69 @@ if ((machdep->ptbl = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc ptbl space."); if ((machdep->machspec->pml4 = @@ -9350,7 +11874,7 @@ machdep->kvbase = (ulong)PAGE_OFFSET; machdep->identity_map_base = (ulong)PAGE_OFFSET; machdep->is_kvaddr = x86_64_is_kvaddr; -@@ -111,7 +177,6 @@ +@@ -111,7 +180,6 @@ machdep->eframe_search = x86_64_eframe_search; machdep->back_trace = x86_64_low_budget_back_trace_cmd; machdep->processor_speed = x86_64_processor_speed; @@ -9358,28 +11882,37 @@ machdep->kvtop = x86_64_kvtop; machdep->get_task_pgd = x86_64_get_task_pgd; machdep->get_stack_frame = x86_64_get_stack_frame; -@@ -126,6 +191,10 @@ +@@ -126,6 +194,11 @@ machdep->line_number_hooks = x86_64_line_number_hooks; machdep->value_to_symbol = generic_machdep_value_to_symbol; machdep->init_kernel_pgd = x86_64_init_kernel_pgd; + machdep->clear_machdep_cache = x86_64_clear_machdep_cache; -+ machdep->xendump_ptm_create = x86_64_xendump_ptm_create; ++ machdep->xendump_p2m_create = x86_64_xendump_p2m_create; + machdep->get_xendump_regs = x86_64_get_xendump_regs; ++ machdep->xen_kdump_p2m_create = x86_64_xen_kdump_p2m_create; + machdep->xendump_panic_task = x86_64_xendump_panic_task; break; case POST_GDB: -@@ -168,6 +237,20 @@ - machdep->hz = HZ; - if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) - machdep->hz = 1000; +@@ -165,9 +238,25 @@ + machdep->nr_irqs = 224; /* NR_IRQS (at least) */ + machdep->vmalloc_start = x86_64_vmalloc_start; + machdep->dump_irq = x86_64_dump_irq; +- machdep->hz = HZ; +- if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) +- machdep->hz = 1000; ++ if (!machdep->hz) { ++ machdep->hz = HZ; ++ if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) ++ machdep->hz = 1000; ++ } + machdep->section_size_bits = _SECTION_SIZE_BITS; + machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; -+ if (XEN() && (kt->xen_flags & WRITABLE_PAGE_TABLES)) -+ machdep->uvtop = x86_64_uvtop_level4_xen_wpt; -+ else -+ machdep->uvtop = x86_64_uvtop_level4; + if (XEN()) { ++ if (kt->xen_flags & WRITABLE_PAGE_TABLES) ++ machdep->uvtop = x86_64_uvtop_level4_xen_wpt; ++ else ++ machdep->uvtop = x86_64_uvtop_level4; + MEMBER_OFFSET_INIT(vcpu_guest_context_user_regs, + "vcpu_guest_context", "user_regs"); + ASSIGN_OFFSET(cpu_user_regs_rsp) = @@ -9390,7 +11923,7 @@ break; case POST_INIT: -@@ -191,10 +274,18 @@ +@@ -191,10 +280,18 @@ fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); if (machdep->flags & PT_REGS_INIT) fprintf(fp, "%sPT_REGS_INIT", others++ ? "|" : ""); @@ -9411,7 +11944,7 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); -@@ -220,7 +311,14 @@ +@@ -220,7 +317,14 @@ fprintf(fp, " back_trace: %lx\n", (ulong)machdep->back_trace); fprintf(fp, " processor_speed: x86_64_processor_speed()\n"); @@ -9427,18 +11960,19 @@ fprintf(fp, " kvtop: x86_64_kvtop()\n"); fprintf(fp, " get_task_pgd: x86_64_get_task_pgd()\n"); fprintf(fp, " dump_irq: x86_64_dump_irq()\n"); -@@ -239,6 +337,10 @@ +@@ -239,6 +343,11 @@ fprintf(fp, " is_uvaddr: x86_64_is_uvaddr()\n"); fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); fprintf(fp, " init_kernel_pgd: x86_64_init_kernel_pgd()\n"); + fprintf(fp, "clear_machdep_cache: x86_64_clear_machdep_cache()\n"); -+ fprintf(fp, " xendump_ptm_create: x86_64_xendump_ptm_create()\n"); ++ fprintf(fp, " xendump_p2m_create: x86_64_xendump_p2m_create()\n"); + fprintf(fp, " get_xendump_regs: x86_64_get_xendump_regs()\n"); + fprintf(fp, " xendump_panic_task: x86_64_xendump_panic_task()\n"); ++ fprintf(fp, "xen_kdump_p2m_create: x86_64_xen_kdump_p2m_create()\n"); fprintf(fp, " line_number_hooks: x86_64_line_number_hooks\n"); fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); -@@ -248,8 +350,26 @@ +@@ -248,8 +357,26 @@ fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); @@ -9466,7 +12000,7 @@ fprintf(fp, " irqstack: %lx\n", (ulong)ms->irqstack); fprintf(fp, " pto: %s", machdep->flags & PT_REGS_INIT ? "\n" : "(uninitialized)\n"); -@@ -276,8 +396,10 @@ +@@ -276,8 +403,10 @@ fprintf(fp, " rsp: %ld\n", ms->pto.rsp); fprintf(fp, " ss: %ld\n", ms->pto.ss); } @@ -9479,7 +12013,7 @@ fprintf(fp, " ebase[%s][7]:", arg ? "NR_CPUS" : "cpus"); cpus = arg ? NR_CPUS : kt->cpus; -@@ -306,9 +428,9 @@ +@@ -306,9 +435,9 @@ static void x86_64_cpu_pda_init(void) { @@ -9491,7 +12025,7 @@ struct syment *sp, *nsp; ulong offset, istacksize; -@@ -320,18 +442,36 @@ +@@ -320,18 +449,36 @@ MEMBER_OFFSET_INIT(x8664_pda_irqstackptr, "x8664_pda", "irqstackptr"); MEMBER_OFFSET_INIT(x8664_pda_level4_pgt, "x8664_pda", "level4_pgt"); MEMBER_OFFSET_INIT(x8664_pda_cpunumber, "x8664_pda", "cpunumber"); @@ -9534,7 +12068,7 @@ break; cpus++; -@@ -448,6 +588,13 @@ +@@ -448,6 +595,13 @@ if (ms->stkinfo.ebase[c][0] == 0) break; } @@ -9548,7 +12082,7 @@ } if (ms->stkinfo.ebase[0][0] && ms->stkinfo.ebase[0][1]) -@@ -535,6 +682,10 @@ +@@ -535,6 +689,10 @@ if (clues >= 2) kt->cpu_flags[c] |= NMI; } @@ -9559,7 +12093,7 @@ } /* -@@ -584,12 +735,19 @@ +@@ -584,12 +742,19 @@ /* * Include both vmalloc'd and module address space as VMALLOC space. */ @@ -9580,7 +12114,7 @@ /* * Refining this may cause more problems than just doing it this way. */ -@@ -616,6 +774,257 @@ +@@ -616,6 +781,257 @@ */ static int @@ -9735,7 +12269,7 @@ + goto no_upage; + + pgd_paddr = pml_pte & PHYSICAL_PAGE_MASK; -+ pgd_paddr = xen_machine_to_pseudo(pgd_paddr); ++ pgd_paddr = xen_m2p(pgd_paddr); + if (verbose) + fprintf(fp, " PML: %lx\n", pgd_paddr); + FILL_PGD(pgd_paddr, PHYSADDR, PAGESIZE()); @@ -9750,7 +12284,7 @@ + * pmd = pmd_offset(pgd, address); + */ + pmd_paddr = pgd_pte & PHYSICAL_PAGE_MASK; -+ pmd_paddr = xen_machine_to_pseudo(pmd_paddr); ++ pmd_paddr = xen_m2p(pmd_paddr); + if (verbose) + fprintf(fp, " PUD: %lx\n", pmd_paddr); + FILL_PMD(pmd_paddr, PHYSADDR, PAGESIZE()); @@ -9765,9 +12299,9 @@ + fprintf(fp, " PAGE: %lx (2MB) [machine]\n", + PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK); + -+ pseudo_pmd_pte = xen_machine_to_pseudo(PAGEBASE(pmd_pte)); ++ pseudo_pmd_pte = xen_m2p(PAGEBASE(pmd_pte)); + -+ if (pseudo_pmd_pte == XEN_MFN_NOT_FOUND) { ++ if (pseudo_pmd_pte == XEN_MACHADDR_NOT_FOUND) { + if (verbose) + fprintf(fp, " PAGE: page not available\n"); + *paddr = PADDR_NOT_AVAILABLE; @@ -9797,7 +12331,7 @@ + * pte = *ptep; + */ + pte_paddr = pmd_pte & PHYSICAL_PAGE_MASK; -+ pte_paddr = xen_machine_to_pseudo(pte_paddr); ++ pte_paddr = xen_m2p(pte_paddr); + if (verbose) + fprintf(fp, " PMD: %lx\n", pte_paddr); + FILL_PTBL(pte_paddr, PHYSADDR, PAGESIZE()); @@ -9813,7 +12347,7 @@ + goto no_upage; + } + -+ pseudo_pte = xen_machine_to_pseudo(pte & PHYSICAL_PAGE_MASK); ++ pseudo_pte = xen_m2p(pte & PHYSICAL_PAGE_MASK); + if (verbose) + fprintf(fp, " PTE: %lx\n", pseudo_pte + PAGEOFFSET(pte)); + @@ -9838,7 +12372,7 @@ x86_64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose) { ulong mm; -@@ -748,6 +1157,9 @@ +@@ -748,6 +1164,9 @@ return TRUE; } @@ -9848,7 +12382,7 @@ /* * pgd = pgd_offset_k(addr); */ -@@ -764,7 +1176,7 @@ +@@ -764,7 +1183,7 @@ pgd = ((ulong *)pgd_paddr) + pgd_index(kvaddr); pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(pgd)); if (verbose) @@ -9857,14 +12391,31 @@ if (!(pgd_pte & _PAGE_PRESENT)) goto no_kpage; -@@ -824,6 +1236,136 @@ +@@ -824,47 +1243,177 @@ return FALSE; } -+ -+static int +-/* +- * Determine where vmalloc'd memory starts. +- */ +-static ulong +-x86_64_vmalloc_start(void) +-{ +- return ((ulong)VMALLOC_START); +-} + +-/* +- * thread_info implementation makes for less accurate results here. +- */ + static int +-x86_64_is_task_addr(ulong task) +x86_64_kvtop_xen_wpt(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) -+{ + { +- if (tt->flags & THREAD_INFO) +- return IS_KVADDR(task); +- else +- return (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0)); +-} + ulong *pml4; + ulong *pgd; + ulong pgd_paddr; @@ -9879,7 +12430,7 @@ + ulong pseudo_pte; + physaddr_t physpage; + char buf[BUFSIZE]; -+ + + /* + * pgd = pgd_offset_k(addr); + */ @@ -9892,7 +12443,7 @@ + if (!(*pml4) & _PAGE_PRESENT) + goto no_kpage; + pgd_paddr = (*pml4) & PHYSICAL_PAGE_MASK; -+ pgd_paddr = xen_machine_to_pseudo(pgd_paddr); ++ pgd_paddr = xen_m2p(pgd_paddr); + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd_paddr); + FILL_PGD(pgd_paddr, PHYSADDR, PAGESIZE()); @@ -9902,12 +12453,19 @@ + fprintf(fp, " PUD: %lx => %lx [machine]\n", (ulong)pgd, pgd_pte); + if (!(pgd_pte & _PAGE_PRESENT)) + goto no_kpage; -+ + +-/* +- * easy enough... +- */ +-static ulong +-x86_64_processor_speed(void) +-{ +- unsigned long cpu_khz; + /* + * pmd = pmd_offset(pgd, addr); + */ + pmd_paddr = pgd_pte & PHYSICAL_PAGE_MASK; -+ pmd_paddr = xen_machine_to_pseudo(pmd_paddr); ++ pmd_paddr = xen_m2p(pmd_paddr); + if (verbose) + fprintf(fp, " PUD: %lx\n", pmd_paddr); + FILL_PMD(pmd_paddr, PHYSADDR, PAGESIZE()); @@ -9921,16 +12479,25 @@ + if (verbose) + fprintf(fp, " PAGE: %lx (2MB) [machine]\n", + PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK); -+ -+ pseudo_pmd_pte = xen_machine_to_pseudo(PAGEBASE(pmd_pte)); -+ -+ if (pseudo_pmd_pte == XEN_MFN_NOT_FOUND) { + +- if (machdep->mhz) +- return (machdep->mhz); ++ pseudo_pmd_pte = xen_m2p(PAGEBASE(pmd_pte)); + +- if (symbol_exists("cpu_khz")) { +- get_symbol_data("cpu_khz", sizeof(long), &cpu_khz); +- if (cpu_khz) +- return(machdep->mhz = cpu_khz/1000); +- } ++ if (pseudo_pmd_pte == XEN_MACHADDR_NOT_FOUND) { + if (verbose) + fprintf(fp, " PAGE: page not available\n"); + *paddr = PADDR_NOT_AVAILABLE; + return FALSE; + } -+ + +- return 0; +-} + pseudo_pmd_pte |= PAGEOFFSET(pmd_pte); + + if (verbose) { @@ -9954,7 +12521,7 @@ + * pte = *ptep; + */ + pte_paddr = pmd_pte & PHYSICAL_PAGE_MASK; -+ pte_paddr = xen_machine_to_pseudo(pte_paddr); ++ pte_paddr = xen_m2p(pte_paddr); + if (verbose) + fprintf(fp, " PMD: %lx\n", pte_paddr); + FILL_PTBL(pte_paddr, PHYSADDR, PAGESIZE()); @@ -9970,7 +12537,7 @@ + goto no_kpage; + } + -+ pseudo_pte = xen_machine_to_pseudo(pte & PHYSICAL_PAGE_MASK); ++ pseudo_pte = xen_m2p(pte & PHYSICAL_PAGE_MASK); + if (verbose) + fprintf(fp, " PTE: %lx\n", pseudo_pte + PAGEOFFSET(pte)); + @@ -9991,26 +12558,51 @@ +} + + - /* - * Determine where vmalloc'd memory starts. - */ -@@ -852,13 +1394,13 @@ - static ulong - x86_64_processor_speed(void) - { -- unsigned long cpu_khz; ++/* ++ * Determine where vmalloc'd memory starts. ++ */ ++static ulong ++x86_64_vmalloc_start(void) ++{ ++ return ((ulong)VMALLOC_START); ++} ++ ++/* ++ * thread_info implementation makes for less accurate results here. ++ */ ++static int ++x86_64_is_task_addr(ulong task) ++{ ++ if (tt->flags & THREAD_INFO) ++ return IS_KVADDR(task); ++ else ++ return (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0)); ++} ++ ++ ++/* ++ * easy enough... ++ */ ++static ulong ++x86_64_processor_speed(void) ++{ + unsigned long cpu_khz = 0; - - if (machdep->mhz) - return (machdep->mhz); - - if (symbol_exists("cpu_khz")) { -- get_symbol_data("cpu_khz", sizeof(long), &cpu_khz); ++ ++ if (machdep->mhz) ++ return (machdep->mhz); ++ ++ if (symbol_exists("cpu_khz")) { + get_symbol_data("cpu_khz", sizeof(int), &cpu_khz); - if (cpu_khz) - return(machdep->mhz = cpu_khz/1000); - } -@@ -878,7 +1420,6 @@ ++ if (cpu_khz) ++ return(machdep->mhz = cpu_khz/1000); ++ } ++ ++ return 0; ++} + + + /* +@@ -878,7 +1427,6 @@ if (!name || !strlen(name) || !(machdep->flags & KSYMS_START)) return FALSE; @@ -10018,7 +12610,7 @@ return TRUE; } -@@ -1091,6 +1632,9 @@ +@@ -1091,6 +1639,9 @@ ulong *up; ulong words, addr; @@ -10028,7 +12620,7 @@ words = (rsp - bt->frameptr) / sizeof(ulong) + 1; addr = bt->frameptr; -@@ -1308,7 +1852,7 @@ +@@ -1308,7 +1859,7 @@ (rsp < (ms->stkinfo.ebase[c][i] + ms->stkinfo.esize))) { estack = ms->stkinfo.ebase[c][i]; @@ -10037,7 +12629,7 @@ error(INFO, "task cpu: %d exception stack cpu: %d\n", bt->tc->processor, c); -@@ -1341,7 +1885,7 @@ +@@ -1341,7 +1892,7 @@ if ((rsp >= ms->stkinfo.ibase[c]) && (rsp < (ms->stkinfo.ibase[c] + ms->stkinfo.isize))) { irqstack = ms->stkinfo.ibase[c]; @@ -10046,7 +12638,7 @@ error(INFO, "task cpu: %d IRQ stack cpu: %d\n", bt->tc->processor, c); -@@ -1399,12 +1943,13 @@ +@@ -1399,12 +1950,13 @@ ofp = fp; if (bt->flags & BT_TEXT_SYMBOLS) { @@ -10066,7 +12658,7 @@ } else if (bt->flags & BT_START) { x86_64_print_stack_entry(bt, ofp, level, 0, bt->instptr); -@@ -1647,8 +2192,12 @@ +@@ -1647,8 +2199,12 @@ bt->stackbuf + (irq_eframe - bt->stackbase), bt, ofp); if (cs & 3) done = TRUE; /* IRQ from user-mode */ @@ -10080,7 +12672,7 @@ level++; } -@@ -1691,6 +2240,10 @@ +@@ -1691,6 +2247,10 @@ bt->call_target); continue; } @@ -10091,7 +12683,7 @@ } else if (!STREQ(sp->name, bt->call_target)) { /* * We got function called by the text routine, -@@ -1709,6 +2262,8 @@ +@@ -1709,6 +2269,8 @@ { case BACKTRACE_ENTRY_AND_EFRAME_DISPLAYED: last_process_stack_eframe = rsp + 8; @@ -10100,7 +12692,7 @@ rsp += SIZE(pt_regs); i += SIZE(pt_regs)/sizeof(ulong); case BACKTRACE_ENTRY_DISPLAYED: -@@ -1842,6 +2397,8 @@ +@@ -1842,6 +2404,8 @@ long rax, rbx, rcx, rdx, rsi, rdi; long r8, r9, r10, r11, r12, r13, r14, r15; struct machine_specific *ms; @@ -10109,7 +12701,7 @@ char *pt_regs_buf; long verified; int err; -@@ -1950,8 +2507,17 @@ +@@ -1950,8 +2514,17 @@ cs & 3 ? "USER" : "KERNEL", kvaddr ? kvaddr : (local - bt->stackbuf) + bt->stackbase); @@ -10128,7 +12720,7 @@ fprintf(ofp, " RIP: %016lx RSP: %016lx RFLAGS: %08lx\n", rip, rsp, rflags); fprintf(ofp, " RAX: %016lx RBX: %016lx RCX: %016lx\n", -@@ -2006,6 +2572,39 @@ +@@ -2006,6 +2579,39 @@ return 0; } @@ -10168,7 +12760,7 @@ /* * Check that the verifiable registers contain reasonable data. */ -@@ -2021,6 +2620,11 @@ +@@ -2021,6 +2627,11 @@ if ((cs == 0x10) && (ss == 0x18)) { if (is_kernel_text(rip) && IS_KVADDR(rsp)) return TRUE; @@ -10180,7 +12772,7 @@ } if ((cs == 0x10) && kvaddr) { -@@ -2040,6 +2644,26 @@ +@@ -2040,6 +2651,26 @@ return TRUE; } @@ -10207,7 +12799,7 @@ return FALSE; } -@@ -2065,7 +2689,7 @@ +@@ -2065,7 +2696,7 @@ x86_64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *rip, ulong *rsp) { int panic_task; @@ -10216,7 +12808,7 @@ char *sym; struct syment *sp; ulong *up; -@@ -2080,6 +2704,7 @@ +@@ -2080,6 +2711,7 @@ ms = machdep->machspec; ur_rip = ur_rsp = 0; stage = 0; @@ -10224,7 +12816,7 @@ panic_task = tt->panic_task == bt->task ? TRUE : FALSE; -@@ -2119,13 +2744,14 @@ +@@ -2119,13 +2751,14 @@ STREQ(sym, "netpoll_start_netdump") || STREQ(sym, "start_disk_dump") || STREQ(sym, "disk_dump") || @@ -10240,7 +12832,7 @@ (STREQ(sym, "nmi_watchdog_tick") || STREQ(sym, "default_do_nmi"))) { sp = x86_64_function_called_by((*up)-5); -@@ -2161,7 +2787,7 @@ +@@ -2161,7 +2794,7 @@ next_sysrq: *rip = *up; *rsp = bt->stackbase + ((char *)(up) - bt->stackbuf); @@ -10249,7 +12841,7 @@ for (i++, up++; i < LONGS_PER_STACK; i++, up++) { sym = closest_symbol(*up); if (STREQ(sym, "sysrq_handle_crash")) -@@ -2176,6 +2802,12 @@ +@@ -2176,6 +2809,12 @@ *rsp = bt->stackbase + ((char *)(up) - bt->stackbuf); return; } @@ -10262,7 +12854,7 @@ } if (panic) -@@ -2191,25 +2823,30 @@ +@@ -2191,25 +2830,30 @@ bt->stackbase = ms->stkinfo.ibase[bt->tc->processor]; bt->stacktop = ms->stkinfo.ibase[bt->tc->processor] + ms->stkinfo.isize; @@ -10300,7 +12892,7 @@ } /* -@@ -2258,7 +2895,7 @@ +@@ -2258,7 +2902,7 @@ { ulong offset, rip; @@ -10309,7 +12901,7 @@ return symbol_value("thread_return"); if (tt->flags & THREAD_INFO) { -@@ -2457,25 +3094,40 @@ +@@ -2457,25 +3101,40 @@ int x86_64_get_smp_cpus(void) { @@ -10360,7 +12952,7 @@ cpus++; } -@@ -2551,9 +3203,9 @@ +@@ -2551,9 +3210,9 @@ static void x86_64_display_cpu_data(void) { @@ -10372,7 +12964,7 @@ if (symbol_exists("cpu_data")) { cpu_data = symbol_value("cpu_data"); -@@ -2564,7 +3216,13 @@ +@@ -2564,7 +3223,13 @@ boot_cpu = TRUE; cpus = 1; } @@ -10387,7 +12979,7 @@ for (cpu = 0; cpu < cpus; cpu++) { if (boot_cpu) -@@ -2574,10 +3232,17 @@ +@@ -2574,10 +3239,17 @@ dump_struct("cpuinfo_x86", cpu_data, 0); fprintf(fp, "\n"); @@ -10407,7 +12999,7 @@ } } -@@ -2691,4 +3356,440 @@ +@@ -2691,4 +3363,698 @@ x86_64_dump_line_number(0); } @@ -10502,6 +13094,259 @@ + machdep->machspec->last_upml_read = 0; +} + ++#include "netdump.h" ++ ++/* ++ * From the xen vmcore, create an index of mfns for each page that makes ++ * up the dom0 kernel's complete phys_to_machine_mapping[max_pfn] array. ++ */ ++ ++#define MAX_X86_64_FRAMES (512) ++#define MFNS_PER_FRAME (PAGESIZE()/sizeof(ulong)) ++ ++static int ++x86_64_xen_kdump_p2m_create(struct xen_kdump_data *xkd) ++{ ++ int i, j; ++ ulong kvaddr; ++ ulong *up; ++ ulong frames; ++ ulong frame_mfn[MAX_X86_64_FRAMES] = { 0 }; ++ int mfns[MAX_X86_64_FRAMES] = { 0 }; ++ ++ /* ++ * Temporarily read physical (machine) addresses from vmcore by ++ * going directly to read_netdump() instead of via read_kdump(). ++ */ ++ pc->readmem = read_netdump; ++ ++ if (xkd->flags & KDUMP_CR3) ++ goto use_cr3; ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "x86_64_xen_kdump_p2m_create: p2m_mfn: %lx\n", ++ xkd->p2m_mfn); ++ ++ if (!readmem(PTOB(xkd->p2m_mfn), PHYSADDR, xkd->page, PAGESIZE(), ++ "xen kdump p2m mfn page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump p2m mfn page\n"); ++ ++ if (CRASHDEBUG(1)) ++ x86_64_debug_dump_page(fp, xkd->page, "pfn_to_mfn_frame_list"); ++ ++ for (i = 0, up = (ulong *)xkd->page; i < MAX_X86_64_FRAMES; i++, up++) ++ frame_mfn[i] = *up; ++ ++ for (i = 0; i < MAX_X86_64_FRAMES; i++) { ++ if (!frame_mfn[i]) ++ break; ++ ++ if (!readmem(PTOB(frame_mfn[i]), PHYSADDR, xkd->page, ++ PAGESIZE(), "xen kdump p2m mfn list page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump p2m mfn list page\n"); ++ ++ for (j = 0, up = (ulong *)xkd->page; j < MFNS_PER_FRAME; j++, up++) ++ if (*up) ++ mfns[i]++; ++ ++ xkd->p2m_frames += mfns[i]; ++ ++ if (CRASHDEBUG(7)) ++ x86_64_debug_dump_page(fp, xkd->page, "pfn_to_mfn_frame_list page"); ++ } ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "p2m_frames: %d\n", xkd->p2m_frames); ++ ++ if ((xkd->p2m_mfn_frame_list = (ulong *) ++ malloc(xkd->p2m_frames * sizeof(ulong))) == NULL) ++ error(FATAL, "cannot malloc p2m_frame_index_list"); ++ ++ for (i = 0, frames = xkd->p2m_frames; frames; i++) { ++ if (!readmem(PTOB(frame_mfn[i]), PHYSADDR, ++ &xkd->p2m_mfn_frame_list[i * MFNS_PER_FRAME], ++ mfns[i] * sizeof(ulong), "xen kdump p2m mfn list page", ++ RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump p2m mfn list page\n"); ++ ++ frames -= mfns[i]; ++ } ++ ++ pc->readmem = read_kdump; ++ return FALSE; ++ ++use_cr3: ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "x86_64_xen_kdump_p2m_create: cr3: %lx\n", xkd->cr3); ++ ++ if (!readmem(PTOB(xkd->cr3), PHYSADDR, machdep->machspec->pml4, ++ PAGESIZE(), "xen kdump cr3 page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read xen kdump cr3 page\n"); ++ ++ if (CRASHDEBUG(7)) ++ x86_64_debug_dump_page(fp, machdep->machspec->pml4, ++ "contents of PML4 page:"); ++ ++ kvaddr = symbol_value("end_pfn"); ++ if (!x86_64_xen_kdump_load_page(kvaddr, xkd->page)) ++ return FALSE; ++ up = (ulong *)(xkd->page + PAGEOFFSET(kvaddr)); ++ ++ xkd->p2m_frames = (*up/(PAGESIZE()/sizeof(ulong))) + ++ ((*up%(PAGESIZE()/sizeof(ulong))) ? 1 : 0); ++ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "end_pfn at %lx: %lx (%ld) -> %d p2m_frames\n", ++ kvaddr, *up, *up, xkd->p2m_frames); ++ ++ if ((xkd->p2m_mfn_frame_list = (ulong *) ++ malloc(xkd->p2m_frames * sizeof(ulong))) == NULL) ++ error(FATAL, "cannot malloc p2m_frame_index_list"); ++ ++ kvaddr = symbol_value("phys_to_machine_mapping"); ++ if (!x86_64_xen_kdump_load_page(kvaddr, xkd->page)) ++ return FALSE; ++ up = (ulong *)(xkd->page + PAGEOFFSET(kvaddr)); ++ kvaddr = *up; ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "phys_to_machine_mapping: %lx\n", kvaddr); ++ ++ machdep->last_pgd_read = BADADDR; ++ machdep->last_pmd_read = BADADDR; ++ machdep->last_ptbl_read = BADADDR; ++ ++ for (i = 0; i < xkd->p2m_frames; i++) { ++ xkd->p2m_mfn_frame_list[i] = x86_64_xen_kdump_page_mfn(kvaddr); ++ kvaddr += PAGESIZE(); ++ } ++ ++ if (CRASHDEBUG(1)) { ++ for (i = 0; i < xkd->p2m_frames; i++) ++ fprintf(fp, "%lx ", xkd->p2m_mfn_frame_list[i]); ++ fprintf(fp, "\n"); ++ } ++ ++ machdep->last_pgd_read = 0; ++ machdep->last_ptbl_read = 0; ++ machdep->last_pmd_read = 0; ++ pc->readmem = read_kdump; ++ ++ return TRUE; ++} ++ ++static char * ++x86_64_xen_kdump_load_page(ulong kvaddr, char *pgbuf) ++{ ++ ulong mfn; ++ ulong *pml4, *pgd, *pmd, *ptep; ++ ++ pml4 = ((ulong *)machdep->machspec->pml4) + pml4_index(kvaddr); ++ mfn = ((*pml4) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if (CRASHDEBUG(3)) ++ fprintf(fp, ++ "[%lx] pml4: %lx mfn: %lx pml4_index: %lx\n", ++ kvaddr, *pml4, mfn, pml4_index(kvaddr)); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, machdep->pgd, PAGESIZE(), ++ "xen kdump pud page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find pud page\n"); ++ ++ if (CRASHDEBUG(7)) ++ x86_64_debug_dump_page(fp, machdep->pgd, ++ "contents of page upper directory page:"); ++ ++ pgd = ((ulong *)machdep->pgd) + pgd_index(kvaddr); ++ mfn = ((*pgd) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if (CRASHDEBUG(3)) ++ fprintf(fp, ++ "[%lx] pgd: %lx mfn: %lx pgd_index: %lx\n", ++ kvaddr, *pgd, mfn, pgd_index(kvaddr)); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, machdep->pmd, PAGESIZE(), ++ "xen kdump pmd page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find pmd page\n"); ++ ++ if (CRASHDEBUG(7)) ++ x86_64_debug_dump_page(fp, machdep->pmd, ++ "contents of page middle directory page:"); ++ ++ pmd = ((ulong *)machdep->pmd) + pmd_index(kvaddr); ++ mfn = ((*pmd) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if (CRASHDEBUG(3)) ++ fprintf(fp, ++ "[%lx] pmd: %lx mfn: %lx pmd_index: %lx\n", ++ kvaddr, *pmd, mfn, pmd_index(kvaddr)); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, machdep->ptbl, PAGESIZE(), ++ "xen kdump page table page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find page table page\n"); ++ ++ if (CRASHDEBUG(7)) ++ x86_64_debug_dump_page(fp, machdep->ptbl, ++ "contents of page table page:"); ++ ++ ptep = ((ulong *)machdep->ptbl) + pte_index(kvaddr); ++ mfn = ((*ptep) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if (CRASHDEBUG(3)) ++ fprintf(fp, ++ "[%lx] ptep: %lx mfn: %lx pte_index: %lx\n", ++ kvaddr, *ptep, mfn, pte_index(kvaddr)); ++ ++ if (!readmem(PTOB(mfn), PHYSADDR, pgbuf, PAGESIZE(), ++ "xen kdump page table page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find pte page\n"); ++ ++ if (CRASHDEBUG(7)) ++ x86_64_debug_dump_page(fp, pgbuf, ++ "contents of page:"); ++ ++ return pgbuf; ++} ++ ++static ulong ++x86_64_xen_kdump_page_mfn(ulong kvaddr) ++{ ++ ulong mfn; ++ ulong *pml4, *pgd, *pmd, *ptep; ++ ++ pml4 = ((ulong *)machdep->machspec->pml4) + pml4_index(kvaddr); ++ mfn = ((*pml4) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if ((mfn != machdep->last_pgd_read) && ++ !readmem(PTOB(mfn), PHYSADDR, machdep->pgd, PAGESIZE(), ++ "xen kdump pud entry", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find pud page\n"); ++ machdep->last_pgd_read = mfn; ++ ++ pgd = ((ulong *)machdep->pgd) + pgd_index(kvaddr); ++ mfn = ((*pgd) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if ((mfn != machdep->last_pmd_read) && ++ !readmem(PTOB(mfn), PHYSADDR, machdep->pmd, PAGESIZE(), ++ "xen kdump pmd entry", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find pmd page\n"); ++ machdep->last_pmd_read = mfn; ++ ++ pmd = ((ulong *)machdep->pmd) + pmd_index(kvaddr); ++ mfn = ((*pmd) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ if ((mfn != machdep->last_ptbl_read) && ++ !readmem(PTOB(mfn), PHYSADDR, machdep->ptbl, PAGESIZE(), ++ "xen kdump page table page", RETURN_ON_ERROR)) ++ error(FATAL, "cannot read/find page table page\n"); ++ machdep->last_ptbl_read = mfn; ++ ++ ptep = ((ulong *)machdep->ptbl) + pte_index(kvaddr); ++ mfn = ((*ptep) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); ++ ++ return mfn; ++} ++ +#include "xendump.h" + +/* @@ -10509,7 +13354,7 @@ + * kernel's complete phys_to_machine_mapping[max_pfn] array. + */ +static int -+x86_64_xendump_ptm_create(struct xendump_data *xd) ++x86_64_xendump_p2m_create(struct xendump_data *xd) +{ + int i, idx; + ulong mfn, kvaddr, ctrlreg[8], ctrlreg_offset; @@ -10555,11 +13400,12 @@ + if (CRASHDEBUG(1)) + fprintf(xd->ofp, "end_pfn: %lx\n", *up); + -+ xd->xc_core.ptm_frames = *up/(PAGESIZE()/sizeof(ulong)); ++ xd->xc_core.p2m_frames = (*up/(PAGESIZE()/sizeof(ulong))) + ++ ((*up%(PAGESIZE()/sizeof(ulong))) ? 1 : 0); + -+ if ((xd->xc_core.ptm_frame_index_list = (ulong *) -+ malloc(xd->xc_core.ptm_frames * sizeof(ulong))) == NULL) -+ error(FATAL, "cannot malloc ptm_mfn_frame_list"); ++ if ((xd->xc_core.p2m_frame_index_list = (ulong *) ++ malloc(xd->xc_core.p2m_frames * sizeof(ulong))) == NULL) ++ error(FATAL, "cannot malloc p2m_frame_list"); + + kvaddr = symbol_value("phys_to_machine_mapping"); + if (!x86_64_xendump_load_page(kvaddr, xd)) @@ -10572,10 +13418,10 @@ + kvaddr = *up; + machdep->last_ptbl_read = BADADDR; + -+ for (i = 0; i < xd->xc_core.ptm_frames; i++) { ++ for (i = 0; i < xd->xc_core.p2m_frames; i++) { + if ((idx = x86_64_xendump_page_index(kvaddr, xd)) == MFN_NOT_FOUND) + return FALSE; -+ xd->xc_core.ptm_frame_index_list[i] = idx; ++ xd->xc_core.p2m_frame_index_list[i] = idx; + kvaddr += PAGESIZE(); + } + @@ -10687,22 +13533,26 @@ + pml4 = ((ulong *)machdep->machspec->pml4) + pml4_index(kvaddr); + mfn = ((*pml4) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); + -+ if (!xc_core_mfn_to_page(mfn, machdep->pgd)) ++ if ((mfn != machdep->last_pgd_read) && ++ !xc_core_mfn_to_page(mfn, machdep->pgd)) + error(FATAL, "cannot read/find pud page\n"); ++ machdep->last_pgd_read = mfn; + + pgd = ((ulong *)machdep->pgd) + pgd_index(kvaddr); + mfn = ((*pgd) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); + -+ if (!xc_core_mfn_to_page(mfn, machdep->pmd)) ++ if ((mfn != machdep->last_pmd_read) && ++ !xc_core_mfn_to_page(mfn, machdep->pmd)) + error(FATAL, "cannot read/find pmd page\n"); + ++ machdep->last_pmd_read = mfn; ++ + pmd = ((ulong *)machdep->pmd) + pmd_index(kvaddr); + mfn = ((*pmd) & PHYSICAL_PAGE_MASK) >> PAGESHIFT(); + + if ((mfn != machdep->last_ptbl_read) && + !xc_core_mfn_to_page(mfn, machdep->ptbl)) + error(FATAL, "cannot read/find page table page\n"); -+ + machdep->last_ptbl_read = mfn; + + ptep = ((ulong *)machdep->ptbl) + pte_index(kvaddr); @@ -10848,7 +13698,7 @@ + } +} #endif /* X86_64 */ ---- crash/extensions.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/extensions.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/extensions.c 2005-11-10 09:47:46.000000000 -0500 @@ -18,9 +18,6 @@ #include "defs.h" @@ -10878,7 +13728,7 @@ unload_extension(char *lib) { struct extension_table *ext; ---- crash/va_server.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/va_server.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/va_server.c 2006-03-22 08:55:34.000000000 -0500 @@ -57,13 +57,15 @@ @@ -10897,8 +13747,8 @@ if(read_map(crash_file)) { if(va_server_init_v1(crash_file, start, end, stride)) return -1; ---- crash/symbols.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/symbols.c 2006-05-10 14:14:28.000000000 -0400 +--- crash/symbols.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/symbols.c 2006-08-03 14:43:54.000000000 -0400 @@ -1,8 +1,8 @@ /* symbols.c - core analysis suite * @@ -10910,6 +13760,15 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by +@@ -1159,7 +1159,7 @@ + mod_name); + strncpy(lm->mod_name, mod_name, MAX_MOD_NAME-1); + } +- if (CRASHDEBUG(1)) ++ if (CRASHDEBUG(3)) + fprintf(fp, + "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld\n", + mod, lm->mod_base, lm->mod_name, nsyms, @@ -3463,6 +3463,22 @@ } @@ -11052,8 +13911,8 @@ fprintf(fp, "\n array_table:\n"); /* ---- crash/cmdline.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/cmdline.c 2005-11-18 10:49:59.000000000 -0500 +--- crash/cmdline.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/cmdline.c 2006-07-10 10:59:57.000000000 -0400 @@ -71,14 +71,17 @@ * 4. from a terminal. * 5. from a pipe, if stdin is a pipe rather than a terminal. @@ -11076,7 +13935,7 @@ if (!(pc->readline = readline(pc->prompt))) { args[0] = NULL; fprintf(fp, "\n"); -@@ -918,7 +921,7 @@ +@@ -918,13 +921,14 @@ wait_for_children(ZOMBIES_ONLY); @@ -11085,8 +13944,15 @@ pc->sigint_cnt = 0; pc->redirect = 0; pc->pipe_command[0] = NULLCHAR; ---- crash/lkcd_common.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/lkcd_common.c 2005-11-10 15:24:16.000000000 -0500 + pc->pipe_pid = 0; + pc->pipe_shell_pid = 0; + pc->sbrk = sbrk(0); ++ pc->curcmd_flags = 0; + + restore_gdb_sanity(); + +--- crash/lkcd_common.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/lkcd_common.c 2006-06-15 10:34:53.000000000 -0400 @@ -53,6 +53,8 @@ struct lkcd_environment lkcd_environment = { 0 }; @@ -11104,7 +13970,47 @@ lkcd->version = LKCD_DUMP_V8; return TRUE; -@@ -1164,40 +1167,103 @@ +@@ -667,6 +670,8 @@ + { + uint64_t zone, page; + int ii, ret; ++ int max_zones; ++ struct physmem_zone *zones; + + zone = paddr & lkcd->zone_mask; + +@@ -693,6 +698,7 @@ + lkcd->num_zones++; + } + ++retry: + /* find the zone */ + for (ii=0; ii < lkcd->num_zones; ii++) { + if (lkcd->zones[ii].start == zone) { +@@ -734,8 +740,20 @@ + ret = 1; + lkcd->num_zones++; + } else { +- lkcd_print("fixme, need to add more zones (ZONE_ALLOC)\n"); +- exit(1); ++ /* need to expand zone */ ++ max_zones = lkcd->max_zones * 2; ++ zones = malloc(max_zones * sizeof(struct physmem_zone)); ++ if (!zones) { ++ return -1; /* This should be fatal */ ++ } ++ BZERO(zones, max_zones * sizeof(struct physmem_zone)); ++ memcpy(zones, lkcd->zones, ++ lkcd->max_zones * sizeof(struct physmem_zone)); ++ free(lkcd->zones); ++ ++ lkcd->zones = zones; ++ lkcd->max_zones = max_zones; ++ goto retry; + } + } + +@@ -1164,40 +1182,103 @@ return 1; } @@ -11214,7 +14120,7 @@ } -@@ -1252,8 +1318,9 @@ +@@ -1252,8 +1333,9 @@ dp_flags = lkcd->get_dp_flags(); dp_address = lkcd->get_dp_address(); @@ -11225,7 +14131,7 @@ if ((lkcd->flags & LKCD_VALID) && (page > lkcd->total_pages)) lkcd->total_pages = page; ---- crash/lkcd_v7.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/lkcd_v7.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/lkcd_v7.c 2005-11-10 15:21:50.000000000 -0500 @@ -89,7 +89,11 @@ ifd = 0; @@ -11240,7 +14146,7 @@ dump_index_size = (lkcd->memory_pages * sizeof(off_t)); lkcd->page_offsets = 0; strcpy(dumpfile_index_name, dumpfile); ---- crash/lkcd_v8.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/lkcd_v8.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/lkcd_v8.c 2005-12-15 08:59:52.000000000 -0500 @@ -26,6 +26,7 @@ // static dump_header_asm_t dump_header_asm_v8 = { 0 }; @@ -11301,7 +14207,7 @@ set_mb_benchmark((granularity * (i+1))/lkcd->page_size); } } ---- crash/s390_dump.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/s390_dump.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/s390_dump.c 2006-05-15 17:15:56.000000000 -0400 @@ -16,7 +16,7 @@ * GNU General Public License for more details. @@ -11327,7 +14233,7 @@ } int ---- crash/lkcd_x86_trace.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/lkcd_x86_trace.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/lkcd_x86_trace.c 2006-05-15 16:28:35.000000000 -0400 @@ -47,11 +47,13 @@ static int setup_trace_rec(kaddr_t, kaddr_t, int, trace_t *); @@ -11697,8 +14603,8 @@ * Cache 2k starting from the passed-in text address. This sits on top * of the instrbuf 256-byte cache, but we don't want to extend its size * because we can run off the end of a module segment -- if this routine ---- crash/netdump.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/netdump.c 2006-02-14 14:36:21.000000000 -0500 +--- crash/netdump.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/netdump.c 2006-07-10 11:01:03.000000000 -0400 @@ -22,12 +22,12 @@ physaddr_t phys_end; }; @@ -11714,7 +14620,7 @@ uint num_pt_load_segments; struct pt_load_segment *pt_load_segments; Elf32_Ehdr *elf32; -@@ -40,11 +40,14 @@ +@@ -40,11 +40,16 @@ void *nt_prpsinfo; void *nt_taskstruct; ulong task_struct; @@ -11722,22 +14628,25 @@ ulong switch_stack; + uint num_prstatus_notes; + void *nt_prstatus_percpu[NR_CPUS]; ++ struct xen_kdump_data *xen_kdump_data; }; -static struct netdump_data netdump_data = { 0 }; -static struct netdump_data *nd = &netdump_data; +static struct vmcore_data vmcore_data = { 0 }; +static struct vmcore_data *nd = &vmcore_data; ++static struct xen_kdump_data xen_kdump_data = { 0 }; static void netdump_print(char *, ...); static void dump_Elf32_Ehdr(Elf32_Ehdr *); static void dump_Elf32_Phdr(Elf32_Phdr *, int); -@@ -52,19 +55,19 @@ +@@ -52,19 +57,20 @@ static void dump_Elf64_Ehdr(Elf64_Ehdr *); static void dump_Elf64_Phdr(Elf64_Phdr *, int); static size_t dump_Elf64_Nhdr(Elf64_Off offset, int); -static void get_netdump_regs_x86(struct bt_info *, ulong *, ulong *); -static void get_netdump_regs_x86_64(struct bt_info *, ulong *, ulong *); static void get_netdump_regs_ppc64(struct bt_info *, ulong *, ulong *); ++static physaddr_t xen_kdump_p2m(physaddr_t); #define ELFSTORE 1 #define ELFREAD 0 @@ -11756,7 +14665,7 @@ { int i; int fd; -@@ -77,6 +80,8 @@ +@@ -77,6 +83,8 @@ size_t size, len, tot; Elf32_Off offset32; Elf64_Off offset64; @@ -11765,7 +14674,7 @@ if ((fd = open(file, O_RDWR)) < 0) { if ((fd = open(file, O_RDONLY)) < 0) { -@@ -99,11 +104,24 @@ +@@ -99,11 +107,24 @@ goto bailout; } @@ -11791,7 +14700,7 @@ */ if (STRNEQ(elf32->e_ident, ELFMAG) && (elf32->e_ident[EI_CLASS] == ELFCLASS32) && -@@ -120,10 +138,16 @@ +@@ -120,10 +141,16 @@ default: goto bailout; } @@ -11809,7 +14718,7 @@ } else if (STRNEQ(elf64->e_ident, ELFMAG) && (elf64->e_ident[EI_CLASS] == ELFCLASS64) && (elf64->e_ident[EI_VERSION] == EV_CURRENT) && -@@ -153,35 +177,68 @@ +@@ -153,35 +180,68 @@ else goto bailout; @@ -11885,7 +14794,7 @@ nd->num_pt_load_segments = nd->elf32->e_phnum - 1; if ((nd->pt_load_segments = (struct pt_load_segment *) malloc(sizeof(struct pt_load_segment) * -@@ -190,9 +247,11 @@ +@@ -190,9 +250,11 @@ clean_exit(1); } nd->notes32 = (Elf32_Phdr *) @@ -11899,7 +14808,7 @@ dump_Elf32_Ehdr(nd->elf32); dump_Elf32_Phdr(nd->notes32, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -205,8 +264,9 @@ +@@ -205,8 +267,9 @@ break; case NETDUMP_ELF64: @@ -11910,7 +14819,7 @@ nd->num_pt_load_segments = nd->elf64->e_phnum - 1; if ((nd->pt_load_segments = (struct pt_load_segment *) malloc(sizeof(struct pt_load_segment) * -@@ -215,9 +275,11 @@ +@@ -215,9 +278,11 @@ clean_exit(1); } nd->notes64 = (Elf64_Phdr *) @@ -11924,7 +14833,7 @@ dump_Elf64_Ehdr(nd->elf64); dump_Elf64_Phdr(nd->notes64, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -230,6 +292,9 @@ +@@ -230,6 +295,9 @@ break; } @@ -11934,7 +14843,7 @@ return nd->header_size; bailout: -@@ -243,7 +308,7 @@ +@@ -243,7 +311,7 @@ int netdump_init(char *unused, FILE *fptr) { @@ -11943,7 +14852,7 @@ return FALSE; nd->ofp = fptr; -@@ -263,19 +328,19 @@ +@@ -263,19 +331,19 @@ /* * The Elf32_Phdr has 32-bit fields for p_paddr, p_filesz and * p_memsz, so for now, multiple PT_LOAD segment support is @@ -11969,7 +14878,7 @@ if (nd->num_pt_load_segments == 1) { offset = (off_t)paddr + (off_t)nd->header_size; break; -@@ -302,24 +367,57 @@ +@@ -302,24 +370,57 @@ if (read(nd->ndfd, bufptr, cnt) != cnt) return READ_ERROR; @@ -12031,7 +14940,7 @@ return cnt; } -@@ -330,7 +428,7 @@ +@@ -330,7 +431,7 @@ FILE * set_netdump_fp(FILE *fp) { @@ -12040,7 +14949,7 @@ return NULL; nd->ofp = fp; -@@ -346,7 +444,7 @@ +@@ -346,7 +447,7 @@ char buf[BUFSIZE]; va_list ap; @@ -12049,7 +14958,7 @@ return; va_start(ap, fmt); -@@ -362,33 +460,21 @@ +@@ -362,33 +463,21 @@ uint netdump_page_size(void) { @@ -12087,7 +14996,7 @@ } /* -@@ -414,21 +500,57 @@ +@@ -414,21 +503,57 @@ #ifdef DAEMON return nd->task_struct; #else @@ -12153,7 +15062,7 @@ len = sizeof(Elf32_Nhdr); len = roundup(len + note32->n_namesz, 4); len = roundup(len + note32->n_descsz, 4); -@@ -437,14 +559,15 @@ +@@ -437,14 +562,15 @@ - SIZE(user_regs_struct) - sizeof(int); ebp = ULONG(user_regs + OFFSET(user_regs_struct_ebp)); esp = ULONG(user_regs + OFFSET(user_regs_struct_esp)); @@ -12172,7 +15081,7 @@ "get_netdump_panic_task: esp: %lx -> task: %lx\n", esp, task); for (i = 0; task && (i < NR_CPUS); i++) { -@@ -455,7 +578,7 @@ +@@ -455,7 +581,7 @@ if (IS_KVADDR(ebp)) { task = stkptr_to_task(ebp); if (CRASHDEBUG(1)) @@ -12181,7 +15090,7 @@ "get_netdump_panic_task: ebp: %lx -> task: %lx\n", ebp, task); for (i = 0; task && (i < NR_CPUS); i++) { -@@ -464,25 +587,37 @@ +@@ -464,25 +590,37 @@ } } } else if (nd->elf64) { @@ -12225,7 +15134,7 @@ "get_netdump_panic_task: esp: %lx -> task: %lx\n", esp, task); for (i = 0; task && (i < NR_CPUS); i++) { -@@ -493,8 +628,10 @@ +@@ -493,8 +631,10 @@ } } @@ -12237,7 +15146,7 @@ return NO_TASK; #endif -@@ -512,7 +649,7 @@ +@@ -512,7 +652,7 @@ return nd->switch_stack; return 0; #else @@ -12246,7 +15155,7 @@ return 0; if (nd->task_struct == task) -@@ -525,30 +662,36 @@ +@@ -525,32 +665,40 @@ int netdump_memory_dump(FILE *fp) { @@ -12285,8 +15194,12 @@ + netdump_print("%sKDUMP_ELF64", others++ ? "|" : ""); if (nd->flags & PARTIAL_DUMP) netdump_print("%sPARTIAL_DUMP", others++ ? "|" : ""); ++ if (nd->flags & KDUMP_XEN_HV) ++ netdump_print("%sKDUMP_XEN_HV", others++ ? "|" : ""); netdump_print(")\n"); -@@ -566,7 +709,7 @@ + netdump_print(" ndfd: %d\n", nd->ndfd); + netdump_print(" ofp: %lx\n", nd->ofp); +@@ -566,7 +714,7 @@ netdump_print(" phys_end: %llx\n", pls->phys_end); } @@ -12295,13 +15208,49 @@ netdump_print(" elf32: %lx\n", nd->elf32); netdump_print(" notes32: %lx\n", nd->notes32); netdump_print(" load32: %lx\n", nd->load32); -@@ -577,11 +720,28 @@ +@@ -577,11 +725,64 @@ netdump_print(" nt_prpsinfo: %lx\n", nd->nt_prpsinfo); netdump_print(" nt_taskstruct: %lx\n", nd->nt_taskstruct); netdump_print(" task_struct: %lx\n", nd->task_struct); - netdump_print(" switch_stack: %lx\n\n", nd->switch_stack); + netdump_print(" page_size: %d\n", nd->page_size); + netdump_print(" switch_stack: %lx\n", nd->switch_stack); ++ netdump_print(" xen_kdump_data: %s\n", ++ nd->flags & KDUMP_XEN_HV ? " " : "(unused)"); ++ if (nd->flags & KDUMP_XEN_HV) { ++ netdump_print(" flags: %lx (", nd->xen_kdump_data->flags); ++ others = 0; ++ if (nd->xen_kdump_data->flags & KDUMP_P2M_INIT) ++ netdump_print("%sKDUMP_P2M_INIT", others++ ? "|" : ""); ++ if (nd->xen_kdump_data->flags & KDUMP_CR3) ++ netdump_print("%sKDUMP_CR3", others++ ? "|" : ""); ++ if (nd->xen_kdump_data->flags & KDUMP_MFN_LIST) ++ netdump_print("%sKDUMP_MFN_LIST", others++ ? "|" : ""); ++ netdump_print(")\n"); ++ netdump_print(" p2m_mfn: %lx\n", ++ nd->xen_kdump_data->p2m_mfn); ++ netdump_print(" cr3: %lx\n", ++ nd->xen_kdump_data->cr3); ++ netdump_print(" last_mfn_read: %lx\n", ++ nd->xen_kdump_data->last_mfn_read); ++ netdump_print(" page: %lx\n", ++ nd->xen_kdump_data->page); ++ netdump_print(" accesses: %lx\n", ++ nd->xen_kdump_data->accesses); ++ netdump_print(" cache_hits: %lx ", ++ nd->xen_kdump_data->cache_hits); ++ if (nd->xen_kdump_data->accesses) ++ netdump_print("(%ld%%)", ++ nd->xen_kdump_data->cache_hits * 100 / nd->xen_kdump_data->accesses); ++ netdump_print("\n p2m_frames: %d\n", ++ nd->xen_kdump_data->p2m_frames); ++ netdump_print(" p2m_mfn_frame_list: %lx\n", ++ nd->xen_kdump_data->p2m_mfn_frame_list); ++ for (i = 0; i < nd->xen_kdump_data->p2m_frames; i++) ++ netdump_print("%lx ", ++ nd->xen_kdump_data->p2m_mfn_frame_list[i]); ++ if (i) netdump_print("\n"); ++ } + netdump_print(" num_prstatus_notes: %d\n", nd->num_prstatus_notes); + netdump_print(" nt_prstatus_percpu: "); + wrap = sizeof(void *) == SIZEOF_32BIT ? 8 : 4; @@ -12326,7 +15275,7 @@ dump_Elf32_Ehdr(nd->elf32); dump_Elf32_Phdr(nd->notes32, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -594,6 +754,7 @@ +@@ -594,6 +795,7 @@ break; case NETDUMP_ELF64: @@ -12334,7 +15283,7 @@ dump_Elf64_Ehdr(nd->elf64); dump_Elf64_Phdr(nd->notes64, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -865,6 +1026,9 @@ +@@ -865,6 +1067,9 @@ netdump_print(" e_machine: %d ", elf->e_machine); switch (elf->e_machine) { @@ -12344,7 +15293,7 @@ case EM_IA_64: netdump_print("(EM_IA_64)\n"); break; -@@ -1061,7 +1225,7 @@ +@@ -1061,7 +1266,7 @@ */ static size_t @@ -12353,7 +15302,7 @@ { int i, lf; Elf32_Nhdr *note; -@@ -1085,17 +1249,26 @@ +@@ -1085,17 +1290,26 @@ { case NT_PRSTATUS: netdump_print("(NT_PRSTATUS)\n"); @@ -12384,7 +15333,7 @@ nd->nt_taskstruct = (void *)note; nd->task_struct = *((ulong *)(ptr + note->n_namesz)); nd->switch_stack = *((ulong *) -@@ -1105,14 +1278,36 @@ +@@ -1105,14 +1319,59 @@ case NT_DISKDUMP: netdump_print("(NT_DISKDUMP)\n"); uptr = (ulong *)(ptr + note->n_namesz); @@ -12409,20 +15358,53 @@ + } + break; +#endif ++ case NT_XEN_KDUMP_CR3: ++ netdump_print("(NT_XEN_KDUMP_CR3)\n"); ++ if (store) { ++ nd->flags |= KDUMP_XEN_HV; ++ nd->xen_kdump_data = &xen_kdump_data; ++ nd->xen_kdump_data->last_mfn_read = BADVAL; ++ nd->xen_kdump_data->flags |= KDUMP_CR3; ++ /* ++ * Use the first cr3 found. ++ */ ++ if (!nd->xen_kdump_data->cr3) { ++ uptr = (ulong *)(ptr + note->n_namesz); ++ uptr = (ulong *)roundup((ulong)uptr, 4); ++ nd->xen_kdump_data->cr3 = *uptr; ++ } ++ } ++ break; ++ default: netdump_print("(?)\n"); } uptr = (ulong *)(ptr + note->n_namesz); ++ + /* + * kdumps are off-by-1, because their n_namesz is 5 for "CORE". + */ + if ((nd->flags & KDUMP_ELF32) && (note->n_namesz == 5)) + uptr = (ulong *)(ptr + ((note->n_namesz + 3) & ~3)); ++ ++ if (note->n_type == NT_XEN_KDUMP_CR3) ++ uptr = (ulong *)roundup((ulong)uptr, 4); ++ for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) { if (((i%4)==0)) { netdump_print("%s ", -@@ -1135,7 +1330,7 @@ +@@ -1123,7 +1382,8 @@ + netdump_print("%08lx ", *uptr++); + } + if (!lf || (note->n_type == NT_TASKSTRUCT) || +- (note->n_type == NT_DISKDUMP)) ++ (note->n_type == NT_DISKDUMP) || ++ (note->n_type == NT_XEN_KDUMP_CR3)) + netdump_print("\n"); + + len = sizeof(Elf32_Nhdr); +@@ -1135,7 +1395,7 @@ static size_t @@ -12431,7 +15413,15 @@ { int i, lf; Elf64_Nhdr *note; -@@ -1160,17 +1355,26 @@ +@@ -1144,6 +1404,7 @@ + char *ptr; + ulonglong *uptr; + int *iptr; ++ ulong *up; + + note = (Elf64_Nhdr *)((char *)nd->elf64 + offset); + +@@ -1160,17 +1421,26 @@ { case NT_PRSTATUS: netdump_print("(NT_PRSTATUS)\n"); @@ -12462,7 +15452,7 @@ nd->nt_taskstruct = (void *)note; nd->task_struct = *((ulong *)(ptr + note->n_namesz)); nd->switch_stack = *((ulong *) -@@ -1180,16 +1384,49 @@ +@@ -1180,16 +1450,72 @@ case NT_DISKDUMP: netdump_print("(NT_DISKDUMP)\n"); iptr = (int *)(ptr + note->n_namesz); @@ -12500,20 +15490,43 @@ + } + break; +#endif ++ case NT_XEN_KDUMP_CR3: ++ netdump_print("(NT_XEN_KDUMP_CR3)\n"); ++ if (store) { ++ nd->flags |= KDUMP_XEN_HV; ++ nd->xen_kdump_data = &xen_kdump_data; ++ nd->xen_kdump_data->last_mfn_read = BADVAL; ++ nd->xen_kdump_data->flags |= KDUMP_CR3; ++ /* ++ * Use the first cr3 found. ++ */ ++ if (!nd->xen_kdump_data->cr3) { ++ up = (ulong *)(ptr + note->n_namesz); ++ up = (ulong *)roundup((ulong)up, 4); ++ nd->xen_kdump_data->cr3 = *up; ++ } ++ } ++ break; ++ default: netdump_print("(?)\n"); } uptr = (ulonglong *)(ptr + note->n_namesz); ++ + /* + * kdumps are off-by-1, because their n_namesz is 5 for "CORE". + */ + if ((nd->flags & KDUMP_ELF64) && (note->n_namesz == 5)) + uptr = (ulonglong *)(ptr + ((note->n_namesz + 3) & ~3)); ++ ++ if (note->n_type == NT_XEN_KDUMP_CR3) ++ uptr = (ulonglong *)roundup((ulong)uptr, 4); ++ for (i = lf = 0; i < note->n_descsz/sizeof(ulonglong); i++) { if (((i%2)==0)) { netdump_print("%s ", -@@ -1251,12 +1488,12 @@ +@@ -1251,12 +1577,12 @@ default: error(FATAL, @@ -12528,7 +15541,7 @@ get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp) { Elf64_Nhdr *note; -@@ -1267,8 +1504,13 @@ +@@ -1267,8 +1593,13 @@ if (is_task_active(bt->task)) bt->flags |= BT_DUMPFILE_SEARCH; @@ -12544,7 +15557,7 @@ len = sizeof(Elf64_Nhdr); len = roundup(len + note->n_namesz, 4); -@@ -1295,7 +1537,7 @@ +@@ -1295,7 +1626,7 @@ * the raw stack for some reasonable hooks. */ @@ -12553,7 +15566,7 @@ get_netdump_regs_x86(struct bt_info *bt, ulong *eip, ulong *esp) { int i, search, panic; -@@ -1320,6 +1562,7 @@ +@@ -1320,6 +1651,7 @@ if (STREQ(sym, "netconsole_netdump") || STREQ(sym, "netpoll_start_netdump") || STREQ(sym, "start_disk_dump") || @@ -12561,7 +15574,7 @@ STREQ(sym, "disk_dump")) { *eip = *up; *esp = search ? -@@ -1354,7 +1597,7 @@ +@@ -1354,7 +1686,7 @@ next_sysrq: *eip = *up; *esp = bt->stackbase + ((char *)(up+4) - bt->stackbuf); @@ -12570,7 +15583,7 @@ for (i++, up++; i < LONGS_PER_STACK; i++, up++) { sym = closest_symbol(*up); if (STREQ(sym, "sysrq_handle_crash")) -@@ -1371,7 +1614,15 @@ +@@ -1371,7 +1703,15 @@ *esp = search ? bt->stackbase + ((char *)(up+1) - bt->stackbuf) : *(up-1); @@ -12587,7 +15600,7 @@ return; } -@@ -1418,7 +1669,7 @@ +@@ -1418,7 +1758,7 @@ goto retry; } @@ -12596,7 +15609,7 @@ machdep->get_stack_frame(bt, eip, esp); } -@@ -1429,8 +1680,18 @@ +@@ -1429,8 +1769,18 @@ Elf64_Nhdr *note; size_t len; @@ -12617,7 +15630,7 @@ len = sizeof(Elf64_Nhdr); len = roundup(len + note->n_namesz, 4); -@@ -1446,3 +1707,78 @@ +@@ -1446,3 +1796,147 @@ { return (nd->flags & PARTIAL_DUMP ? TRUE : FALSE); } @@ -12650,6 +15663,28 @@ +int +read_kdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr) +{ ++ if ((nd->flags & KDUMP_XEN_HV)) { ++ if (!(nd->xen_kdump_data->flags & KDUMP_P2M_INIT)) { ++ if (!machdep->xen_kdump_p2m_create) ++ error(FATAL, ++ "xen kdump dumpfiles not supported on this architecture\n"); ++ ++ if ((nd->xen_kdump_data->page = ++ (char *)malloc(PAGESIZE())) == NULL) ++ error(FATAL, ++ "cannot malloc xen kdump data page\n"); ++ ++ if (!machdep->xen_kdump_p2m_create(nd->xen_kdump_data)) ++ error(FATAL, ++ "cannot create xen kdump pfn-to-mfn mapping\n"); ++ ++ nd->xen_kdump_data->flags |= KDUMP_P2M_INIT; ++ } ++ ++ if ((paddr = xen_kdump_p2m(paddr)) == P2M_FAILURE) ++ return READ_ERROR; ++ } ++ + return read_netdump(fd, bufptr, cnt, addr, paddr); +} + @@ -12696,7 +15731,54 @@ +{ + return netdump_memory_dump(fp); +} ---- crash/diskdump.c.orig 2006-05-15 17:21:18.000000000 -0400 ++ ++/* ++ * Translate a xen domain's pseudo-physical address into the ++ * xen machine address. Since there's no compression involved, ++ * just the last phys_to_machine_mapping[] page read is cached, ++ * which essentially caches 1024 p2m translations. ++ */ ++static physaddr_t ++xen_kdump_p2m(physaddr_t pseudo) ++{ ++ ulong pfn, mfn_frame; ++ ulong *mfnptr; ++ ulong mfn_idx, frame_idx; ++ physaddr_t paddr; ++ struct xen_kdump_data *xkd = nd->xen_kdump_data; ++ ++ if (pc->curcmd_flags & XEN_MACHINE_ADDR) ++ return pseudo; ++ ++ xkd->accesses++; ++ ++ pfn = (ulong)BTOP(pseudo); ++ mfn_idx = pfn / (PAGESIZE()/sizeof(ulong)); ++ frame_idx = pfn % (PAGESIZE()/sizeof(ulong)); ++ mfn_frame = xkd->p2m_mfn_frame_list[mfn_idx]; ++ ++ if (mfn_frame == xkd->last_mfn_read) ++ xkd->cache_hits++; ++ else if (read_netdump(0, xkd->page, PAGESIZE(), 0, ++ (physaddr_t)PTOB(mfn_frame)) != PAGESIZE()) ++ return P2M_FAILURE; ++ ++ xkd->last_mfn_read = mfn_frame; ++ ++ mfnptr = ((ulong *)(xkd->page)) + frame_idx; ++ paddr = (physaddr_t)PTOB((ulonglong)(*mfnptr)); ++ paddr |= PAGEOFFSET(pseudo); ++ ++ if (CRASHDEBUG(7)) ++ fprintf(fp, ++ "xen_dump_p2m(%llx): mfn_idx: %ld frame_idx: %ld" ++ " mfn_frame: %lx mfn: %lx => %llx\n", ++ (ulonglong)pseudo, mfn_idx, frame_idx, ++ mfn_frame, *mfnptr, (ulonglong)paddr); ++ ++ return paddr; ++} +--- crash/diskdump.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/diskdump.c 2006-03-23 14:29:25.000000000 -0500 @@ -1,16 +1,16 @@ /* @@ -13220,9 +16302,9 @@ } /* ---- crash/xendump.c.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/xendump.c 2006-04-26 16:17:27.000000000 -0400 -@@ -0,0 +1,1167 @@ +--- crash/xendump.c.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/xendump.c 2006-07-11 09:36:03.000000000 -0400 +@@ -0,0 +1,1170 @@ +/* + * xendump.c + * @@ -13253,7 +16335,7 @@ + +static void xen_dump_vmconfig(FILE *); + -+static void xc_core_ptm_create(void); ++static void xc_core_p2m_create(void); +static ulong xc_core_pfn_to_page_index(ulong); + +/* @@ -13352,8 +16434,8 @@ + off_t offset; + int redundant; + -+ if (!(xd->flags & XC_CORE_PTM_INIT)) -+ xc_core_ptm_create(); ++ if (!(xd->flags & XC_CORE_P2M_INIT)) ++ xc_core_p2m_create(); + + pfn = (ulong)BTOP(paddr); + @@ -13698,7 +16780,7 @@ + return SEEK_ERROR; + if (read(xd->xfd, xd->page, xd->page_size) != xd->page_size) + return READ_ERROR; -+ } else ++ } else if (CRASHDEBUG(1)) + console("READ %ld (0x%lx) skipped!\n", reqpfn, reqpfn); + + BCOPY(xd->page + PAGEOFFSET(paddr), bufptr, cnt); @@ -13876,6 +16958,9 @@ +int +read_xendump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr) +{ ++ if (pc->curcmd_flags & XEN_MACHINE_ADDR) ++ return READ_ERROR; ++ + switch (xd->flags & (XC_SAVE|XC_CORE)) + { + case XC_SAVE: @@ -13938,8 +17023,8 @@ + fprintf(fp, "%sXC_SAVE", others++ ? "|" : ""); + if (xd->flags & XC_CORE) + fprintf(fp, "%sXC_CORE", others++ ? "|" : ""); -+ if (xd->flags & XC_CORE_PTM_INIT) -+ fprintf(fp, "%sXC_CORE_PTM_INIT", others++ ? "|" : ""); ++ if (xd->flags & XC_CORE_P2M_INIT) ++ fprintf(fp, "%sXC_CORE_P2M_INIT", others++ ? "|" : ""); + fprintf(fp, ")\n"); + fprintf(fp, " xfd: %d\n", xd->xfd); + fprintf(fp, " page_size: %d\n", xd->page_size); @@ -14045,14 +17130,14 @@ + xd->xc_core.header.xch_pages_offset, + xd->xc_core.header.xch_pages_offset); + -+ fprintf(fp, " ptm_frames: %d\n", -+ xd->xc_core.ptm_frames); -+ fprintf(fp, " ptm_frame_index_list:\n"); -+ for (i = 0; i < xd->xc_core.ptm_frames; i++) { ++ fprintf(fp, " p2m_frames: %d\n", ++ xd->xc_core.p2m_frames); ++ fprintf(fp, " p2m_frame_index_list:\n"); ++ for (i = 0; i < xd->xc_core.p2m_frames; i++) { + fprintf(fp, "%ld ", -+ xd->xc_core.ptm_frame_index_list[i]); ++ xd->xc_core.p2m_frame_index_list[i]); + } -+ fprintf(fp, xd->xc_core.ptm_frames ? "\n\n" : "\n"); ++ fprintf(fp, xd->xc_core.p2m_frames ? "\n\n" : "\n"); + + return 0; +} @@ -14165,17 +17250,17 @@ + * Farm out most of the work to the proper architecture. + */ +static void -+xc_core_ptm_create(void) ++xc_core_p2m_create(void) +{ -+ if (!machdep->xendump_ptm_create) ++ if (!machdep->xendump_p2m_create) + error(FATAL, + "xen xc_core dumpfiles not supported on this architecture"); + -+ if (!machdep->xendump_ptm_create((void *)xd)) ++ if (!machdep->xendump_p2m_create((void *)xd)) + error(FATAL, + "cannot create xen pfn-to-mfn mapping\n"); + -+ xd->flags |= XC_CORE_PTM_INIT; ++ xd->flags |= XC_CORE_P2M_INIT; + + if (CRASHDEBUG(1)) + xendump_memory_dump(xd->ofp); @@ -14306,19 +17391,19 @@ +static ulong +xc_core_pfn_to_page_index(ulong pfn) +{ -+ ulong idx, ptm_idx, mfn_idx; ++ ulong idx, p2m_idx, mfn_idx; + ulong *up, mfn; + off_t offset; + + idx = pfn/PFNS_PER_PAGE; + -+ if (idx >= xd->xc_core.ptm_frames) { ++ if (idx >= xd->xc_core.p2m_frames) { + error(INFO, "pfn: %lx is too large for dumpfile\n", + pfn); + return PFN_NOT_FOUND; + } + -+ ptm_idx = xd->xc_core.ptm_frame_index_list[idx]; ++ p2m_idx = xd->xc_core.p2m_frame_index_list[idx]; + + if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_pages_offset, + SEEK_SET) == -1) { @@ -14326,7 +17411,7 @@ + return PFN_NOT_FOUND; + } + -+ offset = (off_t)(ptm_idx) * (off_t)xd->page_size; ++ offset = (off_t)(p2m_idx) * (off_t)xd->page_size; + + if (lseek(xd->xfd, offset, SEEK_CUR) == -1) { + error(INFO, "cannot lseek to pfn-specified page\n"); @@ -14390,7 +17475,7 @@ + } + } +} ---- crash/unwind.c.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/unwind.c.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/unwind.c 2005-11-23 09:37:52.000000000 -0500 @@ -1397,9 +1397,22 @@ req = &request; @@ -14418,8 +17503,8 @@ machdep->machspec->unw_tables_offset = req->member_offset/BITS_PER_BYTE; ---- crash/defs.h.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/defs.h 2006-05-01 11:49:13.000000000 -0400 +--- crash/defs.h.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/defs.h 2006-08-03 17:25:55.000000000 -0400 @@ -1,8 +1,8 @@ /* defs.h - core analysis suite * @@ -14431,8 +17516,12 @@ * Copyright (C) 2002 Silicon Graphics, Inc. * * This program is free software; you can redistribute it and/or modify -@@ -59,7 +59,7 @@ - #define NR_CPUS (32) +@@ -56,10 +56,10 @@ + #define FALSE (0) + + #ifdef X86 +-#define NR_CPUS (32) ++#define NR_CPUS (256) #endif #ifdef X86_64 -#define NR_CPUS (32) @@ -14440,7 +17529,24 @@ #endif #ifdef ALPHA #define NR_CPUS (64) -@@ -106,6 +106,8 @@ +@@ -68,7 +68,7 @@ + #define NR_CPUS (32) + #endif + #ifdef IA64 +-#define NR_CPUS (512) ++#define NR_CPUS (1024) + #endif + #ifdef PPC64 + #define NR_CPUS (128) +@@ -98,6 +98,7 @@ + #define LASTCHAR(s) (s[strlen(s)-1]) + #define FIRSTCHAR(s) (s[0]) + #define QUOTED_STRING(s) ((FIRSTCHAR(s) == '"') && (LASTCHAR(s) == '"')) ++#define PATHEQ(A, B) ((A) && (B) && (pathcmp((char *)(A), (char *)(B)) == 0)) + + #ifdef roundup + #undef roundup +@@ -106,6 +107,8 @@ typedef uint64_t physaddr_t; @@ -14449,7 +17555,7 @@ typedef unsigned long long int ulonglong; struct number_option { ulong num; -@@ -155,8 +157,8 @@ +@@ -155,8 +158,8 @@ #define UNLINK_MODULES (0x1000000000ULL) #define S390D (0x2000000000ULL) #define REM_S390D (0x4000000000ULL) @@ -14460,7 +17566,7 @@ #define NETDUMP (0x20000000000ULL) #define REM_NETDUMP (0x40000000000ULL) #define SYSMAP (0x80000000000ULL) -@@ -169,11 +171,13 @@ +@@ -169,11 +172,13 @@ #define VERSION_QUERY (0x4000000000000ULL) #define READNOW (0x8000000000000ULL) #define NOCRASHRC (0x10000000000000ULL) @@ -14476,7 +17582,7 @@ #define REMOTE() (pc->flags & REMOTE_DAEMON) #define REMOTE_ACTIVE() (pc->flags & REM_LIVE_SYSTEM) #define REMOTE_DUMPFILE() \ -@@ -182,17 +186,29 @@ +@@ -182,17 +187,30 @@ #define LKCD_DUMPFILE() (pc->flags & (LKCD|REM_LKCD)) #define NETDUMP_DUMPFILE() (pc->flags & (NETDUMP|REM_NETDUMP)) #define DISKDUMP_DUMPFILE() (pc->flags & DISKDUMP) @@ -14494,6 +17600,7 @@ +#define KDUMP_ELF32 (0x20) +#define KDUMP_ELF64 (0x40) +#define KDUMP_LOCAL (0x80) ++#define KDUMP_XEN_HV (0x100) + +#define DUMPFILE_FORMAT(flags) ((flags) & \ + (NETDUMP_ELF32|NETDUMP_ELF64|KDUMP_ELF32|KDUMP_ELF64)) @@ -14507,27 +17614,52 @@ #define CRASHDEBUG(x) (pc->debug >= (x)) #define CRASHDEBUG_SUSPEND(X) { pc->debug_save = pc->debug; pc->debug = X; } -@@ -407,9 +423,19 @@ +@@ -328,6 +346,8 @@ + char *lastcmd; /* previously-executed command */ + ulong cmdgencur; /* current command generation number */ + ulong cmdgenspec; /* specified command generation num */ ++ ulong curcmd_flags; /* general purpose per-command flag */ ++#define XEN_MACHINE_ADDR (0x1) + int cur_gdb_cmd; /* current gdb command */ + int last_gdb_cmd; /* previously-executed gdb command */ + int sigint_cnt; /* number of ignored SIGINTs */ +@@ -407,9 +427,23 @@ #define KALLSYMS_V2 (0x2000) #define TVEC_BASES_V2 (0x4000) #define GCC_3_3_3 (0x8000) +#define USE_OLD_BT (0x10000) +#define ARCH_XEN (0x20000) ++#define NO_IKCONFIG (0x40000) #define GCC_VERSION_DEPRECATED (GCC_3_2|GCC_3_2_3|GCC_2_96|GCC_3_3_2|GCC_3_3_3) +#define XEN() (kt->flags & ARCH_XEN) + -+#define XEN_MACHINE_TO_MFN(m) ((ulong)(m) >> PAGESHIFT()) -+#define XEN_PFN_TO_PSEUDO(p) ((ulong)(p) << PAGESHIFT()) -+#define XEN_PFNS_PER_PAGE (PAGESIZE()/sizeof(ulong)) -+#define XEN_MFN_NOT_FOUND (~0UL) -+#define XEN_FOREIGN_FRAME (1UL << (BITS()-1)) ++#define XEN_MACHINE_TO_MFN(m) ((ulonglong)(m) >> PAGESHIFT()) ++#define XEN_PFN_TO_PSEUDO(p) ((ulonglong)(p) << PAGESHIFT()) ++ ++#define XEN_MFN_NOT_FOUND (~0UL) ++#define XEN_PFNS_PER_PAGE (PAGESIZE()/sizeof(ulong)) ++#define XEN_FOREIGN_FRAME (1UL << (BITS()-1)) ++ ++#define XEN_MACHADDR_NOT_FOUND (~0ULL) + struct kernel_table { /* kernel data */ ulong flags; ulong stext; -@@ -433,8 +459,28 @@ +@@ -420,6 +454,7 @@ + ulong init_end; + ulong end; + int cpus; ++ char *cpus_override; + void (*display_bh)(void); + ulong module_list; + ulong kernel_module; +@@ -430,11 +465,32 @@ + uint kernel_version[3]; + uint gcc_version[3]; + int runq_siblings; ++ int kernel_NR_CPUS; long __rq_idx[NR_CPUS]; long __cpu_idx[NR_CPUS]; long __per_cpu_offset[NR_CPUS]; @@ -14539,47 +17671,59 @@ +#define SHADOW_PAGE_TABLES (0x2) +#define CANONICAL_PAGE_TABLES (0x4) +#define XEN_SUSPEND (0x8) -+ char *machine_to_pseudo; ++ char *m2p_page; + ulong phys_to_machine_mapping; -+ ulong ptm_table_size; -+#define PTM_MAPPING_CACHE (512) -+ struct ptm_mapping_cache { ++ ulong p2m_table_size; ++#define P2M_MAPPING_CACHE (512) ++ struct p2m_mapping_cache { + ulong mapping; + ulong mfn; -+ } ptm_mapping_cache[PTM_MAPPING_CACHE]; -+#define PTM_MAPPING_TO_PAGE_INDEX(c) \ -+ (((kt->ptm_mapping_cache[c].mapping - kt->phys_to_machine_mapping)/PAGESIZE()) \ ++ } p2m_mapping_cache[P2M_MAPPING_CACHE]; ++#define P2M_MAPPING_TO_PAGE_INDEX(c) \ ++ (((kt->p2m_mapping_cache[c].mapping - kt->phys_to_machine_mapping)/PAGESIZE()) \ + * XEN_PFNS_PER_PAGE) + ulong last_mapping_read; -+ ulong ptm_cache_index; -+ ulong ptm_pages_searched; -+ ulong ptm_cache_hits; ++ ulong p2m_cache_index; ++ ulong p2m_pages_searched; ++ ulong p2m_cache_hits; }; /* -@@ -602,6 +648,7 @@ +@@ -602,6 +658,8 @@ (void *)(&bt->stackbuf[(ulong)STACK_OFFSET_TYPE(OFF)]), (size_t)(SZ)) struct machine_specific; /* uniquely defined below each machine's area */ +struct xendump_data; ++struct xen_kdump_data; struct machdep_table { ulong flags; -@@ -653,6 +700,13 @@ +@@ -645,14 +703,24 @@ + char **file; + } *line_number_hooks; + ulong last_pgd_read; ++ ulong last_pud_read; + ulong last_pmd_read; + ulong last_ptbl_read; + char *pgd; ++ char *pud; + char *pmd; + char *ptbl; int ptrs_per_pgd; char *cmdline_arg; struct machine_specific *machspec; + ulong section_size_bits; + ulong max_physmem_bits; + ulong sections_per_root; -+ int (*xendump_ptm_create)(struct xendump_data *); ++ int (*xendump_p2m_create)(struct xendump_data *); + ulong (*xendump_panic_task)(struct xendump_data *); + void (*get_xendump_regs)(struct xendump_data *, struct bt_info *, ulong *, ulong *); + void (*clear_machdep_cache)(void); ++ int (*xen_kdump_p2m_create)(struct xen_kdump_data *); }; /* -@@ -660,13 +714,11 @@ +@@ -660,19 +728,23 @@ * as defined in their processor-specific files below. (see KSYMS_START defs). */ #define HWRESET (0x80000000) @@ -14595,10 +17739,36 @@ +#define MACHDEP_BT_TEXT (0x10000000) +#define DEVMEMRD (0x8000000) +#define INIT (0x4000000) ++#define VM_4_LEVEL (0x2000000) extern struct machdep_table *machdep; -@@ -737,6 +789,7 @@ ++#ifndef HZ ++#define HZ sysconf(_SC_CLK_TCK) ++#endif ++ + #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 IS_LAST_PUD_READ(pud) ((ulong)(pud) == machdep->last_pud_read) + + #define FILL_PGD(PGD, TYPE, SIZE) \ + if (!IS_LAST_PGD_READ(PGD)) { \ +@@ -681,6 +753,13 @@ + machdep->last_pgd_read = (ulong)(PGD); \ + } + ++#define FILL_PUD(PUD, TYPE, SIZE) \ ++ if (!IS_LAST_PUD_READ(PUD)) { \ ++ readmem((ulonglong)((ulong)(PUD)), TYPE, machdep->pud, \ ++ SIZE, "pud page", FAULT_ON_ERROR); \ ++ machdep->last_pud_read = (ulong)(PUD); \ ++ } ++ + #define FILL_PMD(PMD, TYPE, SIZE) \ + if (!IS_LAST_PMD_READ(PMD)) { \ + readmem((ulonglong)(PMD), TYPE, machdep->pmd, \ +@@ -737,6 +816,7 @@ #define FOREACH_c_FLAG (0x40000) #define FOREACH_f_FLAG (0x80000) #define FOREACH_o_FLAG (0x100000) @@ -14606,7 +17776,7 @@ struct foreach_data { ulong flags; -@@ -875,6 +928,7 @@ +@@ -875,6 +955,7 @@ long mm_struct_mmap; long mm_struct_pgd; long mm_struct_rss; @@ -14614,7 +17784,7 @@ long mm_struct_total_vm; long mm_struct_start_code; long vm_area_struct_vm_mm; -@@ -970,6 +1024,11 @@ +@@ -970,6 +1051,11 @@ long hw_interrupt_type_set_affinity; long irq_cpustat_t___softirq_active; long irq_cpustat_t___softirq_mask; @@ -14626,7 +17796,7 @@ long files_struct_max_fds; long files_struct_max_fdset; long files_struct_open_fds; -@@ -1088,6 +1147,8 @@ +@@ -1088,6 +1174,8 @@ long inet_opt_dport; long inet_opt_sport; long inet_opt_num; @@ -14635,7 +17805,7 @@ long timer_list_list; long timer_list_next; long timer_list_entry; -@@ -1123,6 +1184,7 @@ +@@ -1123,6 +1211,7 @@ long zone_struct_name; long zone_struct_size; long zone_struct_memsize; @@ -14643,7 +17813,7 @@ long zone_struct_zone_start_paddr; long zone_struct_zone_start_mapnr; long zone_struct_zone_mem_map; -@@ -1210,7 +1272,14 @@ +@@ -1210,7 +1299,14 @@ long x8664_pda_irqstackptr; long x8664_pda_level4_pgt; long x8664_pda_cpunumber; @@ -14658,7 +17828,7 @@ }; struct size_table { /* stash of commonly-used sizes */ -@@ -1239,6 +1308,7 @@ +@@ -1239,6 +1335,7 @@ long umode_t; long dentry; long files_struct; @@ -14666,7 +17836,7 @@ long fs_struct; long file; long inode; -@@ -1292,15 +1362,19 @@ +@@ -1292,15 +1389,19 @@ long address_space; long char_device_struct; long inet_sock; @@ -14686,7 +17856,7 @@ }; struct array_table { -@@ -1389,6 +1463,7 @@ +@@ -1389,6 +1490,7 @@ #define ULONGLONG(ADDR) *((ulonglong *)((char *)(ADDR))) #define ULONG_PTR(ADDR) *((ulong **)((char *)(ADDR))) #define USHORT(ADDR) *((ushort *)((char *)(ADDR))) @@ -14694,7 +17864,7 @@ #define VOID_PTR(ADDR) *((void **)((char *)(ADDR))) struct node_table { -@@ -1420,6 +1495,7 @@ +@@ -1420,6 +1522,7 @@ ulong kmem_max_limit; ulong kmem_max_cpus; ulong kmem_cache_count; @@ -14702,7 +17872,7 @@ ulong PG_reserved; ulong PG_slab; int kmem_cache_namelen; -@@ -1441,17 +1517,29 @@ +@@ -1441,17 +1544,29 @@ ulong cached_vma_hits[VMA_CACHE]; int vma_cache_index; ulong vma_cache_fills; @@ -14741,7 +17911,15 @@ #define COMMON_VADDR_SPACE() (vt->flags & COMMON_VADDR) #define PADDR_PRLEN (vt->paddr_prlen) -@@ -1680,6 +1768,33 @@ +@@ -1659,6 +1774,7 @@ + #define KVADDR (0x1) + #define UVADDR (0x2) + #define PHYSADDR (0x4) ++#define XENMACHADDR (0x8) + #define AMBIGUOUS (~0) + + #define USE_USER_PGD (UVADDR << 2) +@@ -1680,6 +1796,33 @@ #define VIRTPAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) #define PHYSPAGEBASE(X) (((physaddr_t)(X)) & (physaddr_t)machdep->pagemask) @@ -14775,7 +17953,18 @@ /* * Machine specific stuff */ -@@ -1724,22 +1839,51 @@ +@@ -1689,8 +1832,8 @@ + #define MACHINE_TYPE "X86" + #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) + #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +-#define IS_VMALLOC_ADDR(X) ((ulong)(X) >= vt->vmalloc_start) +-#define KVBASE_MASK (0x1fffff) ++#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) ++#define KVBASE_MASK (0x7fffff) + + #define PGDIR_SHIFT_2LEVEL (22) + #define PTRS_PER_PTE_2LEVEL (1024) +@@ -1724,22 +1867,68 @@ #define TIF_SIGPENDING (2) @@ -14786,6 +17975,23 @@ +// !CONFIG_X86_PAE +#define _SECTION_SIZE_BITS 26 +#define _MAX_PHYSMEM_BITS 32 ++ ++#define IS_LAST_PMD_READ_PAE(pmd) ((ulong)(pmd) == machdep->machspec->last_pmd_read_PAE) ++#define IS_LAST_PTBL_READ_PAE(ptbl) ((ulong)(ptbl) == machdep->machspec->last_ptbl_read_PAE) ++ ++#define FILL_PMD_PAE(PMD, TYPE, SIZE) \ ++ if (!IS_LAST_PMD_READ_PAE(PMD)) { \ ++ readmem((ulonglong)(PMD), TYPE, machdep->pmd, \ ++ SIZE, "pmd page", FAULT_ON_ERROR); \ ++ machdep->machspec->last_pmd_read_PAE = (ulonglong)(PMD); \ ++ } ++ ++#define FILL_PTBL_PAE(PTBL, TYPE, SIZE) \ ++ if (!IS_LAST_PTBL_READ_PAE(PTBL)) { \ ++ readmem((ulonglong)(PTBL), TYPE, machdep->ptbl, \ ++ SIZE, "page table", FAULT_ON_ERROR); \ ++ machdep->machspec->last_ptbl_read_PAE = (ulonglong)(PTBL); \ ++ } + #endif /* X86 */ @@ -14834,7 +18040,7 @@ #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) x86_64_VTOP((ulong)(X)) #define IS_VMALLOC_ADDR(X) x86_64_IS_VMALLOC_ADDR((ulong)(X)) -@@ -1757,12 +1901,25 @@ +@@ -1757,12 +1946,25 @@ #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) @@ -14861,7 +18067,7 @@ /* * PHYSICAL_PAGE_MASK changed (enlarged) between 2.4 and 2.6, so * for safety, use the 2.6 values to generate it. -@@ -1796,6 +1953,15 @@ +@@ -1796,6 +1998,15 @@ #define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) @@ -14877,7 +18083,7 @@ #define CPU_PDA_READ(CPU, BUFFER) \ (STRNEQ("cpu_pda", closest_symbol((symbol_value("cpu_pda") + \ ((CPU) * SIZE(x8664_pda))))) && \ -@@ -1806,6 +1972,9 @@ +@@ -1806,6 +2017,9 @@ #define VALID_LEVEL4_PGT_ADDR(X) \ (((X) == VIRTPAGEBASE(X)) && IS_KVADDR(X) && !IS_VMALLOC_ADDR(X)) @@ -14887,7 +18093,25 @@ #endif /* X86_64 */ #ifdef ALPHA -@@ -1884,6 +2053,9 @@ +@@ -1816,7 +2030,7 @@ + + #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) + #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +-#define IS_VMALLOC_ADDR(X) ((ulong)(X) >= vt->vmalloc_start) ++#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) + #define KSEG_BASE_48_BIT (0xffff800000000000) + #define KSEG_BASE (0xfffffc0000000000) + #define _PFN_MASK (0xFFFFFFFF00000000) +@@ -1861,7 +2075,7 @@ + + #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) + #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +-#define IS_VMALLOC_ADDR(X) ((ulong)(X) >= vt->vmalloc_start) ++#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) + + #define PGDIR_SHIFT (22) + #define PTRS_PER_PTE (1024) +@@ -1884,6 +2098,9 @@ #define TIF_SIGPENDING (2) @@ -14897,7 +18121,88 @@ #endif /* PPC */ #ifdef IA64 -@@ -2067,6 +2239,32 @@ +@@ -1917,16 +2134,57 @@ + + #define SWITCH_STACK_ADDR(X) (ia64_get_switch_stack((ulong)(X))) + +-#define PGDIR_SHIFT (PAGESHIFT() + 2*(PAGESHIFT()-3)) +-#define PMD_SHIFT (PAGESHIFT() + (PAGESHIFT()-3)) +-#define PTRS_PER_PGD (((ulong)(1)) << (PAGESHIFT()-3)) +-#define PTRS_PER_PMD (((ulong)(1)) << (PAGESHIFT()-3)) +-#define PTRS_PER_PTE (((ulong)(1)) << (PAGESHIFT()-3)) +-#define PTRS_PER_PAGE (((ulong)(1)) << (PAGESHIFT()-3)) + #define __IA64_UL(x) ((unsigned long)(x)) + #define IA64_MAX_PHYS_BITS (50) /* max # of phys address bits (architected) */ + + /* ++ * How many pointers will a page table level hold expressed in shift ++ */ ++#define PTRS_PER_PTD_SHIFT (PAGESHIFT()-3) ++ ++/* ++ * Definitions for fourth level: ++ */ ++#define PTRS_PER_PTE (__IA64_UL(1) << (PTRS_PER_PTD_SHIFT)) ++ ++/* ++ * Definitions for third level: ++ * ++ * PMD_SHIFT determines the size of the area a third-level page table ++ * can map. ++ */ ++#define PMD_SHIFT (PAGESHIFT() + (PTRS_PER_PTD_SHIFT)) ++#define PMD_SIZE (1UL << PMD_SHIFT) ++#define PMD_MASK (~(PMD_SIZE-1)) ++#define PTRS_PER_PMD (1UL << (PTRS_PER_PTD_SHIFT)) ++ ++/* ++ * PUD_SHIFT determines the size of the area a second-level page table ++ * can map ++ */ ++#define PUD_SHIFT (PMD_SHIFT + (PTRS_PER_PTD_SHIFT)) ++#define PUD_SIZE (1UL << PUD_SHIFT) ++#define PUD_MASK (~(PUD_SIZE-1)) ++#define PTRS_PER_PUD (1UL << (PTRS_PER_PTD_SHIFT)) ++ ++/* ++ * Definitions for first level: ++ * ++ * PGDIR_SHIFT determines what a first-level page table entry can map. ++ */ ++ ++#define PGDIR_SHIFT_4L (PUD_SHIFT + (PTRS_PER_PTD_SHIFT)) ++#define PGDIR_SHIFT_3L (PMD_SHIFT + (PTRS_PER_PTD_SHIFT)) ++/* Turns out 4L & 3L PGDIR_SHIFT are the same (for now) */ ++#define PGDIR_SHIFT PGDIR_SHIFT_4L ++#define PGDIR_SIZE (__IA64_UL(1) << PGDIR_SHIFT) ++#define PGDIR_MASK (~(PGDIR_SIZE-1)) ++#define PTRS_PER_PGD_SHIFT PTRS_PER_PTD_SHIFT ++#define PTRS_PER_PGD (1UL << PTRS_PER_PGD_SHIFT) ++#define USER_PTRS_PER_PGD (5*PTRS_PER_PGD/8) /* regions 0-4 are user regions */ ++#define FIRST_USER_ADDRESS 0 ++ ++/* + * First, define the various bits in a PTE. Note that the PTE format + * matches the VHPT short format, the firt doubleword of the VHPD long + * format, and the first doubleword of the TLB insertion format. +@@ -1978,6 +2236,7 @@ + #define __DIRTY_BITS _PAGE_ED | __DIRTY_BITS_NO_ED + + #define EFI_PAGE_SHIFT (12) ++ + /* + * NOTE: #include'ing creates too many compiler problems, so + * this stuff is hardwired here; it's probably etched in stone somewhere. +@@ -2042,7 +2301,7 @@ + + #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) + #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +-#define IS_VMALLOC_ADDR(X) ((ulong)(X) >= vt->vmalloc_start) ++#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) + #define KERNELBASE machdep->pageoffset + + #define PGDIR_SHIFT (machdep->pageshift + (machdep->pageshift -3) + (machdep->pageshift - 2)) +@@ -2067,6 +2326,32 @@ #define PGD_OFFSET(vaddr) ((vaddr >> PGDIR_SHIFT) & 0x7ff) #define PMD_OFFSET(vaddr) ((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) @@ -14930,7 +18235,7 @@ #define _PAGE_PRESENT 0x001UL /* software: pte contains a translation */ #define _PAGE_USER 0x002UL /* matches one of the PP bits */ #define _PAGE_RW 0x004UL /* software: user write access allowed */ -@@ -2087,6 +2285,9 @@ +@@ -2087,6 +2372,9 @@ #define STACK_FRAME_OVERHEAD 112 #define EXCP_FRAME_MARKER 0x7265677368657265 @@ -14940,16 +18245,26 @@ #endif /* PPC64 */ #ifdef S390 -@@ -2685,6 +2886,8 @@ +@@ -2116,7 +2404,7 @@ + + #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) + #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +-#define IS_VMALLOC_ADDR(X) ((ulong)(X) >= vt->vmalloc_start) ++#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) + #define PTRS_PER_PTE 512 + #define PTRS_PER_PMD 1024 + #define PTRS_PER_PGD 2048 +@@ -2685,6 +2973,9 @@ int machine_type(char *); void command_not_supported(void); void option_not_supported(int); +void please_wait(char *); +void please_wait_done(void); ++int pathcmp(char *, char *); /* -@@ -2721,6 +2924,7 @@ +@@ -2721,6 +3012,7 @@ struct syment *next_symbol(char *, struct syment *); struct syment *prev_symbol(char *, struct syment *); void get_symbol_data(char *, long, void *); @@ -14957,7 +18272,7 @@ char *value_to_symstr(ulong, char *, ulong); char *value_symbol(ulong); ulong symbol_value(char *); -@@ -2807,6 +3011,7 @@ +@@ -2807,6 +3099,7 @@ char *swap_location(ulonglong, char *); void clear_swap_info_cache(void); uint memory_page_size(void); @@ -14965,7 +18280,15 @@ ulong first_vmalloc_address(void); int l1_cache_size(void); int dumpfile_memory(int); -@@ -3005,6 +3210,8 @@ +@@ -2838,6 +3131,7 @@ + void open_files_dump(ulong, int, struct reference *); + void get_pathname(ulong, char *, int, int, ulong); + ulong file_to_dentry(ulong); ++ulong file_to_vfsmnt(ulong); + void nlm_files_dump(void); + int get_proc_version(void); + int file_checksum(char *, long *); +@@ -3005,6 +3299,8 @@ */ void register_extension(struct command_table_entry *); void dump_extension_table(int); @@ -14974,7 +18297,7 @@ /* * kernel.c -@@ -3020,7 +3227,8 @@ +@@ -3020,7 +3316,8 @@ void generic_dump_irq(int); int generic_dis_filter(ulong, char *); void display_sys_stats(void); @@ -14984,7 +18307,7 @@ void dump_bt_info(struct bt_info *); void dump_log(int); void set_cpu(int); -@@ -3069,6 +3277,8 @@ +@@ -3069,6 +3366,8 @@ #define BT_DUMPFILE_SEARCH (0x800000000ULL) #define BT_EFRAME_SEARCH2 (0x1000000000ULL) #define BT_START (0x2000000000ULL) @@ -14993,16 +18316,34 @@ #define BT_REF_HEXVAL (0x1) #define BT_REF_SYMBOL (0x2) -@@ -3101,6 +3311,8 @@ +@@ -3101,6 +3400,17 @@ #define TYPE_S390D (REMOTE_VERBOSE << 6) #define TYPE_NETDUMP (REMOTE_VERBOSE << 7) -+ulong xen_machine_to_pseudo(ulong); ++ulonglong xen_m2p(ulonglong); ++ ++void read_in_kernel_config(int); ++ ++#define IKCFG_INIT (0) ++#define IKCFG_READ (1) ++ ++#define MAGIC_START "IKCFG_ST" ++#define MAGIC_END "IKCFG_ED" ++#define MAGIC_SIZE (sizeof(MAGIC_START) - 1) + /* * dev.c */ -@@ -3194,7 +3406,16 @@ +@@ -3140,6 +3450,8 @@ + ulong entry_tramp_start; + ulong entry_tramp_end; + physaddr_t entry_tramp_start_phys; ++ ulonglong last_pmd_read_PAE; ++ ulonglong last_ptbl_read_PAE; + }; + + struct syment *x86_is_entry_tramp_address(ulong, ulong *); +@@ -3194,7 +3506,16 @@ #define NMI_STACK 2 /* ebase[] offset to NMI exception stack */ struct machine_specific { @@ -15019,7 +18360,7 @@ char *irqstack; struct x86_64_pt_regs_offsets pto; struct x86_64_stkinfo stkinfo; -@@ -3202,6 +3423,11 @@ +@@ -3202,6 +3523,11 @@ #define KSYMS_START (0x1) #define PT_REGS_INIT (0x2) @@ -15031,7 +18372,7 @@ #define _2MB_PAGE_MASK (~((MEGABYTES(2))-1)) #endif -@@ -3240,13 +3466,43 @@ +@@ -3240,13 +3566,42 @@ ulong hwintrstack[NR_CPUS]; char *hwstackbuf; uint hwstacksize; @@ -15072,11 +18413,10 @@ error(FATAL, "-d option is not applicable to PowerPC architecture\n") #define KSYMS_START (0x1) +#define VM_ORIG (0x2) -+#define VM_4_LEVEL (0x4) #endif /* -@@ -3396,10 +3652,23 @@ +@@ -3396,10 +3751,23 @@ int netdump_init(char *, FILE *); ulong get_netdump_panic_task(void); ulong get_netdump_switch_stack(ulong); @@ -15101,7 +18441,7 @@ /* * diskdump.c -@@ -3418,6 +3687,23 @@ +@@ -3418,6 +3786,23 @@ void get_diskdump_regs(struct bt_info *, ulong *, ulong *); /* @@ -15125,7 +18465,7 @@ * net.c */ void net_init(void); -@@ -3560,6 +3846,7 @@ +@@ -3560,6 +3945,7 @@ #define LKCD_DUMP_V7 (0x7) /* DUMP_VERSION_NUMBER */ #define LKCD_DUMP_V8 (0x8) /* DUMP_VERSION_NUMBER */ #define LKCD_DUMP_V9 (0x9) /* DUMP_VERSION_NUMBER */ @@ -15133,7 +18473,7 @@ #define LKCD_DUMP_VERSION_NUMBER_MASK (0xf) #define LKCD_DUMP_RAW (0x1) /* DUMP_[DH_]RAW */ ---- crash/vas_crash.h.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/vas_crash.h.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/vas_crash.h 2006-05-15 16:50:28.000000000 -0400 @@ -19,7 +19,7 @@ */ @@ -15144,9 +18484,9 @@ void save_core(void); ---- crash/netdump.h.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/netdump.h 2005-11-04 17:37:53.000000000 -0500 -@@ -24,3 +24,14 @@ +--- crash/netdump.h.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/netdump.h 2006-06-28 14:16:16.000000000 -0400 +@@ -24,3 +24,37 @@ #define NT_TASKSTRUCT 4 #define NT_DISKDUMP 0x70000001 @@ -15161,7 +18501,30 @@ +#endif + +#endif /* NOTDEF */ ---- crash/diskdump.h.orig 2006-05-15 17:21:18.000000000 -0400 ++ ++/* ++ * Proposed ELF note for Xen (writable pagetable) per-vcpu CR3. ++ */ ++#define NT_XEN_KDUMP_CR3 0x10000001 ++ ++struct xen_kdump_data { ++ ulong flags; ++ ulong cr3; ++ ulong p2m_mfn; ++ char *page; ++ ulong last_mfn_read; ++ ulong cache_hits; ++ ulong accesses; ++ int p2m_frames; ++ ulong *p2m_mfn_frame_list; ++}; ++ ++#define KDUMP_P2M_INIT (0x1) ++#define KDUMP_CR3 (0x2) ++#define KDUMP_MFN_LIST (0x4) ++ ++#define P2M_FAILURE ((physaddr_t)(0xffffffffffffffffLL)) +--- crash/diskdump.h.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/diskdump.h 2005-11-30 15:15:00.000000000 -0500 @@ -3,6 +3,8 @@ * @@ -15234,8 +18597,8 @@ +#define PAGE_VALID (0x1) /* flags */ +#define DISKDUMP_VALID_PAGE(flags) ((flags) & PAGE_VALID) + ---- crash/xendump.h.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/xendump.h 2006-04-26 15:58:59.000000000 -0400 +--- crash/xendump.h.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/xendump.h 2006-06-09 11:26:09.000000000 -0400 @@ -0,0 +1,97 @@ +/* + * xendump.h @@ -15289,8 +18652,8 @@ + struct pfn_offset_cache *poc; + + struct xc_core_data { -+ int ptm_frames; -+ ulong *ptm_frame_index_list; ++ int p2m_frames; ++ ulong *p2m_frame_index_list; + struct xc_core_header header; + } xc_core; + @@ -15314,7 +18677,7 @@ + +#define XC_SAVE (XENDUMP_LOCAL << 1) +#define XC_CORE (XENDUMP_LOCAL << 2) -+#define XC_CORE_PTM_INIT (XENDUMP_LOCAL << 3) ++#define XC_CORE_P2M_INIT (XENDUMP_LOCAL << 3) + +#define MACHINE_BYTE_ORDER() \ + (machine_type("X86") || \ @@ -15334,7 +18697,7 @@ + +#define MFN_NOT_FOUND (-1) +#define PFN_NOT_FOUND (-1) ---- crash/lkcd_dump_v5.h.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/lkcd_dump_v5.h.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/lkcd_dump_v5.h 2006-03-22 08:45:35.000000000 -0500 @@ -35,7 +35,7 @@ #ifndef _DUMP_H @@ -15345,7 +18708,7 @@ /* define TRUE and FALSE for use in our dump modules */ #ifndef FALSE ---- crash/lkcd_dump_v7.h.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/lkcd_dump_v7.h.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/lkcd_dump_v7.h 2006-03-22 08:45:57.000000000 -0500 @@ -35,7 +35,7 @@ #ifndef _DUMP_H @@ -15356,8 +18719,8 @@ /* define TRUE and FALSE for use in our dump modules */ #ifndef FALSE ---- crash/Makefile.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/Makefile 2006-05-15 17:21:18.000000000 -0400 +--- crash/Makefile.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/Makefile 2006-08-07 11:31:15.000000000 -0400 @@ -3,8 +3,8 @@ # Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. # www.missioncriticallinux.com, info@missioncriticallinux.com @@ -15533,7 +18896,7 @@ + +do_extensions: + @(cd extensions; make -i OBJECTS="$(EXTENSION_OBJECT_FILES)" TARGET=$(TARGET)) ---- crash/gdb-6.1.patch.orig 2006-05-15 17:21:18.000000000 -0400 +--- crash/gdb-6.1.patch.orig 2006-08-07 11:31:15.000000000 -0400 +++ crash/gdb-6.1.patch 2006-01-03 13:36:25.000000000 -0500 @@ -0,0 +1,11 @@ +--- gdb-6.1/bfd/coff-alpha.c.orig @@ -15547,14 +18910,14 @@ + } + + if (lita_sec_data->gp != 0) ---- crash/README.orig 2006-05-15 17:21:18.000000000 -0400 -+++ crash/README 2006-05-15 17:21:16.000000000 -0400 +--- crash/README.orig 2006-08-07 11:31:15.000000000 -0400 ++++ crash/README 2006-08-07 11:31:12.000000000 -0400 @@ -69,7 +69,7 @@ After the kernel is re-compiled, the uncompressed "vmlinux" kernel that is created in the top-level kernel build directory must be saved. - To build this utility, simply uncompress the tar file, enter the crash-4.0 -+ To build this utility, simply uncompress the tar file, enter the crash-4.0-2.26 ++ To build this utility, simply uncompress the tar file, enter the crash-4.0-3.1 subdirectory, and type "make". The initial build will take several minutes because the gdb module must be configured and and built. Alternatively, the crash source RPM file may be installed and built, and the resultant crash @@ -15566,7 +18929,7 @@ - Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - Copyright (C) 2004, 2005 IBM Corporation - Copyright (C) 1999-2005 Hewlett-Packard Co -+ crash 4.0-2.26 ++ crash 4.0-3.1 + Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006 IBM Corporation + Copyright (C) 1999-2006 Hewlett-Packard Co @@ -15580,7 +18943,7 @@ DUMPFILE: /dev/mem CPUS: 1 - DATE: Wed Jul 13 13:26:00 2005 -+ DATE: Mon May 15 17:21:15 2006 ++ DATE: Mon Aug 7 11:31:12 2006 UPTIME: 10 days, 22:55:18 LOAD AVERAGE: 0.08, 0.03, 0.01 TASKS: 42 @@ -15589,7 +18952,7 @@ extend mach repeat timer - crash version: 4.0 gdb version: 6.1 -+ crash version: 4.0-2.26 gdb version: 6.1 ++ crash version: 4.0-3.1 gdb version: 6.1 For help on any command above, enter "help ". For help on input options, enter "help input". For help on output options, enter "help output". @@ -15601,7 +18964,7 @@ - Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - Copyright (C) 2004, 2005 IBM Corporation - Copyright (C) 1999-2005 Hewlett-Packard Co -+ crash 4.0-2.26 ++ crash 4.0-3.1 + Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006 IBM Corporation + Copyright (C) 1999-2006 Hewlett-Packard Co @@ -15618,7 +18981,7 @@ - Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - Copyright (C) 2004, 2005 IBM Corporation - Copyright (C) 1999-2005 Hewlett-Packard Co -+ crash 4.0-2.26 ++ crash 4.0-3.1 + Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006 IBM Corporation + Copyright (C) 1999-2006 Hewlett-Packard Co diff --git a/crash.spec b/crash.spec index b416aeb..ea87e0f 100644 --- a/crash.spec +++ b/crash.spec @@ -4,13 +4,13 @@ Summary: crash utility for live systems; netdump, diskdump, LKCD or mcore dumpfiles Name: crash Version: 4.0 -Release: 3 +Release: 3.1 License: GPL Group: Development/Debuggers Source: %{name}-%{version}.tar.gz URL: http://people.redhat.com/anderson ExclusiveOS: Linux -ExclusiveArch: i386 ia64 x86_64 ppc64 +ExclusiveArch: i386 ia64 x86_64 ppc64 s390 s390x Buildroot: %{_tmppath}/%{name}-root BuildRequires: ncurses-devel zlib-devel Patch0: crash.patch @@ -18,7 +18,7 @@ Patch0: crash.patch %description The core analysis suite is a self-contained tool that can be used to investigate either live systems, kernel core dumps created from the -netdump and diskdump packages from Red Hat Linux, the mcore kernel patch +netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch offered by Mission Critical Linux, or the LKCD kernel patch. %prep @@ -45,6 +45,11 @@ rm -rf %{buildroot} %doc README %changelog +* Mon Aug 7 2006 Dave Anderson - 4.0-3.1 +- Updated crash.patch to match upstream version 4.0-3.1. +- Added kdump reference to description. +- Added s390 and s390x to ExclusiveArch list. BZ #199125 + * Fri Jul 14 2006 Jesse Keating - 4.0-3 - rebuild