[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |