On Mon, 2012-01-23 at 10:15 +0100, Jan Wagner wrote: > Hi there, > > On Thursday 22 December 2011 12:26:57 Jan Wagner wrote: > > On Monday, 28. November 2011, Ian Campbell wrote: > > > On Fri, 2011-11-25 at 18:27 +0100, Jan Wagner wrote: > > > > I did prepare a source package at > > > > http://ftp.cyconet.org/debian/archive/unofficial/xen/4.0.1-5/. You can > > > > also find some binary packages there ... I tried xen-hypervisor-4.0- > > > > amd64_4.0.1-5_amd64.deb on stable and this fixed the issue on the > > > > affected system. .oO(Yeah! ;) > > > > > > > > Cheers and thanks a lot, Jan. > > > > > > Great, thanks for testing. > > > > do you plan to push that into 6.0.4?
Sorry, I dropped this in the Christmas rush. I am not the maintainer of these packages so I have no ability to push directly into any release. > I don't know, if the timeframe is too short for this, but is there a chance > to > get this into 6.0.4? I suspect it is too late. Bastian what do you think? Fix is attached, unchanged from last time. Ian. -- Ian Campbell The Golden Rule is of no use to you whatever unless you realize it is your move. -- Frank Crane
>From 4ed5ce3d8f29eefebbfbfe5bde767d80fcc74e5e Mon Sep 17 00:00:00 2001 From: Ian Campbell <i...@hellion.org.uk> Date: Tue, 29 Nov 2011 13:38:41 +0000 Subject: [PATCH] Fix 649923 --- xen/debian/changelog | 7 + xen/debian/patches/series | 1 + xen/debian/patches/upstream-22375:426f3a265784 | 1080 ++++++++++++++++++++++++ 3 files changed, 1088 insertions(+), 0 deletions(-) create mode 100644 xen/debian/patches/upstream-22375:426f3a265784 diff --git a/xen/debian/changelog b/xen/debian/changelog index a62d772..2bcde38 100644 --- a/xen/debian/changelog +++ b/xen/debian/changelog @@ -1,3 +1,10 @@ +xen (4.0.1-5) UNRELEASED; urgency=low + + * Backport fix to remove lowmem 1:1 mapping which fixes boot on some classes + of machine. (Closes: #649923) + + -- Ian Campbell <i...@hellion.org.uk> Fri, 25 Nov 2011 10:37:16 +0000 + xen (4.0.1-4) stable-security; urgency=low * Fix overflows and missing error checks in PV kernel loader. diff --git a/xen/debian/patches/series b/xen/debian/patches/series index e558b03..3da54dd 100644 --- a/xen/debian/patches/series +++ b/xen/debian/patches/series @@ -71,3 +71,4 @@ upstream-21413:b05fa0652463 upstream-21461:ee088a0b5cb8-CVE-2011-1166 upstream-21482:c2adc059e931-CVE-2011-1583 upstream-21485:b85a9e58ec3a-CVE-2011-1898 +upstream-22375:426f3a265784 diff --git a/xen/debian/patches/upstream-22375:426f3a265784 b/xen/debian/patches/upstream-22375:426f3a265784 new file mode 100644 index 0000000..052c7a0 --- /dev/null +++ b/xen/debian/patches/upstream-22375:426f3a265784 @@ -0,0 +1,1080 @@ +# HG changeset patch +# User Keir Fraser <k...@xen.org> +# Date 1289303389 0 +# Node ID 426f3a2657844cec77ce0043b0408b0887fafa41 +# Parent 9997a1418633c92286189b33f701ecbac2a98ccd +x86: do away with the boot time low-memory 1:1 mapping + +By doing so, we're no longer restricted to be able to place all boot +loader modules into the low 1Gb/4Gb (32-/64-bit) of memory, nor is +there a dependency anymore on where the boot loader places the +modules. + +We're also no longer restricted to copy the modules into a place below +4Gb, nor to put them all together into a single piece of memory. + +Further it allows even the 32-bit Dom0 kernel to be loaded anywhere in +physical memory (except if it doesn't support PAE-above-4G). + +Signed-off-by: Jan Beulich <jbeul...@novell.com> + +diff -r b536ebfba183 xen/arch/x86/boot/Makefile +--- a/xen/arch/x86/boot/Makefile Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/boot/Makefile Fri Nov 25 10:54:50 2011 +0000 +@@ -4,6 +4,6 @@ head.o: reloc.S + + BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' $(BASEDIR)/include/asm-x86/config.h) + %.S: %.c +- RELOC=$(BOOT_TRAMPOLINE) XEN_BITSPERLONG=$(patsubst x86_%,%,$(TARGET_SUBARCH)) $(MAKE) -f build32.mk $@ ++ RELOC=$(BOOT_TRAMPOLINE) $(MAKE) -f build32.mk $@ + + reloc.S: $(BASEDIR)/include/asm-x86/config.h +diff -r b536ebfba183 xen/arch/x86/boot/build32.mk +--- a/xen/arch/x86/boot/build32.mk Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/boot/build32.mk Fri Nov 25 10:54:50 2011 +0000 +@@ -19,6 +19,6 @@ CFLAGS += -Werror -fno-builtin -msoft-fl + $(LD) $(LDFLAGS_DIRECT) -N -Ttext $(RELOC) -o $@ $< + + %.o: %.c +- $(CC) $(CFLAGS) -DXEN_BITSPERLONG=$(XEN_BITSPERLONG) -c $< -o $@ ++ $(CC) $(CFLAGS) -c $< -o $@ + + reloc.o: $(BASEDIR)/include/asm-x86/config.h +diff -r b536ebfba183 xen/arch/x86/boot/head.S +--- a/xen/arch/x86/boot/head.S Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/boot/head.S Fri Nov 25 10:54:50 2011 +0000 +@@ -110,12 +110,15 @@ 1: mov %edx,sym_phys(cpuid_ext_ + /* Initialise L2 identity-map and xen page table entries (16MB). */ + mov $sym_phys(l2_identmap),%edi + mov $sym_phys(l2_xenmap),%esi ++ mov $sym_phys(l2_bootmap),%edx + mov $0x1e3,%eax /* PRESENT+RW+A+D+2MB+GLOBAL */ + mov $8,%ecx + 1: mov %eax,(%edi) + add $8,%edi + mov %eax,(%esi) + add $8,%esi ++ mov %eax,(%edx) ++ add $8,%edx + add $(1<<L2_PAGETABLE_SHIFT),%eax + loop 1b + /* Initialise L3 identity-map page directory entries. */ +@@ -129,9 +132,13 @@ 1: mov %eax,(%edi) + /* Initialise L3 xen-map page directory entry. */ + mov $(sym_phys(l2_xenmap)+7),%eax + mov %eax,sym_phys(l3_xenmap) + l3_table_offset(XEN_VIRT_START)*8 +- /* Hook identity-map and xen-map L3 tables into PML4. */ ++ /* Initialise L3 boot-map page directory entry. */ ++ mov $(sym_phys(l2_bootmap)+7),%eax ++ mov %eax,sym_phys(l3_bootmap) + 0*8 ++ /* Hook identity-map, xen-map, and boot-map L3 tables into PML4. */ ++ mov $(sym_phys(l3_bootmap)+7),%eax ++ mov %eax,sym_phys(idle_pg_table) + 0*8 + mov $(sym_phys(l3_identmap)+7),%eax +- mov %eax,sym_phys(idle_pg_table) + ( 0*8) /* PML4[ 0]: 1:1 map */ + mov %eax,sym_phys(idle_pg_table) + l4_table_offset(DIRECTMAP_VIRT_START)*8 + mov $(sym_phys(l3_xenmap)+7),%eax + mov %eax,sym_phys(idle_pg_table) + l4_table_offset(XEN_VIRT_START)*8 +@@ -176,6 +183,7 @@ 2: cmp $L1_PAGETABLE_ENTRIES,%e + #if defined(__x86_64__) + mov %edi,sym_phys(l2_identmap) + mov %edi,sym_phys(l2_xenmap) ++ mov %edi,sym_phys(l2_bootmap) + #else + mov %edi,sym_phys(idle_pg_table_l2) + mov %edi,sym_phys(idle_pg_table_l2) + (__PAGE_OFFSET>>18) +diff -r b536ebfba183 xen/arch/x86/boot/reloc.c +--- a/xen/arch/x86/boot/reloc.c Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/boot/reloc.c Fri Nov 25 10:54:50 2011 +0000 +@@ -68,7 +68,6 @@ multiboot_info_t *reloc(multiboot_info_t + { + module_t *mods = reloc_mbi_struct( + (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t)); +- u32 max_addr = 0; + + mbi->mods_addr = (u32)mods; + +@@ -76,29 +75,6 @@ multiboot_info_t *reloc(multiboot_info_t + { + if ( mods[i].string ) + mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string); +- if ( mods[i].mod_end > max_addr ) +- max_addr = mods[i].mod_end; +- } +- +- /* +- * 32-bit Xen only maps bottom 1GB of memory at boot time. Relocate +- * modules which extend beyond this (GRUB2 in particular likes to +- * place modules as high as possible below 4GB). +- */ +-#define BOOTMAP_END (1ul<<30) /* 1GB */ +- if ( (XEN_BITSPERLONG == 32) && (max_addr > BOOTMAP_END) ) +- { +- char *mod_alloc = (char *)BOOTMAP_END; +- for ( i = 0; i < mbi->mods_count; i++ ) +- mod_alloc -= mods[i].mod_end - mods[i].mod_start; +- for ( i = 0; i < mbi->mods_count; i++ ) +- { +- u32 mod_len = mods[i].mod_end - mods[i].mod_start; +- mods[i].mod_start = (u32)memcpy( +- mod_alloc, (char *)mods[i].mod_start, mod_len); +- mods[i].mod_end = mods[i].mod_start + mod_len; +- mod_alloc += mod_len; +- } + } + } + +diff -r b536ebfba183 xen/arch/x86/domain_build.c +--- a/xen/arch/x86/domain_build.c Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/domain_build.c Fri Nov 25 10:54:50 2011 +0000 +@@ -30,6 +30,7 @@ + #include <asm/p2m.h> + #include <asm/e820.h> + #include <asm/acpi.h> ++#include <asm/setup.h> + #include <asm/bzimage.h> /* for bzimage_parse */ + + #include <public/version.h> +@@ -282,9 +283,9 @@ static void __init process_dom0_ioports_ + + int __init construct_dom0( + struct domain *d, +- unsigned long _image_base, +- unsigned long _image_start, unsigned long image_len, +- unsigned long _initrd_start, unsigned long initrd_len, ++ const module_t *image, unsigned long image_headroom, ++ const module_t *initrd, ++ void *(*bootstrap_map)(const module_t *), + char *cmdline) + { + int i, rc, compatible, compat32, order, machine; +@@ -299,16 +300,14 @@ int __init construct_dom0( + start_info_t *si; + struct vcpu *v = d->vcpu[0]; + unsigned long long value; +-#if defined(__i386__) +- char *image_base = (char *)_image_base; /* use lowmem mappings */ +- char *image_start = (char *)_image_start; /* use lowmem mappings */ +- char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */ +-#elif defined(__x86_64__) +- char *image_base = __va(_image_base); +- char *image_start = __va(_image_start); +- char *initrd_start = __va(_initrd_start); +-#endif +-#if CONFIG_PAGING_LEVELS >= 4 ++ char *image_base = bootstrap_map(image); ++ unsigned long image_len = image->mod_end; ++ char *image_start = image_base + image_headroom; ++ unsigned long initrd_len = initrd ? initrd->mod_end : 0; ++#if CONFIG_PAGING_LEVELS < 4 ++ module_t mpt; ++ void *mpt_ptr; ++#else + l4_pgentry_t *l4tab = NULL, *l4start = NULL; + #endif + l3_pgentry_t *l3tab = NULL, *l3start = NULL; +@@ -338,7 +337,7 @@ int __init construct_dom0( + unsigned long v_end; + + /* Machine address of next candidate page-table page. */ +- unsigned long mpt_alloc; ++ paddr_t mpt_alloc; + + /* Sanity! */ + BUG_ON(d->domain_id != 0); +@@ -493,17 +492,17 @@ int __init construct_dom0( + if ( (1UL << order) > nr_pages ) + panic("Domain 0 allocation is too small for kernel image.\n"); + +-#ifdef __i386__ +- /* Ensure that our low-memory 1:1 mapping covers the allocation. */ +- page = alloc_domheap_pages(d, order, MEMF_bits(30)); +-#else + if ( parms.p2m_base != UNSET_ADDR ) + { + vphysmap_start = parms.p2m_base; + vphysmap_end = vphysmap_start + nr_pages * sizeof(unsigned long); + } +- page = alloc_domheap_pages(d, order, 0); ++#ifdef __i386__ ++ if ( !test_bit(XENFEAT_pae_pgdir_above_4gb, parms.f_supported) ) ++ page = alloc_domheap_pages(d, order, MEMF_bits(32)); ++ else + #endif ++ page = alloc_domheap_pages(d, order, 0); + if ( page == NULL ) + panic("Not enough RAM for domain 0 allocation.\n"); + alloc_spfn = page_to_mfn(page); +@@ -532,8 +531,7 @@ int __init construct_dom0( + _p(v_start), _p(v_end)); + printk(" ENTRY ADDRESS: %p\n", _p(parms.virt_entry)); + +- mpt_alloc = (vpt_start - v_start) + +- (unsigned long)pfn_to_paddr(alloc_spfn); ++ mpt_alloc = (vpt_start - v_start) + pfn_to_paddr(alloc_spfn); + + #if defined(__i386__) + /* +@@ -546,17 +544,25 @@ int __init construct_dom0( + return -EINVAL; + } + ++ mpt.mod_start = mpt_alloc >> PAGE_SHIFT; ++ mpt.mod_end = vpt_end - vpt_start; ++ mpt_ptr = bootstrap_map(&mpt); ++#define MPT_ALLOC(n) (mpt_ptr += (n)*PAGE_SIZE, mpt_alloc += (n)*PAGE_SIZE) ++ + /* WARNING: The new domain must have its 'processor' field filled in! */ +- l3start = l3tab = (l3_pgentry_t *)mpt_alloc; mpt_alloc += PAGE_SIZE; +- l2start = l2tab = (l2_pgentry_t *)mpt_alloc; mpt_alloc += 4*PAGE_SIZE; ++ l3start = l3tab = mpt_ptr; MPT_ALLOC(1); ++ l2start = l2tab = mpt_ptr; MPT_ALLOC(4); + for (i = 0; i < L3_PAGETABLE_ENTRIES; i++) { +- copy_page(l2tab + i * L2_PAGETABLE_ENTRIES, +- idle_pg_table_l2 + i * L2_PAGETABLE_ENTRIES); +- l3tab[i] = l3e_from_paddr((u32)l2tab + i*PAGE_SIZE, L3_PROT); ++ if ( i < 3 ) ++ clear_page(l2tab + i * L2_PAGETABLE_ENTRIES); ++ else ++ copy_page(l2tab + i * L2_PAGETABLE_ENTRIES, ++ idle_pg_table_l2 + i * L2_PAGETABLE_ENTRIES); ++ l3tab[i] = l3e_from_pfn(mpt.mod_start + 1 + i, L3_PROT); + l2tab[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT)+i] = +- l2e_from_paddr((u32)l2tab + i*PAGE_SIZE, __PAGE_HYPERVISOR); ++ l2e_from_pfn(mpt.mod_start + 1 + i, __PAGE_HYPERVISOR); + } +- v->arch.guest_table = pagetable_from_paddr((unsigned long)l3start); ++ v->arch.guest_table = pagetable_from_pfn(mpt.mod_start); + + for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) + l2tab[l2_linear_offset(PERDOMAIN_VIRT_START) + i] = +@@ -568,9 +574,9 @@ int __init construct_dom0( + { + if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) + { +- l1start = l1tab = (l1_pgentry_t *)mpt_alloc; +- mpt_alloc += PAGE_SIZE; +- *l2tab = l2e_from_paddr((unsigned long)l1start, L2_PROT); ++ l1tab = mpt_ptr; ++ *l2tab = l2e_from_paddr(mpt_alloc, L2_PROT); ++ MPT_ALLOC(1); + l2tab++; + clear_page(l1tab); + if ( count == 0 ) +@@ -585,11 +591,14 @@ int __init construct_dom0( + + mfn++; + } ++#undef MPT_ALLOC + + /* Pages that are part of page tables must be read only. */ ++ mpt_alloc = (paddr_t)mpt.mod_start << PAGE_SHIFT; ++ mpt_ptr = l3start; + l2tab = l2start + l2_linear_offset(vpt_start); +- l1start = l1tab = (l1_pgentry_t *)(u32)l2e_get_paddr(*l2tab); +- l1tab += l1_table_offset(vpt_start); ++ l1start = mpt_ptr + (l2e_get_paddr(*l2tab) - mpt_alloc); ++ l1tab = l1start + l1_table_offset(vpt_start); + for ( count = 0; count < nr_pt_pages; count++ ) + { + page = mfn_to_page(l1e_get_pfn(*l1tab)); +@@ -625,9 +634,15 @@ int __init construct_dom0( + break; + } + if ( !((unsigned long)++l1tab & (PAGE_SIZE - 1)) ) +- l1start = l1tab = (l1_pgentry_t *)(u32)l2e_get_paddr(*++l2tab); ++ l1tab = mpt_ptr + (l2e_get_paddr(*++l2tab) - mpt_alloc); + } + ++ /* ++ * Put Xen's first L3 entry into Dom0's page tables so that updates ++ * through bootstrap_map() will affect the page tables we will run on. ++ */ ++ l3start[0] = l3e_from_paddr(__pa(idle_pg_table_l2), L3_PROT); ++ + #elif defined(__x86_64__) + + /* Overlap with Xen protected area? */ +@@ -801,6 +816,7 @@ int __init construct_dom0( + /* Copy the OS image and free temporary buffer. */ + elf.dest = (void*)vkern_start; + elf_load_binary(&elf); ++ bootstrap_map(NULL); + + if ( UNSET_ADDR != parms.virt_hypercall ) + { +@@ -817,7 +833,12 @@ int __init construct_dom0( + + /* Copy the initial ramdisk. */ + if ( initrd_len != 0 ) ++ { ++ char *initrd_start = bootstrap_map(initrd); ++ + memcpy((void *)vinitrd_start, initrd_start, initrd_len); ++ bootstrap_map(NULL); ++ } + + /* Free temporary buffers. */ + discard_initial_images(); +@@ -1025,7 +1046,22 @@ int __init construct_dom0( + write_ptbase(current); + + #if defined(__i386__) +- /* Destroy low mappings - they were only for our convenience. */ ++ /* Restore Dom0's first L3 entry. */ ++ mpt.mod_end = 5 * PAGE_SIZE; ++ l3start = mpt_ptr = bootstrap_map(&mpt); ++ l2start = mpt_ptr + PAGE_SIZE; ++ l3start[0] = l3e_from_pfn(mpt.mod_start + 1, L3_PROT); ++ ++ /* Re-setup CR3 */ ++ if ( paging_mode_enabled(d) ) ++ paging_update_paging_modes(v); ++ else ++ update_cr3(v); ++ ++ /* ++ * Destroy low mappings - they were only for our convenience. Note ++ * that zap_low_mappings() exceeds what bootstrap_map(NULL) would do. ++ */ + zap_low_mappings(l2start); + #endif + +diff -r b536ebfba183 xen/arch/x86/setup.c +--- a/xen/arch/x86/setup.c Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/setup.c Fri Nov 25 10:54:50 2011 +0000 +@@ -43,14 +43,6 @@ + #include <asm/mach-generic/mach_apic.h> /* for generic_apic_probe */ + #include <asm/setup.h> + +-#if defined(CONFIG_X86_64) +-#define BOOTSTRAP_DIRECTMAP_END (1UL << 32) /* 4GB */ +-#define maddr_to_bootstrap_virt(m) maddr_to_virt(m) +-#else +-#define BOOTSTRAP_DIRECTMAP_END (1UL << 30) /* 1GB */ +-#define maddr_to_bootstrap_virt(m) ((void *)(long)(m)) +-#endif +- + extern u16 boot_edid_caps; + extern u8 boot_edid_info[128]; + extern struct boot_video_info boot_vid_info; +@@ -167,21 +159,34 @@ static void __init do_initcalls(void) + for ( ; ; ) halt(); \ + } while (0) + +-static unsigned long __initdata initial_images_base; +-static unsigned long __initdata initial_images_start; +-static unsigned long __initdata initial_images_end; ++static const module_t *__initdata initial_images; ++static unsigned int __initdata nr_initial_images; + + unsigned long __init initial_images_nrpages(void) + { +- ASSERT(!(initial_images_base & ~PAGE_MASK)); +- ASSERT(!(initial_images_end & ~PAGE_MASK)); +- return ((initial_images_end >> PAGE_SHIFT) - +- (initial_images_base >> PAGE_SHIFT)); ++ unsigned long nr; ++ unsigned int i; ++ ++ for ( nr = i = 0; i < nr_initial_images; ++i ) ++ nr += PFN_UP(initial_images[i].mod_end); ++ ++ return nr; + } + + void __init discard_initial_images(void) + { +- init_domheap_pages(initial_images_base, initial_images_end); ++ unsigned int i; ++ ++ for ( i = 0; i < nr_initial_images; ++i ) ++ { ++ uint64_t start = (uint64_t)initial_images[i].mod_start << PAGE_SHIFT; ++ ++ init_domheap_pages(start, ++ start + PAGE_ALIGN(initial_images[i].mod_end)); ++ } ++ ++ nr_initial_images = 0; ++ initial_images = NULL; + } + + static void free_xen_data(char *s, char *e) +@@ -273,33 +278,128 @@ void __devinit srat_detect_node(int cpu) + printk("CPU %d APIC %d -> Node %d\n", cpu, apicid, node); + } + ++#define BOOTSTRAP_MAP_BASE (16UL << 20) ++#define BOOTSTRAP_MAP_LIMIT (1UL << L3_PAGETABLE_SHIFT) ++ + /* + * Ensure a given physical memory range is present in the bootstrap mappings. + * Use superpage mappings to ensure that pagetable memory needn't be allocated. + */ +-static void __init bootstrap_map(unsigned long start, unsigned long end) ++static void *__init bootstrap_map(const module_t *mod) + { +- unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1; +- start = max_t(unsigned long, start & ~mask, 16UL << 20); +- end = (end + mask) & ~mask; ++ static unsigned long __initdata map_cur = BOOTSTRAP_MAP_BASE; ++ uint64_t start, end, mask = (1L << L2_PAGETABLE_SHIFT) - 1; ++ void *ret; ++ ++#ifdef __x86_64__ ++ if ( !early_boot ) ++ return mod ? mfn_to_virt(mod->mod_start) : NULL; ++#endif ++ ++ if ( !mod ) ++ { ++ destroy_xen_mappings(BOOTSTRAP_MAP_BASE, BOOTSTRAP_MAP_LIMIT); ++ map_cur = BOOTSTRAP_MAP_BASE; ++ return NULL; ++ } ++ ++ start = (uint64_t)mod->mod_start << PAGE_SHIFT; ++ end = start + mod->mod_end; + if ( start >= end ) +- return; +- if ( end > BOOTSTRAP_DIRECTMAP_END ) +- panic("Cannot access memory beyond end of " +- "bootstrap direct-map area\n"); +- map_pages_to_xen( +- (unsigned long)maddr_to_bootstrap_virt(start), +- start >> PAGE_SHIFT, (end-start) >> PAGE_SHIFT, PAGE_HYPERVISOR); ++ return NULL; ++ ++ if ( end <= BOOTSTRAP_MAP_BASE ) ++ return (void *)(unsigned long)start; ++ ++ ret = (void *)(map_cur + (unsigned long)(start & mask)); ++ start &= ~mask; ++ end = (end + mask) & ~mask; ++ if ( end - start > BOOTSTRAP_MAP_LIMIT - map_cur ) ++ return NULL; ++ ++ map_pages_to_xen(map_cur, start >> PAGE_SHIFT, ++ (end - start) >> PAGE_SHIFT, PAGE_HYPERVISOR); ++ map_cur += end - start; ++ return ret; + } + +-static void __init move_memory( +- unsigned long dst, unsigned long src_start, unsigned long src_end) ++static void *__init move_memory( ++ uint64_t dst, uint64_t src, unsigned int size, bool_t keep) + { +- bootstrap_map(src_start, src_end); +- bootstrap_map(dst, dst + src_end - src_start); +- memmove(maddr_to_bootstrap_virt(dst), +- maddr_to_bootstrap_virt(src_start), +- src_end - src_start); ++ unsigned int blksz = BOOTSTRAP_MAP_LIMIT - BOOTSTRAP_MAP_BASE; ++ unsigned int mask = (1L << L2_PAGETABLE_SHIFT) - 1; ++ ++ if ( src + size > BOOTSTRAP_MAP_BASE ) ++ blksz >>= 1; ++ ++ while ( size ) ++ { ++ module_t mod; ++ unsigned int soffs = src & mask; ++ unsigned int doffs = dst & mask; ++ unsigned int sz; ++ void *d, *s; ++ ++ mod.mod_start = (src - soffs) >> PAGE_SHIFT; ++ mod.mod_end = soffs + size; ++ if ( mod.mod_end > blksz ) ++ mod.mod_end = blksz; ++ sz = mod.mod_end - soffs; ++ s = bootstrap_map(&mod); ++ ++ mod.mod_start = (dst - doffs) >> PAGE_SHIFT; ++ mod.mod_end = doffs + size; ++ if ( mod.mod_end > blksz ) ++ mod.mod_end = blksz; ++ if ( sz > mod.mod_end - doffs ) ++ sz = mod.mod_end - doffs; ++ d = bootstrap_map(&mod); ++ ++ memmove(d + doffs, s + soffs, sz); ++ ++ dst += sz; ++ src += sz; ++ size -= sz; ++ ++ if ( keep ) ++ return size ? NULL : d + doffs; ++ ++ bootstrap_map(NULL); ++ } ++ ++ return NULL; ++} ++ ++static uint64_t __init consider_modules( ++ uint64_t s, uint64_t e, uint32_t size, const module_t *mod, ++ unsigned int nr_mods, unsigned int this_mod) ++{ ++ unsigned int i; ++ ++ if ( s > e || e - s < size ) ++ return 0; ++ ++ for ( i = 0; i < nr_mods ; ++i ) ++ { ++ uint64_t start = (uint64_t)mod[i].mod_start << PAGE_SHIFT; ++ uint64_t end = start + PAGE_ALIGN(mod[i].mod_end); ++ ++ if ( i == this_mod ) ++ continue; ++ ++ if ( s < end && start < e ) ++ { ++ end = consider_modules(end, e, size, mod + i + 1, ++ nr_mods - i - 1, this_mod - i - 1); ++ if ( end ) ++ return end; ++ ++ return consider_modules(s, start, size, mod + i + 1, ++ nr_mods - i - 1, this_mod - i - 1); ++ } ++ } ++ ++ return e; + } + + static void __init setup_max_pdx(void) +@@ -463,11 +563,10 @@ void __init __start_xen(unsigned long mb + { + char *memmap_type = NULL; + char *cmdline, *kextra, *loader; +- unsigned long _initrd_start = 0, _initrd_len = 0; + unsigned int initrdidx = 1; + multiboot_info_t *mbi = __va(mbi_p); + module_t *mod = (module_t *)__va(mbi->mods_addr); +- unsigned long nr_pages, modules_length, modules_headroom; ++ unsigned long nr_pages, modules_headroom; + int i, j, e820_warn = 0, bytes = 0; + bool_t acpi_boot_table_init_done = 0; + struct ns16550_defaults ns16550 = { +@@ -666,6 +765,9 @@ void __init __start_xen(unsigned long mb + /* Early kexec reservation (explicit static start address). */ + kexec_reserve_area(&boot_e820); + ++ initial_images = mod; ++ nr_initial_images = mbi->mods_count; ++ + /* + * Iterate backwards over all superpage-aligned RAM regions. + * +@@ -679,48 +781,64 @@ void __init __start_xen(unsigned long mb + * we can relocate the dom0 kernel and other multiboot modules. Also, on + * x86/64, we relocate Xen to higher memory. + */ +- modules_length = 0; + for ( i = 0; i < mbi->mods_count; i++ ) +- modules_length += mod[i].mod_end - mod[i].mod_start; ++ { ++ if ( mod[i].mod_start & (PAGE_SIZE - 1) ) ++ EARLY_FAIL("Bootloader didn't honor module alignment request.\n"); ++ mod[i].mod_end -= mod[i].mod_start; ++ mod[i].mod_start >>= PAGE_SHIFT; ++ mod[i].reserved = 0; ++ } + +- /* ensure mod[0] is mapped before parsing */ +- bootstrap_map(mod[0].mod_start, mod[0].mod_end); +- modules_headroom = bzimage_headroom( +- (char *)(unsigned long)mod[0].mod_start, +- (unsigned long)(mod[0].mod_end - mod[0].mod_start)); ++ modules_headroom = bzimage_headroom(bootstrap_map(mod), mod->mod_end); ++ bootstrap_map(NULL); + + for ( i = boot_e820.nr_map-1; i >= 0; i-- ) + { + uint64_t s, e, mask = (1UL << L2_PAGETABLE_SHIFT) - 1; ++ uint64_t end, limit = ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT; + +- /* Superpage-aligned chunks from 16MB to BOOTSTRAP_DIRECTMAP_END. */ ++ /* Superpage-aligned chunks from BOOTSTRAP_MAP_BASE. */ + s = (boot_e820.map[i].addr + mask) & ~mask; + e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask; +- s = max_t(uint64_t, s, 16 << 20); +- e = min_t(uint64_t, e, BOOTSTRAP_DIRECTMAP_END); ++ s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE); + if ( (boot_e820.map[i].type != E820_RAM) || (s >= e) ) + continue; + +- set_pdx_range(s >> PAGE_SHIFT, e >> PAGE_SHIFT); +- +- /* Map the chunk. No memory will need to be allocated to do this. */ +- map_pages_to_xen( +- (unsigned long)maddr_to_bootstrap_virt(s), +- s >> PAGE_SHIFT, (e-s) >> PAGE_SHIFT, PAGE_HYPERVISOR); ++ if ( s < limit ) ++ { ++ end = min(e, limit); ++ set_pdx_range(s >> PAGE_SHIFT, end >> PAGE_SHIFT); ++#ifdef CONFIG_X86_64 ++ map_pages_to_xen((unsigned long)__va(s), s >> PAGE_SHIFT, ++ (end - s) >> PAGE_SHIFT, PAGE_HYPERVISOR); ++#endif ++ } + + #if defined(CONFIG_X86_64) ++ e = min_t(uint64_t, e, 1ULL << (PAGE_SHIFT + 32)); + #define reloc_size ((__pa(&_end) + mask) & ~mask) + /* Is the region suitable for relocating Xen? */ +- if ( !xen_phys_start && ((e-s) >= reloc_size) ) ++ if ( !xen_phys_start && e <= limit ) ++ { ++ /* Don't overlap with modules. */ ++ end = consider_modules(s, e, reloc_size + mask, ++ mod, mbi->mods_count, -1); ++ end &= ~mask; ++ } ++ else ++ end = 0; ++ if ( end > s ) + { + extern l2_pgentry_t l2_xenmap[]; + l4_pgentry_t *pl4e; + l3_pgentry_t *pl3e; + l2_pgentry_t *pl2e; + int i, j, k; ++ void *dst; + + /* Select relocation address. */ +- e -= reloc_size; ++ e = end - reloc_size; + xen_phys_start = e; + bootsym(trampoline_xen_phys_start) = e; + +@@ -731,10 +849,10 @@ void __init __start_xen(unsigned long mb + * data until after we have switched to the relocated pagetables! + */ + barrier(); +- move_memory(e, 0, __pa(&_end) - xen_phys_start); ++ dst = move_memory(e, 0, (unsigned long)&_end - XEN_VIRT_START, 1); + + /* Poison low 1MB to detect stray pointers to physical 0-1MB. */ +- memset(maddr_to_bootstrap_virt(e), 0x55, 1U<<20); ++ memset(dst, 0x55, 1U << 20); + + /* Walk initial pagetables, relocating page directory entries. */ + pl4e = __va(__pa(idle_pg_table)); +@@ -791,38 +909,58 @@ void __init __start_xen(unsigned long mb + "movq %%rsi,%%cr4 " /* CR4.PGE == 1 */ + : : "r" (__pa(idle_pg_table)), "S" (cpu0_stack), + "D" (__va(__pa(cpu0_stack))), "c" (STACK_SIZE) : "memory" ); ++ ++ bootstrap_map(NULL); + } + #endif + + /* Is the region suitable for relocating the multiboot modules? */ +- if ( !initial_images_start && (s < e) && +- ((e-s) >= (modules_length+modules_headroom)) ) ++ for ( j = mbi->mods_count - 1; j >= 0; j-- ) + { +- initial_images_end = e; +- initial_images_start = initial_images_end - modules_length; +- initial_images_base = initial_images_start - modules_headroom; +- initial_images_base &= PAGE_MASK; +- for ( j = mbi->mods_count-1; j >= 0; j-- ) ++ unsigned long headroom = j ? 0 : modules_headroom; ++ unsigned long size = PAGE_ALIGN(headroom + mod[j].mod_end); ++ ++ if ( mod[j].reserved ) ++ continue; ++ ++ /* Don't overlap with other modules. */ ++ end = consider_modules(s, e, size, mod, mbi->mods_count, j); ++ ++ if ( s < end && ++ (headroom || ++ ((end - size) >> PAGE_SHIFT) > mod[j].mod_start) ) + { +- e -= mod[j].mod_end - mod[j].mod_start; +- move_memory(e, mod[j].mod_start, mod[j].mod_end); +- mod[j].mod_end += e - mod[j].mod_start; +- mod[j].mod_start = e; ++ move_memory(end - size + headroom, ++ (uint64_t)mod[j].mod_start << PAGE_SHIFT, ++ mod[j].mod_end, 0); ++ mod[j].mod_start = (end - size) >> PAGE_SHIFT; ++ mod[j].mod_end += headroom; ++ mod[j].reserved = 1; + } +- e = initial_images_base; + } + +- if ( !kexec_crash_area.start && (s < e) && +- ((e-s) >= kexec_crash_area.size) ) ++#ifdef CONFIG_X86_32 ++ /* Confine the kexec area to below 4Gb. */ ++ e = min_t(uint64_t, e, 1ULL << 32); ++#endif ++ /* Don't overlap with modules. */ ++ e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), ++ mod, mbi->mods_count, -1); ++ if ( !kexec_crash_area.start && (s < e) ) + { + e = (e - kexec_crash_area.size) & PAGE_MASK; + kexec_crash_area.start = e; + } + } + +- if ( !initial_images_start ) ++ if ( modules_headroom && !mod->reserved ) + EARLY_FAIL("Not enough memory to relocate the dom0 kernel image.\n"); +- reserve_e820_ram(&boot_e820, initial_images_base, initial_images_end); ++ for ( i = 0; i < mbi->mods_count; ++i ) ++ { ++ uint64_t s = (uint64_t)mod[i].mod_start << PAGE_SHIFT; ++ ++ reserve_e820_ram(&boot_e820, s, s + PAGE_ALIGN(mod[i].mod_end)); ++ } + + #if defined(CONFIG_X86_32) + xenheap_initial_phys_start = (PFN_UP(__pa(&_end)) + 1) << PAGE_SHIFT; +@@ -846,7 +984,10 @@ void __init __start_xen(unsigned long mb + */ + for ( i = 0; i < boot_e820.nr_map; i++ ) + { +- uint64_t s, e, map_s, map_e, mask = PAGE_SIZE - 1; ++ uint64_t s, e, mask = PAGE_SIZE - 1; ++#ifdef CONFIG_X86_64 ++ uint64_t map_s, map_e; ++#endif + + /* Only page alignment required now. */ + s = (boot_e820.map[i].addr + mask) & ~mask; +@@ -861,7 +1002,7 @@ void __init __start_xen(unsigned long mb + + #ifdef __x86_64__ + if ( !acpi_boot_table_init_done && +- s >= BOOTSTRAP_DIRECTMAP_END && ++ s >= (1ULL << 32) && + !acpi_boot_table_init() ) + { + acpi_boot_table_init_done = 1; +@@ -900,26 +1041,60 @@ void __init __start_xen(unsigned long mb + + set_pdx_range(s >> PAGE_SHIFT, e >> PAGE_SHIFT); + +- /* Need to create mappings above 16MB. */ +- map_s = max_t(uint64_t, s, 16<<20); +- map_e = e; +-#if defined(CONFIG_X86_32) /* mappings are truncated on x86_32 */ +- map_e = min_t(uint64_t, map_e, BOOTSTRAP_DIRECTMAP_END); +-#endif ++#ifdef CONFIG_X86_64 ++ /* Need to create mappings above BOOTSTRAP_MAP_BASE. */ ++ map_s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE); ++ map_e = min_t(uint64_t, e, ++ ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT); + + /* Pass mapped memory to allocator /before/ creating new mappings. */ +- init_boot_pages(s, min_t(uint64_t, map_s, e)); ++ init_boot_pages(s, min(map_s, e)); ++ s = map_s; ++ if ( s < map_e ) ++ { ++ uint64_t mask = (1UL << L2_PAGETABLE_SHIFT) - 1; ++ ++ map_s = (s + mask) & ~mask; ++ map_e &= ~mask; ++ init_boot_pages(map_s, map_e); ++ } ++ ++ if ( map_s > map_e ) ++ map_s = map_e = s; + + /* Create new mappings /before/ passing memory to the allocator. */ +- if ( map_s < map_e ) +- map_pages_to_xen( +- (unsigned long)maddr_to_bootstrap_virt(map_s), +- map_s >> PAGE_SHIFT, (map_e-map_s) >> PAGE_SHIFT, +- PAGE_HYPERVISOR); ++ if ( map_e < e ) ++ { ++ map_pages_to_xen((unsigned long)__va(map_e), map_e >> PAGE_SHIFT, ++ (e - map_e) >> PAGE_SHIFT, PAGE_HYPERVISOR); ++ init_boot_pages(map_e, e); ++ } ++ if ( s < map_s ) ++ { ++ map_pages_to_xen((unsigned long)__va(s), s >> PAGE_SHIFT, ++ (map_s - s) >> PAGE_SHIFT, PAGE_HYPERVISOR); ++ init_boot_pages(s, map_s); ++ } ++#else ++ init_boot_pages(s, e); ++#endif ++ } + +- /* Pass remainder of this memory chunk to the allocator. */ +- init_boot_pages(map_s, e); ++ for ( i = 0; i < mbi->mods_count; ++i ) ++ { ++ set_pdx_range(mod[i].mod_start, ++ mod[i].mod_start + PFN_UP(mod[i].mod_end)); ++#ifdef CONFIG_X86_64 ++ map_pages_to_xen((unsigned long)mfn_to_virt(mod[i].mod_start), ++ mod[i].mod_start, ++ PFN_UP(mod[i].mod_end), PAGE_HYPERVISOR); ++#endif + } ++#ifdef CONFIG_X86_64 ++ map_pages_to_xen((unsigned long)__va(kexec_crash_area.start), ++ kexec_crash_area.start >> PAGE_SHIFT, ++ PFN_UP(kexec_crash_area.size), PAGE_HYPERVISOR); ++#endif + + memguard_init(); + +@@ -1041,7 +1216,7 @@ void __init __start_xen(unsigned long mb + + init_IRQ(); + +- xsm_init(&initrdidx, mbi, initial_images_start); ++ xsm_init(&initrdidx, mbi, bootstrap_map); + + init_idle_domain(); + +@@ -1158,12 +1333,6 @@ void __init __start_xen(unsigned long mb + cmdline = dom0_cmdline; + } + +- if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) ) +- { +- _initrd_start = mod[initrdidx].mod_start; +- _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start; +- } +- + if ( xen_cpuidle ) + xen_processor_pmbits |= XEN_PROCESSOR_PM_CX; + +@@ -1171,13 +1340,10 @@ void __init __start_xen(unsigned long mb + * We're going to setup domain0 using the module(s) that we stashed safely + * above our heap. The second module, if present, is an initrd ramdisk. + */ +- if ( construct_dom0(dom0, +- initial_images_base, +- initial_images_start, +- mod[0].mod_end-mod[0].mod_start, +- _initrd_start, +- _initrd_len, +- cmdline) != 0) ++ if ( construct_dom0(dom0, mod, modules_headroom, ++ (initrdidx > 0) && (initrdidx < mbi->mods_count) ++ ? mod + initrdidx : NULL, ++ bootstrap_map, cmdline) != 0) + panic("Could not set up DOM0 guest OS\n"); + + /* Scrub RAM that is still free and so may go to an unprivileged domain. */ +diff -r b536ebfba183 xen/arch/x86/x86_64/mm.c +--- a/xen/arch/x86/x86_64/mm.c Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/arch/x86/x86_64/mm.c Fri Nov 25 10:54:50 2011 +0000 +@@ -65,6 +65,12 @@ l3_pgentry_t __attribute__ ((__section__ + l2_pgentry_t __attribute__ ((__section__ (".bss.page_aligned"))) + l2_xenmap[L2_PAGETABLE_ENTRIES]; + ++/* Enough page directories to map into the bottom 1GB. */ ++l3_pgentry_t __attribute__ ((__section__ (".bss.page_aligned"))) ++ l3_bootmap[L3_PAGETABLE_ENTRIES]; ++l2_pgentry_t __attribute__ ((__section__ (".bss.page_aligned"))) ++ l2_bootmap[L2_PAGETABLE_ENTRIES]; ++ + int __mfn_valid(unsigned long mfn) + { + return likely(mfn < max_page) && +diff -r b536ebfba183 xen/include/asm-x86/domain.h +--- a/xen/include/asm-x86/domain.h Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/include/asm-x86/domain.h Fri Nov 25 10:54:50 2011 +0000 +@@ -483,16 +483,6 @@ void domain_cpuid(struct domain *d, + unsigned int *ecx, + unsigned int *edx); + +-int construct_dom0( +- struct domain *d, +- unsigned long image_base, +- unsigned long image_start, unsigned long image_len, +- unsigned long initrd_start, unsigned long initrd_len, +- char *cmdline); +- +-extern unsigned long initial_images_nrpages(void); +-extern void discard_initial_images(void); +- + #endif /* __ASM_DOMAIN_H__ */ + + /* +diff -r b536ebfba183 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Fri Nov 25 10:54:50 2011 +0000 +@@ -30,7 +30,6 @@ + &amd_iommu_head, list) + + #define DMA_32BIT_MASK 0x00000000ffffffffULL +-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) + + extern int amd_iommu_debug; + extern int amd_iommu_perdev_intremap; +diff -r b536ebfba183 xen/include/asm-x86/page.h +--- a/xen/include/asm-x86/page.h Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/include/asm-x86/page.h Fri Nov 25 10:54:50 2011 +0000 +@@ -292,6 +292,7 @@ extern l2_pgentry_t idle_pg_table_l2[ + extern l2_pgentry_t *compat_idle_pg_table_l2; + extern unsigned int m2p_compat_vstart; + #endif ++extern l2_pgentry_t l2_identmap[4*L2_PAGETABLE_ENTRIES]; + void paging_init(void); + void setup_idle_pagetable(void); + #endif /* !defined(__ASSEMBLY__) */ +@@ -387,6 +388,7 @@ static inline uint32_t cacheattr_to_pte_ + + #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) + #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) ++#define PAGE_ALIGN(x) (((x) + PAGE_SIZE - 1) & PAGE_MASK) + + #endif /* __X86_PAGE_H__ */ + +diff -r b536ebfba183 xen/include/asm-x86/setup.h +--- a/xen/include/asm-x86/setup.h Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/include/asm-x86/setup.h Fri Nov 25 10:54:50 2011 +0000 +@@ -1,6 +1,8 @@ + #ifndef __X86_SETUP_H_ + #define __X86_SETUP_H_ + ++#include <xen/multiboot.h> ++ + extern int early_boot; + extern unsigned long xenheap_initial_phys_start; + +@@ -26,4 +28,14 @@ void init_tmem(void); + void vesa_init(void); + void vesa_mtrr_init(void); + ++int construct_dom0( ++ struct domain *d, ++ const module_t *kernel, unsigned long kernel_headroom, ++ const module_t *initrd, ++ void *(*bootstrap_map)(const module_t *), ++ char *cmdline); ++ ++unsigned long initial_images_nrpages(void); ++void discard_initial_images(void); ++ + #endif +diff -r b536ebfba183 xen/include/xsm/xsm.h +--- a/xen/include/xsm/xsm.h Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/include/xsm/xsm.h Fri Nov 25 10:54:50 2011 +0000 +@@ -431,14 +431,15 @@ static inline long __do_xsm_op (XEN_GUES + + #ifdef XSM_ENABLE + extern int xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, +- unsigned long initial_images_start); ++ void *(*bootstrap_map)(const module_t *)); + extern int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi, +- unsigned long initial_images_start); ++ void *(*bootstrap_map)(const module_t *)); + extern int register_xsm(struct xsm_operations *ops); + extern int unregister_xsm(struct xsm_operations *ops); + #else + static inline int xsm_init (unsigned int *initrdidx, +- const multiboot_info_t *mbi, unsigned long initial_images_start) ++ const multiboot_info_t *mbi, ++ void *(*bootstrap_map)(const module_t *)) + { + return 0; + } +diff -r b536ebfba183 xen/xsm/xsm_core.c +--- a/xen/xsm/xsm_core.c Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/xsm/xsm_core.c Fri Nov 25 10:54:50 2011 +0000 +@@ -47,7 +47,7 @@ static void __init do_xsm_initcalls(void + } + + int __init xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, +- unsigned long initial_images_start) ++ void *(*bootstrap_map)(const module_t *)) + { + int ret = 0; + +@@ -55,9 +55,10 @@ int __init xsm_init(unsigned int *initrd + + if ( XSM_MAGIC ) + { +- ret = xsm_policy_init(initrdidx, mbi, initial_images_start); ++ ret = xsm_policy_init(initrdidx, mbi, bootstrap_map); + if ( ret ) + { ++ bootstrap_map(NULL); + printk("%s: Error initializing policy.\n", __FUNCTION__); + return -EINVAL; + } +@@ -65,6 +66,7 @@ int __init xsm_init(unsigned int *initrd + + if ( verify(&dummy_xsm_ops) ) + { ++ bootstrap_map(NULL); + printk("%s could not verify " + "dummy_xsm_ops structure.\n", __FUNCTION__); + return -EIO; +@@ -72,6 +74,7 @@ int __init xsm_init(unsigned int *initrd + + xsm_ops = &dummy_xsm_ops; + do_xsm_initcalls(); ++ bootstrap_map(NULL); + + return 0; + } +diff -r b536ebfba183 xen/xsm/xsm_policy.c +--- a/xen/xsm/xsm_policy.c Wed Aug 25 09:22:42 2010 +0100 ++++ b/xen/xsm/xsm_policy.c Fri Nov 25 10:54:50 2011 +0000 +@@ -22,11 +22,11 @@ + #include <xsm/xsm.h> + #include <xen/multiboot.h> + +-char *policy_buffer = NULL; +-u32 policy_size = 0; ++char *__initdata policy_buffer = NULL; ++u32 __initdata policy_size = 0; + + int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi, +- unsigned long initial_images_start) ++ void *(*bootstrap_map)(const module_t *)) + { + int i; + module_t *mod = (module_t *)__va(mbi->mods_addr); +@@ -40,15 +40,8 @@ int xsm_policy_init(unsigned int *initrd + */ + for ( i = mbi->mods_count-1; i >= 1; i-- ) + { +- start = initial_images_start + (mod[i].mod_start-mod[0].mod_start); +-#if defined(__i386__) +- _policy_start = (u32 *)start; +-#elif defined(__x86_64__) +- _policy_start = maddr_to_virt(start); +-#else +- _policy_start = NULL; +-#endif +- _policy_len = mod[i].mod_end - mod[i].mod_start; ++ _policy_start = bootstrap_map(mod + i); ++ _policy_len = mod[i].mod_end; + + if ( (xsm_magic_t)(*_policy_start) == XSM_MAGIC ) + { +@@ -63,6 +56,8 @@ int xsm_policy_init(unsigned int *initrd + break; + + } ++ ++ bootstrap_map(NULL); + } + + return rc; -- 1.7.8.3