# 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
|