[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] Support cross-bitness guest when core-dumping
The "change" to the format is as follows: Now the file format for a cross-bit configuration will be the same as would have been produced by a same-bitness configuration, which crash of course already handles. So crash should be fine with this change. In fact that was part of how I determined that it was working right. I consider that the cross-bitness format was simply not valid as there is no reason for there to be a different format for the file simply because the host was a different bitsize than the guest (and it didn't work with crash & gdb-xenserver as it was). - Bruce >>> Isaku Yamahata <yamahata@xxxxxxxxxxxxx> 01/14/09 8:17 PM >>> [CCed to Anderson, Oda and crash-utility ml] Hi Bruce. Nice patch. Could you please update the documentation about its format too? docs/misc/dump-core-format.txt - Elf header section, and - revision history at the end of the file. And what is the impact on the crash utility? thanks, On Wed, Jan 14, 2009 at 04:47:41PM -0700, Bruce Rogers wrote: > This patch allows core-dumping to work on a cross-bit host/guest > configuration, whereas previously that was not supported. It supports both > PV and FV guests. The core file format generated by the host, needs to match > that of the guest, so an alignment issue is addressed, along with the p2m > frame list handling being done according to the guest size. > > Signed-off-by: Bruce Rogers <brogers@xxxxxxxxxx> > > diff -r 77476eeb8c42 tools/libxc/xc_core.c > --- a/tools/libxc/xc_core.c Wed Jan 14 11:39:01 2009 +0000 > +++ b/tools/libxc/xc_core.c Wed Jan 14 16:40:17 2009 -0700 > @@ -57,9 +57,6 @@ > > /* number of pages to write at a time */ > #define DUMP_INCREMENT (4 * 1024) > - > -/* Don't yet support cross-address-size core dump */ > -#define guest_width (sizeof (unsigned long)) > > /* string table */ > struct xc_core_strtab { > @@ -240,7 +237,7 @@ xc_core_ehdr_init(Elf64_Ehdr *ehdr) > ehdr->e_ident[EI_ABIVERSION] = EV_CURRENT; > > ehdr->e_type = ET_CORE; > - ehdr->e_machine = ELF_ARCH_MACHINE; > + /* e_machine will be filled in later */ > ehdr->e_version = EV_CURRENT; > ehdr->e_entry = 0; > ehdr->e_phoff = 0; > @@ -359,7 +356,8 @@ elfnote_dump_core_header( > } > > static int > -elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int xc_handle) > +elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int xc_handle, > + unsigned int guest_width) > { > int sts; > struct elfnote elfnote; > @@ -371,6 +369,12 @@ elfnote_dump_xen_version(void *args, dum > elfnote.descsz = sizeof(xen_version); > elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION; > elfnote_fill_xen_version(xc_handle, &xen_version); > + if (guest_width < sizeof(unsigned long)) > + { > + // 32 bit elf file format differs in pagesize's alignment > + char *p = (char *)&xen_version.pagesize; > + memmove(p - 4, p, sizeof(xen_version.pagesize)); > + } > sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote)); > if ( sts != 0 ) > return sts; > @@ -396,6 +400,24 @@ elfnote_dump_format_version(void *args, > return dump_rtn(args, (char*)&format_version, sizeof(format_version)); > } > > +static int > +get_guest_width(int xc_handle, > + uint32_t domid, > + unsigned int *guest_width) > +{ > + DECLARE_DOMCTL; > + > + memset(&domctl, 0, sizeof(domctl)); > + domctl.domain = domid; > + domctl.cmd = XEN_DOMCTL_get_address_size; > + > + if ( do_domctl(xc_handle, &domctl) != 0 ) > + return 1; > + > + *guest_width = domctl.u.address_size.size / 8; > + return 0; > +} > + > int > xc_domain_dumpcore_via_callback(int xc_handle, > uint32_t domid, > @@ -403,7 +425,8 @@ xc_domain_dumpcore_via_callback(int xc_h > dumpcore_rtn_t dump_rtn) > { > xc_dominfo_t info; > - shared_info_t *live_shinfo = NULL; > + shared_info_any_t *live_shinfo = NULL; > + unsigned int guest_width; > > int nr_vcpus = 0; > char *dump_mem, *dump_mem_start = NULL; > @@ -437,6 +460,12 @@ xc_domain_dumpcore_via_callback(int xc_h > uint16_t strtab_idx; > struct xc_core_section_headers *sheaders = NULL; > Elf64_Shdr *shdr; > + > + if ( get_guest_width(xc_handle, domid, &guest_width) != 0 ) > + { > + PERROR("Could not get address size for domain"); > + return sts; > + } > > xc_core_arch_context_init(&arch_ctxt); > if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL ) > @@ -500,7 +529,7 @@ xc_domain_dumpcore_via_callback(int xc_h > goto out; > } > > - sts = xc_core_arch_map_p2m(xc_handle, &info, live_shinfo, > + sts = xc_core_arch_map_p2m(xc_handle, guest_width, &info, > live_shinfo, > &p2m, &p2m_size); > if ( sts != 0 ) > goto out; > @@ -676,6 +705,7 @@ xc_domain_dumpcore_via_callback(int xc_h > /* write out elf header */ > ehdr.e_shnum = sheaders->num; > ehdr.e_shstrndx = strtab_idx; > + ehdr.e_machine = ELF_ARCH_MACHINE; > sts = dump_rtn(args, (char*)&ehdr, sizeof(ehdr)); > if ( sts != 0 ) > goto out; > @@ -697,7 +727,7 @@ xc_domain_dumpcore_via_callback(int xc_h > goto out; > > /* elf note section: xen version */ > - sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle); > + sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle, guest_width); > if ( sts != 0 ) > goto out; > > @@ -757,9 +787,21 @@ xc_domain_dumpcore_via_callback(int xc_h > > if ( !auto_translated_physmap ) > { > - gmfn = p2m[i]; > - if ( gmfn == INVALID_P2M_ENTRY ) > - continue; > + if ( guest_width >= sizeof(unsigned long) ) > + { > + if ( guest_width == sizeof(unsigned long) ) > + gmfn = p2m[i]; > + else > + gmfn = ((uint64_t *)p2m)[i]; > + if ( gmfn == INVALID_P2M_ENTRY ) > + continue; > + } > + else > + { > + gmfn = ((uint32_t *)p2m)[i]; > + if ( gmfn == (uint32_t)INVALID_P2M_ENTRY ) > + continue; > + } > > p2m_array[j].pfn = i; > p2m_array[j].gmfn = gmfn; > @@ -802,7 +844,7 @@ copy_done: > /* When live dump-mode (-L option) is specified, > * guest domain may reduce memory. pad with zero pages. > */ > - IPRINTF("j (%ld) != nr_pages (%ld)", j , nr_pages); > + IPRINTF("j (%ld) != nr_pages (%ld)", j, nr_pages); > memset(dump_mem_start, 0, PAGE_SIZE); > for (; j < nr_pages; j++) { > sts = dump_rtn(args, dump_mem_start, PAGE_SIZE); > @@ -891,7 +933,7 @@ xc_domain_dumpcore(int xc_handle, > struct dump_args da; > int sts; > > - if ( (da.fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0 ) > + if ( (da.fd = open(corename, O_CREAT|O_RDWR|O_TRUNC, S_IWUSR|S_IRUSR)) < > 0 ) > { > PERROR("Could not open corefile %s", corename); > return -errno; > diff -r 77476eeb8c42 tools/libxc/xc_core.h > --- a/tools/libxc/xc_core.h Wed Jan 14 11:39:01 2009 +0000 > +++ b/tools/libxc/xc_core.h Wed Jan 14 16:40:17 2009 -0700 > @@ -136,12 +136,12 @@ struct xc_core_arch_context; > struct xc_core_arch_context; > int xc_core_arch_memory_map_get(int xc_handle, > struct xc_core_arch_context *arch_ctxt, > - xc_dominfo_t *info, shared_info_t > *live_shinfo, > + xc_dominfo_t *info, shared_info_any_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); > +int xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width, > + xc_dominfo_t *info, shared_info_any_t *live_shinfo, > + xen_pfn_t **live_p2m, unsigned long *pfnp); > > > #if defined (__i386__) || defined (__x86_64__) > diff -r 77476eeb8c42 tools/libxc/xc_core_ia64.c > --- a/tools/libxc/xc_core_ia64.c Wed Jan 14 11:39:01 2009 +0000 > +++ b/tools/libxc/xc_core_ia64.c Wed Jan 14 16:40:17 2009 -0700 > @@ -235,7 +235,7 @@ old: > } > > int > -xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info, > +xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width, xc_dominfo_t > *info, > shared_info_t *live_shinfo, xen_pfn_t **live_p2m, > unsigned long *pfnp) > { > diff -r 77476eeb8c42 tools/libxc/xc_core_x86.c > --- a/tools/libxc/xc_core_x86.c Wed Jan 14 11:39:01 2009 +0000 > +++ b/tools/libxc/xc_core_x86.c Wed Jan 14 16:40:17 2009 -0700 > @@ -20,9 +20,25 @@ > > #include "xg_private.h" > #include "xc_core.h" > +#include "xc_e820.h" > > -/* Don't yet support cross-address-size core dump */ > -#define guest_width (sizeof (unsigned long)) > +#define GET_FIELD(_p, _f) ((guest_width==8) ? ((_p)->x64._f) : > ((_p)->x32._f)) > + > +#ifndef MAX > +#define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b)) > +#endif > + > +int > +xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt, > + unsigned long pfn) > +{ > + if ((pfn >= 0xa0 && pfn < 0xc0) /* VGA hole */ > + || (pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) > + && pfn < (1ULL<<32) >> PAGE_SHIFT)) /* MMIO */ > + return 0; > + return 1; > +} > + > > static int nr_gpfns(int xc_handle, domid_t domid) > { > @@ -37,7 +53,7 @@ xc_core_arch_auto_translated_physmap(con > > int > xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context > *unused, > - xc_dominfo_t *info, shared_info_t *live_shinfo, > + xc_dominfo_t *info, shared_info_any_t > *live_shinfo, > xc_core_memory_map_t **mapp, > unsigned int *nr_entries) > { > @@ -60,17 +76,22 @@ xc_core_arch_memory_map_get(int xc_handl > } > > int > -xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info, > - shared_info_t *live_shinfo, xen_pfn_t **live_p2m, > +xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width, xc_dominfo_t > *info, > + shared_info_any_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; > + /* Copies of the above. */ > + xen_pfn_t *p2m_frame_list_list = NULL; > + xen_pfn_t *p2m_frame_list = NULL; > + > uint32_t dom = info->domid; > unsigned long p2m_size = nr_gpfns(xc_handle, info->domid); > int ret = -1; > int err; > + int i; > > if ( p2m_size < info->nr_pages ) > { > @@ -80,7 +101,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d > > 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); > + GET_FIELD(live_shinfo, > arch.pfn_to_mfn_frame_list_list)); > > if ( !live_p2m_frame_list_list ) > { > @@ -88,9 +109,28 @@ xc_core_arch_map_p2m(int xc_handle, xc_d > goto out; > } > > + /* Get a local copy of the live_P2M_frame_list_list */ > + if ( !(p2m_frame_list_list = malloc(PAGE_SIZE)) ) > + { > + ERROR("Couldn't allocate p2m_frame_list_list array"); > + goto out; > + } > + memcpy(p2m_frame_list_list, live_p2m_frame_list_list, PAGE_SIZE); > + > + /* Canonicalize guest's unsigned long vs ours */ > + if ( guest_width > sizeof(unsigned long) ) > + for ( i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++ ) > + if ( i < PAGE_SIZE/guest_width ) > + p2m_frame_list_list[i] = ((uint64_t > *)p2m_frame_list_list)[i]; > + else > + p2m_frame_list_list[i] = 0; > + else if ( guest_width < sizeof(unsigned long) ) > + for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- ) > + p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i]; > + > live_p2m_frame_list = > xc_map_foreign_pages(xc_handle, dom, PROT_READ, > - live_p2m_frame_list_list, > + p2m_frame_list_list, > P2M_FLL_ENTRIES); > > if ( !live_p2m_frame_list ) > @@ -99,8 +139,25 @@ xc_core_arch_map_p2m(int xc_handle, xc_d > goto out; > } > > + /* Get a local copy of the live_P2M_frame_list */ > + if ( !(p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) ) > + { > + ERROR("Couldn't allocate p2m_frame_list array"); > + goto out; > + } > + memset(p2m_frame_list, 0, P2M_TOOLS_FL_SIZE); > + memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE); > + > + /* Canonicalize guest's unsigned long vs ours */ > + if ( guest_width > sizeof(unsigned long) ) > + for ( i = 0; i < P2M_FL_ENTRIES; i++ ) > + p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i]; > + else if ( guest_width < sizeof(unsigned long) ) > + for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- ) > + p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i]; > + > *live_p2m = xc_map_foreign_pages(xc_handle, dom, PROT_READ, > - live_p2m_frame_list, > + p2m_frame_list, > P2M_FL_ENTRIES); > > if ( !*live_p2m ) > @@ -122,6 +179,12 @@ out: > if ( live_p2m_frame_list ) > munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE); > > + if ( p2m_frame_list_list ) > + free(p2m_frame_list_list); > + > + if ( p2m_frame_list ) > + free(p2m_frame_list); > + > errno = err; > return ret; > } > diff -r 77476eeb8c42 tools/libxc/xc_core_x86.h > --- a/tools/libxc/xc_core_x86.h Wed Jan 14 11:39:01 2009 +0000 > +++ b/tools/libxc/xc_core_x86.h Wed Jan 14 16:40:17 2009 -0700 > @@ -21,15 +21,8 @@ > #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__ */ > - > +#define ELF_ARCH_MACHINE (guest_width == 8 ? EM_X86_64 : EM_386) > > struct xc_core_arch_context { > /* nothing */ > @@ -40,8 +33,10 @@ struct xc_core_arch_context { > #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) > -#define xc_core_arch_gpfn_may_present(arch_ctxt, i) (1) > > +int > +xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt, > + unsigned long pfn); > static inline int > xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, > struct xc_core_section_headers *sheaders, > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel -- yamahata _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |