WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] linux-2.6.18/x86: replace order-based range checking

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] linux-2.6.18/x86: replace order-based range checking of M2P table by linear one
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Mon, 25 Jul 2011 11:05:22 +0100
Delivery-date: Mon, 25 Jul 2011 03:06:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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>

--- a/arch/i386/mach-xen/setup.c
+++ b/arch/i386/mach-xen/setup.c
@@ -92,13 +92,12 @@ extern void nmi(void);
 
 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;
@@ -112,10 +111,13 @@ void __init pre_setup_arch_hook(void)
 
        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 =
--- a/arch/x86_64/kernel/head64-xen.c
+++ b/arch/x86_64/kernel/head64-xen.c
@@ -92,13 +92,12 @@ static void __init setup_boot_cpu_data(v
 #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;
 
@@ -112,13 +111,11 @@ void __init x86_64_start_kernel(char * r
                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++)
--- a/arch/x86_64/mm/init-xen.c
+++ b/arch/x86_64/mm/init-xen.c
@@ -1155,7 +1155,7 @@ int kern_addr_valid(unsigned long addr) 
         */
        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;
--- a/include/asm-i386/mach-xen/asm/maddr.h
+++ b/include/asm-i386/mach-xen/asm/maddr.h
@@ -25,7 +25,7 @@ extern unsigned long  max_mapnr;
 
 #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 @@ static inline unsigned long mfn_to_pfn(u
        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). */
--- a/include/asm-x86_64/mach-xen/asm/maddr.h
+++ b/include/asm-x86_64/mach-xen/asm/maddr.h
@@ -19,7 +19,7 @@ extern unsigned long *phys_to_machine_ma
 
 #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 @@ static inline unsigned long mfn_to_pfn(u
        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). */


Attachment: xen-x86-m2p-nr.patch
Description: Text document

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