mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Xen coredump format: ELF formatified with note section.
added PFN-GMFN table for non-auto translated physmap added PFN table for auto translated physmap. HVM domain support. IA64 support Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Use the guest's own p2m table instead of xc_get_pfn_list(), which cannot handle PFNs with no MFN. Dump a zeroed page for PFNs with no MFN. Clearly deprecate xc_get_pfn_list(). Do not include a P2M table with HVM domains. Refuse to dump HVM until we can map its pages with PFNs. Signed-off-by: John Levon <john.levon@sun.com>
This commit is contained in:
1 parent
4062095bcb
commit
e3ce7ff90f
10 files changed
+1549
-42
No files matched your search
@@ -6,6 +6,8 @@ MINOR = 0
|
||||
|
||||
CTRL_SRCS-y :=
|
||||
CTRL_SRCS-y += xc_core.c
|
||||
CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c
|
||||
CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c
|
||||
CTRL_SRCS-y += xc_domain.c
|
||||
CTRL_SRCS-y += xc_evtchn.c
|
||||
CTRL_SRCS-y += xc_misc.c
|
||||
|
||||
+699
-42
@@ -1,10 +1,62 @@
|
||||
/*
|
||||
* Elf format, (pfn, gmfn) table, IA64 support.
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
* xen dump-core file format follows ELF format specification.
|
||||
* Analisys tools shouldn't depends on the order of sections.
|
||||
* They should follow elf header and check section names.
|
||||
*
|
||||
* +--------------------------------------------------------+
|
||||
* |ELF header |
|
||||
* +--------------------------------------------------------+
|
||||
* |section headers |
|
||||
* | null section header |
|
||||
* | .shstrtab |
|
||||
* | .note.Xen |
|
||||
* | .xen_prstatus |
|
||||
* | .xen_ia64_mmapped_regs if ia64 |
|
||||
* | .xen_shared_info if present |
|
||||
* | .xen_p2m or .xen_pfn |
|
||||
* | .xen_pages |
|
||||
* +--------------------------------------------------------+
|
||||
* |.note.Xen:note section |
|
||||
* | "Xen" is used as note name, |
|
||||
* | types are defined in xen/include/public/elfnote.h |
|
||||
* | and descriptors are defined in xc_core.h. |
|
||||
* | dumpcore none |
|
||||
* | dumpcore header |
|
||||
* | dumpcore xen version |
|
||||
* | dumpcore format version |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_prstatus |
|
||||
* | vcpu_guest_context_t[nr_vcpus] |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_ia64_mmapped_regs if ia64 |
|
||||
* | mmapped_regs_t[nr_vcpus] |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_shared_info if possible |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_p2m or .xen_pfn |
|
||||
* | .xen_p2m: struct xen_dumpcore_p2m[nr_pages] |
|
||||
* | .xen_pfn: uint64_t[nr_pages] |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_pages |
|
||||
* | page * nr_pages |
|
||||
* +--------------------------------------------------------+
|
||||
* |.shstrtab: section header string table |
|
||||
* +--------------------------------------------------------+
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_core.h"
|
||||
#include "xc_dom.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* number of pages to write at a time */
|
||||
#define DUMP_INCREMENT (4 * 1024)
|
||||
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
|
||||
|
||||
static int
|
||||
copy_from_domain_page(int xc_handle,
|
||||
@@ -21,107 +73,712 @@ copy_from_domain_page(int xc_handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* string table */
|
||||
struct xc_core_strtab {
|
||||
char *strings;
|
||||
uint16_t current;
|
||||
uint16_t max;
|
||||
};
|
||||
|
||||
static struct xc_core_strtab*
|
||||
xc_core_strtab_init(void)
|
||||
{
|
||||
struct xc_core_strtab *strtab;
|
||||
char *strings;
|
||||
strtab = malloc(sizeof(strtab));
|
||||
if ( strtab == NULL )
|
||||
return NULL;
|
||||
|
||||
strings = malloc(PAGE_SIZE);
|
||||
if ( strings == NULL )
|
||||
{
|
||||
PERROR("Could not allocate string table init");
|
||||
free(strtab);
|
||||
return NULL;
|
||||
}
|
||||
strtab->strings = strings;
|
||||
strtab->max = PAGE_SIZE;
|
||||
|
||||
/* index 0 represents none */
|
||||
strtab->strings[0] = '\0';
|
||||
strtab->current = 1;
|
||||
|
||||
return strtab;
|
||||
}
|
||||
|
||||
static void
|
||||
xc_core_strtab_free(struct xc_core_strtab *strtab)
|
||||
{
|
||||
free(strtab->strings);
|
||||
free(strtab);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
xc_core_strtab_get(struct xc_core_strtab *strtab, const char *name)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
uint16_t len = strlen(name) + 1;
|
||||
|
||||
if ( strtab->current + len > strtab->max )
|
||||
{
|
||||
char *tmp;
|
||||
if ( strtab->max * 2 < strtab->max )
|
||||
{
|
||||
PERROR("too long string table");
|
||||
errno = ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
tmp = realloc(strtab->strings, strtab->max * 2);
|
||||
if ( tmp == NULL )
|
||||
{
|
||||
PERROR("Could not allocate string table");
|
||||
return ret;
|
||||
}
|
||||
|
||||
strtab->strings = tmp;
|
||||
strtab->max *= 2;
|
||||
}
|
||||
|
||||
ret = strtab->current;
|
||||
strcpy(strtab->strings + strtab->current, name);
|
||||
strtab->current += len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* section headers */
|
||||
struct xc_core_section_headers {
|
||||
uint16_t num;
|
||||
uint16_t num_max;
|
||||
|
||||
Elf_Shdr *shdrs;
|
||||
};
|
||||
#define SHDR_INIT 16
|
||||
#define SHDR_INC 4
|
||||
|
||||
static struct xc_core_section_headers*
|
||||
xc_core_shdr_init(void)
|
||||
{
|
||||
struct xc_core_section_headers *sheaders;
|
||||
sheaders = malloc(sizeof(*sheaders));
|
||||
if ( sheaders == NULL )
|
||||
return NULL;
|
||||
|
||||
sheaders->num = 0;
|
||||
sheaders->num_max = SHDR_INIT;
|
||||
sheaders->shdrs = malloc(sizeof(sheaders->shdrs[0]) * sheaders->num_max);
|
||||
if ( sheaders->shdrs == NULL )
|
||||
{
|
||||
free(sheaders);
|
||||
return NULL;
|
||||
}
|
||||
return sheaders;
|
||||
}
|
||||
|
||||
static void
|
||||
xc_core_shdr_free(struct xc_core_section_headers *sheaders)
|
||||
{
|
||||
free(sheaders->shdrs);
|
||||
free(sheaders);
|
||||
}
|
||||
|
||||
Elf_Shdr*
|
||||
xc_core_shdr_get(struct xc_core_section_headers *sheaders)
|
||||
{
|
||||
Elf_Shdr *shdr;
|
||||
|
||||
if ( sheaders->num == sheaders->num_max )
|
||||
{
|
||||
Elf_Shdr *shdrs;
|
||||
if ( sheaders->num_max + SHDR_INC < sheaders->num_max )
|
||||
{
|
||||
errno = E2BIG;
|
||||
return NULL;
|
||||
}
|
||||
sheaders->num_max += SHDR_INC;
|
||||
shdrs = realloc(sheaders->shdrs,
|
||||
sizeof(sheaders->shdrs[0]) * sheaders->num_max);
|
||||
if ( shdrs == NULL )
|
||||
return NULL;
|
||||
sheaders->shdrs = shdrs;
|
||||
}
|
||||
|
||||
shdr = &sheaders->shdrs[sheaders->num];
|
||||
sheaders->num++;
|
||||
memset(shdr, 0, sizeof(*shdr));
|
||||
return shdr;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_shdr_set(Elf_Shdr *shdr,
|
||||
struct xc_core_strtab *strtab,
|
||||
const char *name, uint32_t type,
|
||||
uint64_t offset, uint64_t size,
|
||||
uint64_t addralign, uint64_t entsize)
|
||||
{
|
||||
uint64_t name_idx = xc_core_strtab_get(strtab, name);
|
||||
if ( name_idx == 0 )
|
||||
return -1;
|
||||
|
||||
shdr->sh_name = name_idx;
|
||||
shdr->sh_type = type;
|
||||
shdr->sh_offset = offset;
|
||||
shdr->sh_size = size;
|
||||
shdr->sh_addralign = addralign;
|
||||
shdr->sh_entsize = entsize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
elfnote_fill_xen_version(int xc_handle,
|
||||
struct xen_dumpcore_elfnote_xen_version_desc
|
||||
*xen_version)
|
||||
{
|
||||
int rc;
|
||||
memset(xen_version, 0, sizeof(*xen_version));
|
||||
|
||||
rc = xc_version(xc_handle, XENVER_version, NULL);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
xen_version->major_version = rc >> 16;
|
||||
xen_version->minor_version = rc & ((1 << 16) - 1);
|
||||
|
||||
rc = xc_version(xc_handle, XENVER_extraversion,
|
||||
&xen_version->extra_version);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
rc = xc_version(xc_handle, XENVER_compile_info,
|
||||
&xen_version->compile_info);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
rc = xc_version(xc_handle,
|
||||
XENVER_capabilities, &xen_version->capabilities);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
rc = xc_version(xc_handle, XENVER_changeset, &xen_version->changeset);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
rc = xc_version(xc_handle, XENVER_platform_parameters,
|
||||
&xen_version->platform_parameters);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
rc = xc_version(xc_handle, XENVER_pagesize, NULL);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
xen_version->pagesize = rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
elfnote_fill_format_version(struct xen_dumpcore_elfnote_format_version_desc
|
||||
*format_version)
|
||||
{
|
||||
format_version->version = XEN_DUMPCORE_FORMAT_VERSION_CURRENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_domain_dumpcore_via_callback(int xc_handle,
|
||||
uint32_t domid,
|
||||
void *args,
|
||||
dumpcore_rtn_t dump_rtn)
|
||||
{
|
||||
unsigned long nr_pages;
|
||||
uint64_t *page_array = NULL;
|
||||
xc_dominfo_t info;
|
||||
int i, nr_vcpus = 0;
|
||||
shared_info_t *live_shinfo = NULL;
|
||||
|
||||
int nr_vcpus = 0;
|
||||
char *dump_mem, *dump_mem_start = NULL;
|
||||
struct xc_core_header header;
|
||||
vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
|
||||
struct xc_core_arch_context arch_ctxt;
|
||||
char dummy[PAGE_SIZE];
|
||||
int dummy_len;
|
||||
int sts;
|
||||
int sts = -1;
|
||||
|
||||
unsigned long i;
|
||||
unsigned long j;
|
||||
unsigned long nr_pages;
|
||||
|
||||
xc_core_memory_map_t *memory_map = NULL;
|
||||
unsigned int nr_memory_map;
|
||||
unsigned int map_idx;
|
||||
|
||||
int auto_translated_physmap;
|
||||
xen_pfn_t *p2m = NULL;
|
||||
unsigned long max_pfn = 0;
|
||||
struct xen_dumpcore_p2m *p2m_array = NULL;
|
||||
|
||||
uint64_t *pfn_array = NULL;
|
||||
|
||||
Elf_Ehdr ehdr;
|
||||
unsigned long filesz;
|
||||
unsigned long offset;
|
||||
unsigned long fixup;
|
||||
|
||||
struct xc_core_strtab *strtab = NULL;
|
||||
uint16_t strtab_idx;
|
||||
struct xc_core_section_headers *sheaders = NULL;
|
||||
Elf_Shdr *shdr;
|
||||
|
||||
/* elf notes */
|
||||
struct xen_elfnote elfnote;
|
||||
struct xen_dumpcore_elfnote_none_desc none;
|
||||
struct xen_dumpcore_elfnote_header_desc header;
|
||||
struct xen_dumpcore_elfnote_xen_version_desc xen_version;
|
||||
struct xen_dumpcore_elfnote_format_version_desc format_version;
|
||||
|
||||
xc_core_arch_context_init(&arch_ctxt);
|
||||
if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
|
||||
{
|
||||
PERROR("Could not allocate dump_mem");
|
||||
goto error_out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
|
||||
{
|
||||
PERROR("Could not get info for domain");
|
||||
goto error_out;
|
||||
goto out;
|
||||
}
|
||||
/* Map the shared info frame */
|
||||
live_shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
|
||||
PROT_READ, info.shared_info_frame);
|
||||
if ( !live_shinfo
|
||||
#ifdef __ia64__
|
||||
&& !info.hvm
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PERROR("Couldn't map live_shinfo");
|
||||
goto out;
|
||||
}
|
||||
auto_translated_physmap = xc_core_arch_auto_translated_physmap(&info);
|
||||
|
||||
if ( domid != info.domid )
|
||||
{
|
||||
PERROR("Domain %d does not exist", domid);
|
||||
goto error_out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for ( i = 0; i <= info.max_vcpu_id; i++ )
|
||||
if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0)
|
||||
{
|
||||
if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0 )
|
||||
{
|
||||
if ( xc_core_arch_context_get(&arch_ctxt, &ctxt[nr_vcpus],
|
||||
xc_handle, domid) )
|
||||
continue;
|
||||
nr_vcpus++;
|
||||
}
|
||||
}
|
||||
if ( nr_vcpus == 0 )
|
||||
{
|
||||
PERROR("No VCPU context could be grabbed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* obtain memory map */
|
||||
sts = xc_core_arch_memory_map_get(xc_handle, &info, live_shinfo,
|
||||
&memory_map, &nr_memory_map);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
nr_pages = info.nr_pages;
|
||||
if ( !auto_translated_physmap )
|
||||
{
|
||||
/* obtain p2m table */
|
||||
p2m_array = malloc(nr_pages * sizeof(p2m_array[0]));
|
||||
if ( p2m_array == NULL )
|
||||
{
|
||||
PERROR("Could not allocate p2m array");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sts = xc_core_arch_map_p2m(xc_handle, &info, live_shinfo,
|
||||
&p2m, &max_pfn);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfn_array = malloc(nr_pages * sizeof(pfn_array[0]));
|
||||
if ( pfn_array == NULL )
|
||||
{
|
||||
PERROR("Could not allocate pfn array");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* create .xen_p2m or .xen_pfn */
|
||||
j = 0;
|
||||
for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
|
||||
{
|
||||
uint64_t pfn_start;
|
||||
uint64_t pfn_end;
|
||||
|
||||
pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
|
||||
pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
|
||||
for ( i = pfn_start; i < pfn_end; i++ )
|
||||
{
|
||||
if ( !auto_translated_physmap )
|
||||
{
|
||||
if ( p2m[i] == INVALID_P2M_ENTRY )
|
||||
continue;
|
||||
p2m_array[j].pfn = i;
|
||||
p2m_array[j].gmfn = p2m[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* try to map page to determin wheter it has underlying page */
|
||||
void *vaddr = xc_map_foreign_range(xc_handle, domid,
|
||||
PAGE_SIZE, PROT_READ, i);
|
||||
if ( vaddr == NULL )
|
||||
continue;
|
||||
munmap(vaddr, PAGE_SIZE);
|
||||
pfn_array[j] = i;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if ( j != nr_pages )
|
||||
{
|
||||
PERROR("j (%ld) != nr_pages (%ld)", j , nr_pages);
|
||||
/* When live dump-mode (-L option) is specified,
|
||||
* guest domain may change its mapping.
|
||||
*/
|
||||
nr_pages = j;
|
||||
}
|
||||
|
||||
memset(&ehdr, 0, sizeof(ehdr));
|
||||
ehdr.e_ident[EI_MAG0] = ELFMAG0;
|
||||
ehdr.e_ident[EI_MAG1] = ELFMAG1;
|
||||
ehdr.e_ident[EI_MAG2] = ELFMAG2;
|
||||
ehdr.e_ident[EI_MAG3] = ELFMAG3;
|
||||
ehdr.e_ident[EI_CLASS] = ELFCLASS;
|
||||
ehdr.e_ident[EI_DATA] = ELF_ARCH_DATA;
|
||||
ehdr.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV;
|
||||
ehdr.e_ident[EI_ABIVERSION] = EV_CURRENT;
|
||||
|
||||
ehdr.e_type = ET_CORE;
|
||||
ehdr.e_machine = ELF_ARCH_MACHINE;
|
||||
ehdr.e_version = EV_CURRENT;
|
||||
ehdr.e_entry = 0;
|
||||
ehdr.e_phoff = 0;
|
||||
ehdr.e_shoff = sizeof(ehdr);
|
||||
ehdr.e_flags = ELF_CORE_EFLAGS;
|
||||
ehdr.e_ehsize = sizeof(ehdr);
|
||||
ehdr.e_phentsize = sizeof(Elf_Phdr);
|
||||
ehdr.e_phnum = 0;
|
||||
ehdr.e_shentsize = sizeof(Elf_Shdr);
|
||||
/* ehdr.e_shnum and ehdr.e_shstrndx aren't known here yet. fill it later*/
|
||||
|
||||
/* create section header */
|
||||
strtab = xc_core_strtab_init();
|
||||
if ( strtab == NULL )
|
||||
{
|
||||
PERROR("Could not allocate string table");
|
||||
goto out;
|
||||
}
|
||||
sheaders = xc_core_shdr_init();
|
||||
if ( sheaders == NULL )
|
||||
{
|
||||
PERROR("Could not allocate section headers");
|
||||
goto out;
|
||||
}
|
||||
/* null section */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for null section");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* .shstrtab */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for shstrtab");
|
||||
goto out;
|
||||
}
|
||||
strtab_idx = shdr - sheaders->shdrs;
|
||||
/* strtab_shdr.sh_offset, strtab_shdr.sh_size aren't unknown.
|
||||
* fill it later
|
||||
*/
|
||||
sts = xc_core_shdr_set(shdr, strtab, ELF_SHSTRTAB, SHT_STRTAB, 0, 0, 0, 0);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* elf note section */
|
||||
/* here the number of section header is unknown. fix up offset later. */
|
||||
offset = sizeof(ehdr);
|
||||
filesz =
|
||||
sizeof(struct xen_dumpcore_elfnote_none) + /* none */
|
||||
sizeof(struct xen_dumpcore_elfnote_header) + /* core header */
|
||||
sizeof(struct xen_dumpcore_elfnote_xen_version) + /* xen version */
|
||||
sizeof(struct xen_dumpcore_elfnote_format_version);/* format version */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for note section");
|
||||
goto out;
|
||||
}
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_NOTE, SHT_NOTE,
|
||||
offset, filesz, 0, 0);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
offset += filesz;
|
||||
|
||||
/* prstatus */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for .xen_prstatus");
|
||||
goto out;
|
||||
}
|
||||
filesz = sizeof(ctxt[0]) * nr_vcpus;
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PRSTATUS,
|
||||
SHT_PROGBITS, offset, filesz,
|
||||
__alignof__(ctxt[0]), sizeof(ctxt[0]));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
offset += filesz;
|
||||
|
||||
/* arch context */
|
||||
sts = xc_core_arch_context_get_shdr(&arch_ctxt, sheaders, strtab,
|
||||
&filesz, offset);
|
||||
if ( sts != 0)
|
||||
goto out;
|
||||
offset += filesz;
|
||||
|
||||
/* shared_info */
|
||||
if ( live_shinfo != NULL )
|
||||
{
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for .xen_shared_info");
|
||||
goto out;
|
||||
}
|
||||
filesz = PAGE_SIZE;
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_SHARED_INFO,
|
||||
SHT_PROGBITS, offset, filesz,
|
||||
__alignof__(*live_shinfo), PAGE_SIZE);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
offset += filesz;
|
||||
}
|
||||
|
||||
/* p2m/pfn table */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for .xen_{p2m, pfn} table");
|
||||
goto out;
|
||||
}
|
||||
if ( !auto_translated_physmap )
|
||||
{
|
||||
filesz = nr_pages * sizeof(p2m_array[0]);
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_P2M,
|
||||
SHT_PROGBITS,
|
||||
offset, filesz, __alignof__(p2m_array[0]),
|
||||
sizeof(p2m_array[0]));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
filesz = nr_pages * sizeof(pfn_array[0]);
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PFN,
|
||||
SHT_PROGBITS,
|
||||
offset, filesz, __alignof__(pfn_array[0]),
|
||||
sizeof(pfn_array[0]));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
}
|
||||
offset += filesz;
|
||||
|
||||
/* pages */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("could not get section headers for .xen_pages");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* pages are the last section to allocate section headers
|
||||
* so that we know the number of section headers here.
|
||||
*/
|
||||
fixup = sheaders->num * sizeof(*shdr);
|
||||
/* zeroth section should have zero offset */
|
||||
for ( i = 1; i < sheaders->num; i++ )
|
||||
sheaders->shdrs[i].sh_offset += fixup;
|
||||
offset += fixup;
|
||||
dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /* padding length */
|
||||
offset += dummy_len;
|
||||
|
||||
filesz = nr_pages * PAGE_SIZE;
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
|
||||
offset, filesz, PAGE_SIZE, PAGE_SIZE);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
offset += filesz;
|
||||
|
||||
/* fixing up section header string table section header */
|
||||
filesz = strtab->current;
|
||||
sheaders->shdrs[strtab_idx].sh_offset = offset;
|
||||
sheaders->shdrs[strtab_idx].sh_size = filesz;
|
||||
|
||||
/* write out elf header */
|
||||
ehdr.e_shnum = sheaders->num;
|
||||
ehdr.e_shstrndx = strtab_idx;
|
||||
sts = dump_rtn(args, (char*)&ehdr, sizeof(ehdr));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* section headers */
|
||||
sts = dump_rtn(args, (char*)sheaders->shdrs,
|
||||
sheaders->num * sizeof(sheaders->shdrs[0]));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* elf note section */
|
||||
memset(&elfnote, 0, sizeof(elfnote));
|
||||
elfnote.namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
|
||||
strncpy(elfnote.name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote.name));
|
||||
|
||||
/* elf note section:xen core header */
|
||||
elfnote.descsz = sizeof(none);
|
||||
elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
|
||||
sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
sts = dump_rtn(args, (char*)&none, sizeof(none));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* elf note section:xen core header */
|
||||
elfnote.descsz = sizeof(header);
|
||||
elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
|
||||
header.xch_magic = info.hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
|
||||
header.xch_nr_vcpus = nr_vcpus;
|
||||
header.xch_nr_pages = nr_pages;
|
||||
header.xch_ctxt_offset = sizeof(struct xc_core_header);
|
||||
header.xch_index_offset = sizeof(struct xc_core_header) +
|
||||
sizeof(vcpu_guest_context_t)*nr_vcpus;
|
||||
dummy_len = (sizeof(struct xc_core_header) +
|
||||
(sizeof(vcpu_guest_context_t) * nr_vcpus) +
|
||||
(nr_pages * sizeof(*page_array)));
|
||||
header.xch_pages_offset = round_pgup(dummy_len);
|
||||
|
||||
sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
|
||||
header.xch_page_size = PAGE_SIZE;
|
||||
sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
goto out;
|
||||
sts = dump_rtn(args, (char*)&header, sizeof(header));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* elf note section: xen version */
|
||||
elfnote.descsz = sizeof(xen_version);
|
||||
elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
|
||||
elfnote_fill_xen_version(xc_handle, &xen_version);
|
||||
sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
sts = dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* elf note section: format version */
|
||||
elfnote.descsz = sizeof(format_version);
|
||||
elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
|
||||
elfnote_fill_format_version(&format_version);
|
||||
sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
sts = dump_rtn(args, (char*)&format_version, sizeof(format_version));
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* prstatus: .xen_prstatus */
|
||||
sts = dump_rtn(args, (char *)&ctxt, sizeof(ctxt[0]) * nr_vcpus);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
goto out;
|
||||
|
||||
if ( (page_array = malloc(nr_pages * sizeof(*page_array))) == NULL )
|
||||
if ( live_shinfo != NULL )
|
||||
{
|
||||
IPRINTF("Could not allocate memory\n");
|
||||
goto error_out;
|
||||
/* shared_info: .xen_shared_info */
|
||||
sts = dump_rtn(args, (char*)live_shinfo, PAGE_SIZE);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
}
|
||||
if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
|
||||
{
|
||||
IPRINTF("Could not get the page frame list\n");
|
||||
goto error_out;
|
||||
}
|
||||
sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(*page_array));
|
||||
|
||||
/* arch specific context */
|
||||
sts = xc_core_arch_context_dump(&arch_ctxt, args, dump_rtn);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
goto out;
|
||||
|
||||
/* p2m/pfn table: .xen_p2m/.xen_pfn */
|
||||
if ( !auto_translated_physmap )
|
||||
sts = dump_rtn(args, (char *)p2m_array,
|
||||
sizeof(p2m_array[0]) * nr_pages);
|
||||
else
|
||||
sts = dump_rtn(args, (char *)pfn_array,
|
||||
sizeof(pfn_array[0]) * nr_pages);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
/* Pad the output data to page alignment. */
|
||||
memset(dummy, 0, PAGE_SIZE);
|
||||
sts = dump_rtn(args, dummy, header.xch_pages_offset - dummy_len);
|
||||
sts = dump_rtn(args, dummy, dummy_len);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
goto out;
|
||||
|
||||
/* dump pages: .xen_pages */
|
||||
for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
|
||||
{
|
||||
copy_from_domain_page(xc_handle, domid, page_array[i], dump_mem);
|
||||
uint64_t gmfn;
|
||||
if ( !auto_translated_physmap )
|
||||
gmfn = p2m_array[i].gmfn;
|
||||
else
|
||||
gmfn = pfn_array[i];
|
||||
|
||||
copy_from_domain_page(xc_handle, domid, gmfn, dump_mem);
|
||||
dump_mem += PAGE_SIZE;
|
||||
if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
|
||||
{
|
||||
sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
goto out;
|
||||
dump_mem = dump_mem_start;
|
||||
}
|
||||
}
|
||||
|
||||
free(dump_mem_start);
|
||||
free(page_array);
|
||||
return 0;
|
||||
/* elf section header string table: .shstrtab */
|
||||
sts = dump_rtn(args, strtab->strings, strtab->current);
|
||||
if ( sts != 0 )
|
||||
goto out;
|
||||
|
||||
error_out:
|
||||
free(dump_mem_start);
|
||||
free(page_array);
|
||||
return -1;
|
||||
sts = 0;
|
||||
|
||||
out:
|
||||
if ( p2m != NULL )
|
||||
munmap(p2m, PAGE_SIZE * P2M_FL_ENTRIES);
|
||||
if ( p2m_array != NULL )
|
||||
free(p2m_array);
|
||||
if ( pfn_array != NULL )
|
||||
free(pfn_array);
|
||||
if ( sheaders != NULL )
|
||||
xc_core_shdr_free(sheaders);
|
||||
if ( strtab != NULL )
|
||||
xc_core_strtab_free(strtab);
|
||||
if ( dump_mem_start != NULL )
|
||||
free(dump_mem_start);
|
||||
if ( live_shinfo != NULL )
|
||||
munmap(live_shinfo, PAGE_SIZE);
|
||||
xc_core_arch_context_free(&arch_ctxt);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/* Callback args for writing to a local dump file. */
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XC_CORE_H
|
||||
#define XC_CORE_H
|
||||
|
||||
#include "xen/version.h"
|
||||
#include "xg_private.h"
|
||||
#include "xen/elfstructs.h"
|
||||
|
||||
/* section names */
|
||||
#define XEN_DUMPCORE_SEC_NOTE ".note.Xen"
|
||||
#define XEN_DUMPCORE_SEC_PRSTATUS ".xen_prstatus"
|
||||
#define XEN_DUMPCORE_SEC_SHARED_INFO ".xen_shared_info"
|
||||
#define XEN_DUMPCORE_SEC_P2M ".xen_p2m"
|
||||
#define XEN_DUMPCORE_SEC_PFN ".xen_pfn"
|
||||
#define XEN_DUMPCORE_SEC_PAGES ".xen_pages"
|
||||
|
||||
#define XEN_DUMPCORE_SEC_IA64_MAPPED_REGS ".xen_ia64_mapped_regs"
|
||||
|
||||
/* elf note name */
|
||||
#define XEN_DUMPCORE_ELFNOTE_NAME "Xen"
|
||||
/* note numbers are defined in xen/elfnote.h */
|
||||
|
||||
struct xen_elfnote {
|
||||
uint32_t namesz; /* Elf_Note note; */
|
||||
uint32_t descsz;
|
||||
uint32_t type;
|
||||
char name[4]; /* sizeof("Xen") = 4
|
||||
* Fotunately this is 64bit aligned so that
|
||||
* we can use same structore for both 32/64bit
|
||||
*/
|
||||
};
|
||||
|
||||
struct xen_dumpcore_elfnote_none_desc {
|
||||
/* nothing */
|
||||
};
|
||||
|
||||
struct xen_dumpcore_elfnote_header_desc {
|
||||
uint64_t xch_magic;
|
||||
uint64_t xch_nr_vcpus;
|
||||
uint64_t xch_nr_pages;
|
||||
uint64_t xch_page_size;
|
||||
};
|
||||
|
||||
struct xen_dumpcore_elfnote_xen_version_desc {
|
||||
uint64_t major_version;
|
||||
uint64_t minor_version;
|
||||
xen_extraversion_t extra_version;
|
||||
xen_compile_info_t compile_info;
|
||||
xen_capabilities_info_t capabilities;
|
||||
xen_changeset_info_t changeset;
|
||||
xen_platform_parameters_t platform_parameters;
|
||||
uint64_t pagesize;
|
||||
};
|
||||
|
||||
#define XEN_DUMPCORE_FORMAT_VERSION(major, minor) \
|
||||
((major) << 32) | ((minor) & 0xffffffff)
|
||||
#define XEN_DUMPCORE_FORMAT_MAJOR(version) ((major) >> 32)
|
||||
#define XEN_DUMPCORE_FORMAT_MINOR(version) ((minor) & 0xffffffff)
|
||||
|
||||
#define XEN_DUMPCORE_FORMAT_MAJOR_CURRENT ((uint64_t)0)
|
||||
#define XEN_DUMPCORE_FORMAT_MINOR_CURRENT ((uint64_t)1)
|
||||
#define XEN_DUMPCORE_FORMAT_VERSION_CURRENT \
|
||||
XEN_DUMPCORE_FORMAT_VERSION(XEN_DUMPCORE_FORMAT_MAJOR_CURRENT, \
|
||||
XEN_DUMPCORE_FORMAT_MINOR_CURRENT)
|
||||
|
||||
struct xen_dumpcore_elfnote_format_version_desc {
|
||||
uint64_t version;
|
||||
};
|
||||
|
||||
|
||||
struct xen_dumpcore_elfnote_none {
|
||||
struct xen_elfnote elfnote;
|
||||
struct xen_dumpcore_elfnote_none_desc none;
|
||||
};
|
||||
|
||||
struct xen_dumpcore_elfnote_header {
|
||||
struct xen_elfnote elfnote;
|
||||
struct xen_dumpcore_elfnote_header_desc header;
|
||||
};
|
||||
|
||||
struct xen_dumpcore_elfnote_xen_version {
|
||||
struct xen_elfnote elfnote;
|
||||
struct xen_dumpcore_elfnote_xen_version_desc xen_version;
|
||||
};
|
||||
|
||||
struct xen_dumpcore_elfnote_format_version {
|
||||
struct xen_elfnote elfnote;
|
||||
struct xen_dumpcore_elfnote_format_version_desc format_version;
|
||||
};
|
||||
|
||||
struct xen_dumpcore_p2m {
|
||||
uint64_t pfn;
|
||||
uint64_t gmfn;
|
||||
};
|
||||
|
||||
|
||||
struct xc_core_strtab;
|
||||
struct xc_core_section_headers;
|
||||
|
||||
Elf_Shdr*
|
||||
xc_core_shdr_get(struct xc_core_section_headers *sheaders);
|
||||
int
|
||||
xc_core_shdr_set(Elf_Shdr *shdr,
|
||||
struct xc_core_strtab *strtab,
|
||||
const char *name, uint32_t type,
|
||||
uint64_t offset, uint64_t size,
|
||||
uint64_t addralign, uint64_t entsize);
|
||||
|
||||
struct xc_core_memory_map {
|
||||
uint64_t addr;
|
||||
uint64_t size;
|
||||
};
|
||||
typedef struct xc_core_memory_map xc_core_memory_map_t;
|
||||
int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info);
|
||||
int xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp,
|
||||
unsigned int *nr_entries);
|
||||
int xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
|
||||
unsigned long *pfnp);
|
||||
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
# include "xc_core_x86.h"
|
||||
#elif defined (__ia64__)
|
||||
# include "xc_core_ia64.h"
|
||||
#else
|
||||
# error "unsupported architecture"
|
||||
#endif
|
||||
|
||||
#ifndef ELF_CORE_EFLAGS
|
||||
# define ELF_CORE_EFLAGS 0
|
||||
#endif
|
||||
|
||||
#endif /* XC_CORE_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_core.h"
|
||||
#include "xc_efi.h"
|
||||
#include "xc_dom.h"
|
||||
|
||||
int
|
||||
xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
|
||||
{
|
||||
/*
|
||||
* on ia64, both paravirtualize domain and hvm domain are
|
||||
* auto_translated_physmap mode
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* see setup_guest() @ xc_linux_build.c */
|
||||
static int
|
||||
memory_map_get_old_domu(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp, unsigned int *nr_entries)
|
||||
{
|
||||
xc_core_memory_map_t *map = NULL;
|
||||
|
||||
map = malloc(sizeof(*map));
|
||||
if ( map == NULL )
|
||||
{
|
||||
PERROR("Could not allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
map->addr = 0;
|
||||
map->size = info->max_memkb * 1024;
|
||||
|
||||
*mapp = map;
|
||||
*nr_entries = 1;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if ( map != NULL )
|
||||
free(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* see setup_guest() @ xc_ia64_hvm_build.c */
|
||||
static int
|
||||
memory_map_get_old_hvm(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp, unsigned int *nr_entries)
|
||||
{
|
||||
const xc_core_memory_map_t gfw_map[] = {
|
||||
{IO_PAGE_START, IO_PAGE_SIZE},
|
||||
{STORE_PAGE_START, STORE_PAGE_SIZE},
|
||||
{BUFFER_IO_PAGE_START, BUFFER_IO_PAGE_SIZE},
|
||||
{GFW_START, GFW_SIZE},
|
||||
};
|
||||
const unsigned int nr_gfw_map = sizeof(gfw_map)/sizeof(gfw_map[0]);
|
||||
xc_core_memory_map_t *map = NULL;
|
||||
unsigned int i;
|
||||
|
||||
#define VGA_IO_END (VGA_IO_START + VGA_IO_SIZE)
|
||||
/* [0, VGA_IO_START) [VGA_IO_END, 3GB), [4GB, ...) + gfw_map */
|
||||
map = malloc((3 + nr_gfw_map) * sizeof(*map));
|
||||
if ( map == NULL )
|
||||
{
|
||||
PERROR("Could not allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for ( i = 0; i < nr_gfw_map; i++ )
|
||||
map[i] = gfw_map[i];
|
||||
map[i].addr = 0;
|
||||
map[i].size = info->max_memkb * 1024;
|
||||
i++;
|
||||
if ( map[i - 1].size < VGA_IO_END )
|
||||
{
|
||||
map[i - 1].size = VGA_IO_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[i].addr = VGA_IO_END;
|
||||
map[i].size = map[i - 1].size - VGA_IO_END;
|
||||
map[i - 1].size = VGA_IO_START;
|
||||
i++;
|
||||
if ( map[i - 1].addr + map[i - 1].size > MMIO_START )
|
||||
{
|
||||
map[i].addr = MMIO_START + 1 * MEM_G;
|
||||
map[i].size = map[i - 1].addr + map[i - 1].size - MMIO_START;
|
||||
map[i - 1].size = MMIO_START - map[i - 1].addr;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
*mapp = map;
|
||||
*nr_entries = i;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if ( map != NULL )
|
||||
free(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
memory_map_get_old(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp, unsigned int *nr_entries)
|
||||
{
|
||||
if ( info->hvm )
|
||||
return memory_map_get_old_hvm(xc_handle, info, live_shinfo,
|
||||
mapp, nr_entries);
|
||||
if ( live_shinfo == NULL )
|
||||
return -1;
|
||||
return memory_map_get_old_domu(xc_handle, info, live_shinfo,
|
||||
mapp, nr_entries);
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp,
|
||||
unsigned int *nr_entries)
|
||||
{
|
||||
#ifdef notyet
|
||||
int ret = -1;
|
||||
xen_ia64_memmap_info_t *memmap_info;
|
||||
xc_core_memory_map_t *map;
|
||||
char *start;
|
||||
char *end;
|
||||
char *p;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
if ( live_shinfo == NULL || live_shinfo->arch.memmap_info_pfn == 0 )
|
||||
goto old;
|
||||
|
||||
memmap_info = xc_map_foreign_range(xc_handle, info->domid,
|
||||
PAGE_SIZE, PROT_READ,
|
||||
live_shinfo->arch.memmap_info_pfn);
|
||||
if ( memmap_info == NULL )
|
||||
{
|
||||
PERROR("Could not map memmap info.");
|
||||
return -1;
|
||||
}
|
||||
if ( memmap_info->efi_memdesc_size != sizeof(*md) ||
|
||||
(memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size) == 0 ||
|
||||
memmap_info->efi_memmap_size > PAGE_SIZE - sizeof(memmap_info) ||
|
||||
memmap_info->efi_memdesc_version != EFI_MEMORY_DESCRIPTOR_VERSION )
|
||||
{
|
||||
PERROR("unknown memmap header. defaulting to compat mode.");
|
||||
munmap(memmap_info, PAGE_SIZE);
|
||||
goto old;
|
||||
}
|
||||
|
||||
*nr_entries = memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size;
|
||||
map = malloc(*nr_entries * sizeof(*md));
|
||||
if ( map == NULL )
|
||||
{
|
||||
PERROR("Could not allocate memory for memmap.");
|
||||
goto out;
|
||||
}
|
||||
*mapp = map;
|
||||
|
||||
*nr_entries = 0;
|
||||
start = (char*)&memmap_info->memdesc;
|
||||
end = start + memmap_info->efi_memmap_size;
|
||||
for ( p = start; p < end; p += memmap_info->efi_memdesc_size )
|
||||
{
|
||||
md = (efi_memory_desc_t*)p;
|
||||
if ( md->type != EFI_CONVENTIONAL_MEMORY ||
|
||||
md->attribute != EFI_MEMORY_WB ||
|
||||
md->num_pages == 0 )
|
||||
continue;
|
||||
|
||||
map[*nr_entries].addr = md->phys_addr;
|
||||
map[*nr_entries].size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
(*nr_entries)++;
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
munmap(memmap_info, PAGE_SIZE);
|
||||
return ret;
|
||||
|
||||
old:
|
||||
#endif
|
||||
return memory_map_get_old(xc_handle, info, live_shinfo, mapp, nr_entries);
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
|
||||
unsigned long *pfnp)
|
||||
{
|
||||
/*
|
||||
* on ia64, both paravirtualize domain and hvm domain are
|
||||
* auto_translated_physmap mode
|
||||
*/
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
xc_core_arch_context_init(struct xc_core_arch_context* arch_ctxt)
|
||||
{
|
||||
int i;
|
||||
|
||||
arch_ctxt->mapped_regs_size =
|
||||
(XMAPPEDREGS_SIZE < PAGE_SIZE) ? PAGE_SIZE: XMAPPEDREGS_SIZE;
|
||||
arch_ctxt->nr_vcpus = 0;
|
||||
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
|
||||
arch_ctxt->mapped_regs[i] = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
xc_core_arch_context_free(struct xc_core_arch_context* arch_ctxt)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < arch_ctxt->nr_vcpus; i++ )
|
||||
if ( arch_ctxt->mapped_regs[i] != NULL )
|
||||
munmap(arch_ctxt->mapped_regs[i], arch_ctxt->mapped_regs_size);
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
|
||||
vcpu_guest_context_t* ctxt,
|
||||
int xc_handle, uint32_t domid)
|
||||
{
|
||||
mapped_regs_t* mapped_regs;
|
||||
if ( ctxt->privregs_pfn == INVALID_P2M_ENTRY )
|
||||
{
|
||||
PERROR("Could not get mmapped privregs gmfn");
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
mapped_regs = xc_map_foreign_range(xc_handle, domid,
|
||||
arch_ctxt->mapped_regs_size,
|
||||
PROT_READ, ctxt->privregs_pfn);
|
||||
if ( mapped_regs == NULL )
|
||||
{
|
||||
PERROR("Could not map mapped privregs");
|
||||
return -1;
|
||||
}
|
||||
arch_ctxt->mapped_regs[arch_ctxt->nr_vcpus] = mapped_regs;
|
||||
arch_ctxt->nr_vcpus++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt,
|
||||
struct xc_core_section_headers *sheaders,
|
||||
struct xc_core_strtab *strtab,
|
||||
unsigned long *filesz, unsigned long offset)
|
||||
{
|
||||
int sts = -1;
|
||||
Elf_Shdr *shdr;
|
||||
|
||||
/* mmapped priv regs */
|
||||
shdr = xc_core_shdr_get(sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for .xen_ia64_mapped_regs");
|
||||
return sts;
|
||||
}
|
||||
*filesz = arch_ctxt->mapped_regs_size * arch_ctxt->nr_vcpus;
|
||||
sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_IA64_MAPPED_REGS,
|
||||
SHT_PROGBITS, offset, *filesz,
|
||||
__alignof__(*arch_ctxt->mapped_regs[0]),
|
||||
arch_ctxt->mapped_regs_size);
|
||||
return sts;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_context_dump(struct xc_core_arch_context* arch_ctxt,
|
||||
void* args, dumpcore_rtn_t dump_rtn)
|
||||
{
|
||||
int sts = 0;
|
||||
int i;
|
||||
|
||||
/* ia64 mapped_regs: .xen_ia64_mapped_regs */
|
||||
for ( i = 0; i < arch_ctxt->nr_vcpus; i++ )
|
||||
{
|
||||
sts = dump_rtn(args, (char*)arch_ctxt->mapped_regs[i],
|
||||
arch_ctxt->mapped_regs_size);
|
||||
if ( sts != 0 )
|
||||
break;
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XC_CORE_IA64_H
|
||||
#define XC_CORE_IA64_H
|
||||
|
||||
#define ELF_ARCH_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH_MACHINE EM_IA_64
|
||||
|
||||
struct xc_core_arch_context {
|
||||
size_t mapped_regs_size;
|
||||
int nr_vcpus;
|
||||
mapped_regs_t* mapped_regs[MAX_VIRT_CPUS];
|
||||
};
|
||||
|
||||
void
|
||||
xc_core_arch_context_init(struct xc_core_arch_context* arch_ctxt);
|
||||
void
|
||||
xc_core_arch_context_free(struct xc_core_arch_context* arch_ctxt);
|
||||
int
|
||||
xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
|
||||
vcpu_guest_context_t* ctxt,
|
||||
int xc_handle, uint32_t domid);
|
||||
int
|
||||
xc_core_arch_context_get_shdr(struct xc_core_arch_context* arch_ctxt,
|
||||
struct xc_core_section_headers *sheaders,
|
||||
struct xc_core_strtab *strtab,
|
||||
unsigned long *filesz, unsigned long offset);
|
||||
int
|
||||
xc_core_arch_context_dump(struct xc_core_arch_context* arch_ctxt,
|
||||
void* args, dumpcore_rtn_t dump_rtn);
|
||||
|
||||
#endif /* XC_CORE_IA64_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_core.h"
|
||||
|
||||
int
|
||||
xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
|
||||
{
|
||||
if ( info->hvm )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp,
|
||||
unsigned int *nr_entries)
|
||||
{
|
||||
unsigned long max_pfn = live_shinfo->arch.max_pfn;
|
||||
xc_core_memory_map_t *map = NULL;
|
||||
|
||||
map = malloc(sizeof(*map));
|
||||
if ( !map )
|
||||
{
|
||||
PERROR("Could not allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
map->addr = 0;
|
||||
map->size = max_pfn << PAGE_SHIFT;
|
||||
|
||||
*mapp = map;
|
||||
*nr_entries = 1;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if ( map )
|
||||
free(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
|
||||
shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
|
||||
unsigned long *pfnp)
|
||||
{
|
||||
/* Double and single indirect references to the live P2M table */
|
||||
xen_pfn_t *live_p2m_frame_list_list = NULL;
|
||||
xen_pfn_t *live_p2m_frame_list = NULL;
|
||||
uint32_t dom = info->domid;
|
||||
unsigned long max_pfn = live_shinfo->arch.max_pfn;
|
||||
int ret = -1;
|
||||
int err;
|
||||
|
||||
if ( max_pfn < info->nr_pages )
|
||||
{
|
||||
ERROR("max_pfn < nr_pages -1 (%lx < %lx", max_pfn, info->nr_pages - 1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
live_p2m_frame_list_list =
|
||||
xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
|
||||
live_shinfo->arch.pfn_to_mfn_frame_list_list);
|
||||
|
||||
if ( !live_p2m_frame_list_list )
|
||||
{
|
||||
PERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
live_p2m_frame_list =
|
||||
xc_map_foreign_batch(xc_handle, dom, PROT_READ,
|
||||
live_p2m_frame_list_list,
|
||||
P2M_FLL_ENTRIES);
|
||||
|
||||
if ( !live_p2m_frame_list )
|
||||
{
|
||||
PERROR("Couldn't map p2m_frame_list");
|
||||
goto out;
|
||||
}
|
||||
|
||||
*live_p2m = xc_map_foreign_batch(xc_handle, dom, PROT_READ,
|
||||
live_p2m_frame_list,
|
||||
P2M_FL_ENTRIES);
|
||||
|
||||
if ( !*live_p2m )
|
||||
{
|
||||
PERROR("Couldn't map p2m table");
|
||||
goto out;
|
||||
}
|
||||
|
||||
*pfnp = max_pfn;
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
err = errno;
|
||||
|
||||
if ( live_p2m_frame_list_list )
|
||||
munmap(live_p2m_frame_list_list, PAGE_SIZE);
|
||||
|
||||
if ( live_p2m_frame_list )
|
||||
munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE);
|
||||
|
||||
errno = err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XC_CORE_X86_H
|
||||
#define XC_CORE_X86_H
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define ELF_ARCH_DATA ELFDATA2LSB
|
||||
#if defined (__i386__)
|
||||
# define ELF_ARCH_MACHINE EM_386
|
||||
#else
|
||||
# define ELF_ARCH_MACHINE EM_X86_64
|
||||
#endif
|
||||
#endif /* __i386__ or __x86_64__ */
|
||||
|
||||
|
||||
struct xc_core_arch_context {
|
||||
/* nothing */
|
||||
};
|
||||
|
||||
#define xc_core_arch_context_init(arch_ctxt) do {} while (0)
|
||||
#define xc_core_arch_context_free(arch_ctxt) do {} while (0)
|
||||
#define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
|
||||
(0)
|
||||
#define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn) (0)
|
||||
|
||||
static inline int
|
||||
xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt,
|
||||
struct xc_core_section_headers *sheaders,
|
||||
struct xc_core_strtab *strtab,
|
||||
unsigned long *filesz, unsigned long offset)
|
||||
{
|
||||
*filesz = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* XC_CORE_X86_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,68 @@
|
||||
#ifndef XC_EFI_H
|
||||
#define XC_EFI_H
|
||||
|
||||
/* definitions from xen/include/asm-ia64/linux-xen/linux/efi.h */
|
||||
|
||||
/*
|
||||
* Extensible Firmware Interface
|
||||
* Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999
|
||||
*
|
||||
* Copyright (C) 1999 VA Linux Systems
|
||||
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
|
||||
* Copyright (C) 1999, 2002-2003 Hewlett-Packard Co.
|
||||
* David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
* Stephane Eranian <eranian@hpl.hp.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory map descriptor:
|
||||
*/
|
||||
|
||||
/* Memory types: */
|
||||
#define EFI_RESERVED_TYPE 0
|
||||
#define EFI_LOADER_CODE 1
|
||||
#define EFI_LOADER_DATA 2
|
||||
#define EFI_BOOT_SERVICES_CODE 3
|
||||
#define EFI_BOOT_SERVICES_DATA 4
|
||||
#define EFI_RUNTIME_SERVICES_CODE 5
|
||||
#define EFI_RUNTIME_SERVICES_DATA 6
|
||||
#define EFI_CONVENTIONAL_MEMORY 7
|
||||
#define EFI_UNUSABLE_MEMORY 8
|
||||
#define EFI_ACPI_RECLAIM_MEMORY 9
|
||||
#define EFI_ACPI_MEMORY_NVS 10
|
||||
#define EFI_MEMORY_MAPPED_IO 11
|
||||
#define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12
|
||||
#define EFI_PAL_CODE 13
|
||||
#define EFI_MAX_MEMORY_TYPE 14
|
||||
|
||||
/* Attribute values: */
|
||||
#define EFI_MEMORY_UC ((uint64_t)0x0000000000000001ULL) /* uncached */
|
||||
#define EFI_MEMORY_WC ((uint64_t)0x0000000000000002ULL) /* write-coalescing */
|
||||
#define EFI_MEMORY_WT ((uint64_t)0x0000000000000004ULL) /* write-through */
|
||||
#define EFI_MEMORY_WB ((uint64_t)0x0000000000000008ULL) /* write-back */
|
||||
#define EFI_MEMORY_WP ((uint64_t)0x0000000000001000ULL) /* write-protect */
|
||||
#define EFI_MEMORY_RP ((uint64_t)0x0000000000002000ULL) /* read-protect */
|
||||
#define EFI_MEMORY_XP ((uint64_t)0x0000000000004000ULL) /* execute-protect */
|
||||
#define EFI_MEMORY_RUNTIME ((uint64_t)0x8000000000000000ULL) /* range requires runtime mapping */
|
||||
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
|
||||
|
||||
#define EFI_PAGE_SHIFT 12
|
||||
|
||||
/*
|
||||
* For current x86 implementations of EFI, there is
|
||||
* additional padding in the mem descriptors. This is not
|
||||
* the case in ia64. Need to have this fixed in the f/w.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t pad;
|
||||
uint64_t phys_addr;
|
||||
uint64_t virt_addr;
|
||||
uint64_t num_pages;
|
||||
uint64_t attribute;
|
||||
#if defined (__i386__)
|
||||
uint64_t pad1;
|
||||
#endif
|
||||
} efi_memory_desc_t;
|
||||
|
||||
#endif /* XC_EFI_H */
|
||||
@@ -570,6 +570,11 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
|
||||
unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
|
||||
int vcpu, unsigned long long virt);
|
||||
|
||||
|
||||
/**
|
||||
* DEPRECATED. Avoid using this, as it does not correctly account for PFNs
|
||||
* without a backing MFN.
|
||||
*/
|
||||
int xc_get_pfn_list(int xc_handle, uint32_t domid, uint64_t *pfn_buf,
|
||||
unsigned long max_pfns);
|
||||
|
||||
|
||||
@@ -175,6 +175,41 @@
|
||||
*/
|
||||
#define XEN_ELFNOTE_CRASH_REGS 0x1000002
|
||||
|
||||
|
||||
/*
|
||||
* xen dump-core none note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE
|
||||
* in its dump file to indicate that the file is xen dump-core
|
||||
* file. This note doesn't have any other information.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_NONE 0x2000000
|
||||
|
||||
/*
|
||||
* xen dump-core header note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER
|
||||
* in its dump file.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_HEADER 0x2000001
|
||||
|
||||
/*
|
||||
* xen dump-core xen version note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION
|
||||
* in its dump file. It contains the xen version obtained via the
|
||||
* XENVER hypercall.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_XEN_VERSION 0x2000002
|
||||
|
||||
/*
|
||||
* xen dump-core format version note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION
|
||||
* in its dump file. It contains a format version identifier.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION 0x2000003
|
||||
|
||||
#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
|
||||
|
||||
/*
|
||||
|
||||