]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
Add new XENMEM_machphys_mapping to get info about location and
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 20 Jun 2006 14:41:40 +0000 (15:41 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 20 Jun 2006 14:41:40 +0000 (15:41 +0100)
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>
xen-unstable changeset:   10466:46e853c34a2eb537bbac8f45ba6adda949d305f0
xen-unstable date:        Tue Jun 20 14:45:46 2006 +0100

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

index 77176d0a321af269d55e842f02ba0980e0f4881e..de53871f36cff74973166fd49b101def9e42200a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/percpu.h>
+#include <linux/module.h>
 
 #include <asm/processor.h>
 #include <asm/proto.h>
@@ -92,8 +93,16 @@ static void __init setup_boot_cpu_data(void)
        boot_cpu_data.x86_mask = eax & 0xf;
 }
 
+#include <xen/interface/memory.h>
+unsigned long *machine_to_phys_mapping;
+EXPORT_SYMBOL(machine_to_phys_mapping);
+unsigned int machine_to_phys_order;
+EXPORT_SYMBOL(machine_to_phys_order);
+
 void __init x86_64_start_kernel(char * real_mode_data)
 {
+       struct xen_machphys_mapping mapping;
+       unsigned long machine_to_phys_nr_ents;
        char *s;
        int i;
 
@@ -105,6 +114,16 @@ void __init x86_64_start_kernel(char * real_mode_data)
                        xen_start_info->nr_pt_frames;
        }
 
+
+       machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
+       machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+       if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
+               machine_to_phys_mapping = (unsigned long *)mapping.v_start;
+               machine_to_phys_nr_ents = mapping.max_mfn + 1;
+       }
+       while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
+               machine_to_phys_order++;
+
 #if 0
        for (i = 0; i < 256; i++)
                set_intr_gate(i, early_idt_handler);
index f2990702bdd7292f346787528b281acbf8bd90c4..8171578175181e996a41345320da5418be1ff30f 100644 (file)
 
 extern unsigned long *phys_to_machine_mapping;
 
+#undef machine_to_phys_mapping
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int   machine_to_phys_order;
+
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -90,7 +94,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return mfn;
 
-       if (mfn >= MACH2PHYS_NR_ENTRIES)
+       if (unlikely((mfn >> machine_to_phys_order) != 0))
                return max_mapnr;
 
        /* The array access can fail (e.g., device space beyond end of RAM). */
@@ -106,7 +110,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
                "       .long 1b,3b\n"
                ".previous"
                : "=r" (pfn)
-               : "m" (machine_to_phys_mapping[mfn]), "ir" (max_mapnr) );
+               : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
 
        return pfn;
 }
index f0a3bd58fdfe95da8b119a26231b791ceab24a7b..59a84ff307ae084c271eb68afcc384b8997618a7 100644 (file)
@@ -6,6 +6,8 @@
  *     use of all of the static functions.
  **/
 
+#include <xen/interface/memory.h>
+
 static char * __init machine_specific_memory_setup(void)
 {
        unsigned long max_pfn = xen_start_info->nr_pages;
@@ -20,8 +22,15 @@ extern void hypervisor_callback(void);
 extern void failsafe_callback(void);
 extern void nmi(void);
 
+unsigned long *machine_to_phys_mapping;
+EXPORT_SYMBOL(machine_to_phys_mapping);
+unsigned int machine_to_phys_order;
+EXPORT_SYMBOL(machine_to_phys_order);
+
 static void __init machine_specific_arch_setup(void)
 {
+       struct xen_machphys_mapping mapping;
+       unsigned long machine_to_phys_nr_ents;
        struct xen_platform_parameters pp;
        struct xennmi_callback cb;
 
@@ -35,4 +44,13 @@ static void __init machine_specific_arch_setup(void)
        if (HYPERVISOR_xen_version(XENVER_platform_parameters,
                                   &pp) == 0)
                set_fixaddr_top(pp.virt_start - PAGE_SIZE);
+
+       machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
+       machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+       if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
+               machine_to_phys_mapping = (unsigned long *)mapping.v_start;
+               machine_to_phys_nr_ents = mapping.max_mfn + 1;
+       }
+       while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
+               machine_to_phys_order++;
 }
index 26a450a6b143d9595877d14c574026128f4e3031..46ce1cd5df96ba621cbf2c4f9f1b960b6ad26573 100644 (file)
@@ -85,6 +85,10 @@ void copy_page(void *, void *);
 
 extern unsigned long *phys_to_machine_mapping;
 
+#undef machine_to_phys_mapping
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int   machine_to_phys_order;
+
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -107,7 +111,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return mfn;
 
-       if (mfn >= MACH2PHYS_NR_ENTRIES)
+       if (unlikely((mfn >> machine_to_phys_order) != 0))
                return end_pfn;
 
        /* The array access can fail (e.g., device space beyond end of RAM). */
@@ -123,7 +127,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
                "       .quad 1b,3b\n"
                ".previous"
                : "=r" (pfn)
-               : "m" (machine_to_phys_mapping[mfn]), "ir" (end_pfn) );
+               : "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
 
        return pfn;
 }
index 2ce0d88939e02a98380546a3d0e7d7b18d25988c..da11df57b07088c769ce000a4febd4ec34952d50 100644 (file)
@@ -2892,6 +2892,20 @@ long arch_memory_op(int op, GUEST_HANDLE(void) arg)
         break;
     }
 
+    case XENMEM_machphys_mapping:
+    {
+        struct xen_machphys_mapping mapping = {
+            .v_start = MACH2PHYS_VIRT_START,
+            .v_end   = MACH2PHYS_VIRT_END,
+            .max_mfn = MACH2PHYS_NR_ENTRIES - 1
+        };
+
+        if ( copy_to_guest(arg, &mapping, 1) )
+            return -EFAULT;
+
+        return 0;
+    }
+
     default:
         return subarch_memory_op(op, arg);
     }
index 09ddcef7891da88b7a37b59eca55027f147df51e..912639b9db8bb3f80fa42ed6d720e71ab0d4c461 100644 (file)
@@ -137,6 +137,19 @@ typedef struct xen_machphys_mfn_list {
 } xen_machphys_mfn_list_t;
 DEFINE_GUEST_HANDLE(xen_machphys_mfn_list_t);
 
+/*
+ * Returns the location in virtual address space of the machine_to_phys
+ * mapping table. Architectures which do not have a m2p table, or which do not
+ * map it by default into guest address space, do not implement this command.
+ * arg == addr of xen_machphys_mapping_t.
+ */
+#define XENMEM_machphys_mapping     12
+typedef struct xen_machphys_mapping {
+    unsigned long v_start, v_end; /* Start and end virtual addresses.   */
+    unsigned long max_mfn;        /* Maximum MFN that can be looked up. */
+} xen_machphys_mapping_t;
+DEFINE_GUEST_HANDLE(xen_machphys_mapping_t);
+
 /*
  * Sets the GPFN at which a particular page appears in the specified guest's
  * pseudophysical address space.