[PATCH 2/3] makedumpfile: Xen4: copy Xen4 memory distribution symbol values from xen header file

Petr Tesarik ptesarik at suse.cz
Tue Jul 24 16:58:01 EDT 2012


My comments continued...

Dne Pá 22. června 2012 17:48:26 Norbert Trapp napsal(a):
> copied Xen4 memmory values from xen config.h file to makedumpfile.h
> and added _XEN3 to the old Xen3 symbols. kvtop_xen_x86_64 in arch/x86_64.c
> distinguishes between Xen3 and Xen4.
> 
> Signed-off-by: Norbert Trapp <norbert.trapp at ts.fujitsu.com>
> ---
>  arch/x86_64.c  |  121
> +++++++++++++++++++++++++++++++++++++++++-------------- makedumpfile.h |  
> 76 +++++++++++++++++++++++++++++------
>  2 files changed, 154 insertions(+), 43 deletions(-)
> 
> diff --git a/arch/x86_64.c b/arch/x86_64.c
> index 6d2f9cc..da61fd8 100644
> --- a/arch/x86_64.c
> +++ b/arch/x86_64.c
> @@ -278,6 +278,54 @@ vaddr_to_paddr_x86_64(unsigned long vaddr)
>  	return paddr;
>  }
> 
> +int
> +is_xen_vaddr(unsigned long kvaddr)
> +{
> +	int retval;
> +
> +	if (info->xen_major_version < 4) {
> +		retval = (kvaddr >= HYPERVISOR_VIRT_START_XEN3 && kvaddr <
> HYPERVISOR_VIRT_END_XEN3); +		return retval;
> +	}
> +	retval = (kvaddr >= HYPERVISOR_VIRT_START && kvaddr <
> HYPERVISOR_VIRT_END); +	return retval;
> +}

Why do you need two versions of HYPERVISOR_VIRT_START? Aren't they numerically 
equal both for Xen3 and Xen4?

> +
> +int
> +is_xen_text(unsigned long kvaddr, unsigned long long *entry)
> +{
> +	int retval;
> +
> +	if (info->xen_major_version < 4) {
> +		retval = (kvaddr >= XEN_VIRT_START_XEN3 && kvaddr <
> DIRECTMAP_VIRT_START_XEN3); +		if (retval)
> +			*entry = (unsigned long)kvaddr - XEN_VIRT_START_XEN3 +
> info->xen_phys_start; +		return retval;
> +	}
> +	retval = (kvaddr >= XEN_VIRT_START && kvaddr < XEN_VIRT_START + GB(1));
> +	if (retval)
> +		*entry = (unsigned long)kvaddr - XEN_VIRT_START + info-
>xen_phys_start;
> +	return retval;
> +}
> +
> +int
> +is_direct(unsigned long kvaddr, unsigned long long *entry)
> +{
> +	int retval;
> +
> +	if (info->xen_major_version < 4) {
> +		retval = (kvaddr >= DIRECTMAP_VIRT_START_XEN3 && kvaddr <
> DIRECTMAP_VIRT_END_XEN3); +		if (retval)
> +			*entry = (unsigned long)kvaddr - DIRECTMAP_VIRT_START_XEN3;
> +		return retval;
> +	}
> +	retval = (kvaddr >= DIRECTMAP_VIRT_START && kvaddr < DIRECTMAP_VIRT_END);
> +	if (retval)
> +		*entry = (unsigned long)kvaddr - DIRECTMAP_VIRT_START;
> +	return retval;
> +}


My patch does basically the same thing, but instead of modifying is_xen_vaddr 
and is_xen_text I made XEN_VIRT_START and DIRECTMAP_VIRT_START non-constant.

> +
> +
>  /*
>   * for Xen extraction
>   */
> @@ -289,11 +337,11 @@ 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_xen_text(kvaddr, &entry))
> +		return entry;
> 
> -	if (is_direct(kvaddr))
> -		return (unsigned long)kvaddr - DIRECTMAP_VIRT_START;
> +	if (is_direct(kvaddr, &entry))
> +		return entry;

My patch doesn't have to touch this code, because it modifies the macros 
instead.

> 
>  	if ((dirp = kvtop_xen_x86_64(SYMBOL(pgd_l4))) == NOT_PADDR)
>  		return NOT_PADDR;
> @@ -350,34 +398,45 @@ int get_xen_info_x86_64(void)
>  	}
> 
>  	if (SYMBOL(frame_table) == NOT_FOUND_SYMBOL) {
> -		ERRMSG("Can't get the symbol of frame_table.\n");
> -		return FALSE;
> -	}
> -	if (!readmem(VADDR_XEN, SYMBOL(frame_table), &frame_table_vaddr,
> -	    sizeof(frame_table_vaddr))) {
> -		ERRMSG("Can't get the value of frame_table.\n");
> -		return FALSE;
> -	}
> -	info->frame_table_vaddr = frame_table_vaddr;
> -
> -	if (SYMBOL(xenheap_phys_end) == NOT_FOUND_SYMBOL) {
> -		ERRMSG("Can't get the symbol of xenheap_phys_end.\n");
> -		return FALSE;
> -	}
> -	if (!readmem(VADDR_XEN, SYMBOL(xenheap_phys_end), &xen_end,
> -	    sizeof(xen_end))) {
> -		ERRMSG("Can't get the value of xenheap_phys_end.\n");
> -		return FALSE;
> +		if (info->elf_machine != EM_X86_64) {
> +			ERRMSG("Can't get the symbol of frame_table.\n");
> +			return FALSE;
> +		}
> +		info->frame_table_vaddr = FRAMETABLE_VIRT_START;
> +	} else {
> +		if (!readmem(VADDR_XEN, SYMBOL(frame_table), &frame_table_vaddr,
> +		    sizeof(frame_table_vaddr))) {
> +			ERRMSG("Can't get the value of frame_table.\n");
> +			return FALSE;
> +		}
> +		info->frame_table_vaddr = frame_table_vaddr;
>  	}
> -	info->xen_heap_start = 0;
> -	info->xen_heap_end   = paddr_to_pfn(xen_end);
> -
> -	/*
> -	 * pickled_id == domain addr for x86_64
> -	 */
> -	for (i = 0; i < info->num_domain; i++) {
> -		info->domain_list[i].pickled_id =
> -			info->domain_list[i].domain_addr;
> +	if (info->xen_major_version < 4) {
> +		if (SYMBOL(xenheap_phys_end) == NOT_FOUND_SYMBOL) {
> +			ERRMSG("Can't get the symbol of xenheap_phys_end.\n");
> +			return FALSE;
> +		}
> +		if (!readmem(VADDR_XEN, SYMBOL(xenheap_phys_end), &xen_end,
> +		    sizeof(xen_end))) {
> +			ERRMSG("Can't get the value of xenheap_phys_end.\n");
> +			return FALSE;
> +		}
> +		info->xen_heap_start = 0;
> +		info->xen_heap_end   = paddr_to_pfn(xen_end);
> +
> +		/*
> +		 * pickled_id == domain addr for x86_64
> +		 */
> +		for (i = 0; i < info->num_domain; i++) {
> +			info->domain_list[i].pickled_id =
> +				info->domain_list[i].domain_addr;
> +		}
> +	} else {
> +		for (i = 0; i < info->num_domain; i++) {
> +			info->domain_list[i].pickled_id =
> +				((unsigned long)info->domain_list[i].domain_addr -
> +				DIRECTMAP_VIRT_START) >> PAGESHIFT();
> +		}

This part seems more robust than my version, because your code don't simply 
assume that missing symbols always mean Xen4. You know what you expect and act 
accordingly.

>  	}
> 
>  	return TRUE;
> diff --git a/makedumpfile.h b/makedumpfile.h
> index d8d7779..0d8cc15 100644
> --- a/makedumpfile.h
> +++ b/makedumpfile.h
> @@ -1308,18 +1308,70 @@ int get_xen_info_x86(void);
>  #define MAX_X86_64_FRAMES	(info->page_size / sizeof(unsigned long))
> 
>  #define PAGE_OFFSET_XEN_DOM0  (0xffff880000000000) /* different from linux
> */ -#define HYPERVISOR_VIRT_START (0xffff800000000000)
> -#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)
> +#define HYPERVISOR_VIRT_START_XEN3 (0xffff800000000000)
> +#define HYPERVISOR_VIRT_END_XEN3   (0xffff880000000000)
> +#define DIRECTMAP_VIRT_START_XEN3  (0xffff830000000000)
> +#define DIRECTMAP_VIRT_END_XEN3    (0xffff840000000000)
> +#define XEN_VIRT_START_XEN3        (0xffff828c80000000)
> +
> +/* copied from xen-4..../xen/include/asm-x86/config.h */
> +
> +#define L1_PAGETABLE_SHIFT      12
> +#define PAGE_SHIFT              L1_PAGETABLE_SHIFT
> +
> +#define PML4_ENTRY_BITS 39
> +#define PML4_ENTRY_BYTES (1UL << PML4_ENTRY_BITS)
> +#define GB(_gb) (_gb ## UL << 30)
> +
> +#define PML4_ADDR(_slot)        \
> +    ((((_slot ## UL) >> 8) * 0xffff000000000000UL) | \
> +    (_slot ## UL << PML4_ENTRY_BITS))
> +
> +#define HYPERVISOR_VIRT_START   (PML4_ADDR(256))
> +#define HYPERVISOR_VIRT_END     (HYPERVISOR_VIRT_START +
> PML4_ENTRY_BYTES*16) +#define RO_MPT_VIRT_START       (PML4_ADDR(256))
> +#define MPT_VIRT_SIZE           (PML4_ENTRY_BYTES / 2)
> +#define RO_MPT_VIRT_END         (RO_MPT_VIRT_START + MPT_VIRT_SIZE)
> +/* Slot 257: ioremap for PCI mmconfig space for 2048 segments (512GB)
> + *     - full 16-bit segment support needs 44 bits
> + *     - since PML4 slot has 39 bits, we limit segments to 2048 (11-bits)
> + */
> +#define PCI_MCFG_VIRT_START     (PML4_ADDR(257))
> +#define PCI_MCFG_VIRT_END       (PCI_MCFG_VIRT_START + PML4_ENTRY_BYTES)
> +/* Slot 258: linear page table (guest table). */
> +#define LINEAR_PT_VIRT_START    (PML4_ADDR(258))
> +#define LINEAR_PT_VIRT_END      (LINEAR_PT_VIRT_START + PML4_ENTRY_BYTES)
> +/* Slot 259: linear page table (shadow table). */
> +#define SH_LINEAR_PT_VIRT_START (PML4_ADDR(259))
> +#define SH_LINEAR_PT_VIRT_END   (SH_LINEAR_PT_VIRT_START +
> PML4_ENTRY_BYTES) +/* Slot 260: per-domain mappings. */
> +#define PERDOMAIN_VIRT_START    (PML4_ADDR(260))
> +#define PERDOMAIN_VIRT_END      (PERDOMAIN_VIRT_START +
> (PERDOMAIN_MBYTES<<20)) +#define PERDOMAIN_MBYTES        (PML4_ENTRY_BYTES
> >> (20 + PAGETABLE_ORDER)) +/* Slot 261: machine-to-phys conversion table
> (256GB). */
> +#define RDWR_MPT_VIRT_START     (PML4_ADDR(261))
> +#define RDWR_MPT_VIRT_END       (RDWR_MPT_VIRT_START + MPT_VIRT_SIZE)
> +/* Slot 261: ioremap()/fixmap area (16GB). */
> +#define IOREMAP_VIRT_START      RDWR_MPT_VIRT_END
> +#define IOREMAP_VIRT_END        (IOREMAP_VIRT_START + GB(16))
> +/* Slot 261: compatibility machine-to-phys conversion table (1GB). */
> +#define RDWR_COMPAT_MPT_VIRT_START IOREMAP_VIRT_END
> +#define RDWR_COMPAT_MPT_VIRT_END (RDWR_COMPAT_MPT_VIRT_START + GB(1))
> +/* Slot 261: high read-only compat machine-to-phys conversion table (1GB).
> */ +#define HIRO_COMPAT_MPT_VIRT_START RDWR_COMPAT_MPT_VIRT_END
> +#define HIRO_COMPAT_MPT_VIRT_END (HIRO_COMPAT_MPT_VIRT_START + GB(1))
> +/* Slot 261: xen text, static data and bss (1GB). */
> +#define XEN_VIRT_START          (HIRO_COMPAT_MPT_VIRT_END)
> +#define XEN_VIRT_END            (XEN_VIRT_START + GB(1))
> +/* Slot 261: page-frame information array (40GB). */
> +#define FRAMETABLE_VIRT_END     DIRECTMAP_VIRT_START
> +#define FRAMETABLE_SIZE         ((DIRECTMAP_SIZE >> PAGE_SHIFT) * \
> +                                 SIZE(page_info))
> +#define FRAMETABLE_VIRT_START   (FRAMETABLE_VIRT_END - FRAMETABLE_SIZE)
> +/* Slot 262-271: A direct 1:1 mapping of all of physical memory. */
> +#define DIRECTMAP_VIRT_START    (PML4_ADDR(262))
> +#define DIRECTMAP_SIZE          (PML4_ENTRY_BYTES*10)
> +#define DIRECTMAP_VIRT_END      (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE)
> 
>  unsigned long long kvtop_xen_x86_64(unsigned long kvaddr);
>  #define kvtop_xen(X)	kvtop_xen_x86_64(X)

Eh, I simply computed the constants instead of importing this whole chunk. See 
also my side-by-side comparison of the virtual address space. That reminds me 
that I initially wrote that comparison as an HTML table and intended to 
publish it in the Xensource wiki...

Petr Tesarik
SUSE Linux



More information about the kexec mailing list