diff options
Diffstat (limited to 'arch/x86/kernel/e820.c')
| -rw-r--r-- | arch/x86/kernel/e820.c | 46 | 
1 files changed, 38 insertions, 8 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 00628130292..7271fa33d79 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -617,7 +617,7 @@ __init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,   */  __init void e820_setup_gap(void)  { -	unsigned long gapstart, gapsize, round; +	unsigned long gapstart, gapsize;  	int found;  	gapstart = 0x10000000; @@ -635,14 +635,9 @@ __init void e820_setup_gap(void)  #endif  	/* -	 * See how much we want to round up: start off with -	 * rounding to the next 1MB area. +	 * e820_reserve_resources_late protect stolen RAM already  	 */ -	round = 0x100000; -	while ((gapsize >> 4) > round) -		round += round; -	/* Fun with two's complement */ -	pci_mem_start = (gapstart + round) & -round; +	pci_mem_start = gapstart;  	printk(KERN_INFO  	       "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", @@ -1371,6 +1366,23 @@ void __init e820_reserve_resources(void)  	}  } +/* How much should we pad RAM ending depending on where it is? */ +static unsigned long ram_alignment(resource_size_t pos) +{ +	unsigned long mb = pos >> 20; + +	/* To 64kB in the first megabyte */ +	if (!mb) +		return 64*1024; + +	/* To 1MB in the first 16MB */ +	if (mb < 16) +		return 1024*1024; + +	/* To 32MB for anything above that */ +	return 32*1024*1024; +} +  void __init e820_reserve_resources_late(void)  {  	int i; @@ -1382,6 +1394,24 @@ void __init e820_reserve_resources_late(void)  			insert_resource_expand_to_fit(&iomem_resource, res);  		res++;  	} + +	/* +	 * Try to bump up RAM regions to reasonable boundaries to +	 * avoid stolen RAM: +	 */ +	for (i = 0; i < e820.nr_map; i++) { +		struct e820entry *entry = &e820_saved.map[i]; +		resource_size_t start, end; + +		if (entry->type != E820_RAM) +			continue; +		start = entry->addr + entry->size; +		end = round_up(start, ram_alignment(start)); +		if (start == end) +			continue; +		reserve_region_with_split(&iomem_resource, start, +						  end - 1, "RAM buffer"); +	}  }  char *__init default_machine_specific_memory_setup(void)  |