Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/numa: Add constraints check for nid parameters mm, x86: Remove debug_pagealloc_enabled x86/mm: Initialize high mem before free_all_bootmem() arch/x86/kernel/e820.c: quiet sparse noise about plain integer as NULL pointer arch/x86/kernel/e820.c: Eliminate bubble sort from sanitize_e820_map() x86: Fix mmap random address range x86, mm: Unify zone_sizes_init() x86, mm: Prepare zone_sizes_init() for unification x86, mm: Use max_low_pfn for ZONE_NORMAL on 64-bit x86, mm: Wrap ZONE_DMA32 with CONFIG_ZONE_DMA32 x86, mm: Use max_pfn instead of highend_pfn x86, mm: Move zone init from paging_init() on 64-bit x86, mm: Use MAX_DMA_PFN for ZONE_DMA on 32-bit
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/firmware-map.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include <asm/e820.h>
|
||||
#include <asm/proto.h>
|
||||
@@ -227,22 +228,38 @@ void __init e820_print_map(char *who)
|
||||
* ____________________33__
|
||||
* ______________________4_
|
||||
*/
|
||||
struct change_member {
|
||||
struct e820entry *pbios; /* pointer to original bios entry */
|
||||
unsigned long long addr; /* address for this change point */
|
||||
};
|
||||
|
||||
static int __init cpcompare(const void *a, const void *b)
|
||||
{
|
||||
struct change_member * const *app = a, * const *bpp = b;
|
||||
const struct change_member *ap = *app, *bp = *bpp;
|
||||
|
||||
/*
|
||||
* Inputs are pointers to two elements of change_point[]. If their
|
||||
* addresses are unequal, their difference dominates. If the addresses
|
||||
* are equal, then consider one that represents the end of its region
|
||||
* to be greater than one that does not.
|
||||
*/
|
||||
if (ap->addr != bp->addr)
|
||||
return ap->addr > bp->addr ? 1 : -1;
|
||||
|
||||
return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
|
||||
}
|
||||
|
||||
int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
|
||||
u32 *pnr_map)
|
||||
{
|
||||
struct change_member {
|
||||
struct e820entry *pbios; /* pointer to original bios entry */
|
||||
unsigned long long addr; /* address for this change point */
|
||||
};
|
||||
static struct change_member change_point_list[2*E820_X_MAX] __initdata;
|
||||
static struct change_member *change_point[2*E820_X_MAX] __initdata;
|
||||
static struct e820entry *overlap_list[E820_X_MAX] __initdata;
|
||||
static struct e820entry new_bios[E820_X_MAX] __initdata;
|
||||
struct change_member *change_tmp;
|
||||
unsigned long current_type, last_type;
|
||||
unsigned long long last_addr;
|
||||
int chgidx, still_changing;
|
||||
int chgidx;
|
||||
int overlap_entries;
|
||||
int new_bios_entry;
|
||||
int old_nr, new_nr, chg_nr;
|
||||
@@ -279,35 +296,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
|
||||
chg_nr = chgidx;
|
||||
|
||||
/* sort change-point list by memory addresses (low -> high) */
|
||||
still_changing = 1;
|
||||
while (still_changing) {
|
||||
still_changing = 0;
|
||||
for (i = 1; i < chg_nr; i++) {
|
||||
unsigned long long curaddr, lastaddr;
|
||||
unsigned long long curpbaddr, lastpbaddr;
|
||||
|
||||
curaddr = change_point[i]->addr;
|
||||
lastaddr = change_point[i - 1]->addr;
|
||||
curpbaddr = change_point[i]->pbios->addr;
|
||||
lastpbaddr = change_point[i - 1]->pbios->addr;
|
||||
|
||||
/*
|
||||
* swap entries, when:
|
||||
*
|
||||
* curaddr > lastaddr or
|
||||
* curaddr == lastaddr and curaddr == curpbaddr and
|
||||
* lastaddr != lastpbaddr
|
||||
*/
|
||||
if (curaddr < lastaddr ||
|
||||
(curaddr == lastaddr && curaddr == curpbaddr &&
|
||||
lastaddr != lastpbaddr)) {
|
||||
change_tmp = change_point[i];
|
||||
change_point[i] = change_point[i-1];
|
||||
change_point[i-1] = change_tmp;
|
||||
still_changing = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
sort(change_point, chg_nr, sizeof *change_point, cpcompare, NULL);
|
||||
|
||||
/* create a new bios memory map, removing overlaps */
|
||||
overlap_entries = 0; /* number of entries in the overlap table */
|
||||
|
Reference in New Issue
Block a user