Index: defs.h =================================================================== RCS file: /cvsroot/xen_ia64/people/xencrash/src/crash/defs.h,v retrieving revision 1.9 retrieving revision 1.9.4.2 diff -u -r1.9 -r1.9.4.2 --- defs.h 28 Apr 2007 02:19:07 -0000 1.9 +++ defs.h 14 May 2007 02:46:25 -0000 1.9.4.2 @@ -3809,6 +3809,7 @@ error(FATAL, "-d option TBD on ia64 architecture\n"); int ia64_in_init_stack(ulong addr); int ia64_in_mca_stack_hyper(ulong addr, struct bt_info *bt); +physaddr_t ia64_xen_kdump_p2m(struct xen_kdump_data *xkd, physaddr_t pseudo); #define OLD_UNWIND (0x1) /* CONFIG_IA64_NEW_UNWIND not turned on */ #define NEW_UNWIND (0x2) /* CONFIG_IA64_NEW_UNWIND turned on */ @@ -3941,6 +3942,7 @@ int kdump_memory_dump(FILE *); void get_kdump_regs(struct bt_info *, ulong *, ulong *); void xen_kdump_p2m_mfn(char *); +int is_sadump_xen(void); /* * diskdump.c Index: ia64.c =================================================================== RCS file: /cvsroot/xen_ia64/people/xencrash/src/crash/ia64.c,v retrieving revision 1.5 retrieving revision 1.5.4.2 diff -u -r1.5 -r1.5.4.2 --- ia64.c 28 Apr 2007 02:19:07 -0000 1.5 +++ ia64.c 14 May 2007 02:46:25 -0000 1.5.4.2 @@ -3855,7 +3855,83 @@ * 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. */ +static int +ia64_xen_kdump_p2m_create(struct xen_kdump_data *xkd) +{ + /* + * Temporarily read physical (machine) addresses from vmcore by + * going directly to read_netdump() instead of via read_kdump(). + */ + pc->readmem = read_netdump; + + if (CRASHDEBUG(1)) + fprintf(fp, "ia64_xen_kdump_p2m_create: p2m_mfn: %lx\n", xkd->p2m_mfn); + + if ((xkd->p2m_mfn_frame_list = (ulong *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc p2m_frame_list"); + + if (!readmem(PTOB(xkd->p2m_mfn), PHYSADDR, xkd->p2m_mfn_frame_list, PAGESIZE(), + "xen kdump p2m mfn page", RETURN_ON_ERROR)) + error(FATAL, "cannot read xen kdump p2m mfn page\n"); + + pc->readmem = read_kdump; + + return TRUE; +} + +physaddr_t +ia64_xen_kdump_p2m(struct xen_kdump_data *xkd, physaddr_t pseudo) +{ + ulong pgd_idx, pte_idx; + ulong pmd, pte; + physaddr_t paddr; + + /* + * Temporarily read physical (machine) addresses from vmcore by + * going directly to read_netdump() instead of via read_kdump(). + */ + pc->readmem = read_netdump; + + xkd->accesses++; + + pgd_idx = (pseudo >> PGDIR_SHIFT_3L) & (PTRS_PER_PGD - 1); + pmd = xkd->p2m_mfn_frame_list[pgd_idx] & _PFN_MASK; + if (!pmd) { + paddr = P2M_FAILURE; + goto out; + } + + pmd += ((pseudo >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) * sizeof(ulong); + readmem(pmd, PHYSADDR, &pte, sizeof(ulong), + "ia64_xen_kdump_p2m pmd", FAULT_ON_ERROR); + pte = pte & _PFN_MASK; + if (!pte) { + paddr = P2M_FAILURE; + goto out; + } + + if (pte != xkd->last_mfn_read) { + readmem(pte, PHYSADDR, xkd->page, PAGESIZE(), + "ia64_xen_kdump_p2m pte page", FAULT_ON_ERROR); + xkd->last_mfn_read = pte; + } else { + xkd->cache_hits++; + } + + pte_idx = (pseudo >> PAGESHIFT()) & (PTRS_PER_PTE - 1); + paddr = *(((ulong *)xkd->page) + pte_idx); + if (!(paddr & _PAGE_P)) { + paddr = P2M_FAILURE; + goto out; + } + paddr = (paddr & _PFN_MASK) | PAGEOFFSET(pseudo); + +out: + pc->readmem = read_kdump; + return paddr; +} +#if 0 static int ia64_xen_kdump_p2m_create(struct xen_kdump_data *xkd) { @@ -3868,6 +3944,7 @@ return FALSE; } +#endif static char * ia64_xen_kdump_load_page(ulong kvaddr, char *pgbuf) Index: main.c =================================================================== RCS file: /cvsroot/xen_ia64/people/xencrash/src/crash/main.c,v retrieving revision 1.7 retrieving revision 1.7.6.2 diff -u -r1.7 -r1.7.6.2 --- main.c 20 Apr 2007 04:40:21 -0000 1.7 +++ main.c 14 May 2007 02:46:25 -0000 1.7.6.2 @@ -302,8 +302,14 @@ } pc->flags |= NETDUMP; pc->dumpfile = argv[optind]; - pc->readmem = read_netdump; - pc->writemem = write_netdump; + + if (is_sadump_xen()) { + pc->readmem = read_kdump; + pc->writemem = write_kdump; + } else { + pc->readmem = read_netdump; + pc->writemem = write_netdump; + } } else if (is_kdump(argv[optind], KDUMP_LOCAL)) { if (pc->flags & MEMORY_SOURCES) { Index: netdump.c =================================================================== RCS file: /cvsroot/xen_ia64/people/xencrash/src/crash/netdump.c,v retrieving revision 1.5 retrieving revision 1.5.6.2 diff -u -r1.5 -r1.5.6.2 --- netdump.c 20 Apr 2007 04:40:21 -0000 1.5 +++ netdump.c 14 May 2007 02:46:25 -0000 1.5.6.2 @@ -2091,11 +2091,17 @@ if (pc->curcmd_flags & XEN_MACHINE_ADDR) return pseudo; +#ifdef IA64 + return ia64_xen_kdump_p2m(xkd, pseudo); +#endif + xkd->accesses++; pfn = (ulong)BTOP(pseudo); mfn_idx = pfn / (PAGESIZE()/sizeof(ulong)); frame_idx = pfn % (PAGESIZE()/sizeof(ulong)); + if (mfn_idx >= xkd->p2m_frames) + return P2M_FAILURE; mfn_frame = xkd->p2m_mfn_frame_list[mfn_idx]; if (mfn_frame == xkd->last_mfn_read) @@ -2149,4 +2155,24 @@ value); } else error(WARNING, "invalid p2m_mfn argument: %s\n", arg); +} + +/* + * Fujitsu dom0/HV sadump-generated dumpfile, which requires + * the --p2m_mfn command line argument. + */ +int +is_sadump_xen(void) +{ + if (xen_kdump_data.p2m_mfn) { + if (!XEN_CORE_DUMPFILE()) { + pc->flags |= XEN_CORE; + nd->xen_kdump_data = &xen_kdump_data; + nd->xen_kdump_data->last_mfn_read = BADVAL; + nd->xen_kdump_data->flags |= KDUMP_MFN_LIST; + } + return TRUE; + } + + return FALSE; }