ia64/xen-unstable

changeset 10498:46e853c34a2e

Add new XENMEM_machphys_mapping to get info about location and
sizeof of the mach2phys table default mapping. Use this in Linux to
dynamically adapt the mfn_to_pfn() routine to undelrying hypervisor.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@dhcp93.uk.xensource.com
date Tue Jun 20 14:45:46 2006 +0100 (2006-06-20)
parents b6ee2a730139
children 69f7e0ea2985
files linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h xen/arch/x86/mm.c xen/include/public/memory.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c	Tue Jun 20 13:45:23 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c	Tue Jun 20 14:45:46 2006 +0100
     1.3 @@ -15,6 +15,7 @@
     1.4  #include <linux/kernel.h>
     1.5  #include <linux/string.h>
     1.6  #include <linux/percpu.h>
     1.7 +#include <linux/module.h>
     1.8  
     1.9  #include <asm/processor.h>
    1.10  #include <asm/proto.h>
    1.11 @@ -92,8 +93,16 @@ static void __init setup_boot_cpu_data(v
    1.12  	boot_cpu_data.x86_mask = eax & 0xf;
    1.13  }
    1.14  
    1.15 +#include <xen/interface/memory.h>
    1.16 +unsigned long *machine_to_phys_mapping;
    1.17 +EXPORT_SYMBOL(machine_to_phys_mapping);
    1.18 +unsigned int machine_to_phys_order;
    1.19 +EXPORT_SYMBOL(machine_to_phys_order);
    1.20 +
    1.21  void __init x86_64_start_kernel(char * real_mode_data)
    1.22  {
    1.23 +	struct xen_machphys_mapping mapping;
    1.24 +	unsigned long machine_to_phys_nr_ents;
    1.25  	char *s;
    1.26  	int i;
    1.27  
    1.28 @@ -105,6 +114,16 @@ void __init x86_64_start_kernel(char * r
    1.29  			xen_start_info->nr_pt_frames;
    1.30  	}
    1.31  
    1.32 +
    1.33 +	machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
    1.34 +	machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
    1.35 +	if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
    1.36 +		machine_to_phys_mapping = (unsigned long *)mapping.v_start;
    1.37 +		machine_to_phys_nr_ents = mapping.max_mfn + 1;
    1.38 +	}
    1.39 +	while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
    1.40 +		machine_to_phys_order++;
    1.41 +
    1.42  #if 0
    1.43  	for (i = 0; i < 256; i++)
    1.44  		set_intr_gate(i, early_idt_handler);
     2.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Tue Jun 20 13:45:23 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Tue Jun 20 14:45:46 2006 +0100
     2.3 @@ -67,6 +67,10 @@
     2.4  
     2.5  extern unsigned long *phys_to_machine_mapping;
     2.6  
     2.7 +#undef machine_to_phys_mapping
     2.8 +extern unsigned long *machine_to_phys_mapping;
     2.9 +extern unsigned int   machine_to_phys_order;
    2.10 +
    2.11  static inline unsigned long pfn_to_mfn(unsigned long pfn)
    2.12  {
    2.13  	if (xen_feature(XENFEAT_auto_translated_physmap))
    2.14 @@ -90,7 +94,7 @@ static inline unsigned long mfn_to_pfn(u
    2.15  	if (xen_feature(XENFEAT_auto_translated_physmap))
    2.16  		return mfn;
    2.17  
    2.18 -	if (mfn >= MACH2PHYS_NR_ENTRIES)
    2.19 +	if (unlikely((mfn >> machine_to_phys_order) != 0))
    2.20  		return max_mapnr;
    2.21  
    2.22  	/* The array access can fail (e.g., device space beyond end of RAM). */
    2.23 @@ -106,7 +110,7 @@ static inline unsigned long mfn_to_pfn(u
    2.24  		"	.long 1b,3b\n"
    2.25  		".previous"
    2.26  		: "=r" (pfn)
    2.27 -		: "m" (machine_to_phys_mapping[mfn]), "ir" (max_mapnr) );
    2.28 +		: "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
    2.29  
    2.30  	return pfn;
    2.31  }
     3.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Tue Jun 20 13:45:23 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Tue Jun 20 14:45:46 2006 +0100
     3.3 @@ -7,6 +7,7 @@
     3.4   **/
     3.5  
     3.6  #include <xen/interface/callback.h>
     3.7 +#include <xen/interface/memory.h>
     3.8  
     3.9  static char * __init machine_specific_memory_setup(void)
    3.10  {
    3.11 @@ -44,9 +45,16 @@ extern void hypervisor_callback(void);
    3.12  extern void failsafe_callback(void);
    3.13  extern void nmi(void);
    3.14  
    3.15 +unsigned long *machine_to_phys_mapping;
    3.16 +EXPORT_SYMBOL(machine_to_phys_mapping);
    3.17 +unsigned int machine_to_phys_order;
    3.18 +EXPORT_SYMBOL(machine_to_phys_order);
    3.19 +
    3.20  static void __init machine_specific_arch_setup(void)
    3.21  {
    3.22  	int ret;
    3.23 +	struct xen_machphys_mapping mapping;
    3.24 +	unsigned long machine_to_phys_nr_ents;
    3.25  	struct xen_platform_parameters pp;
    3.26  	struct callback_register event = {
    3.27  		.type = CALLBACKTYPE_event,
    3.28 @@ -81,4 +89,13 @@ static void __init machine_specific_arch
    3.29  	if (HYPERVISOR_xen_version(XENVER_platform_parameters,
    3.30  				   &pp) == 0)
    3.31  		set_fixaddr_top(pp.virt_start - PAGE_SIZE);
    3.32 +
    3.33 +	machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
    3.34 +	machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
    3.35 +	if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
    3.36 +		machine_to_phys_mapping = (unsigned long *)mapping.v_start;
    3.37 +		machine_to_phys_nr_ents = mapping.max_mfn + 1;
    3.38 +	}
    3.39 +	while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
    3.40 +		machine_to_phys_order++;
    3.41  }
     4.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Tue Jun 20 13:45:23 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Tue Jun 20 14:45:46 2006 +0100
     4.3 @@ -85,6 +85,10 @@ void copy_page(void *, void *);
     4.4  
     4.5  extern unsigned long *phys_to_machine_mapping;
     4.6  
     4.7 +#undef machine_to_phys_mapping
     4.8 +extern unsigned long *machine_to_phys_mapping;
     4.9 +extern unsigned int   machine_to_phys_order;
    4.10 +
    4.11  static inline unsigned long pfn_to_mfn(unsigned long pfn)
    4.12  {
    4.13  	if (xen_feature(XENFEAT_auto_translated_physmap))
    4.14 @@ -107,7 +111,7 @@ static inline unsigned long mfn_to_pfn(u
    4.15  	if (xen_feature(XENFEAT_auto_translated_physmap))
    4.16  		return mfn;
    4.17  
    4.18 -	if (mfn >= MACH2PHYS_NR_ENTRIES)
    4.19 +	if (unlikely((mfn >> machine_to_phys_order) != 0))
    4.20  		return end_pfn;
    4.21  
    4.22  	/* The array access can fail (e.g., device space beyond end of RAM). */
    4.23 @@ -123,7 +127,7 @@ static inline unsigned long mfn_to_pfn(u
    4.24  		"	.quad 1b,3b\n"
    4.25  		".previous"
    4.26  		: "=r" (pfn)
    4.27 -		: "m" (machine_to_phys_mapping[mfn]), "ir" (end_pfn) );
    4.28 +		: "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
    4.29  
    4.30  	return pfn;
    4.31  }
     5.1 --- a/xen/arch/x86/mm.c	Tue Jun 20 13:45:23 2006 +0100
     5.2 +++ b/xen/arch/x86/mm.c	Tue Jun 20 14:45:46 2006 +0100
     5.3 @@ -3051,6 +3051,20 @@ long arch_memory_op(int op, XEN_GUEST_HA
     5.4          return 0;
     5.5      }
     5.6  
     5.7 +    case XENMEM_machphys_mapping:
     5.8 +    {
     5.9 +        struct xen_machphys_mapping mapping = {
    5.10 +            .v_start = MACH2PHYS_VIRT_START,
    5.11 +            .v_end   = MACH2PHYS_VIRT_END,
    5.12 +            .max_mfn = MACH2PHYS_NR_ENTRIES - 1
    5.13 +        };
    5.14 +
    5.15 +        if ( copy_to_guest(arg, &mapping, 1) )
    5.16 +            return -EFAULT;
    5.17 +
    5.18 +        return 0;
    5.19 +    }
    5.20 +
    5.21      default:
    5.22          return subarch_memory_op(op, arg);
    5.23      }
     6.1 --- a/xen/include/public/memory.h	Tue Jun 20 13:45:23 2006 +0100
     6.2 +++ b/xen/include/public/memory.h	Tue Jun 20 14:45:46 2006 +0100
     6.3 @@ -141,6 +141,20 @@ typedef struct xen_machphys_mfn_list xen
     6.4  DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);
     6.5  
     6.6  /*
     6.7 + * Returns the location in virtual address space of the machine_to_phys
     6.8 + * mapping table. Architectures which do not have a m2p table, or which do not
     6.9 + * map it by default into guest address space, do not implement this command.
    6.10 + * arg == addr of xen_machphys_mapping_t.
    6.11 + */
    6.12 +#define XENMEM_machphys_mapping     12
    6.13 +struct xen_machphys_mapping {
    6.14 +    unsigned long v_start, v_end; /* Start and end virtual addresses.   */
    6.15 +    unsigned long max_mfn;        /* Maximum MFN that can be looked up. */
    6.16 +};
    6.17 +typedef struct xen_machphys_mapping xen_machphys_mapping_t;
    6.18 +DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
    6.19 +
    6.20 +/*
    6.21   * Sets the GPFN at which a particular page appears in the specified guest's
    6.22   * pseudophysical address space.
    6.23   * arg == addr of xen_add_to_physmap_t.