ia64/xen-unstable

changeset 10131:8fa46042348c

Convert x86/64 Linux to use the new memory map hypercall.

This change removes several of the differences between the bare-metal
and Xen versions.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian.Campbell@xensource.com
date Mon May 22 09:23:15 2006 +0100 (2006-05-22)
parents d61211a6c273
children 9d838b8ceebf
files linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c linux-2.6-xen-sparse/include/asm-x86_64/e820.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Mon May 22 09:23:03 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Mon May 22 09:23:15 2006 +0100
     1.3 @@ -26,8 +26,6 @@
     1.4  #include <asm/sections.h>
     1.5  #include <xen/interface/memory.h>
     1.6  
     1.7 -unsigned long pci_mem_start = 0xaeedbabe;
     1.8 -
     1.9  /* 
    1.10   * PFN of last memory page.
    1.11   */
    1.12 @@ -47,15 +45,15 @@ unsigned long end_pfn_map;
    1.13  unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
    1.14  
    1.15  #ifndef CONFIG_XEN
    1.16 -
    1.17 -
    1.18  extern struct resource code_resource, data_resource;
    1.19 +#endif
    1.20  
    1.21  /* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
    1.22  static inline int bad_addr(unsigned long *addrp, unsigned long size)
    1.23  { 
    1.24  	unsigned long addr = *addrp, last = addr + size; 
    1.25  
    1.26 +#ifndef CONFIG_XEN
    1.27  	/* various gunk below that needed for SMP startup */
    1.28  	if (addr < 0x8000) { 
    1.29  		*addrp = 0x8000;
    1.30 @@ -83,9 +81,16 @@ static inline int bad_addr(unsigned long
    1.31  		return 1;
    1.32  	}
    1.33  	/* XXX ramdisk image here? */ 
    1.34 +#else
    1.35 +	if (last < (table_end<<PAGE_SHIFT)) {
    1.36 +		*addrp = table_end << PAGE_SHIFT;
    1.37 +		return 1;
    1.38 +	}
    1.39 +#endif
    1.40  	return 0;
    1.41  } 
    1.42  
    1.43 +#ifndef CONFIG_XEN
    1.44  int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) 
    1.45  { 
    1.46  	int i;
    1.47 @@ -99,6 +104,7 @@ int __init e820_mapped(unsigned long sta
    1.48  	} 
    1.49  	return 0;
    1.50  }
    1.51 +#endif
    1.52  
    1.53  /* 
    1.54   * Find a free area in a specific range. 
    1.55 @@ -229,22 +235,23 @@ e820_hole_size(unsigned long start_pfn, 
    1.56  /*
    1.57   * Mark e820 reserved areas as busy for the resource manager.
    1.58   */
    1.59 -void __init e820_reserve_resources(void)
    1.60 +void __init e820_reserve_resources(struct e820entry *e820, int nr_map)
    1.61  {
    1.62  	int i;
    1.63 -	for (i = 0; i < e820.nr_map; i++) {
    1.64 +	for (i = 0; i < nr_map; i++) {
    1.65  		struct resource *res;
    1.66  		res = alloc_bootmem_low(sizeof(struct resource));
    1.67 -		switch (e820.map[i].type) {
    1.68 +		switch (e820[i].type) {
    1.69  		case E820_RAM:	res->name = "System RAM"; break;
    1.70  		case E820_ACPI:	res->name = "ACPI Tables"; break;
    1.71  		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
    1.72  		default:	res->name = "reserved";
    1.73  		}
    1.74 -		res->start = e820.map[i].addr;
    1.75 -		res->end = res->start + e820.map[i].size - 1;
    1.76 +		res->start = e820[i].addr;
    1.77 +		res->end = res->start + e820[i].size - 1;
    1.78  		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
    1.79  		request_resource(&iomem_resource, res);
    1.80 +#ifndef CONFIG_XEN
    1.81  		if (e820.map[i].type == E820_RAM) {
    1.82  			/*
    1.83  			 *  We don't know which RAM region contains kernel data,
    1.84 @@ -257,74 +264,9 @@ void __init e820_reserve_resources(void)
    1.85  			request_resource(res, &crashk_res);
    1.86  #endif
    1.87  		}
    1.88 +#endif
    1.89  	}
    1.90  }
    1.91 -#else
    1.92 -void __init e820_reserve_resources(void) 
    1.93 -{
    1.94 -	dom0_op_t op;
    1.95 -	struct dom0_memory_map_entry *map;
    1.96 -	unsigned long gapstart, gapsize, round, last;
    1.97 -	int i, found = 0;
    1.98 -
    1.99 -	if (!(xen_start_info->flags & SIF_INITDOMAIN))
   1.100 -		return;
   1.101 -
   1.102 -	map = alloc_bootmem_low_pages(PAGE_SIZE);
   1.103 -	op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
   1.104 -	set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
   1.105 -	op.u.physical_memory_map.max_map_entries =
   1.106 -		PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
   1.107 -	BUG_ON(HYPERVISOR_dom0_op(&op));
   1.108 -
   1.109 -	last = 0x100000000ULL;
   1.110 -	gapstart = 0x10000000;
   1.111 -	gapsize = 0x400000;
   1.112 -
   1.113 -	for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
   1.114 -		struct resource *res;
   1.115 -
   1.116 -		if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
   1.117 -			gapsize = last - map[i].end;
   1.118 -			gapstart = map[i].end;
   1.119 -			found = 1;
   1.120 -		}
   1.121 -		if (map[i].start < last)
   1.122 -			last = map[i].start;
   1.123 -
   1.124 -		if (map[i].end > 0x100000000ULL)
   1.125 -			continue;
   1.126 -		res = alloc_bootmem_low(sizeof(struct resource));
   1.127 -		res->name = map[i].is_ram ? "System RAM" : "reserved";
   1.128 -		res->start = map[i].start;
   1.129 -		res->end = map[i].end - 1;
   1.130 -		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
   1.131 -		request_resource(&iomem_resource, res);
   1.132 -	}
   1.133 -
   1.134 -	free_bootmem(__pa(map), PAGE_SIZE);
   1.135 -
   1.136 -	if (!found) {
   1.137 -		gapstart = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
   1.138 -		gapstart = (gapstart << PAGE_SHIFT) + 1024*1024;
   1.139 -		printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
   1.140 -		       KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
   1.141 -	}
   1.142 -
   1.143 -	/*
   1.144 -	 * See how much we want to round up: start off with
   1.145 -	 * rounding to the next 1MB area.
   1.146 -	 */
   1.147 -	round = 0x100000;
   1.148 -	while ((gapsize >> 4) > round)
   1.149 -		round += round;
   1.150 -	/* Fun with two's complement */
   1.151 -	pci_mem_start = (gapstart + round) & -round;
   1.152 -
   1.153 -	printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
   1.154 -		pci_mem_start, gapstart, gapsize);
   1.155 -}
   1.156 -#endif /* CONFIG_XEN */
   1.157  
   1.158  /* 
   1.159   * Add a memory region to the kernel e820 map.
   1.160 @@ -370,7 +312,6 @@ void __init e820_print_map(char *who)
   1.161  	}
   1.162  }
   1.163  
   1.164 -#ifndef CONFIG_XEN
   1.165  /*
   1.166   * Sanitize the BIOS e820 map.
   1.167   *
   1.168 @@ -557,9 +498,13 @@ static int __init sanitize_e820_map(stru
   1.169   */
   1.170  static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
   1.171  {
   1.172 +#ifndef CONFIG_XEN
   1.173  	/* Only one memory region (or negative)? Ignore it */
   1.174  	if (nr_map < 2)
   1.175  		return -1;
   1.176 +#else
   1.177 +	BUG_ON(nr_map < 1);
   1.178 +#endif
   1.179  
   1.180  	do {
   1.181  		unsigned long start = biosmap->addr;
   1.182 @@ -571,6 +516,7 @@ static int __init copy_e820_map(struct e
   1.183  		if (start > end)
   1.184  			return -1;
   1.185  
   1.186 +#ifndef CONFIG_XEN
   1.187  		/*
   1.188  		 * Some BIOSes claim RAM in the 640k - 1M region.
   1.189  		 * Not right. Fix it up.
   1.190 @@ -589,12 +535,14 @@ static int __init copy_e820_map(struct e
   1.191  				size = end - start;
   1.192  			}
   1.193  		}
   1.194 +#endif
   1.195  
   1.196  		add_memory_region(start, size, type);
   1.197  	} while (biosmap++,--nr_map);
   1.198  	return 0;
   1.199  }
   1.200  
   1.201 +#ifndef CONFIG_XEN
   1.202  void __init setup_memory_region(void)
   1.203  {
   1.204  	char *who = "BIOS-e820";
   1.205 @@ -628,39 +576,63 @@ void __init setup_memory_region(void)
   1.206  
   1.207  #else  /* CONFIG_XEN */
   1.208  
   1.209 -extern unsigned long xen_override_max_pfn;
   1.210 -extern union xen_start_info_union xen_start_info_union;
   1.211 +void __init setup_memory_region(void)
   1.212 +{
   1.213 +	int rc;
   1.214 +	struct xen_memory_map memmap;
   1.215 +	/*
   1.216 +	 * This is rather large for a stack variable but this early in
   1.217 +	 * the boot process we know we have plenty slack space.
   1.218 +	 */
   1.219 +	struct e820entry map[E820MAX];
   1.220  
   1.221 -unsigned long __init e820_end_of_ram(void)
   1.222 -{
   1.223 -	unsigned long max_end_pfn;
   1.224 +	memmap.nr_entries = E820MAX;
   1.225 +	set_xen_guest_handle(memmap.buffer, map);
   1.226  
   1.227 -	if (xen_override_max_pfn == 0) {
   1.228 -		max_end_pfn = xen_start_info->nr_pages;
   1.229 -		/* Default 8MB slack (to balance backend allocations). */
   1.230 -		max_end_pfn += 8 << (20 - PAGE_SHIFT);
   1.231 -	} else if (xen_override_max_pfn > xen_start_info->nr_pages) {
   1.232 -		max_end_pfn = xen_override_max_pfn;
   1.233 -	} else {
   1.234 -		max_end_pfn = xen_start_info->nr_pages;
   1.235 +	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
   1.236 +	if ( rc == -ENOSYS ) {
   1.237 +		memmap.nr_entries = 1;
   1.238 +		map[0].addr = 0ULL;
   1.239 +		map[0].size = xen_start_info->nr_pages << PAGE_SHIFT;
   1.240 +		/* 8MB slack (to balance backend allocations). */
   1.241 +		map[0].size += 8 << 20;
   1.242 +		map[0].type = E820_RAM;
   1.243 +		rc = 0;
   1.244  	}
   1.245 +	BUG_ON(rc);
   1.246  
   1.247 -	return max_end_pfn;
   1.248 -}
   1.249 +	sanitize_e820_map(map, (char *)&memmap.nr_entries);
   1.250 +
   1.251 +	BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0);
   1.252  
   1.253 -unsigned long __init
   1.254 -e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
   1.255 -{
   1.256 -	return 0;
   1.257 +	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
   1.258 +	e820_print_map("Xen");
   1.259  }
   1.260 -
   1.261  #endif
   1.262  
   1.263  void __init parse_memopt(char *p, char **from) 
   1.264  { 
   1.265 +	int i;
   1.266 +	unsigned long current_end;
   1.267 +	unsigned long end;
   1.268 +
   1.269  	end_user_pfn = memparse(p, from);
   1.270  	end_user_pfn >>= PAGE_SHIFT;	
   1.271 -	xen_override_max_pfn = (unsigned long) end_user_pfn;
   1.272 +
   1.273 +	end = end_user_pfn<<PAGE_SHIFT;
   1.274 +	i = e820.nr_map-1;
   1.275 +	current_end = e820.map[i].addr + e820.map[i].size;
   1.276 +
   1.277 +	if (current_end < end) {
   1.278 +		/*
   1.279 +                 * The e820 map ends before our requested size so
   1.280 +                 * extend the final entry to the requested address.
   1.281 +                 */
   1.282 +		if (e820.map[i].type == E820_RAM)
   1.283 +			e820.map[i].size = end - e820.map[i].addr;
   1.284 +		else
   1.285 +			add_memory_region(current_end, end - current_end, E820_RAM);
   1.286 +	}
   1.287  } 
   1.288  
   1.289  void __init parse_memmapopt(char *p, char **from)
   1.290 @@ -684,16 +656,17 @@ void __init parse_memmapopt(char *p, cha
   1.291  	p = *from;
   1.292  }
   1.293  
   1.294 +unsigned long pci_mem_start = 0xaeedbabe;
   1.295 +
   1.296  /*
   1.297   * Search for the biggest gap in the low 32 bits of the e820
   1.298   * memory space.  We pass this space to PCI to assign MMIO resources
   1.299   * for hotplug or unconfigured devices in.
   1.300   * Hopefully the BIOS let enough space left.
   1.301   */
   1.302 -__init void e820_setup_gap(void)
   1.303 +__init void e820_setup_gap(struct e820entry *e820, int nr_map)
   1.304  {
   1.305 -#ifndef CONFIG_XEN
   1.306 -	unsigned long gapstart, gapsize;
   1.307 +	unsigned long gapstart, gapsize, round;
   1.308  	unsigned long last;
   1.309  	int i;
   1.310  	int found = 0;
   1.311 @@ -701,10 +674,10 @@ void __init parse_memmapopt(char *p, cha
   1.312  	last = 0x100000000ull;
   1.313  	gapstart = 0x10000000;
   1.314  	gapsize = 0x400000;
   1.315 -	i = e820.nr_map;
   1.316 +	i = nr_map;
   1.317  	while (--i >= 0) {
   1.318 -		unsigned long long start = e820.map[i].addr;
   1.319 -		unsigned long long end = start + e820.map[i].size;
   1.320 +		unsigned long long start = e820[i].addr;
   1.321 +		unsigned long long end = start + e820[i].size;
   1.322  
   1.323  		/*
   1.324  		 * Since "last" is at most 4GB, we know we'll
   1.325 @@ -730,16 +703,15 @@ void __init parse_memmapopt(char *p, cha
   1.326  	}
   1.327  
   1.328  	/*
   1.329 -	 * Start allocating dynamic PCI memory a bit into the gap,
   1.330 -	 * aligned up to the nearest megabyte.
   1.331 -	 *
   1.332 -	 * Question: should we try to pad it up a bit (do something
   1.333 -	 * like " + (gapsize >> 3)" in there too?). We now have the
   1.334 -	 * technology.
   1.335 +	 * See how much we want to round up: start off with
   1.336 +	 * rounding to the next 1MB area.
   1.337  	 */
   1.338 -	pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
   1.339 +	round = 0x100000;
   1.340 +	while ((gapsize >> 4) > round)
   1.341 +		round += round;
   1.342 +	/* Fun with two's complement */
   1.343 +	pci_mem_start = (gapstart + round) & -round;
   1.344  
   1.345  	printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
   1.346  		pci_mem_start, gapstart, gapsize);
   1.347 -#endif
   1.348  }
     2.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Mon May 22 09:23:03 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Mon May 22 09:23:15 2006 +0100
     2.3 @@ -76,8 +76,8 @@
     2.4  #include <xen/features.h>
     2.5  #define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
     2.6  #define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
     2.7 -#define end_pfn_map end_pfn
     2.8  #include <asm/mach-xen/setup_arch_post.h>
     2.9 +#include <xen/interface/memory.h>
    2.10  
    2.11  extern unsigned long start_pfn;
    2.12  extern struct edid_info edid_info;
    2.13 @@ -490,19 +490,6 @@ static __init void parse_cmdline_early (
    2.14  }
    2.15  
    2.16  #ifndef CONFIG_NUMA
    2.17 -#ifdef CONFIG_XEN
    2.18 -static void __init
    2.19 -contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
    2.20 -{
    2.21 -        unsigned long bootmap_size;
    2.22 -
    2.23 -        bootmap_size = init_bootmem(start_pfn, end_pfn);
    2.24 -        free_bootmem(0, xen_start_info->nr_pages << PAGE_SHIFT);   
    2.25 -        reserve_bootmem(HIGH_MEMORY,
    2.26 -                        (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1)
    2.27 -                        - HIGH_MEMORY);
    2.28 -}
    2.29 -#else
    2.30  static void __init
    2.31  contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
    2.32  {
    2.33 @@ -513,10 +500,13 @@ contig_initmem_init(unsigned long start_
    2.34  	if (bootmap == -1L)
    2.35  		panic("Cannot find bootmem map of size %ld\n",bootmap_size);
    2.36  	bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
    2.37 +#ifdef CONFIG_XEN
    2.38 +	e820_bootmem_free(NODE_DATA(0), 0, xen_start_info->nr_pages<<PAGE_SHIFT);
    2.39 +#else
    2.40  	e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
    2.41 +#endif
    2.42  	reserve_bootmem(bootmap, bootmap_size);
    2.43  } 
    2.44 -#endif	/* !CONFIG_XEN */
    2.45  #endif
    2.46  
    2.47  /* Use inline assembly to define this because the nops are defined 
    2.48 @@ -637,6 +627,9 @@ void __init setup_arch(char **cmdline_p)
    2.49  	unsigned long kernel_end;
    2.50  
    2.51  #ifdef CONFIG_XEN
    2.52 +	struct e820entry *machine_e820;
    2.53 +	struct xen_memory_map memmap;
    2.54 +
    2.55  	/* Register a call for panic conditions. */
    2.56  	notifier_chain_register(&panic_notifier_list, &xen_panic_block);
    2.57  
    2.58 @@ -693,20 +686,18 @@ void __init setup_arch(char **cmdline_p)
    2.59  	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
    2.60  	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
    2.61  #endif
    2.62 +#endif	/* !CONFIG_XEN */
    2.63  	setup_memory_region();
    2.64  	copy_edd();
    2.65 -#endif	/* !CONFIG_XEN */
    2.66  
    2.67  	if (!MOUNT_ROOT_RDONLY)
    2.68  		root_mountflags &= ~MS_RDONLY;
    2.69  	init_mm.start_code = (unsigned long) &_text;
    2.70  	init_mm.end_code = (unsigned long) &_etext;
    2.71  	init_mm.end_data = (unsigned long) &_edata;
    2.72 -#ifdef CONFIG_XEN
    2.73 -	init_mm.brk = start_pfn << PAGE_SHIFT;
    2.74 -#else
    2.75 -	init_mm.brk = (unsigned long) &_end;	
    2.76 +	init_mm.brk = (unsigned long) &_end;
    2.77  
    2.78 +#ifndef CONFIG_XEN
    2.79  	code_resource.start = virt_to_phys(&_text);
    2.80  	code_resource.end = virt_to_phys(&_etext)-1;
    2.81  	data_resource.start = virt_to_phys(&_etext);
    2.82 @@ -735,12 +726,11 @@ void __init setup_arch(char **cmdline_p)
    2.83  #endif
    2.84  
    2.85  #ifdef CONFIG_NUMA
    2.86 -	numa_initmem_init(start_pfn, end_pfn); 
    2.87 +	numa_initmem_init(0, end_pfn); 
    2.88  #else
    2.89 -	contig_initmem_init(start_pfn, end_pfn);
    2.90 +	contig_initmem_init(0, end_pfn);
    2.91  #endif
    2.92  
    2.93 -#ifndef CONFIG_XEN
    2.94  	/* Reserve direct mapping */
    2.95  	reserve_bootmem_generic(table_start << PAGE_SHIFT, 
    2.96  				(table_end - table_start) << PAGE_SHIFT);
    2.97 @@ -749,6 +739,10 @@ void __init setup_arch(char **cmdline_p)
    2.98  	kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE);
    2.99  	reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);
   2.100  
   2.101 +#ifdef CONFIG_XEN
   2.102 +	/* reserve physmap, start info and initial page tables */
   2.103 +	reserve_bootmem(kernel_end, table_start<<PAGE_SHIFT);
   2.104 +#else
   2.105  	/*
   2.106  	 * reserve physical page 0 - it's a special BIOS page on many boxes,
   2.107  	 * enabling clean reboots, SMP operation, laptop functions.
   2.108 @@ -933,13 +927,24 @@ void __init setup_arch(char **cmdline_p)
   2.109  	prefill_possible_map();
   2.110  #endif
   2.111  
   2.112 -#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
   2.113  	/*
   2.114  	 * Request address space for all standard RAM and ROM resources
   2.115  	 * and also for regions reported as reserved by the e820.
   2.116  	 */
   2.117  	probe_roms();
   2.118 -	e820_reserve_resources(); 
   2.119 +#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
   2.120 +	if (xen_start_info->flags & SIF_INITDOMAIN) {
   2.121 +		machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
   2.122 +
   2.123 +		memmap.nr_entries = E820MAX;
   2.124 +		set_xen_guest_handle(memmap.buffer, machine_e820);
   2.125 +
   2.126 +		BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
   2.127 +
   2.128 +		e820_reserve_resources(machine_e820, memmap.nr_entries);
   2.129 +	}
   2.130 +#elif !defined(CONFIG_XEN)
   2.131 +	e820_reserve_resources(e820.map, e820.nr_map);
   2.132  #endif
   2.133  
   2.134  	request_resource(&iomem_resource, &video_ram_resource);
   2.135 @@ -951,7 +956,14 @@ void __init setup_arch(char **cmdline_p)
   2.136  		request_resource(&ioport_resource, &standard_io_resources[i]);
   2.137  	}
   2.138  
   2.139 -	e820_setup_gap();
   2.140 +#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
   2.141 +	if (xen_start_info->flags & SIF_INITDOMAIN) {
   2.142 +		e820_setup_gap(machine_e820, memmap.nr_entries);
   2.143 +		free_bootmem(__pa(machine_e820), PAGE_SIZE);
   2.144 +	}
   2.145 +#elif !defined(CONFIG_XEN)
   2.146 +	e820_setup_gap(e820.map, e820.nr_map);
   2.147 +#endif
   2.148  
   2.149  #ifdef CONFIG_GART_IOMMU
   2.150  	iommu_hole_init();
     3.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Mon May 22 09:23:03 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Mon May 22 09:23:15 2006 +0100
     3.3 @@ -370,7 +370,7 @@ void __set_fixmap_user (enum fixed_addre
     3.4  	set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
     3.5  }
     3.6  
     3.7 -unsigned long __initdata table_start, tables_space; 
     3.8 +unsigned long __initdata table_start, table_end; 
     3.9  
    3.10  unsigned long get_machine_pfn(unsigned long addr)
    3.11  {
    3.12 @@ -409,11 +409,17 @@ static inline int make_readonly(unsigned
    3.13  {
    3.14  	int readonly = 0;
    3.15  
    3.16 -	/* Make old and new page tables read-only. */
    3.17 +	/* Make new page tables read-only. */
    3.18 +	if (!xen_feature(XENFEAT_writable_page_tables)
    3.19 +	    && (paddr >= (table_start << PAGE_SHIFT))
    3.20 +	    && (paddr < (table_end << PAGE_SHIFT)))
    3.21 +		readonly = 1;
    3.22 +	/* Make old page tables read-only. */
    3.23  	if (!xen_feature(XENFEAT_writable_page_tables)
    3.24  	    && (paddr >= (xen_start_info->pt_base - __START_KERNEL_map))
    3.25 -	    && (paddr < ((table_start << PAGE_SHIFT) + tables_space)))
    3.26 +	    && (paddr < (start_pfn << PAGE_SHIFT)))
    3.27  		readonly = 1;
    3.28 +
    3.29  	/*
    3.30  	 * No need for writable mapping of kernel image. This also ensures that
    3.31  	 * page and descriptor tables embedded inside don't have writable
    3.32 @@ -544,7 +550,7 @@ void __init xen_init_pt(void)
    3.33  		mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
    3.34  }
    3.35  
    3.36 -void __init extend_init_mapping(void) 
    3.37 +void __init extend_init_mapping(unsigned long tables_space)
    3.38  {
    3.39  	unsigned long va = __START_KERNEL_map;
    3.40  	unsigned long phys, addr, *pte_page;
    3.41 @@ -599,23 +605,23 @@ void __init extend_init_mapping(void)
    3.42  
    3.43  static void __init find_early_table_space(unsigned long end)
    3.44  {
    3.45 -	unsigned long puds, pmds, ptes; 
    3.46 +	unsigned long puds, pmds, ptes, tables; 
    3.47  
    3.48  	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
    3.49  	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
    3.50  	ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT;
    3.51  
    3.52 -	tables_space =
    3.53 -		round_up(puds * 8, PAGE_SIZE) + 
    3.54 +	tables = round_up(puds * 8, PAGE_SIZE) + 
    3.55  		round_up(pmds * 8, PAGE_SIZE) + 
    3.56  		round_up(ptes * 8, PAGE_SIZE); 
    3.57  
    3.58 -	extend_init_mapping();
    3.59 +	extend_init_mapping(tables);
    3.60  
    3.61  	table_start = start_pfn;
    3.62 +	table_end = table_start + (tables>>PAGE_SHIFT);
    3.63  
    3.64  	early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n",
    3.65 -		end, table_start << PAGE_SHIFT, start_pfn << PAGE_SHIFT);
    3.66 +		end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
    3.67  }
    3.68  
    3.69  /* Setup the direct mapping of the physical memory at PAGE_OFFSET.
    3.70 @@ -660,7 +666,7 @@ void __meminit init_memory_mapping(unsig
    3.71  			set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
    3.72  	}
    3.73  
    3.74 -	BUG_ON(!after_bootmem && start_pfn != table_start + (tables_space >> PAGE_SHIFT));
    3.75 +	BUG_ON(!after_bootmem && start_pfn != table_end);
    3.76  
    3.77  	__flush_tlb_all();
    3.78  }
     4.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/e820.h	Mon May 22 09:23:03 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/e820.h	Mon May 22 09:23:15 2006 +0100
     4.3 @@ -45,12 +45,12 @@ extern void add_memory_region(unsigned l
     4.4  extern void setup_memory_region(void);
     4.5  extern void contig_e820_setup(void); 
     4.6  extern unsigned long e820_end_of_ram(void);
     4.7 -extern void e820_reserve_resources(void);
     4.8 +extern void e820_reserve_resources(struct e820entry *e820, int nr_map);
     4.9  extern void e820_print_map(char *who);
    4.10  extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
    4.11  
    4.12  extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
    4.13 -extern void e820_setup_gap(void);
    4.14 +extern void e820_setup_gap(struct e820entry *e820, int nr_map);
    4.15  extern unsigned long e820_hole_size(unsigned long start_pfn,
    4.16  				    unsigned long end_pfn);
    4.17