ia64/xen-unstable

changeset 10130:d61211a6c273

Convert x86/32 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:03 2006 +0100 (2006-05-22)
parents 810ad61870e8
children 8fa46042348c
files linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c linux-2.6-xen-sparse/arch/i386/mm/init-xen.c linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon May 22 09:22:18 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon May 22 09:23:03 2006 +0100
     1.3 @@ -71,9 +71,6 @@
     1.4  /* Forward Declaration. */
     1.5  void __init find_max_pfn(void);
     1.6  
     1.7 -/* Allows setting of maximum possible memory size  */
     1.8 -static unsigned long xen_override_max_pfn;
     1.9 -
    1.10  static int xen_panic_event(struct notifier_block *, unsigned long, void *);
    1.11  static struct notifier_block xen_panic_block = {
    1.12  	xen_panic_event, NULL, 0 /* try to go last */
    1.13 @@ -462,6 +459,19 @@ static void __init limit_regions(unsigne
    1.14  		}
    1.15  		return;
    1.16  	}
    1.17 +#ifdef CONFIG_XEN
    1.18 +	if (i==e820.nr_map && current_addr < size) {
    1.19 +		/*
    1.20 +                 * The e820 map finished before our requested size so
    1.21 +                 * extend the final entry to the requested address.
    1.22 +                 */
    1.23 +		--i;
    1.24 +		if (e820.map[i].type == E820_RAM)
    1.25 +			e820.map[i].size -= current_addr - size;
    1.26 +		else
    1.27 +			add_memory_region(current_addr, size - current_addr, E820_RAM);
    1.28 +	}
    1.29 +#endif
    1.30  }
    1.31  
    1.32  #define E820_DEBUG	1
    1.33 @@ -492,7 +502,6 @@ static void __init print_memory_map(char
    1.34  	}
    1.35  }
    1.36  
    1.37 -#if 0
    1.38  /*
    1.39   * Sanitize the BIOS e820 map.
    1.40   *
    1.41 @@ -680,9 +689,13 @@ static int __init sanitize_e820_map(stru
    1.42   */
    1.43  static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
    1.44  {
    1.45 +#ifndef CONFIG_XEN
    1.46  	/* Only one memory region (or negative)? Ignore it */
    1.47  	if (nr_map < 2)
    1.48  		return -1;
    1.49 +#else
    1.50 +	BUG_ON(nr_map < 1);
    1.51 +#endif
    1.52  
    1.53  	do {
    1.54  		unsigned long long start = biosmap->addr;
    1.55 @@ -694,6 +707,7 @@ static int __init copy_e820_map(struct e
    1.56  		if (start > end)
    1.57  			return -1;
    1.58  
    1.59 +#ifndef CONFIG_XEN
    1.60  		/*
    1.61  		 * Some BIOSes claim RAM in the 640k - 1M region.
    1.62  		 * Not right. Fix it up.
    1.63 @@ -708,11 +722,11 @@ static int __init copy_e820_map(struct e
    1.64  				size = end - start;
    1.65  			}
    1.66  		}
    1.67 +#endif
    1.68  		add_memory_region(start, size, type);
    1.69  	} while (biosmap++,--nr_map);
    1.70  	return 0;
    1.71  }
    1.72 -#endif
    1.73  
    1.74  #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
    1.75  struct edd edd;
    1.76 @@ -785,13 +799,8 @@ static void __init parse_cmdline_early (
    1.77  				unsigned long long mem_size;
    1.78   
    1.79  				mem_size = memparse(from+4, &from);
    1.80 -#if 0
    1.81  				limit_regions(mem_size);
    1.82  				userdef=1;
    1.83 -#else
    1.84 -				xen_override_max_pfn =
    1.85 -					(unsigned long)(mem_size>>PAGE_SHIFT);
    1.86 -#endif
    1.87  			}
    1.88  		}
    1.89  
    1.90 @@ -984,7 +993,6 @@ static void __init parse_cmdline_early (
    1.91  	}
    1.92  }
    1.93  
    1.94 -#if 0 /* !XEN */
    1.95  /*
    1.96   * Callback for efi_memory_walk.
    1.97   */
    1.98 @@ -1036,21 +1044,6 @@ void __init find_max_pfn(void)
    1.99  		memory_present(0, start, end);
   1.100  	}
   1.101  }
   1.102 -#else
   1.103 -/* We don't use the fake e820 because we need to respond to user override. */
   1.104 -void __init find_max_pfn(void)
   1.105 -{
   1.106 -	if (xen_override_max_pfn == 0) {
   1.107 -		max_pfn = xen_start_info->nr_pages;
   1.108 -		/* Default 8MB slack (to balance backend allocations). */
   1.109 -		max_pfn += 8 << (20 - PAGE_SHIFT);
   1.110 -	} else if (xen_override_max_pfn > xen_start_info->nr_pages) {
   1.111 -		max_pfn = xen_override_max_pfn;
   1.112 -	} else {
   1.113 -		max_pfn = xen_start_info->nr_pages;
   1.114 -	}
   1.115 -}
   1.116 -#endif /* XEN */
   1.117  
   1.118  /*
   1.119   * Determine low and high memory ranges:
   1.120 @@ -1158,6 +1151,15 @@ static void __init register_bootmem_low_
   1.121  		 */
   1.122  		last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
   1.123  
   1.124 +#ifdef CONFIG_XEN
   1.125 +		/*
   1.126 +                 * Truncate to the number of actual pages currently
   1.127 +                 * present.
   1.128 +                 */
   1.129 +		if (last_pfn > xen_start_info->nr_pages)
   1.130 +			last_pfn = xen_start_info->nr_pages;
   1.131 +#endif
   1.132 +
   1.133  		if (last_pfn > max_low_pfn)
   1.134  			last_pfn = max_low_pfn;
   1.135  
   1.136 @@ -1351,83 +1353,33 @@ void __init remapped_pgdat_init(void)
   1.137   * and also for regions reported as reserved by the e820.
   1.138   */
   1.139  static void __init
   1.140 -legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
   1.141 +legacy_init_iomem_resources(struct e820entry *e820, int nr_map,
   1.142 +			    struct resource *code_resource,
   1.143 +			    struct resource *data_resource)
   1.144  {
   1.145  	int i;
   1.146 -#ifdef CONFIG_XEN
   1.147 -	dom0_op_t op;
   1.148 -	struct dom0_memory_map_entry *map;
   1.149 -	unsigned long gapstart, gapsize;
   1.150 -	unsigned long long last;
   1.151 -#endif
   1.152  
   1.153 -#ifdef CONFIG_XEN_PRIVILEGED_GUEST
   1.154 +#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
   1.155  	probe_roms();
   1.156  #endif
   1.157  
   1.158 -#ifdef CONFIG_XEN
   1.159 -	map = alloc_bootmem_low_pages(PAGE_SIZE);
   1.160 -	op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
   1.161 -	set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
   1.162 -	op.u.physical_memory_map.max_map_entries =
   1.163 -		PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
   1.164 -	BUG_ON(HYPERVISOR_dom0_op(&op));
   1.165 -
   1.166 -	last = 0x100000000ULL;
   1.167 -	gapstart = 0x10000000;
   1.168 -	gapsize = 0x400000;
   1.169 -
   1.170 -	for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
   1.171 +	for (i = 0; i < nr_map; i++) {
   1.172  		struct resource *res;
   1.173 -
   1.174 -		if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
   1.175 -			gapsize = last - map[i].end;
   1.176 -			gapstart = map[i].end;
   1.177 -		}
   1.178 -		if (map[i].start < last)
   1.179 -			last = map[i].start;
   1.180 -
   1.181 -		if (map[i].end > 0x100000000ULL)
   1.182 +		if (e820[i].addr + e820[i].size > 0x100000000ULL)
   1.183  			continue;
   1.184  		res = alloc_bootmem_low(sizeof(struct resource));
   1.185 -		res->name = map[i].is_ram ? "System RAM" : "reserved";
   1.186 -		res->start = map[i].start;
   1.187 -		res->end = map[i].end - 1;
   1.188 -		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
   1.189 -		request_resource(&iomem_resource, res);
   1.190 -	}
   1.191 -
   1.192 -	free_bootmem(__pa(map), PAGE_SIZE);
   1.193 -
   1.194 -	/*
   1.195 -	 * Start allocating dynamic PCI memory a bit into the gap,
   1.196 -	 * aligned up to the nearest megabyte.
   1.197 -	 *
   1.198 -	 * Question: should we try to pad it up a bit (do something
   1.199 -	 * like " + (gapsize >> 3)" in there too?). We now have the
   1.200 -	 * technology.
   1.201 -	 */
   1.202 -	pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
   1.203 -
   1.204 -	printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
   1.205 -		pci_mem_start, gapstart, gapsize);
   1.206 -#else
   1.207 -	for (i = 0; i < e820.nr_map; i++) {
   1.208 -		struct resource *res;
   1.209 -		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
   1.210 -			continue;
   1.211 -		res = alloc_bootmem_low(sizeof(struct resource));
   1.212 -		switch (e820.map[i].type) {
   1.213 +		switch (e820[i].type) {
   1.214  		case E820_RAM:	res->name = "System RAM"; break;
   1.215  		case E820_ACPI:	res->name = "ACPI Tables"; break;
   1.216  		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
   1.217  		default:	res->name = "reserved";
   1.218  		}
   1.219 -		res->start = e820.map[i].addr;
   1.220 -		res->end = res->start + e820.map[i].size - 1;
   1.221 +		res->start = e820[i].addr;
   1.222 +		res->end = res->start + e820[i].size - 1;
   1.223  		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
   1.224  		request_resource(&iomem_resource, res);
   1.225 -		if (e820.map[i].type == E820_RAM) {
   1.226 +#ifndef CONFIG_XEN
   1.227 +		if (e820[i].type == E820_RAM) {
   1.228  			/*
   1.229  			 *  We don't know which RAM region contains kernel data,
   1.230  			 *  so we try it repeatedly and let the resource manager
   1.231 @@ -1439,38 +1391,21 @@ legacy_init_iomem_resources(struct resou
   1.232  			request_resource(res, &crashk_res);
   1.233  #endif
   1.234  		}
   1.235 +#endif
   1.236  	}
   1.237 -#endif
   1.238  }
   1.239  
   1.240  /*
   1.241 - * Request address space for all standard resources
   1.242 + * Locate a unused range of the physical address space below 4G which
   1.243 + * can be used for PCI mappings.
   1.244   */
   1.245 -static void __init register_memory(void)
   1.246 +static void __init
   1.247 +e820_setup_gap(struct e820entry *e820, int nr_map)
   1.248  {
   1.249 -#ifndef CONFIG_XEN
   1.250  	unsigned long gapstart, gapsize, round;
   1.251  	unsigned long long last;
   1.252 -#endif
   1.253 -	int	      i;
   1.254 -
   1.255 -	/* Nothing to do if not running in dom0. */
   1.256 -	if (!(xen_start_info->flags & SIF_INITDOMAIN))
   1.257 -		return;
   1.258 +	int i;
   1.259  
   1.260 -	if (efi_enabled)
   1.261 -		efi_initialize_iomem_resources(&code_resource, &data_resource);
   1.262 -	else
   1.263 -		legacy_init_iomem_resources(&code_resource, &data_resource);
   1.264 -
   1.265 -	/* EFI systems may still have VGA */
   1.266 -	request_resource(&iomem_resource, &video_ram_resource);
   1.267 -
   1.268 -	/* request I/O space for devices used on all i[345]86 PCs */
   1.269 -	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
   1.270 -		request_resource(&ioport_resource, &standard_io_resources[i]);
   1.271 -
   1.272 -#ifndef CONFIG_XEN
   1.273  	/*
   1.274  	 * Search for the bigest gap in the low 32 bits of the e820
   1.275  	 * memory space.
   1.276 @@ -1478,10 +1413,10 @@ static void __init register_memory(void)
   1.277  	last = 0x100000000ull;
   1.278  	gapstart = 0x10000000;
   1.279  	gapsize = 0x400000;
   1.280 -	i = e820.nr_map;
   1.281 +	i = nr_map;
   1.282  	while (--i >= 0) {
   1.283 -		unsigned long long start = e820.map[i].addr;
   1.284 -		unsigned long long end = start + e820.map[i].size;
   1.285 +		unsigned long long start = e820[i].addr;
   1.286 +		unsigned long long end = start + e820[i].size;
   1.287  
   1.288  		/*
   1.289  		 * Since "last" is at most 4GB, we know we'll
   1.290 @@ -1511,6 +1446,53 @@ static void __init register_memory(void)
   1.291  
   1.292  	printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
   1.293  		pci_mem_start, gapstart, gapsize);
   1.294 +}
   1.295 +
   1.296 +/*
   1.297 + * Request address space for all standard resources
   1.298 + */
   1.299 +static void __init register_memory(void)
   1.300 +{
   1.301 +#ifdef CONFIG_XEN
   1.302 +	struct e820entry *machine_e820;
   1.303 +	struct xen_memory_map memmap;
   1.304 +#endif
   1.305 +	int	      i;
   1.306 +
   1.307 +	/* Nothing to do if not running in dom0. */
   1.308 +	if (!(xen_start_info->flags & SIF_INITDOMAIN))
   1.309 +		return;
   1.310 +
   1.311 +#ifdef CONFIG_XEN
   1.312 +	machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
   1.313 +
   1.314 +	memmap.nr_entries = E820MAX;
   1.315 +	set_xen_guest_handle(memmap.buffer, machine_e820);
   1.316 +
   1.317 +	BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
   1.318 +
   1.319 +	legacy_init_iomem_resources(machine_e820, memmap.nr_entries,
   1.320 +				    &code_resource, &data_resource);
   1.321 +#else
   1.322 +	if (efi_enabled)
   1.323 +		efi_initialize_iomem_resources(&code_resource, &data_resource);
   1.324 +	else
   1.325 +		legacy_init_iomem_resources(e820.map, e820.nr_map,
   1.326 +					    &code_resource, &data_resource);
   1.327 +#endif
   1.328 +
   1.329 +	/* EFI systems may still have VGA */
   1.330 +	request_resource(&iomem_resource, &video_ram_resource);
   1.331 +
   1.332 +	/* request I/O space for devices used on all i[345]86 PCs */
   1.333 +	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
   1.334 +		request_resource(&ioport_resource, &standard_io_resources[i]);
   1.335 +
   1.336 +#ifdef CONFIG_XEN
   1.337 +	e820_setup_gap(machine_e820, memmap.nr_entries);
   1.338 +	free_bootmem(__pa(machine_e820), PAGE_SIZE);
   1.339 +#else
   1.340 +	e820_setup_gap(e820.map, e820.nr_map);
   1.341  #endif
   1.342  }
   1.343  
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c	Mon May 22 09:22:18 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c	Mon May 22 09:23:03 2006 +0100
     2.3 @@ -228,6 +228,12 @@ static inline int page_kills_ppro(unsign
     2.4  	return 0;
     2.5  }
     2.6  
     2.7 +#else
     2.8 +
     2.9 +#define page_kills_ppro(p)	0
    2.10 +
    2.11 +#endif
    2.12 +
    2.13  extern int is_available_memory(efi_memory_desc_t *);
    2.14  
    2.15  int page_is_ram(unsigned long pagenr)
    2.16 @@ -269,13 +275,6 @@ int page_is_ram(unsigned long pagenr)
    2.17  	return 0;
    2.18  }
    2.19  
    2.20 -#else /* CONFIG_XEN */
    2.21 -
    2.22 -#define page_kills_ppro(p)	0
    2.23 -#define page_is_ram(p)		1
    2.24 -
    2.25 -#endif
    2.26 -
    2.27  #ifdef CONFIG_HIGHMEM
    2.28  pte_t *kmap_pte;
    2.29  pgprot_t kmap_prot;
     3.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Mon May 22 09:22:18 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Mon May 22 09:23:03 2006 +0100
     3.3 @@ -10,10 +10,32 @@
     3.4  
     3.5  static char * __init machine_specific_memory_setup(void)
     3.6  {
     3.7 -	unsigned long max_pfn = xen_start_info->nr_pages;
     3.8 +	int rc;
     3.9 +	struct xen_memory_map memmap;
    3.10 +	/*
    3.11 +	 * This is rather large for a stack variable but this early in
    3.12 +	 * the boot process we know we have plenty slack space.
    3.13 +	 */
    3.14 +	struct e820entry map[E820MAX];
    3.15 +
    3.16 +	memmap.nr_entries = E820MAX;
    3.17 +	set_xen_guest_handle(memmap.buffer, map);
    3.18  
    3.19 -	e820.nr_map = 0;
    3.20 -	add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
    3.21 +	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
    3.22 +	if ( rc == -ENOSYS ) {
    3.23 +		memmap.nr_entries = 1;
    3.24 +		map[0].addr = 0ULL;
    3.25 +		map[0].size = xen_start_info->nr_pages << PAGE_SHIFT;
    3.26 +		/* 8MB slack (to balance backend allocations). */
    3.27 +		map[0].size += 8 << 20;
    3.28 +		map[0].type = E820_RAM;
    3.29 +		rc = 0;
    3.30 +	}
    3.31 +	BUG_ON(rc);
    3.32 +
    3.33 +	sanitize_e820_map(map, (char *)&memmap.nr_entries);
    3.34 +
    3.35 +	BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0);
    3.36  
    3.37  	return "Xen";
    3.38  }