[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] linux-2.6.18/x86: replace order-based range checking of M2P table by linear one



# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxxxx>
# Date 1311598121 -3600
# Node ID 2ed0cbc7769eb34404efcf8877b22b2635ccf589
# Parent  678eefedc07b94b15774d05b7239201d7038a298
linux-2.6.18/x86: replace order-based range checking of M2P table by linear one

The order-based approach is not only less efficient (requiring a shift
and a compare, typical generated code looking like this

        mov     eax, [machine_to_phys_order]
        mov     ecx, eax
        shr     ebx, cl
        test    ebx, ebx
        jnz     ...

whereas a direct check requires just a compare, like in

        cmp     ebx, [machine_to_phys_nr]
        jae     ...

), but also slightly dangerous in the 32-on-64 case - the element
address calculation can wrap if the next power of two boundary is
sufficiently far away from the actual upper limit of the table, and
hence can result in user space addresses being accessed (with it being
unknown what may actually be mapped there).

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---


diff -r 678eefedc07b -r 2ed0cbc7769e arch/i386/mach-xen/setup.c
--- a/arch/i386/mach-xen/setup.c        Sat Jul 23 08:51:31 2011 +0100
+++ b/arch/i386/mach-xen/setup.c        Mon Jul 25 13:48:41 2011 +0100
@@ -90,13 +90,12 @@
 
 unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
 EXPORT_SYMBOL(machine_to_phys_mapping);
-unsigned int machine_to_phys_order;
-EXPORT_SYMBOL(machine_to_phys_order);
+unsigned long machine_to_phys_nr;
+EXPORT_SYMBOL(machine_to_phys_nr);
 
 void __init pre_setup_arch_hook(void)
 {
        struct xen_machphys_mapping mapping;
-       unsigned long machine_to_phys_nr_ents;
        struct xen_platform_parameters pp;
 
        init_mm.pgd = swapper_pg_dir = (pgd_t *)xen_start_info->pt_base;
@@ -108,10 +107,13 @@
 
        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;
+               machine_to_phys_nr = mapping.max_mfn + 1;
        } else
-               machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
-       machine_to_phys_order = fls(machine_to_phys_nr_ents - 1);
+               machine_to_phys_nr = MACH2PHYS_NR_ENTRIES;
+       if (machine_to_phys_mapping + machine_to_phys_nr
+           < machine_to_phys_mapping)
+               machine_to_phys_nr = (unsigned long *)NULL
+                                    - machine_to_phys_mapping;
 
        if (!xen_feature(XENFEAT_auto_translated_physmap))
                phys_to_machine_mapping =
diff -r 678eefedc07b -r 2ed0cbc7769e arch/x86_64/kernel/head64-xen.c
--- a/arch/x86_64/kernel/head64-xen.c   Sat Jul 23 08:51:31 2011 +0100
+++ b/arch/x86_64/kernel/head64-xen.c   Mon Jul 25 13:48:41 2011 +0100
@@ -94,13 +94,12 @@
 #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);
+unsigned long machine_to_phys_nr;
+EXPORT_SYMBOL(machine_to_phys_nr);
 
 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;
 
@@ -114,13 +113,11 @@
                xen_start_info->nr_pt_frames;
 
        machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
-       machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+       machine_to_phys_nr = 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;
+               machine_to_phys_nr = 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++)
diff -r 678eefedc07b -r 2ed0cbc7769e arch/x86_64/mm/init-xen.c
--- a/arch/x86_64/mm/init-xen.c Sat Jul 23 08:51:31 2011 +0100
+++ b/arch/x86_64/mm/init-xen.c Mon Jul 25 13:48:41 2011 +0100
@@ -1156,7 +1156,7 @@
         */
        if (addr >= (unsigned long)machine_to_phys_mapping &&
            addr < (unsigned long)(machine_to_phys_mapping +
-                                  (1UL << machine_to_phys_order)))
+                                  machine_to_phys_nr))
                return 1;
        if (addr >= HYPERVISOR_VIRT_START && addr < HYPERVISOR_VIRT_END)
                return 0;
diff -r 678eefedc07b -r 2ed0cbc7769e include/asm-i386/mach-xen/asm/maddr.h
--- a/include/asm-i386/mach-xen/asm/maddr.h     Sat Jul 23 08:51:31 2011 +0100
+++ b/include/asm-i386/mach-xen/asm/maddr.h     Mon Jul 25 13:48:41 2011 +0100
@@ -25,7 +25,7 @@
 
 #undef machine_to_phys_mapping
 extern unsigned long *machine_to_phys_mapping;
-extern unsigned int   machine_to_phys_order;
+extern unsigned long  machine_to_phys_nr;
 
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
@@ -50,7 +50,7 @@
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return mfn;
 
-       if (unlikely((mfn >> machine_to_phys_order) != 0))
+       if (unlikely(mfn >= machine_to_phys_nr))
                return max_mapnr;
 
        /* The array access can fail (e.g., device space beyond end of RAM). */
diff -r 678eefedc07b -r 2ed0cbc7769e include/asm-x86_64/mach-xen/asm/maddr.h
--- a/include/asm-x86_64/mach-xen/asm/maddr.h   Sat Jul 23 08:51:31 2011 +0100
+++ b/include/asm-x86_64/mach-xen/asm/maddr.h   Mon Jul 25 13:48:41 2011 +0100
@@ -19,7 +19,7 @@
 
 #undef machine_to_phys_mapping
 extern unsigned long *machine_to_phys_mapping;
-extern unsigned int   machine_to_phys_order;
+extern unsigned long  machine_to_phys_nr;
 
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
@@ -44,7 +44,7 @@
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return mfn;
 
-       if (unlikely((mfn >> machine_to_phys_order) != 0))
+       if (unlikely(mfn >= machine_to_phys_nr))
                return end_pfn;
 
        /* The array access can fail (e.g., device space beyond end of RAM). */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.