[makedumpfile][PATCH] handle x86_64 xen code/data relocation

Ken'ichi Ohmichi oomichi at mxs.nes.nec.co.jp
Mon Jul 7 04:23:34 EDT 2008


Hi ODA-san,

I tested your patch on RHEL5.2 (based on xen-3.1.2).
If both your patch and Takebe-san's patch ([1]) are applied to makedumpfile,
it can work fine. Thank you so much.

I will merge them into the next release.


Thanks
Ken'ichi Ohmichi

[1]: [RFC] makedumpfile: fix for xen-3.1.2
     http://lists.infradead.org/pipermail/kexec/2008-April/001533.html


Itsuro ODA wrote:
> Hi all,
> 
> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> moves the physical(machine) address of xen code/data area after 
> the system started up. The start address of this is stored in
> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> from its virtual address, calculate 
> "va - __XEN_VIRT_START +  xen_phys_start".
> 
> makedumpfile command need the value of xen_phys_start.
> They know the virtual address of 'xen_phys_start' symbol but
> no way to extract the value of xen_phys_start.
> 
> I posted a patch which adds the xen_phys_start value to the 
> CRASHINFO ElfNote section and It was merged the upstream (xen-unstable
> tree).
> 
> This patch enables as follows:
> * add --xen_phys_start option for a vmcore which is relocated and does not
>   include the xen_phys_start value in the CRASHINFO.
> * extract the xen_phys_start value from the CRASHINFO if the CRASHINFO
>   includes the xen_phys_start value.
> 
> (note that the crash command includes this function already.)
> 
> This patch is for makedumpfile-1.2.6.
> 
> Thanks.
> Itsuro Oda
> 
> ---
> --- makedumpfile.h.org	2008-06-12 15:25:43.000000000 +0900
> +++ makedumpfile.h	2008-07-03 10:48:07.000000000 +0900
> @@ -467,6 +467,7 @@ do { \
>  #define STRLEN_OSRELEASE (65)	/* same length as diskdump.h */
>  
>  #define XEN_ELFNOTE_CRASH_INFO	(0x1000001)
> +#define SIZE_XEN_CRASH_INFO_V2	(sizeof(unsigned long) * 10)
>  
>  /*
>   * The value of dependence on machine
> @@ -778,6 +779,9 @@ struct DumpInfo {
>  	/*
>  	 * for Xen extraction
>  	 */
> +	off_t			offset_xen_crash_info;
> +	unsigned long		size_xen_crash_info;
> +	unsigned long xen_phys_start;
>  	unsigned long xen_heap_start;	/* start mfn of xen heap area */
>  	unsigned long xen_heap_end;	/* end mfn(+1) of xen heap area */
>  	unsigned long frame_table_vaddr;
> @@ -1051,11 +1055,14 @@ int get_xen_info_x86();
>  #define HYPERVISOR_VIRT_END   (0xffff880000000000)
>  #define DIRECTMAP_VIRT_START  (0xffff830000000000)
>  #define DIRECTMAP_VIRT_END    (0xffff840000000000)
> +#define XEN_VIRT_START        (0xffff828c80000000)
>  
>  #define is_xen_vaddr(x) \
>          ((x) >= HYPERVISOR_VIRT_START && (x) < HYPERVISOR_VIRT_END)
>  #define is_direct(x) \
>          ((x) >= DIRECTMAP_VIRT_START && (x) < DIRECTMAP_VIRT_END)
> +#define is_xen_text(x) \
> +        ((x) >= XEN_VIRT_START && (x) < DIRECTMAP_VIRT_START)
>  
>  unsigned long long kvtop_xen_x86_64(unsigned long kvaddr);
>  #define kvtop_xen(X)	kvtop_xen_x86_64(X)
> --- makedumpfile.c.org	2008-06-12 15:01:26.000000000 +0900
> +++ makedumpfile.c	2008-07-03 12:02:44.000000000 +0900
> @@ -2187,6 +2187,8 @@ read_vmcoreinfo_basic_info()
>  
>  	while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
>  		i = strlen(buf);
> +		if (!i)
> +			break;
>  		if (buf[i - 1] == '\n')
>  			buf[i - 1] = '\0';
>  		if (strncmp(buf, STR_OSRELEASE, strlen(STR_OSRELEASE)) == 0) {
> @@ -2244,6 +2246,8 @@ read_vmcoreinfo_symbol(char *str_symbol)
>  
>  	while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
>  		i = strlen(buf);
> +		if (!i)
> +			break;
>  		if (buf[i - 1] == '\n')
>  			buf[i - 1] = '\0';
>  		if (strncmp(buf, str_symbol, strlen(str_symbol)) == 0) {
> @@ -2275,6 +2279,8 @@ read_vmcoreinfo_long(char *str_structure
>  
>  	while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
>  		i = strlen(buf);
> +		if (!i)
> +			break;
>  		if (buf[i - 1] == '\n')
>  			buf[i - 1] = '\0';
>  		if (strncmp(buf, str_structure, strlen(str_structure)) == 0) {
> @@ -2304,6 +2310,8 @@ read_vmcoreinfo_string(char *str_in, cha
>  
>  	while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
>  		i = strlen(buf);
> +		if (!i)
> +			break;
>  		if (buf[i - 1] == '\n')
>  			buf[i - 1] = '\0';
>  		if (strncmp(buf, str_in, strlen(str_in)) == 0) {
> @@ -2467,8 +2475,20 @@ get_pt_note_info(off_t off_note, unsigne
>  		/*
>  		 * Check whether /proc/vmcore contains xen's note.
>  		 */
> -		} else if (n_type == XEN_ELFNOTE_CRASH_INFO)
> +		} else if (n_type == XEN_ELFNOTE_CRASH_INFO) {
>  			vt.mem_flags |= MEMORY_XEN;
> +			if (info->flag_elf64) {
> +				info->offset_xen_crash_info = offset
> +				    + (sizeof(note64)
> +				    + ((note64.n_namesz + 3) & ~3));
> +				info->size_xen_crash_info = note64.n_descsz;
> +			} else {
> +				info->offset_xen_crash_info = offset
> +				    + (sizeof(note32)
> +				    + ((note32.n_namesz + 3) & ~3));
> +				info->size_xen_crash_info = note32.n_descsz;
> +			}
> +		}
>  
>  		if (info->flag_elf64) {
>  			offset += sizeof(Elf64_Nhdr)
> @@ -5547,6 +5567,36 @@ get_structure_info_xen()
>  }
>  
>  int
> +get_xen_phys_start(void)
> +{
> +	off_t offset;
> +	unsigned long xen_phys_start;
> +	const off_t failed = (off_t)-1;
> +
> +	if (info->xen_phys_start)
> +		return TRUE;
> +
> +	if (info->size_xen_crash_info >= SIZE_XEN_CRASH_INFO_V2) {
> +		offset = info->offset_xen_crash_info + info->size_xen_crash_info
> +			 - sizeof(unsigned long) * 2;
> +		if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
> +			ERRMSG("Can't seek the dump memory(%s). %s\n",
> +			    info->name_memory, strerror(errno));
> +			return FALSE;
> +		}
> +		if (read(info->fd_memory, &xen_phys_start, sizeof(unsigned long))
> +		    != sizeof(unsigned long)) {
> +			ERRMSG("Can't read the dump memory(%s). %s\n",
> +			    info->name_memory, strerror(errno));
> +			return FALSE;
> +		}
> +		info->xen_phys_start = xen_phys_start;
> +	}
> +
> +	return TRUE;
> +}
> +
> +int
>  get_xen_info()
>  {
>  	unsigned long domain;
> @@ -5706,6 +5756,7 @@ show_data_xen()
>  	MSG("OFFSET(domain.next_in_list): %ld\n", OFFSET(domain.next_in_list));
>  
>  	MSG("\n");
> +	MSG("xen_phys_start: %lx\n", info->xen_phys_start);
>  	MSG("frame_table_vaddr: %lx\n", info->frame_table_vaddr);
>  	MSG("xen_heap_start: %lx\n", info->xen_heap_start);
>  	MSG("xen_heap_end:%lx\n", info->xen_heap_end);
> @@ -5790,6 +5841,8 @@ read_vmcoreinfo_basic_info_xen()
>  
>  	while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
>  		i = strlen(buf);
> +		if (!i)
> +			break;
>  		if (buf[i - 1] == '\n')
>  			buf[i - 1] = '\0';
>  		if (strncmp(buf, STR_PAGESIZE, strlen(STR_PAGESIZE)) == 0) {
> @@ -6023,6 +6076,8 @@ initial_xen()
>  			return FALSE;
>  		unlink(info->name_vmcoreinfo);
>  	}
> +	if (!get_xen_phys_start())
> +		return FALSE;
>  	if (!get_xen_info())
>  		return FALSE;
>  
> @@ -6204,6 +6259,7 @@ check_param_for_creating_dumpfile(int ar
>  static struct option longopts[] = {
>  	{"xen-syms", required_argument, NULL, 'y'},
>  	{"xen-vmcoreinfo", required_argument, NULL, 'z'},
> +	{"xen_phys_start", required_argument, NULL, 'P'},
>  	{"message-level", required_argument, NULL, 'm'},
>  	{"help", no_argument, NULL, 'h'},
>  	{0, 0, 0, 0}
> @@ -6266,6 +6322,9 @@ main(int argc, char *argv[])
>  		case 'm':
>  			message_level = atoi(optarg);
>  			break;
> +		case 'P':
> +			info->xen_phys_start = strtoul(optarg, NULL, 0);
> +			break;
>  		case 'R':
>  			info->flag_rearrange = 1;
>  			break;
> --- x86_64.c.org	2008-06-12 15:16:48.000000000 +0900
> +++ x86_64.c	2008-07-03 10:58:24.000000000 +0900
> @@ -190,6 +190,9 @@ kvtop_xen_x86_64(unsigned long kvaddr)
>  	if (!is_xen_vaddr(kvaddr))
>  		return NOT_PADDR;
>  
> +	if (is_xen_text(kvaddr))
> +		return (unsigned long)kvaddr - XEN_VIRT_START + info->xen_phys_start;
> +
>  	if (is_direct(kvaddr))
>  		return (unsigned long)kvaddr - DIRECTMAP_VIRT_START;




More information about the kexec mailing list