unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr) { unsigned long phys_base; unsigned long long paddr; /* * Check the relocatable kernel. */ if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL) phys_base = info->phys_base; else phys_base = 0; if (is_vmalloc_addr(vaddr)) { if ((paddr = vtop4_x86_64(vaddr)) == NOT_PADDR) { ERRMSG("Can't convert a virtual address(%lx) to " \ "physical address.\n", vaddr); return NOT_PADDR; } } else if (vaddr >= __START_KERNEL_map) { paddr = vaddr - __START_KERNEL_map + phys_base; } else { if (is_xen_memory()) paddr = vaddr - PAGE_OFFSET_XEN_DOM0; else paddr = vaddr - PAGE_OFFSET; } return paddr; }
int get_machdep_info_x86_64(void) { int i, j, mfns[MAX_X86_64_FRAMES]; unsigned long frame_mfn[MAX_X86_64_FRAMES]; unsigned long buf[MFNS_PER_FRAME]; info->section_size_bits = _SECTION_SIZE_BITS; if (!is_xen_memory()) return TRUE; /* * Get the information for translating domain-0's physical * address into machine address. */ if (!readmem(MADDR_XEN, pfn_to_paddr(get_xen_p2m_mfn()), &frame_mfn, PAGESIZE())) { ERRMSG("Can't get p2m_mfn.\n"); return FALSE; } /* * Count the number of p2m frame. */ for (i = 0; i < MAX_X86_64_FRAMES; i++) { mfns[i] = 0; if (!frame_mfn[i]) break; if (!readmem(MADDR_XEN, pfn_to_paddr(frame_mfn[i]), &buf, PAGESIZE())) { ERRMSG("Can't get frame_mfn[%d].\n", i); return FALSE; } for (j = 0; j < MFNS_PER_FRAME; j++) { if (!buf[j]) break; mfns[i]++; } info->p2m_frames += mfns[i]; } info->p2m_mfn_frame_list = malloc(sizeof(unsigned long) * info->p2m_frames); if (info->p2m_mfn_frame_list == NULL) { ERRMSG("Can't allocate memory for p2m_mfn_frame_list. %s\n", strerror(errno)); return FALSE; } /* * Get p2m_mfn_frame_list. */ for (i = 0; i < MAX_X86_64_FRAMES; i++) { if (!frame_mfn[i]) break; if (!readmem(MADDR_XEN, pfn_to_paddr(frame_mfn[i]), &info->p2m_mfn_frame_list[i * MFNS_PER_FRAME], mfns[i] * sizeof(unsigned long))) { ERRMSG("Can't get p2m_mfn_frame_list.\n"); return FALSE; } if (mfns[i] != MFNS_PER_FRAME) break; } return TRUE; }
static int get_pt_note_info(void) { int n_type, size_name, size_desc; off_t offset, offset_desc; char buf[VMCOREINFO_XEN_NOTE_NAME_BYTES]; char note[MAX_SIZE_NHDR]; nr_cpus = 0; offset = offset_pt_note_memory; while (offset < offset_pt_note_memory + size_pt_note_memory) { if (lseek(fd_memory, offset, SEEK_SET) < 0) { ERRMSG("Can't seek the dump memory(%s). %s\n", name_memory, strerror(errno)); return FALSE; } if (read(fd_memory, note, sizeof(note)) != sizeof(note)) { ERRMSG("Can't read the dump memory(%s). %s\n", name_memory, strerror(errno)); return FALSE; } n_type = note_type(note); size_name = note_namesz(note); size_desc = note_descsz(note); offset_desc = offset + offset_note_desc(note); if (!size_name || size_name >= sizeof(buf)) goto next_note; if (read(fd_memory, &buf, sizeof(buf)) != sizeof(buf)) { ERRMSG("Can't read the dump memory(%s). %s\n", name_memory, strerror(errno)); return FALSE; } if (!strncmp(KEXEC_CORE_NOTE_NAME, buf, KEXEC_CORE_NOTE_NAME_BYTES)) { if (n_type == NT_PRSTATUS) { nr_cpus++; } } else if (!strncmp(VMCOREINFO_NOTE_NAME, buf, VMCOREINFO_NOTE_NAME_BYTES)) { if (n_type == 0) { set_vmcoreinfo(offset_desc, size_desc); } /* * Check whether /proc/vmcore contains vmcoreinfo, * and get both the offset and the size. */ } else if (!strncmp(VMCOREINFO_XEN_NOTE_NAME, buf, VMCOREINFO_XEN_NOTE_NAME_BYTES)) { if (n_type == 0) { offset_vmcoreinfo_xen = offset_desc; size_vmcoreinfo_xen = size_desc; } /* * Check whether /proc/vmcore contains xen's note. */ } else if (!strncmp("Xen", buf, 4)) { if (n_type == XEN_ELFNOTE_CRASH_INFO) { flags_memory |= MEMORY_XEN; offset_xen_crash_info = offset_desc; size_xen_crash_info = size_desc; } /* * Check whether a source dumpfile contains eraseinfo. * /proc/vmcore does not contain eraseinfo, because eraseinfo * is added only by makedumpfile and makedumpfile does not * create /proc/vmcore. */ } else if (!strncmp(ERASEINFO_NOTE_NAME, buf, ERASEINFO_NOTE_NAME_BYTES)) { if (n_type == 0) { set_eraseinfo(offset_desc, size_desc); } } next_note: offset += offset_next_note(note); } if (is_xen_memory()) DEBUG_MSG("Xen kdump\n"); else DEBUG_MSG("Linux kdump\n"); return TRUE; }