Browse Source

Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot updates from Ingo Molnar:
 "The biggest changes in this cycle were:

   - reworking of the e820 code: separate in-kernel and boot-ABI data
     structures and apply a whole range of cleanups to the kernel side.

     No change in functionality.

   - enable KASLR by default: it's used by all major distros and it's
     out of the experimental stage as well.

   - ... misc fixes and cleanups"

* 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (63 commits)
  x86/KASLR: Fix kexec kernel boot crash when KASLR randomization fails
  x86/reboot: Turn off KVM when halting a CPU
  x86/boot: Fix BSS corruption/overwrite bug in early x86 kernel startup
  x86: Enable KASLR by default
  boot/param: Move next_arg() function to lib/cmdline.c for later reuse
  x86/boot: Fix Sparse warning by including required header file
  x86/boot/64: Rename start_cpu()
  x86/xen: Update e820 table handling to the new core x86 E820 code
  x86/boot: Fix pr_debug() API braindamage
  xen, x86/headers: Add <linux/device.h> dependency to <asm/xen/page.h>
  x86/boot/e820: Simplify e820__update_table()
  x86/boot/e820: Separate the E820 ABI structures from the in-kernel structures
  x86/boot/e820: Fix and clean up e820_type switch() statements
  x86/boot/e820: Rename the remaining E820 APIs to the e820__*() prefix
  x86/boot/e820: Remove unnecessary #include's
  x86/boot/e820: Rename e820_mark_nosave_regions() to e820__register_nosave_regions()
  x86/boot/e820: Rename e820_reserve_resources*() to e820__reserve_resources*()
  x86/boot/e820: Use bool in query APIs
  x86/boot/e820: Document e820__reserve_setup_data()
  x86/boot/e820: Clean up __e820__update_table() et al
  ...
Linus Torvalds 8 years ago
parent
commit
16b76293c5
75 changed files with 1127 additions and 944 deletions
  1. 3 3
      Documentation/x86/zero-page.txt
  2. 3 3
      arch/x86/Kconfig
  3. 1 1
      arch/x86/boot/boot.h
  4. 23 21
      arch/x86/boot/compressed/eboot.c
  5. 12 5
      arch/x86/boot/compressed/kaslr.c
  6. 0 1
      arch/x86/boot/header.S
  7. 3 3
      arch/x86/boot/memory.c
  8. 2 0
      arch/x86/configs/i386_defconfig
  9. 2 0
      arch/x86/configs/x86_64_defconfig
  10. 2 0
      arch/x86/include/asm/acpi.h
  11. 0 73
      arch/x86/include/asm/e820.h
  12. 50 0
      arch/x86/include/asm/e820/api.h
  13. 104 0
      arch/x86/include/asm/e820/types.h
  14. 2 2
      arch/x86/include/asm/gart.h
  15. 2 2
      arch/x86/include/asm/mpspec.h
  16. 2 0
      arch/x86/include/asm/pci_x86.h
  17. 1 2
      arch/x86/include/asm/pgtable.h
  18. 1 0
      arch/x86/include/asm/xen/page.h
  19. 16 2
      arch/x86/include/uapi/asm/bootparam.h
  20. 3 2
      arch/x86/kernel/acpi/boot.c
  21. 5 5
      arch/x86/kernel/aperture_64.c
  22. 1 1
      arch/x86/kernel/apic/apic.c
  23. 1 1
      arch/x86/kernel/apic/apic_noop.c
  24. 1 1
      arch/x86/kernel/apic/probe_32.c
  25. 1 0
      arch/x86/kernel/apic/x2apic_uv_x.c
  26. 1 1
      arch/x86/kernel/cpu/centaur.c
  27. 3 3
      arch/x86/kernel/cpu/mtrr/cleanup.c
  28. 1 1
      arch/x86/kernel/cpu/mtrr/main.c
  29. 12 11
      arch/x86/kernel/crash.c
  30. 529 525
      arch/x86/kernel/e820.c
  31. 2 2
      arch/x86/kernel/early-quirks.c
  32. 1 1
      arch/x86/kernel/head32.c
  33. 1 1
      arch/x86/kernel/head64.c
  34. 4 6
      arch/x86/kernel/head_64.S
  35. 9 9
      arch/x86/kernel/kexec-bzimage64.c
  36. 3 3
      arch/x86/kernel/mpparse.c
  37. 1 1
      arch/x86/kernel/probe_roms.c
  38. 4 4
      arch/x86/kernel/resource.c
  39. 27 51
      arch/x86/kernel/setup.c
  40. 3 0
      arch/x86/kernel/smp.c
  41. 8 8
      arch/x86/kernel/tboot.c
  42. 2 2
      arch/x86/kernel/x86_init.c
  43. 4 4
      arch/x86/lguest/boot.c
  44. 1 1
      arch/x86/lib/kaslr.c
  45. 1 1
      arch/x86/mm/amdtopology.c
  46. 53 6
      arch/x86/mm/init.c
  47. 1 1
      arch/x86/mm/init_32.c
  48. 13 13
      arch/x86/mm/init_64.c
  49. 2 1
      arch/x86/mm/ioremap.c
  50. 3 2
      arch/x86/mm/kasan_init_64.c
  51. 1 1
      arch/x86/mm/mmio-mod.c
  52. 1 1
      arch/x86/mm/numa.c
  53. 1 1
      arch/x86/mm/pageattr.c
  54. 2 1
      arch/x86/mm/pat.c
  55. 1 1
      arch/x86/mm/pgtable_32.c
  56. 1 1
      arch/x86/mm/srat.c
  57. 2 2
      arch/x86/pci/i386.c
  58. 11 11
      arch/x86/pci/mmconfig-shared.c
  59. 1 1
      arch/x86/pci/mmconfig_32.c
  60. 1 1
      arch/x86/pci/mmconfig_64.c
  61. 2 0
      arch/x86/pci/pcbios.c
  62. 10 9
      arch/x86/platform/efi/efi.c
  63. 1 1
      arch/x86/platform/efi/efi_64.c
  64. 5 3
      arch/x86/platform/efi/quirks.c
  65. 8 8
      arch/x86/power/hibernate_64.c
  66. 13 14
      arch/x86/xen/enlighten.c
  67. 1 1
      arch/x86/xen/mmu.c
  68. 73 45
      arch/x86/xen/setup.c
  69. 1 1
      drivers/acpi/tables.c
  70. 1 1
      drivers/char/agp/amd64-agp.c
  71. 1 0
      include/linux/kernel.h
  72. 1 1
      include/xen/page.h
  73. 0 52
      kernel/params.c
  74. 57 0
      lib/cmdline.c
  75. 1 1
      tools/lguest/lguest.c

+ 3 - 3
Documentation/x86/zero-page.txt

@@ -27,7 +27,7 @@ Offset	Proto	Name		Meaning
 1C0/020	ALL	efi_info	EFI 32 information (struct efi_info)
 1C0/020	ALL	efi_info	EFI 32 information (struct efi_info)
 1E0/004	ALL	alk_mem_k	Alternative mem check, in KB
 1E0/004	ALL	alk_mem_k	Alternative mem check, in KB
 1E4/004	ALL	scratch		Scratch field for the kernel setup code
 1E4/004	ALL	scratch		Scratch field for the kernel setup code
-1E8/001	ALL	e820_entries	Number of entries in e820_map (below)
+1E8/001	ALL	e820_entries	Number of entries in e820_table (below)
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
 				(below)
 				(below)
@@ -35,6 +35,6 @@ Offset	Proto	Name		Meaning
 1EC/001	ALL     secure_boot	Secure boot is enabled in the firmware
 1EC/001	ALL     secure_boot	Secure boot is enabled in the firmware
 1EF/001	ALL	sentinel	Used to detect broken bootloaders
 1EF/001	ALL	sentinel	Used to detect broken bootloaders
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
-2D0/A00	ALL	e820_map	E820 memory map table
-				(array of struct e820entry)
+2D0/A00	ALL	e820_table	E820 memory map table
+				(array of struct e820_entry)
 D00/1EC	ALL	eddbuf		EDD data (array of struct edd_info)
 D00/1EC	ALL	eddbuf		EDD data (array of struct edd_info)

+ 3 - 3
arch/x86/Kconfig

@@ -1973,7 +1973,7 @@ config RELOCATABLE
 config RANDOMIZE_BASE
 config RANDOMIZE_BASE
 	bool "Randomize the address of the kernel image (KASLR)"
 	bool "Randomize the address of the kernel image (KASLR)"
 	depends on RELOCATABLE
 	depends on RELOCATABLE
-	default n
+	default y
 	---help---
 	---help---
 	  In support of Kernel Address Space Layout Randomization (KASLR),
 	  In support of Kernel Address Space Layout Randomization (KASLR),
 	  this randomizes the physical address at which the kernel image
 	  this randomizes the physical address at which the kernel image
@@ -2003,7 +2003,7 @@ config RANDOMIZE_BASE
 	  theoretically possible, but the implementations are further
 	  theoretically possible, but the implementations are further
 	  limited due to memory layouts.
 	  limited due to memory layouts.
 
 
-	  If unsure, say N.
+	  If unsure, say Y.
 
 
 # Relocation on x86 needs some additional build support
 # Relocation on x86 needs some additional build support
 config X86_NEED_RELOCS
 config X86_NEED_RELOCS
@@ -2052,7 +2052,7 @@ config RANDOMIZE_MEMORY
 	   configuration have in average 30,000 different possible virtual
 	   configuration have in average 30,000 different possible virtual
 	   addresses for each memory section.
 	   addresses for each memory section.
 
 
-	   If unsure, say N.
+	   If unsure, say Y.
 
 
 config RANDOMIZE_MEMORY_PHYSICAL_PADDING
 config RANDOMIZE_MEMORY_PHYSICAL_PADDING
 	hex "Physical memory mapping padding" if EXPERT
 	hex "Physical memory mapping padding" if EXPERT

+ 1 - 1
arch/x86/boot/boot.h

@@ -16,7 +16,7 @@
 #ifndef BOOT_BOOT_H
 #ifndef BOOT_BOOT_H
 #define BOOT_BOOT_H
 #define BOOT_BOOT_H
 
 
-#define STACK_SIZE	512	/* Minimum number of bytes for stack */
+#define STACK_SIZE	1024	/* Minimum number of bytes for stack */
 
 
 #ifndef __ASSEMBLY__
 #ifndef __ASSEMBLY__
 
 

+ 23 - 21
arch/x86/boot/compressed/eboot.c

@@ -9,7 +9,9 @@
 
 
 #include <linux/efi.h>
 #include <linux/efi.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
+
 #include <asm/efi.h>
 #include <asm/efi.h>
+#include <asm/e820/types.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
 #include <asm/desc.h>
 
 
@@ -729,7 +731,7 @@ static void add_e820ext(struct boot_params *params,
 	unsigned long size;
 	unsigned long size;
 
 
 	e820ext->type = SETUP_E820_EXT;
 	e820ext->type = SETUP_E820_EXT;
-	e820ext->len = nr_entries * sizeof(struct e820entry);
+	e820ext->len = nr_entries * sizeof(struct boot_e820_entry);
 	e820ext->next = 0;
 	e820ext->next = 0;
 
 
 	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
 	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
@@ -746,9 +748,9 @@ static void add_e820ext(struct boot_params *params,
 static efi_status_t setup_e820(struct boot_params *params,
 static efi_status_t setup_e820(struct boot_params *params,
 			       struct setup_data *e820ext, u32 e820ext_size)
 			       struct setup_data *e820ext, u32 e820ext_size)
 {
 {
-	struct e820entry *e820_map = &params->e820_map[0];
+	struct boot_e820_entry *entry = params->e820_table;
 	struct efi_info *efi = &params->efi_info;
 	struct efi_info *efi = &params->efi_info;
-	struct e820entry *prev = NULL;
+	struct boot_e820_entry *prev = NULL;
 	u32 nr_entries;
 	u32 nr_entries;
 	u32 nr_desc;
 	u32 nr_desc;
 	int i;
 	int i;
@@ -773,15 +775,15 @@ static efi_status_t setup_e820(struct boot_params *params,
 		case EFI_MEMORY_MAPPED_IO:
 		case EFI_MEMORY_MAPPED_IO:
 		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
 		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
 		case EFI_PAL_CODE:
 		case EFI_PAL_CODE:
-			e820_type = E820_RESERVED;
+			e820_type = E820_TYPE_RESERVED;
 			break;
 			break;
 
 
 		case EFI_UNUSABLE_MEMORY:
 		case EFI_UNUSABLE_MEMORY:
-			e820_type = E820_UNUSABLE;
+			e820_type = E820_TYPE_UNUSABLE;
 			break;
 			break;
 
 
 		case EFI_ACPI_RECLAIM_MEMORY:
 		case EFI_ACPI_RECLAIM_MEMORY:
-			e820_type = E820_ACPI;
+			e820_type = E820_TYPE_ACPI;
 			break;
 			break;
 
 
 		case EFI_LOADER_CODE:
 		case EFI_LOADER_CODE:
@@ -789,15 +791,15 @@ static efi_status_t setup_e820(struct boot_params *params,
 		case EFI_BOOT_SERVICES_CODE:
 		case EFI_BOOT_SERVICES_CODE:
 		case EFI_BOOT_SERVICES_DATA:
 		case EFI_BOOT_SERVICES_DATA:
 		case EFI_CONVENTIONAL_MEMORY:
 		case EFI_CONVENTIONAL_MEMORY:
-			e820_type = E820_RAM;
+			e820_type = E820_TYPE_RAM;
 			break;
 			break;
 
 
 		case EFI_ACPI_MEMORY_NVS:
 		case EFI_ACPI_MEMORY_NVS:
-			e820_type = E820_NVS;
+			e820_type = E820_TYPE_NVS;
 			break;
 			break;
 
 
 		case EFI_PERSISTENT_MEMORY:
 		case EFI_PERSISTENT_MEMORY:
-			e820_type = E820_PMEM;
+			e820_type = E820_TYPE_PMEM;
 			break;
 			break;
 
 
 		default:
 		default:
@@ -811,26 +813,26 @@ static efi_status_t setup_e820(struct boot_params *params,
 			continue;
 			continue;
 		}
 		}
 
 
-		if (nr_entries == ARRAY_SIZE(params->e820_map)) {
-			u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+		if (nr_entries == ARRAY_SIZE(params->e820_table)) {
+			u32 need = (nr_desc - i) * sizeof(struct e820_entry) +
 				   sizeof(struct setup_data);
 				   sizeof(struct setup_data);
 
 
 			if (!e820ext || e820ext_size < need)
 			if (!e820ext || e820ext_size < need)
 				return EFI_BUFFER_TOO_SMALL;
 				return EFI_BUFFER_TOO_SMALL;
 
 
 			/* boot_params map full, switch to e820 extended */
 			/* boot_params map full, switch to e820 extended */
-			e820_map = (struct e820entry *)e820ext->data;
+			entry = (struct boot_e820_entry *)e820ext->data;
 		}
 		}
 
 
-		e820_map->addr = d->phys_addr;
-		e820_map->size = d->num_pages << PAGE_SHIFT;
-		e820_map->type = e820_type;
-		prev = e820_map++;
+		entry->addr = d->phys_addr;
+		entry->size = d->num_pages << PAGE_SHIFT;
+		entry->type = e820_type;
+		prev = entry++;
 		nr_entries++;
 		nr_entries++;
 	}
 	}
 
 
-	if (nr_entries > ARRAY_SIZE(params->e820_map)) {
-		u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map);
+	if (nr_entries > ARRAY_SIZE(params->e820_table)) {
+		u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_table);
 
 
 		add_e820ext(params, e820ext, nr_e820ext);
 		add_e820ext(params, e820ext, nr_e820ext);
 		nr_entries -= nr_e820ext;
 		nr_entries -= nr_e820ext;
@@ -848,7 +850,7 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
 	unsigned long size;
 	unsigned long size;
 
 
 	size = sizeof(struct setup_data) +
 	size = sizeof(struct setup_data) +
-		sizeof(struct e820entry) * nr_desc;
+		sizeof(struct e820_entry) * nr_desc;
 
 
 	if (*e820ext) {
 	if (*e820ext) {
 		efi_call_early(free_pool, *e820ext);
 		efi_call_early(free_pool, *e820ext);
@@ -884,9 +886,9 @@ static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
 
 
 	if (first) {
 	if (first) {
 		nr_desc = *map->buff_size / *map->desc_size;
 		nr_desc = *map->buff_size / *map->desc_size;
-		if (nr_desc > ARRAY_SIZE(p->boot_params->e820_map)) {
+		if (nr_desc > ARRAY_SIZE(p->boot_params->e820_table)) {
 			u32 nr_e820ext = nr_desc -
 			u32 nr_e820ext = nr_desc -
-					ARRAY_SIZE(p->boot_params->e820_map);
+					ARRAY_SIZE(p->boot_params->e820_table);
 
 
 			status = alloc_e820ext(nr_e820ext, &p->e820ext,
 			status = alloc_e820ext(nr_e820ext, &p->e820ext,
 					       &p->e820ext_size);
 					       &p->e820ext_size);

+ 12 - 5
arch/x86/boot/compressed/kaslr.c

@@ -426,7 +426,7 @@ static unsigned long slots_fetch_random(void)
 	return 0;
 	return 0;
 }
 }
 
 
-static void process_e820_entry(struct e820entry *entry,
+static void process_e820_entry(struct boot_e820_entry *entry,
 			       unsigned long minimum,
 			       unsigned long minimum,
 			       unsigned long image_size)
 			       unsigned long image_size)
 {
 {
@@ -435,7 +435,7 @@ static void process_e820_entry(struct e820entry *entry,
 	unsigned long start_orig;
 	unsigned long start_orig;
 
 
 	/* Skip non-RAM entries. */
 	/* Skip non-RAM entries. */
-	if (entry->type != E820_RAM)
+	if (entry->type != E820_TYPE_RAM)
 		return;
 		return;
 
 
 	/* On 32-bit, ignore entries entirely above our maximum. */
 	/* On 32-bit, ignore entries entirely above our maximum. */
@@ -518,7 +518,7 @@ static unsigned long find_random_phys_addr(unsigned long minimum,
 
 
 	/* Verify potential e820 positions, appending to slots list. */
 	/* Verify potential e820 positions, appending to slots list. */
 	for (i = 0; i < boot_params->e820_entries; i++) {
 	for (i = 0; i < boot_params->e820_entries; i++) {
-		process_e820_entry(&boot_params->e820_map[i], minimum,
+		process_e820_entry(&boot_params->e820_table[i], minimum,
 				   image_size);
 				   image_size);
 		if (slot_area_index == MAX_SLOT_AREA) {
 		if (slot_area_index == MAX_SLOT_AREA) {
 			debug_putstr("Aborted e820 scan (slot_areas full)!\n");
 			debug_putstr("Aborted e820 scan (slot_areas full)!\n");
@@ -597,10 +597,17 @@ void choose_random_location(unsigned long input,
 			add_identity_map(random_addr, output_size);
 			add_identity_map(random_addr, output_size);
 			*output = random_addr;
 			*output = random_addr;
 		}
 		}
+
+		/*
+		 * This loads the identity mapping page table.
+		 * This should only be done if a new physical address
+		 * is found for the kernel, otherwise we should keep
+		 * the old page table to make it be like the "nokaslr"
+		 * case.
+		 */
+		finalize_identity_maps();
 	}
 	}
 
 
-	/* This actually loads the identity pagetable on x86_64. */
-	finalize_identity_maps();
 
 
 	/* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */
 	/* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */
 	if (IS_ENABLED(CONFIG_X86_64))
 	if (IS_ENABLED(CONFIG_X86_64))

+ 0 - 1
arch/x86/boot/header.S

@@ -18,7 +18,6 @@
 #include <asm/segment.h>
 #include <asm/segment.h>
 #include <generated/utsrelease.h>
 #include <generated/utsrelease.h>
 #include <asm/boot.h>
 #include <asm/boot.h>
-#include <asm/e820.h>
 #include <asm/page_types.h>
 #include <asm/page_types.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/bootparam.h>
 #include <asm/bootparam.h>

+ 3 - 3
arch/x86/boot/memory.c

@@ -21,8 +21,8 @@ static int detect_memory_e820(void)
 {
 {
 	int count = 0;
 	int count = 0;
 	struct biosregs ireg, oreg;
 	struct biosregs ireg, oreg;
-	struct e820entry *desc = boot_params.e820_map;
-	static struct e820entry buf; /* static so it is zeroed */
+	struct boot_e820_entry *desc = boot_params.e820_table;
+	static struct boot_e820_entry buf; /* static so it is zeroed */
 
 
 	initregs(&ireg);
 	initregs(&ireg);
 	ireg.ax  = 0xe820;
 	ireg.ax  = 0xe820;
@@ -66,7 +66,7 @@ static int detect_memory_e820(void)
 
 
 		*desc++ = buf;
 		*desc++ = buf;
 		count++;
 		count++;
-	} while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));
+	} while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_table));
 
 
 	return boot_params.e820_entries = count;
 	return boot_params.e820_entries = count;
 }
 }

+ 2 - 0
arch/x86/configs/i386_defconfig

@@ -57,6 +57,8 @@ CONFIG_EFI=y
 CONFIG_HZ_1000=y
 CONFIG_HZ_1000=y
 CONFIG_KEXEC=y
 CONFIG_KEXEC=y
 CONFIG_CRASH_DUMP=y
 CONFIG_CRASH_DUMP=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RANDOMIZE_MEMORY=y
 # CONFIG_COMPAT_VDSO is not set
 # CONFIG_COMPAT_VDSO is not set
 CONFIG_HIBERNATION=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_DEBUG=y
 CONFIG_PM_DEBUG=y

+ 2 - 0
arch/x86/configs/x86_64_defconfig

@@ -55,6 +55,8 @@ CONFIG_EFI=y
 CONFIG_HZ_1000=y
 CONFIG_HZ_1000=y
 CONFIG_KEXEC=y
 CONFIG_KEXEC=y
 CONFIG_CRASH_DUMP=y
 CONFIG_CRASH_DUMP=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RANDOMIZE_MEMORY=y
 # CONFIG_COMPAT_VDSO is not set
 # CONFIG_COMPAT_VDSO is not set
 CONFIG_HIBERNATION=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_DEBUG=y
 CONFIG_PM_DEBUG=y

+ 2 - 0
arch/x86/include/asm/acpi.h

@@ -52,6 +52,8 @@ extern u8 acpi_sci_flags;
 extern int acpi_sci_override_gsi;
 extern int acpi_sci_override_gsi;
 void acpi_pic_sci_set_trigger(unsigned int, u16);
 void acpi_pic_sci_set_trigger(unsigned int, u16);
 
 
+struct device;
+
 extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
 extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
 				  int trigger, int polarity);
 				  int trigger, int polarity);
 extern void (*__acpi_unregister_gsi)(u32 gsi);
 extern void (*__acpi_unregister_gsi)(u32 gsi);

+ 0 - 73
arch/x86/include/asm/e820.h

@@ -1,73 +0,0 @@
-#ifndef _ASM_X86_E820_H
-#define _ASM_X86_E820_H
-
-/*
- * E820_X_MAX is the maximum size of the extended E820 table.  The extended
- * table may contain up to 3 extra E820 entries per possible NUMA node, so we
- * make room for 3 * MAX_NUMNODES possible entries, beyond the standard 128.
- * Also note that E820_X_MAX *must* be defined before we include uapi/asm/e820.h.
- */
-#include <linux/numa.h>
-#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
-
-#include <uapi/asm/e820.h>
-
-#ifndef __ASSEMBLY__
-/* see comment in arch/x86/kernel/e820.c */
-extern struct e820map *e820;
-extern struct e820map *e820_saved;
-
-extern unsigned long pci_mem_start;
-extern int e820_any_mapped(u64 start, u64 end, unsigned type);
-extern int e820_all_mapped(u64 start, u64 end, unsigned type);
-extern void e820_add_region(u64 start, u64 size, int type);
-extern void e820_print_map(char *who);
-extern int
-sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map);
-extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
-			       unsigned new_type);
-extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
-			     int checktype);
-extern void update_e820(void);
-extern void e820_setup_gap(void);
-struct setup_data;
-extern void parse_e820_ext(u64 phys_addr, u32 data_len);
-
-#if defined(CONFIG_X86_64) || \
-	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
-extern void e820_mark_nosave_regions(unsigned long limit_pfn);
-#else
-static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
-{
-}
-#endif
-
-extern unsigned long e820_end_of_ram_pfn(void);
-extern unsigned long e820_end_of_low_ram_pfn(void);
-extern u64 early_reserve_e820(u64 sizet, u64 align);
-
-void memblock_x86_fill(void);
-void memblock_find_dma_reserve(void);
-
-extern void finish_e820_parsing(void);
-extern void e820_reserve_resources(void);
-extern void e820_reserve_resources_late(void);
-extern void setup_memory_map(void);
-extern char *default_machine_specific_memory_setup(void);
-
-extern void e820_reallocate_tables(void);
-
-/*
- * Returns true iff the specified range [s,e) is completely contained inside
- * the ISA region.
- */
-static inline bool is_ISA_range(u64 s, u64 e)
-{
-	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
-}
-
-#endif /* __ASSEMBLY__ */
-#include <linux/ioport.h>
-
-#define HIGH_MEMORY	(1024*1024)
-#endif /* _ASM_X86_E820_H */

+ 50 - 0
arch/x86/include/asm/e820/api.h

@@ -0,0 +1,50 @@
+#ifndef _ASM_E820_API_H
+#define _ASM_E820_API_H
+
+#include <asm/e820/types.h>
+
+extern struct e820_table *e820_table;
+extern struct e820_table *e820_table_firmware;
+
+extern unsigned long pci_mem_start;
+
+extern bool e820__mapped_any(u64 start, u64 end, enum e820_type type);
+extern bool e820__mapped_all(u64 start, u64 end, enum e820_type type);
+
+extern void e820__range_add   (u64 start, u64 size, enum e820_type type);
+extern u64  e820__range_update(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type);
+extern u64  e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type);
+
+extern void e820__print_table(char *who);
+extern int  e820__update_table(struct e820_table *table);
+extern void e820__update_table_print(void);
+
+extern unsigned long e820__end_of_ram_pfn(void);
+extern unsigned long e820__end_of_low_ram_pfn(void);
+
+extern u64  e820__memblock_alloc_reserved(u64 size, u64 align);
+extern void e820__memblock_setup(void);
+
+extern void e820__reserve_setup_data(void);
+extern void e820__finish_early_params(void);
+extern void e820__reserve_resources(void);
+extern void e820__reserve_resources_late(void);
+
+extern void e820__memory_setup(void);
+extern void e820__memory_setup_extended(u64 phys_addr, u32 data_len);
+extern char *e820__memory_setup_default(void);
+extern void e820__setup_pci_gap(void);
+
+extern void e820__reallocate_tables(void);
+extern void e820__register_nosave_regions(unsigned long limit_pfn);
+
+/*
+ * Returns true iff the specified range [start,end) is completely contained inside
+ * the ISA region.
+ */
+static inline bool is_ISA_range(u64 start, u64 end)
+{
+	return start >= ISA_START_ADDRESS && end <= ISA_END_ADDRESS;
+}
+
+#endif /* _ASM_E820_API_H */

+ 104 - 0
arch/x86/include/asm/e820/types.h

@@ -0,0 +1,104 @@
+#ifndef _ASM_E820_TYPES_H
+#define _ASM_E820_TYPES_H
+
+#include <uapi/asm/bootparam.h>
+
+/*
+ * These are the E820 types known to the kernel:
+ */
+enum e820_type {
+	E820_TYPE_RAM		= 1,
+	E820_TYPE_RESERVED	= 2,
+	E820_TYPE_ACPI		= 3,
+	E820_TYPE_NVS		= 4,
+	E820_TYPE_UNUSABLE	= 5,
+	E820_TYPE_PMEM		= 7,
+
+	/*
+	 * This is a non-standardized way to represent ADR or
+	 * NVDIMM regions that persist over a reboot.
+	 *
+	 * The kernel will ignore their special capabilities
+	 * unless the CONFIG_X86_PMEM_LEGACY=y option is set.
+	 *
+	 * ( Note that older platforms also used 6 for the same
+	 *   type of memory, but newer versions switched to 12 as
+	 *   6 was assigned differently. Some time they will learn... )
+	 */
+	E820_TYPE_PRAM		= 12,
+
+	/*
+	 * Reserved RAM used by the kernel itself if
+	 * CONFIG_INTEL_TXT=y is enabled, memory of this type
+	 * will be included in the S3 integrity calculation
+	 * and so should not include any memory that the BIOS
+	 * might alter over the S3 transition:
+	 */
+	E820_TYPE_RESERVED_KERN	= 128,
+};
+
+/*
+ * A single E820 map entry, describing a memory range of [addr...addr+size-1],
+ * of 'type' memory type:
+ *
+ * (We pack it because there can be thousands of them on large systems.)
+ */
+struct e820_entry {
+	u64			addr;
+	u64			size;
+	enum e820_type		type;
+} __attribute__((packed));
+
+/*
+ * The legacy E820 BIOS limits us to 128 (E820_MAX_ENTRIES_ZEROPAGE) nodes
+ * due to the constrained space in the zeropage.
+ *
+ * On large systems we can easily have thousands of nodes with RAM,
+ * which cannot be fit into so few entries - so we have a mechanism
+ * to extend the e820 table size at build-time, via the E820_MAX_ENTRIES
+ * define below.
+ *
+ * ( Those extra entries are enumerated via the EFI memory map, not
+ *   via the legacy zeropage mechanism. )
+ *
+ * Size our internal memory map tables to have room for these additional
+ * entries, based on a heuristic calculation: up to three entries per
+ * NUMA node, plus E820_MAX_ENTRIES_ZEROPAGE for some extra space.
+ *
+ * This allows for bootstrap/firmware quirks such as possible duplicate
+ * E820 entries that might need room in the same arrays, prior to the
+ * call to e820__update_table() to remove duplicates.  The allowance
+ * of three memory map entries per node is "enough" entries for
+ * the initial hardware platform motivating this mechanism to make
+ * use of additional EFI map entries.  Future platforms may want
+ * to allow more than three entries per node or otherwise refine
+ * this size.
+ */
+
+#include <linux/numa.h>
+
+#define E820_MAX_ENTRIES	(E820_MAX_ENTRIES_ZEROPAGE + 3*MAX_NUMNODES)
+
+/*
+ * The whole array of E820 entries:
+ */
+struct e820_table {
+	__u32 nr_entries;
+	struct e820_entry entries[E820_MAX_ENTRIES];
+};
+
+/*
+ * Various well-known legacy memory ranges in physical memory:
+ */
+#define ISA_START_ADDRESS	0x000a0000
+#define ISA_END_ADDRESS		0x00100000
+
+#define BIOS_BEGIN		0x000a0000
+#define BIOS_END		0x00100000
+
+#define HIGH_MEMORY		0x00100000
+
+#define BIOS_ROM_BASE		0xffe00000
+#define BIOS_ROM_END		0xffffffff
+
+#endif /* _ASM_E820_TYPES_H */

+ 2 - 2
arch/x86/include/asm/gart.h

@@ -1,7 +1,7 @@
 #ifndef _ASM_X86_GART_H
 #ifndef _ASM_X86_GART_H
 #define _ASM_X86_GART_H
 #define _ASM_X86_GART_H
 
 
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 
 extern void set_up_gart_resume(u32, u32);
 extern void set_up_gart_resume(u32, u32);
 
 
@@ -97,7 +97,7 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
 		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
 		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
 		return 0;
 		return 0;
 	}
 	}
-	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
+	if (e820__mapped_any(aper_base, aper_base + aper_size, E820_TYPE_RAM)) {
 		printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
 		printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
 		return 0;
 		return 0;
 	}
 	}

+ 2 - 2
arch/x86/include/asm/mpspec.h

@@ -64,7 +64,7 @@ static inline void find_smp_config(void)
 }
 }
 
 
 #ifdef CONFIG_X86_MPPARSE
 #ifdef CONFIG_X86_MPPARSE
-extern void early_reserve_e820_mpc_new(void);
+extern void e820__memblock_alloc_reserved_mpc_new(void);
 extern int enable_update_mptable;
 extern int enable_update_mptable;
 extern int default_mpc_apic_id(struct mpc_cpu *m);
 extern int default_mpc_apic_id(struct mpc_cpu *m);
 extern void default_smp_read_mpc_oem(struct mpc_table *mpc);
 extern void default_smp_read_mpc_oem(struct mpc_table *mpc);
@@ -76,7 +76,7 @@ extern void default_mpc_oem_bus_info(struct mpc_bus *m, char *str);
 extern void default_find_smp_config(void);
 extern void default_find_smp_config(void);
 extern void default_get_smp_config(unsigned int early);
 extern void default_get_smp_config(unsigned int early);
 #else
 #else
-static inline void early_reserve_e820_mpc_new(void) { }
+static inline void e820__memblock_alloc_reserved_mpc_new(void) { }
 #define enable_update_mptable 0
 #define enable_update_mptable 0
 #define default_mpc_apic_id NULL
 #define default_mpc_apic_id NULL
 #define default_smp_read_mpc_oem NULL
 #define default_smp_read_mpc_oem NULL

+ 2 - 0
arch/x86/include/asm/pci_x86.h

@@ -4,6 +4,8 @@
  *	(c) 1999 Martin Mares <mj@ucw.cz>
  *	(c) 1999 Martin Mares <mj@ucw.cz>
  */
  */
 
 
+#include <linux/ioport.h>
+
 #undef DEBUG
 #undef DEBUG
 
 
 #ifdef DEBUG
 #ifdef DEBUG

+ 1 - 2
arch/x86/include/asm/pgtable.h

@@ -2,8 +2,6 @@
 #define _ASM_X86_PGTABLE_H
 #define _ASM_X86_PGTABLE_H
 
 
 #include <asm/page.h>
 #include <asm/page.h>
-#include <asm/e820.h>
-
 #include <asm/pgtable_types.h>
 #include <asm/pgtable_types.h>
 
 
 /*
 /*
@@ -845,6 +843,7 @@ static inline int pgd_none(pgd_t pgd)
 extern int direct_gbpages;
 extern int direct_gbpages;
 void init_mem_mapping(void);
 void init_mem_mapping(void);
 void early_alloc_pgt_buf(void);
 void early_alloc_pgt_buf(void);
+extern void memblock_find_dma_reserve(void);
 
 
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_X86_64
 /* Realmode trampoline initialization. */
 /* Realmode trampoline initialization. */

+ 1 - 0
arch/x86/include/asm/xen/page.h

@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/pfn.h>
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
+#include <linux/device.h>
 
 
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 #include <asm/page.h>
 #include <asm/page.h>

+ 16 - 2
arch/x86/include/uapi/asm/bootparam.h

@@ -34,7 +34,6 @@
 #include <linux/screen_info.h>
 #include <linux/screen_info.h>
 #include <linux/apm_bios.h>
 #include <linux/apm_bios.h>
 #include <linux/edd.h>
 #include <linux/edd.h>
-#include <asm/e820.h>
 #include <asm/ist.h>
 #include <asm/ist.h>
 #include <video/edid.h>
 #include <video/edid.h>
 
 
@@ -111,6 +110,21 @@ struct efi_info {
 	__u32 efi_memmap_hi;
 	__u32 efi_memmap_hi;
 };
 };
 
 
+/*
+ * This is the maximum number of entries in struct boot_params::e820_table
+ * (the zeropage), which is part of the x86 boot protocol ABI:
+ */
+#define E820_MAX_ENTRIES_ZEROPAGE 128
+
+/*
+ * The E820 memory region entry of the boot protocol ABI:
+ */
+struct boot_e820_entry {
+	__u64 addr;
+	__u64 size;
+	__u32 type;
+} __attribute__((packed));
+
 /* The so-called "zeropage" */
 /* The so-called "zeropage" */
 struct boot_params {
 struct boot_params {
 	struct screen_info screen_info;			/* 0x000 */
 	struct screen_info screen_info;			/* 0x000 */
@@ -153,7 +167,7 @@ struct boot_params {
 	struct setup_header hdr;    /* setup header */	/* 0x1f1 */
 	struct setup_header hdr;    /* setup header */	/* 0x1f1 */
 	__u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
 	__u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
 	__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];	/* 0x290 */
 	__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];	/* 0x290 */
-	struct e820entry e820_map[E820MAX];		/* 0x2d0 */
+	struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE]; /* 0x2d0 */
 	__u8  _pad8[48];				/* 0xcd0 */
 	__u8  _pad8[48];				/* 0xcd0 */
 	struct edd_info eddbuf[EDDMAXNR];		/* 0xd00 */
 	struct edd_info eddbuf[EDDMAXNR];		/* 0xd00 */
 	__u8  _pad9[276];				/* 0xeec */
 	__u8  _pad9[276];				/* 0xeec */

+ 3 - 2
arch/x86/kernel/acpi/boot.c

@@ -37,6 +37,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/efi-bgrt.h>
 #include <linux/efi-bgrt.h>
 
 
+#include <asm/e820/api.h>
 #include <asm/irqdomain.h>
 #include <asm/irqdomain.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
@@ -1723,6 +1724,6 @@ int __acpi_release_global_lock(unsigned int *lock)
 
 
 void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 {
 {
-	e820_add_region(addr, size, E820_ACPI);
-	update_e820();
+	e820__range_add(addr, size, E820_TYPE_ACPI);
+	e820__update_table_print();
 }
 }

+ 5 - 5
arch/x86/kernel/aperture_64.c

@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/suspend.h>
 #include <linux/suspend.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/iommu.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
 #include <asm/gart.h>
@@ -306,13 +306,13 @@ void __init early_gart_iommu_check(void)
 		fix = 1;
 		fix = 1;
 
 
 	if (gart_fix_e820 && !fix && aper_enabled) {
 	if (gart_fix_e820 && !fix && aper_enabled) {
-		if (e820_any_mapped(aper_base, aper_base + aper_size,
-				    E820_RAM)) {
+		if (e820__mapped_any(aper_base, aper_base + aper_size,
+				    E820_TYPE_RAM)) {
 			/* reserve it, so we can reuse it in second kernel */
 			/* reserve it, so we can reuse it in second kernel */
 			pr_info("e820: reserve [mem %#010Lx-%#010Lx] for GART\n",
 			pr_info("e820: reserve [mem %#010Lx-%#010Lx] for GART\n",
 				aper_base, aper_base + aper_size - 1);
 				aper_base, aper_base + aper_size - 1);
-			e820_add_region(aper_base, aper_size, E820_RESERVED);
-			update_e820();
+			e820__range_add(aper_base, aper_size, E820_TYPE_RESERVED);
+			e820__update_table_print();
 		}
 		}
 	}
 	}
 
 

+ 1 - 1
arch/x86/kernel/apic/apic.c

@@ -2631,7 +2631,7 @@ static int __init lapic_insert_resource(void)
 }
 }
 
 
 /*
 /*
- * need call insert after e820_reserve_resources()
+ * need call insert after e820__reserve_resources()
  * that is using request_resource
  * that is using request_resource
  */
  */
 late_initcall(lapic_insert_resource);
 late_initcall(lapic_insert_resource);

+ 1 - 1
arch/x86/kernel/apic/apic_noop.c

@@ -26,7 +26,7 @@
 
 
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <asm/acpi.h>
 #include <asm/acpi.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 
 static void noop_init_apic_ldr(void) { }
 static void noop_init_apic_ldr(void) { }
 static void noop_send_IPI(int cpu, int vector) { }
 static void noop_send_IPI(int cpu, int vector) { }

+ 1 - 1
arch/x86/kernel/apic/probe_32.c

@@ -25,7 +25,7 @@
 
 
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <asm/acpi.h>
 #include <asm/acpi.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_HOTPLUG_CPU
 #define DEFAULT_SEND_IPI	(1)
 #define DEFAULT_SEND_IPI	(1)

+ 1 - 0
arch/x86/kernel/apic/x2apic_uv_x.c

@@ -34,6 +34,7 @@
 #include <asm/uv/bios.h>
 #include <asm/uv/bios.h>
 #include <asm/uv/uv.h>
 #include <asm/uv/uv.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
+#include <asm/e820/api.h>
 #include <asm/ipi.h>
 #include <asm/ipi.h>
 #include <asm/smp.h>
 #include <asm/smp.h>
 #include <asm/x86_init.h>
 #include <asm/x86_init.h>

+ 1 - 1
arch/x86/kernel/cpu/centaur.c

@@ -3,7 +3,7 @@
 #include <linux/sched/clock.h>
 #include <linux/sched/clock.h>
 
 
 #include <asm/cpufeature.h>
 #include <asm/cpufeature.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 #include <asm/msr.h>
 
 

+ 3 - 3
arch/x86/kernel/cpu/mtrr/cleanup.c

@@ -27,7 +27,7 @@
 #include <linux/range.h>
 #include <linux/range.h>
 
 
 #include <asm/processor.h>
 #include <asm/processor.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 #include <asm/msr.h>
 
 
@@ -860,7 +860,7 @@ real_trim_memory(unsigned long start_pfn, unsigned long limit_pfn)
 	trim_size <<= PAGE_SHIFT;
 	trim_size <<= PAGE_SHIFT;
 	trim_size -= trim_start;
 	trim_size -= trim_start;
 
 
-	return e820_update_range(trim_start, trim_size, E820_RAM, E820_RESERVED);
+	return e820__range_update(trim_start, trim_size, E820_TYPE_RAM, E820_TYPE_RESERVED);
 }
 }
 
 
 /**
 /**
@@ -978,7 +978,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 			WARN_ON(1);
 			WARN_ON(1);
 
 
 		pr_info("update e820 for mtrr\n");
 		pr_info("update e820 for mtrr\n");
-		update_e820();
+		e820__update_table_print();
 
 
 		return 1;
 		return 1;
 	}
 	}

+ 1 - 1
arch/x86/kernel/cpu/mtrr/main.c

@@ -48,7 +48,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/syscore_ops.h>
 
 
 #include <asm/cpufeature.h>
 #include <asm/cpufeature.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 #include <asm/msr.h>
 #include <asm/pat.h>
 #include <asm/pat.h>

+ 12 - 11
arch/x86/kernel/crash.c

@@ -29,6 +29,7 @@
 #include <asm/nmi.h>
 #include <asm/nmi.h>
 #include <asm/hw_irq.h>
 #include <asm/hw_irq.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
+#include <asm/e820/types.h>
 #include <asm/io_apic.h>
 #include <asm/io_apic.h>
 #include <asm/hpet.h>
 #include <asm/hpet.h>
 #include <linux/kdebug.h>
 #include <linux/kdebug.h>
@@ -503,16 +504,16 @@ static int prepare_elf_headers(struct kimage *image, void **addr,
 	return ret;
 	return ret;
 }
 }
 
 
-static int add_e820_entry(struct boot_params *params, struct e820entry *entry)
+static int add_e820_entry(struct boot_params *params, struct e820_entry *entry)
 {
 {
 	unsigned int nr_e820_entries;
 	unsigned int nr_e820_entries;
 
 
 	nr_e820_entries = params->e820_entries;
 	nr_e820_entries = params->e820_entries;
-	if (nr_e820_entries >= E820MAX)
+	if (nr_e820_entries >= E820_MAX_ENTRIES_ZEROPAGE)
 		return 1;
 		return 1;
 
 
-	memcpy(&params->e820_map[nr_e820_entries], entry,
-			sizeof(struct e820entry));
+	memcpy(&params->e820_table[nr_e820_entries], entry,
+			sizeof(struct e820_entry));
 	params->e820_entries++;
 	params->e820_entries++;
 	return 0;
 	return 0;
 }
 }
@@ -521,7 +522,7 @@ static int memmap_entry_callback(u64 start, u64 end, void *arg)
 {
 {
 	struct crash_memmap_data *cmd = arg;
 	struct crash_memmap_data *cmd = arg;
 	struct boot_params *params = cmd->params;
 	struct boot_params *params = cmd->params;
-	struct e820entry ei;
+	struct e820_entry ei;
 
 
 	ei.addr = start;
 	ei.addr = start;
 	ei.size = end - start + 1;
 	ei.size = end - start + 1;
@@ -560,7 +561,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
 {
 {
 	int i, ret = 0;
 	int i, ret = 0;
 	unsigned long flags;
 	unsigned long flags;
-	struct e820entry ei;
+	struct e820_entry ei;
 	struct crash_memmap_data cmd;
 	struct crash_memmap_data cmd;
 	struct crash_mem *cmem;
 	struct crash_mem *cmem;
 
 
@@ -574,17 +575,17 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
 	/* Add first 640K segment */
 	/* Add first 640K segment */
 	ei.addr = image->arch.backup_src_start;
 	ei.addr = image->arch.backup_src_start;
 	ei.size = image->arch.backup_src_sz;
 	ei.size = image->arch.backup_src_sz;
-	ei.type = E820_RAM;
+	ei.type = E820_TYPE_RAM;
 	add_e820_entry(params, &ei);
 	add_e820_entry(params, &ei);
 
 
 	/* Add ACPI tables */
 	/* Add ACPI tables */
-	cmd.type = E820_ACPI;
+	cmd.type = E820_TYPE_ACPI;
 	flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 	flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 	walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, &cmd,
 	walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, &cmd,
 		       memmap_entry_callback);
 		       memmap_entry_callback);
 
 
 	/* Add ACPI Non-volatile Storage */
 	/* Add ACPI Non-volatile Storage */
-	cmd.type = E820_NVS;
+	cmd.type = E820_TYPE_NVS;
 	walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1, &cmd,
 	walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1, &cmd,
 			memmap_entry_callback);
 			memmap_entry_callback);
 
 
@@ -592,7 +593,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
 	if (crashk_low_res.end) {
 	if (crashk_low_res.end) {
 		ei.addr = crashk_low_res.start;
 		ei.addr = crashk_low_res.start;
 		ei.size = crashk_low_res.end - crashk_low_res.start + 1;
 		ei.size = crashk_low_res.end - crashk_low_res.start + 1;
-		ei.type = E820_RAM;
+		ei.type = E820_TYPE_RAM;
 		add_e820_entry(params, &ei);
 		add_e820_entry(params, &ei);
 	}
 	}
 
 
@@ -609,7 +610,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
 		if (ei.size < PAGE_SIZE)
 		if (ei.size < PAGE_SIZE)
 			continue;
 			continue;
 		ei.addr = cmem->ranges[i].start;
 		ei.addr = cmem->ranges[i].start;
-		ei.type = E820_RAM;
+		ei.type = E820_TYPE_RAM;
 		add_e820_entry(params, &ei);
 		add_e820_entry(params, &ei);
 	}
 	}
 
 

+ 529 - 525
arch/x86/kernel/e820.c

@@ -1,49 +1,55 @@
 /*
 /*
- * Handle the memory map.
- * The functions here do the job until bootmem takes over.
+ * Low level x86 E820 memory map handling functions.
  *
  *
- *  Getting sanitize_e820_map() in sync with i386 version by applying change:
- *  -  Provisions for empty E820 memory regions (reported by certain BIOSes).
- *     Alex Achenbach <xela@slit.de>, December 2002.
- *  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * The firmware and bootloader passes us the "E820 table", which is the primary
+ * physical memory layout description available about x86 systems.
  *
  *
+ * The kernel takes the E820 memory layout and optionally modifies it with
+ * quirks and other tweaks, and feeds that into the generic Linux memory
+ * allocation code routines via a platform independent interface (memblock, etc.).
  */
  */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
 #include <linux/crash_dump.h>
 #include <linux/crash_dump.h>
-#include <linux/export.h>
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
-#include <linux/pfn.h>
 #include <linux/suspend.h>
 #include <linux/suspend.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
 #include <linux/firmware-map.h>
 #include <linux/firmware-map.h>
 #include <linux/memblock.h>
 #include <linux/memblock.h>
 #include <linux/sort.h>
 #include <linux/sort.h>
 
 
-#include <asm/e820.h>
-#include <asm/proto.h>
+#include <asm/e820/api.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
-#include <asm/cpufeature.h>
 
 
 /*
 /*
- * The e820 map is the map that gets modified e.g. with command line parameters
- * and that is also registered with modifications in the kernel resource tree
- * with the iomem_resource as parent.
+ * We organize the E820 table into two main data structures:
  *
  *
- * The e820_saved is directly saved after the BIOS-provided memory map is
- * copied. It doesn't get modified afterwards. It's registered for the
- * /sys/firmware/memmap interface.
+ * - 'e820_table_firmware': the original firmware version passed to us by the
+ *   bootloader - not modified by the kernel. We use this to:
  *
  *
- * That memory map is not modified and is used as base for kexec. The kexec'd
- * kernel should get the same memory map as the firmware provides. Then the
- * user can e.g. boot the original kernel with mem=1G while still booting the
- * next kernel with full memory.
+ *       - inform the user about the firmware's notion of memory layout
+ *         via /sys/firmware/memmap
+ *
+ *       - the hibernation code uses it to generate a kernel-independent MD5
+ *         fingerprint of the physical memory layout of a system.
+ *
+ *       - kexec, which is a bootloader in disguise, uses the original E820
+ *         layout to pass to the kexec-ed kernel. This way the original kernel
+ *         can have a restricted E820 map while the kexec()-ed kexec-kernel
+ *         can have access to full memory - etc.
+ *
+ * - 'e820_table': this is the main E820 table that is massaged by the
+ *   low level x86 platform code, or modified by boot parameters, before
+ *   passed on to higher level MM layers.
+ *
+ * Once the E820 map has been converted to the standard Linux memory layout
+ * information its role stops - modifying it has no effect and does not get
+ * re-propagated. So itsmain role is a temporary bootstrap storage of firmware
+ * specific memory layout data during early bootup.
  */
  */
-static struct e820map initial_e820  __initdata;
-static struct e820map initial_e820_saved  __initdata;
-struct e820map *e820 __refdata = &initial_e820;
-struct e820map *e820_saved __refdata = &initial_e820_saved;
+static struct e820_table e820_table_init		__initdata;
+static struct e820_table e820_table_firmware_init	__initdata;
+
+struct e820_table *e820_table __refdata			= &e820_table_init;
+struct e820_table *e820_table_firmware __refdata	= &e820_table_firmware_init;
 
 
 /* For PCI or other memory-mapped resources */
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0xaeedbabe;
 unsigned long pci_mem_start = 0xaeedbabe;
@@ -55,51 +61,53 @@ EXPORT_SYMBOL(pci_mem_start);
  * This function checks if any part of the range <start,end> is mapped
  * This function checks if any part of the range <start,end> is mapped
  * with type.
  * with type.
  */
  */
-int
-e820_any_mapped(u64 start, u64 end, unsigned type)
+bool e820__mapped_any(u64 start, u64 end, enum e820_type type)
 {
 {
 	int i;
 	int i;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 
 
-		if (type && ei->type != type)
+		if (type && entry->type != type)
 			continue;
 			continue;
-		if (ei->addr >= end || ei->addr + ei->size <= start)
+		if (entry->addr >= end || entry->addr + entry->size <= start)
 			continue;
 			continue;
 		return 1;
 		return 1;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL_GPL(e820_any_mapped);
+EXPORT_SYMBOL_GPL(e820__mapped_any);
 
 
 /*
 /*
- * This function checks if the entire range <start,end> is mapped with type.
+ * This function checks if the entire <start,end> range is mapped with 'type'.
  *
  *
- * Note: this function only works correct if the e820 table is sorted and
- * not-overlapping, which is the case
+ * Note: this function only works correctly once the E820 table is sorted and
+ * not-overlapping (at least for the range specified), which is the case normally.
  */
  */
-int __init e820_all_mapped(u64 start, u64 end, unsigned type)
+bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type)
 {
 {
 	int i;
 	int i;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 
 
-		if (type && ei->type != type)
+		if (type && entry->type != type)
 			continue;
 			continue;
-		/* is the region (part) in overlap with the current region ?*/
-		if (ei->addr >= end || ei->addr + ei->size <= start)
+
+		/* Is the region (part) in overlap with the current region? */
+		if (entry->addr >= end || entry->addr + entry->size <= start)
 			continue;
 			continue;
 
 
-		/* if the region is at the beginning of <start,end> we move
-		 * start to the end of the region since it's ok until there
+		/*
+		 * If the region is at the beginning of <start,end> we move
+		 * 'start' to the end of the region since it's ok until there
 		 */
 		 */
-		if (ei->addr <= start)
-			start = ei->addr + ei->size;
+		if (entry->addr <= start)
+			start = entry->addr + entry->size;
+
 		/*
 		/*
-		 * if start is now at or beyond end, we're done, full
-		 * coverage
+		 * If 'start' is now at or beyond 'end', we're done, full
+		 * coverage of the desired range exists:
 		 */
 		 */
 		if (start >= end)
 		if (start >= end)
 			return 1;
 			return 1;
@@ -108,94 +116,77 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type)
 }
 }
 
 
 /*
 /*
- * Add a memory region to the kernel e820 map.
+ * Add a memory region to the kernel E820 map.
  */
  */
-static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
-					 int type)
+static void __init __e820__range_add(struct e820_table *table, u64 start, u64 size, enum e820_type type)
 {
 {
-	int x = e820x->nr_map;
+	int x = table->nr_entries;
 
 
-	if (x >= ARRAY_SIZE(e820x->map)) {
-		printk(KERN_ERR "e820: too many entries; ignoring [mem %#010llx-%#010llx]\n",
-		       (unsigned long long) start,
-		       (unsigned long long) (start + size - 1));
+	if (x >= ARRAY_SIZE(table->entries)) {
+		pr_err("e820: too many entries; ignoring [mem %#010llx-%#010llx]\n", start, start + size - 1);
 		return;
 		return;
 	}
 	}
 
 
-	e820x->map[x].addr = start;
-	e820x->map[x].size = size;
-	e820x->map[x].type = type;
-	e820x->nr_map++;
+	table->entries[x].addr = start;
+	table->entries[x].size = size;
+	table->entries[x].type = type;
+	table->nr_entries++;
 }
 }
 
 
-void __init e820_add_region(u64 start, u64 size, int type)
+void __init e820__range_add(u64 start, u64 size, enum e820_type type)
 {
 {
-	__e820_add_region(e820, start, size, type);
+	__e820__range_add(e820_table, start, size, type);
 }
 }
 
 
-static void __init e820_print_type(u32 type)
+static void __init e820_print_type(enum e820_type type)
 {
 {
 	switch (type) {
 	switch (type) {
-	case E820_RAM:
-	case E820_RESERVED_KERN:
-		printk(KERN_CONT "usable");
-		break;
-	case E820_RESERVED:
-		printk(KERN_CONT "reserved");
-		break;
-	case E820_ACPI:
-		printk(KERN_CONT "ACPI data");
-		break;
-	case E820_NVS:
-		printk(KERN_CONT "ACPI NVS");
-		break;
-	case E820_UNUSABLE:
-		printk(KERN_CONT "unusable");
-		break;
-	case E820_PMEM:
-	case E820_PRAM:
-		printk(KERN_CONT "persistent (type %u)", type);
-		break;
-	default:
-		printk(KERN_CONT "type %u", type);
-		break;
+	case E820_TYPE_RAM:		/* Fall through: */
+	case E820_TYPE_RESERVED_KERN:	pr_cont("usable");			break;
+	case E820_TYPE_RESERVED:	pr_cont("reserved");			break;
+	case E820_TYPE_ACPI:		pr_cont("ACPI data");			break;
+	case E820_TYPE_NVS:		pr_cont("ACPI NVS");			break;
+	case E820_TYPE_UNUSABLE:	pr_cont("unusable");			break;
+	case E820_TYPE_PMEM:		/* Fall through: */
+	case E820_TYPE_PRAM:		pr_cont("persistent (type %u)", type);	break;
+	default:			pr_cont("type %u", type);		break;
 	}
 	}
 }
 }
 
 
-void __init e820_print_map(char *who)
+void __init e820__print_table(char *who)
 {
 {
 	int i;
 	int i;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
-		       (unsigned long long) e820->map[i].addr,
-		       (unsigned long long)
-		       (e820->map[i].addr + e820->map[i].size - 1));
-		e820_print_type(e820->map[i].type);
-		printk(KERN_CONT "\n");
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		pr_info("%s: [mem %#018Lx-%#018Lx] ", who,
+		       e820_table->entries[i].addr,
+		       e820_table->entries[i].addr + e820_table->entries[i].size - 1);
+
+		e820_print_type(e820_table->entries[i].type);
+		pr_cont("\n");
 	}
 	}
 }
 }
 
 
 /*
 /*
- * Sanitize the BIOS e820 map.
+ * Sanitize an E820 map.
  *
  *
- * Some e820 responses include overlapping entries. The following
- * replaces the original e820 map with a new one, removing overlaps,
+ * Some E820 layouts include overlapping entries. The following
+ * replaces the original E820 map with a new one, removing overlaps,
  * and resolving conflicting memory types in favor of highest
  * and resolving conflicting memory types in favor of highest
  * numbered type.
  * numbered type.
  *
  *
- * The input parameter biosmap points to an array of 'struct
- * e820entry' which on entry has elements in the range [0, *pnr_map)
- * valid, and which has space for up to max_nr_map entries.
- * On return, the resulting sanitized e820 map entries will be in
- * overwritten in the same location, starting at biosmap.
+ * The input parameter 'entries' points to an array of 'struct
+ * e820_entry' which on entry has elements in the range [0, *nr_entries)
+ * valid, and which has space for up to max_nr_entries entries.
+ * On return, the resulting sanitized E820 map entries will be in
+ * overwritten in the same location, starting at 'entries'.
  *
  *
- * The integer pointed to by pnr_map must be valid on entry (the
- * current number of valid entries located at biosmap). If the
- * sanitizing succeeds the *pnr_map will be updated with the new
- * number of valid entries (something no more than max_nr_map).
+ * The integer pointed to by nr_entries must be valid on entry (the
+ * current number of valid entries located at 'entries'). If the
+ * sanitizing succeeds the *nr_entries will be updated with the new
+ * number of valid entries (something no more than max_nr_entries).
  *
  *
- * The return value from sanitize_e820_map() is zero if it
+ * The return value from e820__update_table() is zero if it
  * successfully 'sanitized' the map entries passed in, and is -1
  * successfully 'sanitized' the map entries passed in, and is -1
  * if it did nothing, which can happen if either of (1) it was
  * if it did nothing, which can happen if either of (1) it was
  * only passed one map entry, or (2) any of the input map entries
  * only passed one map entry, or (2) any of the input map entries
@@ -238,10 +229,17 @@ void __init e820_print_map(char *who)
  *	   ______________________4_
  *	   ______________________4_
  */
  */
 struct change_member {
 struct change_member {
-	struct e820entry *pbios; /* pointer to original bios entry */
-	unsigned long long addr; /* address for this change point */
+	/* Pointer to the original entry: */
+	struct e820_entry	*entry;
+	/* Address for this change point: */
+	unsigned long long	addr;
 };
 };
 
 
+static struct change_member	change_point_list[2*E820_MAX_ENTRIES]	__initdata;
+static struct change_member	*change_point[2*E820_MAX_ENTRIES]	__initdata;
+static struct e820_entry	*overlap_list[E820_MAX_ENTRIES]		__initdata;
+static struct e820_entry	new_entries[E820_MAX_ENTRIES]		__initdata;
+
 static int __init cpcompare(const void *a, const void *b)
 static int __init cpcompare(const void *a, const void *b)
 {
 {
 	struct change_member * const *app = a, * const *bpp = b;
 	struct change_member * const *app = a, * const *bpp = b;
@@ -249,164 +247,141 @@ static int __init cpcompare(const void *a, const void *b)
 
 
 	/*
 	/*
 	 * Inputs are pointers to two elements of change_point[].  If their
 	 * Inputs are pointers to two elements of change_point[].  If their
-	 * addresses are unequal, their difference dominates.  If the addresses
+	 * addresses are not equal, their difference dominates.  If the addresses
 	 * are equal, then consider one that represents the end of its region
 	 * are equal, then consider one that represents the end of its region
 	 * to be greater than one that does not.
 	 * to be greater than one that does not.
 	 */
 	 */
 	if (ap->addr != bp->addr)
 	if (ap->addr != bp->addr)
 		return ap->addr > bp->addr ? 1 : -1;
 		return ap->addr > bp->addr ? 1 : -1;
 
 
-	return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
+	return (ap->addr != ap->entry->addr) - (bp->addr != bp->entry->addr);
 }
 }
 
 
-int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
-			     u32 *pnr_map)
+int __init e820__update_table(struct e820_table *table)
 {
 {
-	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;
-	unsigned long current_type, last_type;
+	struct e820_entry *entries = table->entries;
+	u32 max_nr_entries = ARRAY_SIZE(table->entries);
+	enum e820_type current_type, last_type;
 	unsigned long long last_addr;
 	unsigned long long last_addr;
-	int chgidx;
-	int overlap_entries;
-	int new_bios_entry;
-	int old_nr, new_nr, chg_nr;
-	int i;
+	u32 new_nr_entries, overlap_entries;
+	u32 i, chg_idx, chg_nr;
 
 
-	/* if there's only one memory region, don't bother */
-	if (*pnr_map < 2)
+	/* If there's only one memory region, don't bother: */
+	if (table->nr_entries < 2)
 		return -1;
 		return -1;
 
 
-	old_nr = *pnr_map;
-	BUG_ON(old_nr > max_nr_map);
+	table->nr_entries = table->nr_entries;
+	BUG_ON(table->nr_entries > max_nr_entries);
 
 
-	/* bail out if we find any unreasonable addresses in bios map */
-	for (i = 0; i < old_nr; i++)
-		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
+	/* Bail out if we find any unreasonable addresses in the map: */
+	for (i = 0; i < table->nr_entries; i++) {
+		if (entries[i].addr + entries[i].size < entries[i].addr)
 			return -1;
 			return -1;
+	}
 
 
-	/* create pointers for initial change-point information (for sorting) */
-	for (i = 0; i < 2 * old_nr; i++)
+	/* Create pointers for initial change-point information (for sorting): */
+	for (i = 0; i < 2 * table->nr_entries; i++)
 		change_point[i] = &change_point_list[i];
 		change_point[i] = &change_point_list[i];
 
 
-	/* record all known change-points (starting and ending addresses),
-	   omitting those that are for empty memory regions */
-	chgidx = 0;
-	for (i = 0; i < old_nr; i++)	{
-		if (biosmap[i].size != 0) {
-			change_point[chgidx]->addr = biosmap[i].addr;
-			change_point[chgidx++]->pbios = &biosmap[i];
-			change_point[chgidx]->addr = biosmap[i].addr +
-				biosmap[i].size;
-			change_point[chgidx++]->pbios = &biosmap[i];
+	/*
+	 * Record all known change-points (starting and ending addresses),
+	 * omitting empty memory regions:
+	 */
+	chg_idx = 0;
+	for (i = 0; i < table->nr_entries; i++)	{
+		if (entries[i].size != 0) {
+			change_point[chg_idx]->addr	= entries[i].addr;
+			change_point[chg_idx++]->entry	= &entries[i];
+			change_point[chg_idx]->addr	= entries[i].addr + entries[i].size;
+			change_point[chg_idx++]->entry	= &entries[i];
 		}
 		}
 	}
 	}
-	chg_nr = chgidx;
-
-	/* sort change-point list by memory addresses (low -> high) */
-	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 */
-	new_bios_entry = 0;	 /* index for creating new bios map entries */
-	last_type = 0;		 /* start with undefined memory type */
-	last_addr = 0;		 /* start with 0 as last starting address */
-
-	/* loop through change-points, determining affect on the new bios map */
-	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
-		/* keep track of all overlapping bios entries */
-		if (change_point[chgidx]->addr ==
-		    change_point[chgidx]->pbios->addr) {
-			/*
-			 * add map entry to overlap list (> 1 entry
-			 * implies an overlap)
-			 */
-			overlap_list[overlap_entries++] =
-				change_point[chgidx]->pbios;
+	chg_nr = chg_idx;
+
+	/* Sort change-point list by memory addresses (low -> high): */
+	sort(change_point, chg_nr, sizeof(*change_point), cpcompare, NULL);
+
+	/* Create a new memory map, removing overlaps: */
+	overlap_entries = 0;	 /* Number of entries in the overlap table */
+	new_nr_entries = 0;	 /* Index for creating new map entries */
+	last_type = 0;		 /* Start with undefined memory type */
+	last_addr = 0;		 /* Start with 0 as last starting address */
+
+	/* Loop through change-points, determining effect on the new map: */
+	for (chg_idx = 0; chg_idx < chg_nr; chg_idx++) {
+		/* Keep track of all overlapping entries */
+		if (change_point[chg_idx]->addr == change_point[chg_idx]->entry->addr) {
+			/* Add map entry to overlap list (> 1 entry implies an overlap) */
+			overlap_list[overlap_entries++] = change_point[chg_idx]->entry;
 		} else {
 		} else {
-			/*
-			 * remove entry from list (order independent,
-			 * so swap with last)
-			 */
+			/* Remove entry from list (order independent, so swap with last): */
 			for (i = 0; i < overlap_entries; i++) {
 			for (i = 0; i < overlap_entries; i++) {
-				if (overlap_list[i] ==
-				    change_point[chgidx]->pbios)
-					overlap_list[i] =
-						overlap_list[overlap_entries-1];
+				if (overlap_list[i] == change_point[chg_idx]->entry)
+					overlap_list[i] = overlap_list[overlap_entries-1];
 			}
 			}
 			overlap_entries--;
 			overlap_entries--;
 		}
 		}
 		/*
 		/*
-		 * if there are overlapping entries, decide which
+		 * If there are overlapping entries, decide which
 		 * "type" to use (larger value takes precedence --
 		 * "type" to use (larger value takes precedence --
 		 * 1=usable, 2,3,4,4+=unusable)
 		 * 1=usable, 2,3,4,4+=unusable)
 		 */
 		 */
 		current_type = 0;
 		current_type = 0;
-		for (i = 0; i < overlap_entries; i++)
+		for (i = 0; i < overlap_entries; i++) {
 			if (overlap_list[i]->type > current_type)
 			if (overlap_list[i]->type > current_type)
 				current_type = overlap_list[i]->type;
 				current_type = overlap_list[i]->type;
-		/*
-		 * continue building up new bios map based on this
-		 * information
-		 */
-		if (current_type != last_type || current_type == E820_PRAM) {
+		}
+
+		/* Continue building up new map based on this information: */
+		if (current_type != last_type || current_type == E820_TYPE_PRAM) {
 			if (last_type != 0)	 {
 			if (last_type != 0)	 {
-				new_bios[new_bios_entry].size =
-					change_point[chgidx]->addr - last_addr;
-				/*
-				 * move forward only if the new size
-				 * was non-zero
-				 */
-				if (new_bios[new_bios_entry].size != 0)
-					/*
-					 * no more space left for new
-					 * bios entries ?
-					 */
-					if (++new_bios_entry >= max_nr_map)
+				new_entries[new_nr_entries].size = change_point[chg_idx]->addr - last_addr;
+				/* Move forward only if the new size was non-zero: */
+				if (new_entries[new_nr_entries].size != 0)
+					/* No more space left for new entries? */
+					if (++new_nr_entries >= max_nr_entries)
 						break;
 						break;
 			}
 			}
 			if (current_type != 0)	{
 			if (current_type != 0)	{
-				new_bios[new_bios_entry].addr =
-					change_point[chgidx]->addr;
-				new_bios[new_bios_entry].type = current_type;
-				last_addr = change_point[chgidx]->addr;
+				new_entries[new_nr_entries].addr = change_point[chg_idx]->addr;
+				new_entries[new_nr_entries].type = current_type;
+				last_addr = change_point[chg_idx]->addr;
 			}
 			}
 			last_type = current_type;
 			last_type = current_type;
 		}
 		}
 	}
 	}
-	/* retain count for new bios entries */
-	new_nr = new_bios_entry;
 
 
-	/* copy new bios mapping into original location */
-	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
-	*pnr_map = new_nr;
+	/* Copy the new entries into the original location: */
+	memcpy(entries, new_entries, new_nr_entries*sizeof(*entries));
+	table->nr_entries = new_nr_entries;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
+static int __init __append_e820_table(struct boot_e820_entry *entries, u32 nr_entries)
 {
 {
-	while (nr_map) {
-		u64 start = biosmap->addr;
-		u64 size = biosmap->size;
+	struct boot_e820_entry *entry = entries;
+
+	while (nr_entries) {
+		u64 start = entry->addr;
+		u64 size = entry->size;
 		u64 end = start + size - 1;
 		u64 end = start + size - 1;
-		u32 type = biosmap->type;
+		u32 type = entry->type;
 
 
-		/* Overflow in 64 bits? Ignore the memory map. */
+		/* Ignore the entry on 64-bit overflow: */
 		if (start > end && likely(size))
 		if (start > end && likely(size))
 			return -1;
 			return -1;
 
 
-		e820_add_region(start, size, type);
+		e820__range_add(start, size, type);
 
 
-		biosmap++;
-		nr_map--;
+		entry++;
+		nr_entries--;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
 /*
 /*
- * Copy the BIOS e820 map into a safe place.
+ * Copy the BIOS E820 map into a safe place.
  *
  *
  * Sanity-check it while we're at it..
  * Sanity-check it while we're at it..
  *
  *
@@ -414,18 +389,17 @@ static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
  * will have given us a memory map that we can use to properly
  * will have given us a memory map that we can use to properly
  * set up memory.  If we aren't, we'll fake a memory map.
  * set up memory.  If we aren't, we'll fake a memory map.
  */
  */
-static int __init append_e820_map(struct e820entry *biosmap, int nr_map)
+static int __init append_e820_table(struct boot_e820_entry *entries, u32 nr_entries)
 {
 {
 	/* Only one memory region (or negative)? Ignore it */
 	/* Only one memory region (or negative)? Ignore it */
-	if (nr_map < 2)
+	if (nr_entries < 2)
 		return -1;
 		return -1;
 
 
-	return __append_e820_map(biosmap, nr_map);
+	return __append_e820_table(entries, nr_entries);
 }
 }
 
 
-static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
-					u64 size, unsigned old_type,
-					unsigned new_type)
+static u64 __init
+__e820__range_update(struct e820_table *table, u64 start, u64 size, enum e820_type old_type, enum e820_type new_type)
 {
 {
 	u64 end;
 	u64 end;
 	unsigned int i;
 	unsigned int i;
@@ -437,77 +411,73 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
 		size = ULLONG_MAX - start;
 		size = ULLONG_MAX - start;
 
 
 	end = start + size;
 	end = start + size;
-	printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ",
-	       (unsigned long long) start, (unsigned long long) (end - 1));
+	printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", start, end - 1);
 	e820_print_type(old_type);
 	e820_print_type(old_type);
-	printk(KERN_CONT " ==> ");
+	pr_cont(" ==> ");
 	e820_print_type(new_type);
 	e820_print_type(new_type);
-	printk(KERN_CONT "\n");
+	pr_cont("\n");
 
 
-	for (i = 0; i < e820x->nr_map; i++) {
-		struct e820entry *ei = &e820x->map[i];
+	for (i = 0; i < table->nr_entries; i++) {
+		struct e820_entry *entry = &table->entries[i];
 		u64 final_start, final_end;
 		u64 final_start, final_end;
-		u64 ei_end;
+		u64 entry_end;
 
 
-		if (ei->type != old_type)
+		if (entry->type != old_type)
 			continue;
 			continue;
 
 
-		ei_end = ei->addr + ei->size;
-		/* totally covered by new range? */
-		if (ei->addr >= start && ei_end <= end) {
-			ei->type = new_type;
-			real_updated_size += ei->size;
+		entry_end = entry->addr + entry->size;
+
+		/* Completely covered by new range? */
+		if (entry->addr >= start && entry_end <= end) {
+			entry->type = new_type;
+			real_updated_size += entry->size;
 			continue;
 			continue;
 		}
 		}
 
 
-		/* new range is totally covered? */
-		if (ei->addr < start && ei_end > end) {
-			__e820_add_region(e820x, start, size, new_type);
-			__e820_add_region(e820x, end, ei_end - end, ei->type);
-			ei->size = start - ei->addr;
+		/* New range is completely covered? */
+		if (entry->addr < start && entry_end > end) {
+			__e820__range_add(table, start, size, new_type);
+			__e820__range_add(table, end, entry_end - end, entry->type);
+			entry->size = start - entry->addr;
 			real_updated_size += size;
 			real_updated_size += size;
 			continue;
 			continue;
 		}
 		}
 
 
-		/* partially covered */
-		final_start = max(start, ei->addr);
-		final_end = min(end, ei_end);
+		/* Partially covered: */
+		final_start = max(start, entry->addr);
+		final_end = min(end, entry_end);
 		if (final_start >= final_end)
 		if (final_start >= final_end)
 			continue;
 			continue;
 
 
-		__e820_add_region(e820x, final_start, final_end - final_start,
-				  new_type);
+		__e820__range_add(table, final_start, final_end - final_start, new_type);
 
 
 		real_updated_size += final_end - final_start;
 		real_updated_size += final_end - final_start;
 
 
 		/*
 		/*
-		 * left range could be head or tail, so need to update
-		 * size at first.
+		 * Left range could be head or tail, so need to update
+		 * its size first:
 		 */
 		 */
-		ei->size -= final_end - final_start;
-		if (ei->addr < final_start)
+		entry->size -= final_end - final_start;
+		if (entry->addr < final_start)
 			continue;
 			continue;
-		ei->addr = final_end;
+
+		entry->addr = final_end;
 	}
 	}
 	return real_updated_size;
 	return real_updated_size;
 }
 }
 
 
-u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
-			     unsigned new_type)
+u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type)
 {
 {
-	return __e820_update_range(e820, start, size, old_type, new_type);
+	return __e820__range_update(e820_table, start, size, old_type, new_type);
 }
 }
 
 
-static u64 __init e820_update_range_saved(u64 start, u64 size,
-					  unsigned old_type, unsigned new_type)
+static u64 __init e820__range_update_firmware(u64 start, u64 size, enum e820_type old_type, enum e820_type  new_type)
 {
 {
-	return __e820_update_range(e820_saved, start, size, old_type,
-				     new_type);
+	return __e820__range_update(e820_table_firmware, start, size, old_type, new_type);
 }
 }
 
 
-/* make e820 not cover the range */
-u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
-			     int checktype)
+/* Remove a range of memory from the E820 table: */
+u64 __init e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type)
 {
 {
 	int i;
 	int i;
 	u64 end;
 	u64 end;
@@ -517,85 +487,89 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
 		size = ULLONG_MAX - start;
 		size = ULLONG_MAX - start;
 
 
 	end = start + size;
 	end = start + size;
-	printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ",
-	       (unsigned long long) start, (unsigned long long) (end - 1));
-	if (checktype)
+	printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1);
+	if (check_type)
 		e820_print_type(old_type);
 		e820_print_type(old_type);
-	printk(KERN_CONT "\n");
+	pr_cont("\n");
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 		u64 final_start, final_end;
 		u64 final_start, final_end;
-		u64 ei_end;
+		u64 entry_end;
 
 
-		if (checktype && ei->type != old_type)
+		if (check_type && entry->type != old_type)
 			continue;
 			continue;
 
 
-		ei_end = ei->addr + ei->size;
-		/* totally covered? */
-		if (ei->addr >= start && ei_end <= end) {
-			real_removed_size += ei->size;
-			memset(ei, 0, sizeof(struct e820entry));
+		entry_end = entry->addr + entry->size;
+
+		/* Completely covered? */
+		if (entry->addr >= start && entry_end <= end) {
+			real_removed_size += entry->size;
+			memset(entry, 0, sizeof(*entry));
 			continue;
 			continue;
 		}
 		}
 
 
-		/* new range is totally covered? */
-		if (ei->addr < start && ei_end > end) {
-			e820_add_region(end, ei_end - end, ei->type);
-			ei->size = start - ei->addr;
+		/* Is the new range completely covered? */
+		if (entry->addr < start && entry_end > end) {
+			e820__range_add(end, entry_end - end, entry->type);
+			entry->size = start - entry->addr;
 			real_removed_size += size;
 			real_removed_size += size;
 			continue;
 			continue;
 		}
 		}
 
 
-		/* partially covered */
-		final_start = max(start, ei->addr);
-		final_end = min(end, ei_end);
+		/* Partially covered: */
+		final_start = max(start, entry->addr);
+		final_end = min(end, entry_end);
 		if (final_start >= final_end)
 		if (final_start >= final_end)
 			continue;
 			continue;
+
 		real_removed_size += final_end - final_start;
 		real_removed_size += final_end - final_start;
 
 
 		/*
 		/*
-		 * left range could be head or tail, so need to update
-		 * size at first.
+		 * Left range could be head or tail, so need to update
+		 * the size first:
 		 */
 		 */
-		ei->size -= final_end - final_start;
-		if (ei->addr < final_start)
+		entry->size -= final_end - final_start;
+		if (entry->addr < final_start)
 			continue;
 			continue;
-		ei->addr = final_end;
+
+		entry->addr = final_end;
 	}
 	}
 	return real_removed_size;
 	return real_removed_size;
 }
 }
 
 
-void __init update_e820(void)
+void __init e820__update_table_print(void)
 {
 {
-	if (sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map))
+	if (e820__update_table(e820_table))
 		return;
 		return;
-	printk(KERN_INFO "e820: modified physical RAM map:\n");
-	e820_print_map("modified");
+
+	pr_info("e820: modified physical RAM map:\n");
+	e820__print_table("modified");
 }
 }
-static void __init update_e820_saved(void)
+
+static void __init e820__update_table_firmware(void)
 {
 {
-	sanitize_e820_map(e820_saved->map, ARRAY_SIZE(e820_saved->map),
-				&e820_saved->nr_map);
+	e820__update_table(e820_table_firmware);
 }
 }
+
 #define MAX_GAP_END 0x100000000ull
 #define MAX_GAP_END 0x100000000ull
+
 /*
 /*
- * Search for a gap in the e820 memory space from 0 to MAX_GAP_END.
+ * Search for a gap in the E820 memory space from 0 to MAX_GAP_END (4GB).
  */
  */
-static int __init e820_search_gap(unsigned long *gapstart,
-		unsigned long *gapsize)
+static int __init e820_search_gap(unsigned long *gapstart, unsigned long *gapsize)
 {
 {
 	unsigned long long last = MAX_GAP_END;
 	unsigned long long last = MAX_GAP_END;
-	int i = e820->nr_map;
+	int i = e820_table->nr_entries;
 	int found = 0;
 	int found = 0;
 
 
 	while (--i >= 0) {
 	while (--i >= 0) {
-		unsigned long long start = e820->map[i].addr;
-		unsigned long long end = start + e820->map[i].size;
+		unsigned long long start = e820_table->entries[i].addr;
+		unsigned long long end = start + e820_table->entries[i].size;
 
 
 		/*
 		/*
 		 * Since "last" is at most 4GB, we know we'll
 		 * Since "last" is at most 4GB, we know we'll
-		 * fit in 32 bits if this condition is true
+		 * fit in 32 bits if this condition is true:
 		 */
 		 */
 		if (last > end) {
 		if (last > end) {
 			unsigned long gap = last - end;
 			unsigned long gap = last - end;
@@ -613,12 +587,14 @@ static int __init e820_search_gap(unsigned long *gapstart,
 }
 }
 
 
 /*
 /*
- * Search for the biggest gap in the low 32 bits of the e820
- * memory space.  We pass this space to PCI to assign MMIO resources
- * for hotplug or unconfigured devices in.
+ * Search for the biggest gap in the low 32 bits of the E820
+ * memory space. We pass this space to the PCI subsystem, so
+ * that it can assign MMIO resources for hotplug or
+ * unconfigured devices in.
+ *
  * Hopefully the BIOS let enough space left.
  * Hopefully the BIOS let enough space left.
  */
  */
-__init void e820_setup_gap(void)
+__init void e820__setup_pci_gap(void)
 {
 {
 	unsigned long gapstart, gapsize;
 	unsigned long gapstart, gapsize;
 	int found;
 	int found;
@@ -629,138 +605,143 @@ __init void e820_setup_gap(void)
 	if (!found) {
 	if (!found) {
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_X86_64
 		gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
 		gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
-		printk(KERN_ERR
-	"e820: cannot find a gap in the 32bit address range\n"
-	"e820: PCI devices with unassigned 32bit BARs may break!\n");
+		pr_err(
+			"e820: Cannot find an available gap in the 32-bit address range\n"
+			"e820: PCI devices with unassigned 32-bit BARs may not work!\n");
 #else
 #else
 		gapstart = 0x10000000;
 		gapstart = 0x10000000;
 #endif
 #endif
 	}
 	}
 
 
 	/*
 	/*
-	 * e820_reserve_resources_late protect stolen RAM already
+	 * e820__reserve_resources_late() protects stolen RAM already:
 	 */
 	 */
 	pci_mem_start = gapstart;
 	pci_mem_start = gapstart;
 
 
-	printk(KERN_INFO
-	       "e820: [mem %#010lx-%#010lx] available for PCI devices\n",
-	       gapstart, gapstart + gapsize - 1);
+	pr_info("e820: [mem %#010lx-%#010lx] available for PCI devices\n", gapstart, gapstart + gapsize - 1);
 }
 }
 
 
 /*
 /*
  * Called late during init, in free_initmem().
  * Called late during init, in free_initmem().
  *
  *
- * Initial e820 and e820_saved are largish __initdata arrays.
- * Copy them to (usually much smaller) dynamically allocated area.
- * This is done after all tweaks we ever do to them:
- * all functions which modify them are __init functions,
- * they won't exist after this point.
+ * Initial e820_table and e820_table_firmware are largish __initdata arrays.
+ *
+ * Copy them to a (usually much smaller) dynamically allocated area that is
+ * sized precisely after the number of e820 entries.
+ *
+ * This is done after we've performed all the fixes and tweaks to the tables.
+ * All functions which modify them are __init functions, which won't exist
+ * after free_initmem().
  */
  */
-__init void e820_reallocate_tables(void)
+__init void e820__reallocate_tables(void)
 {
 {
-	struct e820map *n;
+	struct e820_table *n;
 	int size;
 	int size;
 
 
-	size = offsetof(struct e820map, map) + sizeof(struct e820entry) * e820->nr_map;
+	size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table->nr_entries;
 	n = kmalloc(size, GFP_KERNEL);
 	n = kmalloc(size, GFP_KERNEL);
 	BUG_ON(!n);
 	BUG_ON(!n);
-	memcpy(n, e820, size);
-	e820 = n;
+	memcpy(n, e820_table, size);
+	e820_table = n;
 
 
-	size = offsetof(struct e820map, map) + sizeof(struct e820entry) * e820_saved->nr_map;
+	size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_firmware->nr_entries;
 	n = kmalloc(size, GFP_KERNEL);
 	n = kmalloc(size, GFP_KERNEL);
 	BUG_ON(!n);
 	BUG_ON(!n);
-	memcpy(n, e820_saved, size);
-	e820_saved = n;
+	memcpy(n, e820_table_firmware, size);
+	e820_table_firmware = n;
 }
 }
 
 
-/**
- * Because of the size limitation of struct boot_params, only first
- * 128 E820 memory entries are passed to kernel via
- * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
- * linked list of struct setup_data, which is parsed here.
+/*
+ * Because of the small fixed size of struct boot_params, only the first
+ * 128 E820 memory entries are passed to the kernel via boot_params.e820_table,
+ * the remaining (if any) entries are passed via the SETUP_E820_EXT node of
+ * struct setup_data, which is parsed here.
  */
  */
-void __init parse_e820_ext(u64 phys_addr, u32 data_len)
+void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len)
 {
 {
 	int entries;
 	int entries;
-	struct e820entry *extmap;
+	struct boot_e820_entry *extmap;
 	struct setup_data *sdata;
 	struct setup_data *sdata;
 
 
 	sdata = early_memremap(phys_addr, data_len);
 	sdata = early_memremap(phys_addr, data_len);
-	entries = sdata->len / sizeof(struct e820entry);
-	extmap = (struct e820entry *)(sdata->data);
-	__append_e820_map(extmap, entries);
-	sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
+	entries = sdata->len / sizeof(*extmap);
+	extmap = (struct boot_e820_entry *)(sdata->data);
+
+	__append_e820_table(extmap, entries);
+	e820__update_table(e820_table);
+
 	early_memunmap(sdata, data_len);
 	early_memunmap(sdata, data_len);
-	printk(KERN_INFO "e820: extended physical RAM map:\n");
-	e820_print_map("extended");
+	pr_info("e820: extended physical RAM map:\n");
+	e820__print_table("extended");
 }
 }
 
 
-#if defined(CONFIG_X86_64) || \
-	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
-/**
+/*
  * Find the ranges of physical addresses that do not correspond to
  * Find the ranges of physical addresses that do not correspond to
- * e820 RAM areas and mark the corresponding pages as nosave for
- * hibernation (32 bit) or software suspend and suspend to RAM (64 bit).
+ * E820 RAM areas and register the corresponding pages as 'nosave' for
+ * hibernation (32-bit) or software suspend and suspend to RAM (64-bit).
  *
  *
- * This function requires the e820 map to be sorted and without any
+ * This function requires the E820 map to be sorted and without any
  * overlapping entries.
  * overlapping entries.
  */
  */
-void __init e820_mark_nosave_regions(unsigned long limit_pfn)
+void __init e820__register_nosave_regions(unsigned long limit_pfn)
 {
 {
 	int i;
 	int i;
 	unsigned long pfn = 0;
 	unsigned long pfn = 0;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 
 
-		if (pfn < PFN_UP(ei->addr))
-			register_nosave_region(pfn, PFN_UP(ei->addr));
+		if (pfn < PFN_UP(entry->addr))
+			register_nosave_region(pfn, PFN_UP(entry->addr));
 
 
-		pfn = PFN_DOWN(ei->addr + ei->size);
+		pfn = PFN_DOWN(entry->addr + entry->size);
 
 
-		if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
-			register_nosave_region(PFN_UP(ei->addr), pfn);
+		if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
+			register_nosave_region(PFN_UP(entry->addr), pfn);
 
 
 		if (pfn >= limit_pfn)
 		if (pfn >= limit_pfn)
 			break;
 			break;
 	}
 	}
 }
 }
-#endif
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
-/**
- * Mark ACPI NVS memory region, so that we can save/restore it during
- * hibernation and the subsequent resume.
+/*
+ * Register ACPI NVS memory regions, so that we can save/restore them during
+ * hibernation and the subsequent resume:
  */
  */
-static int __init e820_mark_nvs_memory(void)
+static int __init e820__register_nvs_regions(void)
 {
 {
 	int i;
 	int i;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 
 
-		if (ei->type == E820_NVS)
-			acpi_nvs_register(ei->addr, ei->size);
+		if (entry->type == E820_TYPE_NVS)
+			acpi_nvs_register(entry->addr, entry->size);
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
-core_initcall(e820_mark_nvs_memory);
+core_initcall(e820__register_nvs_regions);
 #endif
 #endif
 
 
 /*
 /*
- * pre allocated 4k and reserved it in memblock and e820_saved
+ * Allocate the requested number of bytes with the requsted alignment
+ * and return (the physical address) to the caller. Also register this
+ * range in the 'firmware' E820 table as a reserved range.
+ *
+ * This allows kexec to fake a new mptable, as if it came from the real
+ * system.
  */
  */
-u64 __init early_reserve_e820(u64 size, u64 align)
+u64 __init e820__memblock_alloc_reserved(u64 size, u64 align)
 {
 {
 	u64 addr;
 	u64 addr;
 
 
 	addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
 	addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
 	if (addr) {
 	if (addr) {
-		e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED);
-		printk(KERN_INFO "e820: update e820_saved for early_reserve_e820\n");
-		update_e820_saved();
+		e820__range_update_firmware(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED);
+		pr_info("e820: update e820_table_firmware for e820__memblock_alloc_reserved()\n");
+		e820__update_table_firmware();
 	}
 	}
 
 
 	return addr;
 	return addr;
@@ -779,22 +760,22 @@ u64 __init early_reserve_e820(u64 size, u64 align)
 /*
 /*
  * Find the highest page frame number we have available
  * Find the highest page frame number we have available
  */
  */
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+static unsigned long __init e820_end_pfn(unsigned long limit_pfn, enum e820_type type)
 {
 {
 	int i;
 	int i;
 	unsigned long last_pfn = 0;
 	unsigned long last_pfn = 0;
 	unsigned long max_arch_pfn = MAX_ARCH_PFN;
 	unsigned long max_arch_pfn = MAX_ARCH_PFN;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 		unsigned long start_pfn;
 		unsigned long start_pfn;
 		unsigned long end_pfn;
 		unsigned long end_pfn;
 
 
-		if (ei->type != type)
+		if (entry->type != type)
 			continue;
 			continue;
 
 
-		start_pfn = ei->addr >> PAGE_SHIFT;
-		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
+		start_pfn = entry->addr >> PAGE_SHIFT;
+		end_pfn = (entry->addr + entry->size) >> PAGE_SHIFT;
 
 
 		if (start_pfn >= limit_pfn)
 		if (start_pfn >= limit_pfn)
 			continue;
 			continue;
@@ -809,18 +790,19 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
 	if (last_pfn > max_arch_pfn)
 	if (last_pfn > max_arch_pfn)
 		last_pfn = max_arch_pfn;
 		last_pfn = max_arch_pfn;
 
 
-	printk(KERN_INFO "e820: last_pfn = %#lx max_arch_pfn = %#lx\n",
+	pr_info("e820: last_pfn = %#lx max_arch_pfn = %#lx\n",
 			 last_pfn, max_arch_pfn);
 			 last_pfn, max_arch_pfn);
 	return last_pfn;
 	return last_pfn;
 }
 }
-unsigned long __init e820_end_of_ram_pfn(void)
+
+unsigned long __init e820__end_of_ram_pfn(void)
 {
 {
-	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
+	return e820_end_pfn(MAX_ARCH_PFN, E820_TYPE_RAM);
 }
 }
 
 
-unsigned long __init e820_end_of_low_ram_pfn(void)
+unsigned long __init e820__end_of_low_ram_pfn(void)
 {
 {
-	return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_RAM);
+	return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_TYPE_RAM);
 }
 }
 
 
 static void __init early_panic(char *msg)
 static void __init early_panic(char *msg)
@@ -831,7 +813,7 @@ static void __init early_panic(char *msg)
 
 
 static int userdef __initdata;
 static int userdef __initdata;
 
 
-/* "mem=nopentium" disables the 4MB page tables. */
+/* The "mem=nopentium" boot option disables 4MB page tables on 32-bit kernels: */
 static int __init parse_memopt(char *p)
 static int __init parse_memopt(char *p)
 {
 {
 	u64 mem_size;
 	u64 mem_size;
@@ -844,17 +826,19 @@ static int __init parse_memopt(char *p)
 		setup_clear_cpu_cap(X86_FEATURE_PSE);
 		setup_clear_cpu_cap(X86_FEATURE_PSE);
 		return 0;
 		return 0;
 #else
 #else
-		printk(KERN_WARNING "mem=nopentium ignored! (only supported on x86_32)\n");
+		pr_warn("mem=nopentium ignored! (only supported on x86_32)\n");
 		return -EINVAL;
 		return -EINVAL;
 #endif
 #endif
 	}
 	}
 
 
 	userdef = 1;
 	userdef = 1;
 	mem_size = memparse(p, &p);
 	mem_size = memparse(p, &p);
-	/* don't remove all of memory when handling "mem={invalid}" param */
+
+	/* Don't remove all memory when getting "mem={invalid}" parameter: */
 	if (mem_size == 0)
 	if (mem_size == 0)
 		return -EINVAL;
 		return -EINVAL;
-	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+
+	e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -872,12 +856,12 @@ static int __init parse_memmap_one(char *p)
 #ifdef CONFIG_CRASH_DUMP
 #ifdef CONFIG_CRASH_DUMP
 		/*
 		/*
 		 * If we are doing a crash dump, we still need to know
 		 * If we are doing a crash dump, we still need to know
-		 * the real mem size before original memory map is
+		 * the real memory size before the original memory map is
 		 * reset.
 		 * reset.
 		 */
 		 */
-		saved_max_pfn = e820_end_of_ram_pfn();
+		saved_max_pfn = e820__end_of_ram_pfn();
 #endif
 #endif
-		e820->nr_map = 0;
+		e820_table->nr_entries = 0;
 		userdef = 1;
 		userdef = 1;
 		return 0;
 		return 0;
 	}
 	}
@@ -890,21 +874,23 @@ static int __init parse_memmap_one(char *p)
 	userdef = 1;
 	userdef = 1;
 	if (*p == '@') {
 	if (*p == '@') {
 		start_at = memparse(p+1, &p);
 		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_RAM);
+		e820__range_add(start_at, mem_size, E820_TYPE_RAM);
 	} else if (*p == '#') {
 	} else if (*p == '#') {
 		start_at = memparse(p+1, &p);
 		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_ACPI);
+		e820__range_add(start_at, mem_size, E820_TYPE_ACPI);
 	} else if (*p == '$') {
 	} else if (*p == '$') {
 		start_at = memparse(p+1, &p);
 		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_RESERVED);
+		e820__range_add(start_at, mem_size, E820_TYPE_RESERVED);
 	} else if (*p == '!') {
 	} else if (*p == '!') {
 		start_at = memparse(p+1, &p);
 		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_PRAM);
-	} else
-		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+		e820__range_add(start_at, mem_size, E820_TYPE_PRAM);
+	} else {
+		e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
+	}
 
 
 	return *p == '\0' ? 0 : -EINVAL;
 	return *p == '\0' ? 0 : -EINVAL;
 }
 }
+
 static int __init parse_memmap_opt(char *str)
 static int __init parse_memmap_opt(char *str)
 {
 {
 	while (str) {
 	while (str) {
@@ -921,68 +907,97 @@ static int __init parse_memmap_opt(char *str)
 }
 }
 early_param("memmap", parse_memmap_opt);
 early_param("memmap", parse_memmap_opt);
 
 
-void __init finish_e820_parsing(void)
+/*
+ * Reserve all entries from the bootloader's extensible data nodes list,
+ * because if present we are going to use it later on to fetch e820
+ * entries from it:
+ */
+void __init e820__reserve_setup_data(void)
+{
+	struct setup_data *data;
+	u64 pa_data;
+
+	pa_data = boot_params.hdr.setup_data;
+	if (!pa_data)
+		return;
+
+	while (pa_data) {
+		data = early_memremap(pa_data, sizeof(*data));
+		e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
+		pa_data = data->next;
+		early_memunmap(data, sizeof(*data));
+	}
+
+	e820__update_table(e820_table);
+
+	memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware));
+
+	pr_info("extended physical RAM map:\n");
+	e820__print_table("reserve setup_data");
+}
+
+/*
+ * Called after parse_early_param(), after early parameters (such as mem=)
+ * have been processed, in which case we already have an E820 table filled in
+ * via the parameter callback function(s), but it's not sorted and printed yet:
+ */
+void __init e820__finish_early_params(void)
 {
 {
 	if (userdef) {
 	if (userdef) {
-		if (sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map),
-					&e820->nr_map) < 0)
+		if (e820__update_table(e820_table) < 0)
 			early_panic("Invalid user supplied memory map");
 			early_panic("Invalid user supplied memory map");
 
 
-		printk(KERN_INFO "e820: user-defined physical RAM map:\n");
-		e820_print_map("user");
+		pr_info("e820: user-defined physical RAM map:\n");
+		e820__print_table("user");
 	}
 	}
 }
 }
 
 
-static const char *__init e820_type_to_string(int e820_type)
+static const char *__init e820_type_to_string(struct e820_entry *entry)
 {
 {
-	switch (e820_type) {
-	case E820_RESERVED_KERN:
-	case E820_RAM:	return "System RAM";
-	case E820_ACPI:	return "ACPI Tables";
-	case E820_NVS:	return "ACPI Non-volatile Storage";
-	case E820_UNUSABLE:	return "Unusable memory";
-	case E820_PRAM: return "Persistent Memory (legacy)";
-	case E820_PMEM: return "Persistent Memory";
-	default:	return "reserved";
+	switch (entry->type) {
+	case E820_TYPE_RESERVED_KERN:	/* Fall-through: */
+	case E820_TYPE_RAM:		return "System RAM";
+	case E820_TYPE_ACPI:		return "ACPI Tables";
+	case E820_TYPE_NVS:		return "ACPI Non-volatile Storage";
+	case E820_TYPE_UNUSABLE:	return "Unusable memory";
+	case E820_TYPE_PRAM:		return "Persistent Memory (legacy)";
+	case E820_TYPE_PMEM:		return "Persistent Memory";
+	case E820_TYPE_RESERVED:	return "Reserved";
+	default:			return "Unknown E820 type";
 	}
 	}
 }
 }
 
 
-static unsigned long __init e820_type_to_iomem_type(int e820_type)
+static unsigned long __init e820_type_to_iomem_type(struct e820_entry *entry)
 {
 {
-	switch (e820_type) {
-	case E820_RESERVED_KERN:
-	case E820_RAM:
-		return IORESOURCE_SYSTEM_RAM;
-	case E820_ACPI:
-	case E820_NVS:
-	case E820_UNUSABLE:
-	case E820_PRAM:
-	case E820_PMEM:
-	default:
-		return IORESOURCE_MEM;
+	switch (entry->type) {
+	case E820_TYPE_RESERVED_KERN:	/* Fall-through: */
+	case E820_TYPE_RAM:		return IORESOURCE_SYSTEM_RAM;
+	case E820_TYPE_ACPI:		/* Fall-through: */
+	case E820_TYPE_NVS:		/* Fall-through: */
+	case E820_TYPE_UNUSABLE:	/* Fall-through: */
+	case E820_TYPE_PRAM:		/* Fall-through: */
+	case E820_TYPE_PMEM:		/* Fall-through: */
+	case E820_TYPE_RESERVED:	/* Fall-through: */
+	default:			return IORESOURCE_MEM;
 	}
 	}
 }
 }
 
 
-static unsigned long __init e820_type_to_iores_desc(int e820_type)
+static unsigned long __init e820_type_to_iores_desc(struct e820_entry *entry)
 {
 {
-	switch (e820_type) {
-	case E820_ACPI:
-		return IORES_DESC_ACPI_TABLES;
-	case E820_NVS:
-		return IORES_DESC_ACPI_NV_STORAGE;
-	case E820_PMEM:
-		return IORES_DESC_PERSISTENT_MEMORY;
-	case E820_PRAM:
-		return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
-	case E820_RESERVED_KERN:
-	case E820_RAM:
-	case E820_UNUSABLE:
-	default:
-		return IORES_DESC_NONE;
+	switch (entry->type) {
+	case E820_TYPE_ACPI:		return IORES_DESC_ACPI_TABLES;
+	case E820_TYPE_NVS:		return IORES_DESC_ACPI_NV_STORAGE;
+	case E820_TYPE_PMEM:		return IORES_DESC_PERSISTENT_MEMORY;
+	case E820_TYPE_PRAM:		return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
+	case E820_TYPE_RESERVED_KERN:	/* Fall-through: */
+	case E820_TYPE_RAM:		/* Fall-through: */
+	case E820_TYPE_UNUSABLE:	/* Fall-through: */
+	case E820_TYPE_RESERVED:	/* Fall-through: */
+	default:			return IORES_DESC_NONE;
 	}
 	}
 }
 }
 
 
-static bool __init do_mark_busy(u32 type, struct resource *res)
+static bool __init do_mark_busy(enum e820_type type, struct resource *res)
 {
 {
 	/* this is the legacy bios/dos rom-shadow + mmio region */
 	/* this is the legacy bios/dos rom-shadow + mmio region */
 	if (res->start < (1ULL<<20))
 	if (res->start < (1ULL<<20))
@@ -993,61 +1008,71 @@ static bool __init do_mark_busy(u32 type, struct resource *res)
 	 * for exclusive use of a driver
 	 * for exclusive use of a driver
 	 */
 	 */
 	switch (type) {
 	switch (type) {
-	case E820_RESERVED:
-	case E820_PRAM:
-	case E820_PMEM:
+	case E820_TYPE_RESERVED:
+	case E820_TYPE_PRAM:
+	case E820_TYPE_PMEM:
 		return false;
 		return false;
+	case E820_TYPE_RESERVED_KERN:
+	case E820_TYPE_RAM:
+	case E820_TYPE_ACPI:
+	case E820_TYPE_NVS:
+	case E820_TYPE_UNUSABLE:
 	default:
 	default:
 		return true;
 		return true;
 	}
 	}
 }
 }
 
 
 /*
 /*
- * Mark e820 reserved areas as busy for the resource manager.
+ * Mark E820 reserved areas as busy for the resource manager:
  */
  */
+
 static struct resource __initdata *e820_res;
 static struct resource __initdata *e820_res;
-void __init e820_reserve_resources(void)
+
+void __init e820__reserve_resources(void)
 {
 {
 	int i;
 	int i;
 	struct resource *res;
 	struct resource *res;
 	u64 end;
 	u64 end;
 
 
-	res = alloc_bootmem(sizeof(struct resource) * e820->nr_map);
+	res = alloc_bootmem(sizeof(*res) * e820_table->nr_entries);
 	e820_res = res;
 	e820_res = res;
-	for (i = 0; i < e820->nr_map; i++) {
-		end = e820->map[i].addr + e820->map[i].size - 1;
+
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = e820_table->entries + i;
+
+		end = entry->addr + entry->size - 1;
 		if (end != (resource_size_t)end) {
 		if (end != (resource_size_t)end) {
 			res++;
 			res++;
 			continue;
 			continue;
 		}
 		}
-		res->name = e820_type_to_string(e820->map[i].type);
-		res->start = e820->map[i].addr;
-		res->end = end;
-
-		res->flags = e820_type_to_iomem_type(e820->map[i].type);
-		res->desc = e820_type_to_iores_desc(e820->map[i].type);
+		res->start = entry->addr;
+		res->end   = end;
+		res->name  = e820_type_to_string(entry);
+		res->flags = e820_type_to_iomem_type(entry);
+		res->desc  = e820_type_to_iores_desc(entry);
 
 
 		/*
 		/*
-		 * don't register the region that could be conflicted with
-		 * pci device BAR resource and insert them later in
-		 * pcibios_resource_survey()
+		 * Don't register the region that could be conflicted with
+		 * PCI device BAR resources and insert them later in
+		 * pcibios_resource_survey():
 		 */
 		 */
-		if (do_mark_busy(e820->map[i].type, res)) {
+		if (do_mark_busy(entry->type, res)) {
 			res->flags |= IORESOURCE_BUSY;
 			res->flags |= IORESOURCE_BUSY;
 			insert_resource(&iomem_resource, res);
 			insert_resource(&iomem_resource, res);
 		}
 		}
 		res++;
 		res++;
 	}
 	}
 
 
-	for (i = 0; i < e820_saved->nr_map; i++) {
-		struct e820entry *entry = &e820_saved->map[i];
-		firmware_map_add_early(entry->addr,
-			entry->addr + entry->size,
-			e820_type_to_string(entry->type));
+	for (i = 0; i < e820_table_firmware->nr_entries; i++) {
+		struct e820_entry *entry = e820_table_firmware->entries + i;
+
+		firmware_map_add_early(entry->addr, entry->addr + entry->size, e820_type_to_string(entry));
 	}
 	}
 }
 }
 
 
-/* How much should we pad RAM ending depending on where it is? */
+/*
+ * How much should we pad the end of RAM, depending on where it is?
+ */
 static unsigned long __init ram_alignment(resource_size_t pos)
 static unsigned long __init ram_alignment(resource_size_t pos)
 {
 {
 	unsigned long mb = pos >> 20;
 	unsigned long mb = pos >> 20;
@@ -1066,64 +1091,59 @@ static unsigned long __init ram_alignment(resource_size_t pos)
 
 
 #define MAX_RESOURCE_SIZE ((resource_size_t)-1)
 #define MAX_RESOURCE_SIZE ((resource_size_t)-1)
 
 
-void __init e820_reserve_resources_late(void)
+void __init e820__reserve_resources_late(void)
 {
 {
 	int i;
 	int i;
 	struct resource *res;
 	struct resource *res;
 
 
 	res = e820_res;
 	res = e820_res;
-	for (i = 0; i < e820->nr_map; i++) {
+	for (i = 0; i < e820_table->nr_entries; i++) {
 		if (!res->parent && res->end)
 		if (!res->parent && res->end)
 			insert_resource_expand_to_fit(&iomem_resource, res);
 			insert_resource_expand_to_fit(&iomem_resource, res);
 		res++;
 		res++;
 	}
 	}
 
 
 	/*
 	/*
-	 * Try to bump up RAM regions to reasonable boundaries to
+	 * Try to bump up RAM regions to reasonable boundaries, to
 	 * avoid stolen RAM:
 	 * avoid stolen RAM:
 	 */
 	 */
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *entry = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 		u64 start, end;
 		u64 start, end;
 
 
-		if (entry->type != E820_RAM)
+		if (entry->type != E820_TYPE_RAM)
 			continue;
 			continue;
+
 		start = entry->addr + entry->size;
 		start = entry->addr + entry->size;
 		end = round_up(start, ram_alignment(start)) - 1;
 		end = round_up(start, ram_alignment(start)) - 1;
 		if (end > MAX_RESOURCE_SIZE)
 		if (end > MAX_RESOURCE_SIZE)
 			end = MAX_RESOURCE_SIZE;
 			end = MAX_RESOURCE_SIZE;
 		if (start >= end)
 		if (start >= end)
 			continue;
 			continue;
-		printk(KERN_DEBUG
-		       "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n",
-		       start, end);
-		reserve_region_with_split(&iomem_resource, start, end,
-					  "RAM buffer");
+
+		printk(KERN_DEBUG "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n", start, end);
+		reserve_region_with_split(&iomem_resource, start, end, "RAM buffer");
 	}
 	}
 }
 }
 
 
-char *__init default_machine_specific_memory_setup(void)
+/*
+ * Pass the firmware (bootloader) E820 map to the kernel and process it:
+ */
+char *__init e820__memory_setup_default(void)
 {
 {
 	char *who = "BIOS-e820";
 	char *who = "BIOS-e820";
-	u32 new_nr;
+
 	/*
 	/*
 	 * Try to copy the BIOS-supplied E820-map.
 	 * Try to copy the BIOS-supplied E820-map.
 	 *
 	 *
 	 * Otherwise fake a memory map; one section from 0k->640k,
 	 * Otherwise fake a memory map; one section from 0k->640k,
 	 * the next section from 1mb->appropriate_mem_k
 	 * the next section from 1mb->appropriate_mem_k
 	 */
 	 */
-	new_nr = boot_params.e820_entries;
-	sanitize_e820_map(boot_params.e820_map,
-			ARRAY_SIZE(boot_params.e820_map),
-			&new_nr);
-	boot_params.e820_entries = new_nr;
-	if (append_e820_map(boot_params.e820_map, boot_params.e820_entries)
-	  < 0) {
+	if (append_e820_table(boot_params.e820_table, boot_params.e820_entries) < 0) {
 		u64 mem_size;
 		u64 mem_size;
 
 
-		/* compare results from other methods and take the greater */
-		if (boot_params.alt_mem_k
-		    < boot_params.screen_info.ext_mem_k) {
+		/* Compare results from other methods and take the one that gives more RAM: */
+		if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) {
 			mem_size = boot_params.screen_info.ext_mem_k;
 			mem_size = boot_params.screen_info.ext_mem_k;
 			who = "BIOS-88";
 			who = "BIOS-88";
 		} else {
 		} else {
@@ -1131,84 +1151,68 @@ char *__init default_machine_specific_memory_setup(void)
 			who = "BIOS-e801";
 			who = "BIOS-e801";
 		}
 		}
 
 
-		e820->nr_map = 0;
-		e820_add_region(0, LOWMEMSIZE(), E820_RAM);
-		e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
+		e820_table->nr_entries = 0;
+		e820__range_add(0, LOWMEMSIZE(), E820_TYPE_RAM);
+		e820__range_add(HIGH_MEMORY, mem_size << 10, E820_TYPE_RAM);
 	}
 	}
 
 
-	/* In case someone cares... */
+	/* We just appended a lot of ranges, sanitize the table: */
+	e820__update_table(e820_table);
+
 	return who;
 	return who;
 }
 }
 
 
-void __init setup_memory_map(void)
+/*
+ * Calls e820__memory_setup_default() in essence to pick up the firmware/bootloader
+ * E820 map - with an optional platform quirk available for virtual platforms
+ * to override this method of boot environment processing:
+ */
+void __init e820__memory_setup(void)
 {
 {
 	char *who;
 	char *who;
 
 
+	/* This is a firmware interface ABI - make sure we don't break it: */
+	BUILD_BUG_ON(sizeof(struct boot_e820_entry) != 20);
+
 	who = x86_init.resources.memory_setup();
 	who = x86_init.resources.memory_setup();
-	memcpy(e820_saved, e820, sizeof(struct e820map));
-	printk(KERN_INFO "e820: BIOS-provided physical RAM map:\n");
-	e820_print_map(who);
+
+	memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware));
+
+	pr_info("e820: BIOS-provided physical RAM map:\n");
+	e820__print_table(who);
 }
 }
 
 
-void __init memblock_x86_fill(void)
+void __init e820__memblock_setup(void)
 {
 {
 	int i;
 	int i;
 	u64 end;
 	u64 end;
 
 
 	/*
 	/*
-	 * EFI may have more than 128 entries
-	 * We are safe to enable resizing, beause memblock_x86_fill()
-	 * is rather later for x86
+	 * The bootstrap memblock region count maximum is 128 entries
+	 * (INIT_MEMBLOCK_REGIONS), but EFI might pass us more E820 entries
+	 * than that - so allow memblock resizing.
+	 *
+	 * This is safe, because this call happens pretty late during x86 setup,
+	 * so we know about reserved memory regions already. (This is important
+	 * so that memblock resizing does no stomp over reserved areas.)
 	 */
 	 */
 	memblock_allow_resize();
 	memblock_allow_resize();
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		struct e820entry *ei = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		struct e820_entry *entry = &e820_table->entries[i];
 
 
-		end = ei->addr + ei->size;
+		end = entry->addr + entry->size;
 		if (end != (resource_size_t)end)
 		if (end != (resource_size_t)end)
 			continue;
 			continue;
 
 
-		if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
+		if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
 			continue;
 			continue;
 
 
-		memblock_add(ei->addr, ei->size);
+		memblock_add(entry->addr, entry->size);
 	}
 	}
 
 
-	/* throw away partial pages */
+	/* Throw away partial pages: */
 	memblock_trim_memory(PAGE_SIZE);
 	memblock_trim_memory(PAGE_SIZE);
 
 
 	memblock_dump_all();
 	memblock_dump_all();
 }
 }
-
-void __init memblock_find_dma_reserve(void)
-{
-#ifdef CONFIG_X86_64
-	u64 nr_pages = 0, nr_free_pages = 0;
-	unsigned long start_pfn, end_pfn;
-	phys_addr_t start, end;
-	int i;
-	u64 u;
-
-	/*
-	 * need to find out used area below MAX_DMA_PFN
-	 * need to use memblock to get free size in [0, MAX_DMA_PFN]
-	 * at first, and assume boot_mem will not take below MAX_DMA_PFN
-	 */
-	for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) {
-		start_pfn = min(start_pfn, MAX_DMA_PFN);
-		end_pfn = min(end_pfn, MAX_DMA_PFN);
-		nr_pages += end_pfn - start_pfn;
-	}
-
-	for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
-				NULL) {
-		start_pfn = min_t(unsigned long, PFN_UP(start), MAX_DMA_PFN);
-		end_pfn = min_t(unsigned long, PFN_DOWN(end), MAX_DMA_PFN);
-		if (start_pfn < end_pfn)
-			nr_free_pages += end_pfn - start_pfn;
-	}
-
-	set_dma_reserve(nr_pages - nr_free_pages);
-#endif
-}

+ 2 - 2
arch/x86/kernel/early-quirks.c

@@ -546,8 +546,8 @@ intel_graphics_stolen(int num, int slot, int func,
 	       &base, &end);
 	       &base, &end);
 
 
 	/* Mark this space as reserved */
 	/* Mark this space as reserved */
-	e820_add_region(base, size, E820_RESERVED);
-	sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
+	e820__range_add(base, size, E820_TYPE_RESERVED);
+	e820__update_table(e820_table);
 }
 }
 
 
 static void __init intel_graphics_quirks(int num, int slot, int func)
 static void __init intel_graphics_quirks(int num, int slot, int func)

+ 1 - 1
arch/x86/kernel/head32.c

@@ -12,7 +12,7 @@
 
 
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/io_apic.h>

+ 1 - 1
arch/x86/kernel/head64.c

@@ -24,7 +24,7 @@
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
 #include <asm/kdebug.h>
 #include <asm/kdebug.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/bios_ebda.h>
 #include <asm/bios_ebda.h>
 #include <asm/bootparam_utils.h>
 #include <asm/bootparam_utils.h>
 #include <asm/microcode.h>
 #include <asm/microcode.h>

+ 4 - 6
arch/x86/kernel/head_64.S

@@ -269,10 +269,8 @@ ENTRY(secondary_startup_64)
 	/* rsi is pointer to real mode structure with interesting info.
 	/* rsi is pointer to real mode structure with interesting info.
 	   pass it to C */
 	   pass it to C */
 	movq	%rsi, %rdi
 	movq	%rsi, %rdi
-	jmp	start_cpu
-ENDPROC(secondary_startup_64)
 
 
-ENTRY(start_cpu)
+.Ljump_to_C_code:
 	/*
 	/*
 	 * Jump to run C code and to be on a real kernel address.
 	 * Jump to run C code and to be on a real kernel address.
 	 * Since we are running on identity-mapped space we have to jump
 	 * Since we are running on identity-mapped space we have to jump
@@ -305,7 +303,7 @@ ENTRY(start_cpu)
 	pushq	%rax		# target address in negative space
 	pushq	%rax		# target address in negative space
 	lretq
 	lretq
 .Lafter_lret:
 .Lafter_lret:
-ENDPROC(start_cpu)
+ENDPROC(secondary_startup_64)
 
 
 #include "verify_cpu.S"
 #include "verify_cpu.S"
 
 
@@ -313,11 +311,11 @@ ENDPROC(start_cpu)
 /*
 /*
  * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
  * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
  * up already except stack. We just set up stack here. Then call
  * up already except stack. We just set up stack here. Then call
- * start_secondary() via start_cpu().
+ * start_secondary() via .Ljump_to_C_code.
  */
  */
 ENTRY(start_cpu0)
 ENTRY(start_cpu0)
 	movq	initial_stack(%rip), %rsp
 	movq	initial_stack(%rip), %rsp
-	jmp	start_cpu
+	jmp	.Ljump_to_C_code
 ENDPROC(start_cpu0)
 ENDPROC(start_cpu0)
 #endif
 #endif
 
 

+ 9 - 9
arch/x86/kernel/kexec-bzimage64.c

@@ -25,6 +25,7 @@
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/crash.h>
 #include <asm/crash.h>
 #include <asm/efi.h>
 #include <asm/efi.h>
+#include <asm/e820/api.h>
 #include <asm/kexec-bzimage64.h>
 #include <asm/kexec-bzimage64.h>
 
 
 #define MAX_ELFCOREHDR_STR_LEN	30	/* elfcorehdr=0x<64bit-value> */
 #define MAX_ELFCOREHDR_STR_LEN	30	/* elfcorehdr=0x<64bit-value> */
@@ -99,15 +100,14 @@ static int setup_e820_entries(struct boot_params *params)
 {
 {
 	unsigned int nr_e820_entries;
 	unsigned int nr_e820_entries;
 
 
-	nr_e820_entries = e820_saved->nr_map;
+	nr_e820_entries = e820_table_firmware->nr_entries;
 
 
-	/* TODO: Pass entries more than E820MAX in bootparams setup data */
-	if (nr_e820_entries > E820MAX)
-		nr_e820_entries = E820MAX;
+	/* TODO: Pass entries more than E820_MAX_ENTRIES_ZEROPAGE in bootparams setup data */
+	if (nr_e820_entries > E820_MAX_ENTRIES_ZEROPAGE)
+		nr_e820_entries = E820_MAX_ENTRIES_ZEROPAGE;
 
 
 	params->e820_entries = nr_e820_entries;
 	params->e820_entries = nr_e820_entries;
-	memcpy(&params->e820_map, &e820_saved->map,
-	       nr_e820_entries * sizeof(struct e820entry));
+	memcpy(&params->e820_table, &e820_table_firmware->entries, nr_e820_entries*sizeof(struct e820_entry));
 
 
 	return 0;
 	return 0;
 }
 }
@@ -232,10 +232,10 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
 	nr_e820_entries = params->e820_entries;
 	nr_e820_entries = params->e820_entries;
 
 
 	for (i = 0; i < nr_e820_entries; i++) {
 	for (i = 0; i < nr_e820_entries; i++) {
-		if (params->e820_map[i].type != E820_RAM)
+		if (params->e820_table[i].type != E820_TYPE_RAM)
 			continue;
 			continue;
-		start = params->e820_map[i].addr;
-		end = params->e820_map[i].addr + params->e820_map[i].size - 1;
+		start = params->e820_table[i].addr;
+		end = params->e820_table[i].addr + params->e820_table[i].size - 1;
 
 
 		if ((start <= 0x100000) && end > 0x100000) {
 		if ((start <= 0x100000) && end > 0x100000) {
 			mem_k = (end >> 10) - (0x100000 >> 10);
 			mem_k = (end >> 10) - (0x100000 >> 10);

+ 3 - 3
arch/x86/kernel/mpparse.c

@@ -26,7 +26,7 @@
 #include <asm/io_apic.h>
 #include <asm/io_apic.h>
 #include <asm/proto.h>
 #include <asm/proto.h>
 #include <asm/bios_ebda.h>
 #include <asm/bios_ebda.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/smp.h>
 
 
@@ -826,10 +826,10 @@ static int __init parse_alloc_mptable_opt(char *p)
 }
 }
 early_param("alloc_mptable", parse_alloc_mptable_opt);
 early_param("alloc_mptable", parse_alloc_mptable_opt);
 
 
-void __init early_reserve_e820_mpc_new(void)
+void __init e820__memblock_alloc_reserved_mpc_new(void)
 {
 {
 	if (enable_update_mptable && alloc_mptable)
 	if (enable_update_mptable && alloc_mptable)
-		mpc_new_phys = early_reserve_e820(mpc_new_length, 4);
+		mpc_new_phys = e820__memblock_alloc_reserved(mpc_new_length, 4);
 }
 }
 
 
 static int __init update_mp_table(void)
 static int __init update_mp_table(void)

+ 1 - 1
arch/x86/kernel/probe_roms.c

@@ -14,7 +14,7 @@
 
 
 #include <asm/probe_roms.h>
 #include <asm/probe_roms.h>
 #include <asm/pci-direct.h>
 #include <asm/pci-direct.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mmzone.h>
 #include <asm/mmzone.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/sections.h>

+ 4 - 4
arch/x86/kernel/resource.c

@@ -1,5 +1,5 @@
 #include <linux/ioport.h>
 #include <linux/ioport.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 
 static void resource_clip(struct resource *res, resource_size_t start,
 static void resource_clip(struct resource *res, resource_size_t start,
 			  resource_size_t end)
 			  resource_size_t end)
@@ -25,10 +25,10 @@ static void resource_clip(struct resource *res, resource_size_t start,
 static void remove_e820_regions(struct resource *avail)
 static void remove_e820_regions(struct resource *avail)
 {
 {
 	int i;
 	int i;
-	struct e820entry *entry;
+	struct e820_entry *entry;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		entry = &e820->map[i];
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		entry = &e820_table->entries[i];
 
 
 		resource_clip(avail, entry->addr,
 		resource_clip(avail, entry->addr,
 			      entry->addr + entry->size - 1);
 			      entry->addr + entry->size - 1);

+ 27 - 51
arch/x86/kernel/setup.c

@@ -75,7 +75,7 @@
 #include <asm/mtrr.h>
 #include <asm/mtrr.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
 #include <asm/realmode.h>
 #include <asm/realmode.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mpspec.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/efi.h>
 #include <asm/efi.h>
@@ -119,7 +119,7 @@
  * max_low_pfn_mapped: highest direct mapped pfn under 4GB
  * max_low_pfn_mapped: highest direct mapped pfn under 4GB
  * max_pfn_mapped:     highest direct mapped pfn over 4GB
  * max_pfn_mapped:     highest direct mapped pfn over 4GB
  *
  *
- * The direct mapping only covers E820_RAM regions, so the ranges and gaps are
+ * The direct mapping only covers E820_TYPE_RAM regions, so the ranges and gaps are
  * represented by pfn_mapped
  * represented by pfn_mapped
  */
  */
 unsigned long max_low_pfn_mapped;
 unsigned long max_low_pfn_mapped;
@@ -426,7 +426,7 @@ static void __init parse_setup_data(void)
 
 
 		switch (data_type) {
 		switch (data_type) {
 		case SETUP_E820_EXT:
 		case SETUP_E820_EXT:
-			parse_e820_ext(pa_data, data_len);
+			e820__memory_setup_extended(pa_data, data_len);
 			break;
 			break;
 		case SETUP_DTB:
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			add_dtb(pa_data);
@@ -441,29 +441,6 @@ static void __init parse_setup_data(void)
 	}
 	}
 }
 }
 
 
-static void __init e820_reserve_setup_data(void)
-{
-	struct setup_data *data;
-	u64 pa_data;
-
-	pa_data = boot_params.hdr.setup_data;
-	if (!pa_data)
-		return;
-
-	while (pa_data) {
-		data = early_memremap(pa_data, sizeof(*data));
-		e820_update_range(pa_data, sizeof(*data)+data->len,
-			 E820_RAM, E820_RESERVED_KERN);
-		pa_data = data->next;
-		early_memunmap(data, sizeof(*data));
-	}
-
-	sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
-	memcpy(e820_saved, e820, sizeof(struct e820map));
-	printk(KERN_INFO "extended physical RAM map:\n");
-	e820_print_map("reserve setup_data");
-}
-
 static void __init memblock_x86_reserve_range_setup_data(void)
 static void __init memblock_x86_reserve_range_setup_data(void)
 {
 {
 	struct setup_data *data;
 	struct setup_data *data;
@@ -756,16 +733,16 @@ static void __init trim_bios_range(void)
 	 * since some BIOSes are known to corrupt low memory.  See the
 	 * since some BIOSes are known to corrupt low memory.  See the
 	 * Kconfig help text for X86_RESERVE_LOW.
 	 * Kconfig help text for X86_RESERVE_LOW.
 	 */
 	 */
-	e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED);
+	e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
 
 
 	/*
 	/*
 	 * special case: Some BIOSen report the PC BIOS
 	 * special case: Some BIOSen report the PC BIOS
 	 * area (640->1Mb) as ram even though it is not.
 	 * area (640->1Mb) as ram even though it is not.
 	 * take them out.
 	 * take them out.
 	 */
 	 */
-	e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
+	e820__range_remove(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_TYPE_RAM, 1);
 
 
-	sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
+	e820__update_table(e820_table);
 }
 }
 
 
 /* called before trim_bios_range() to spare extra sanitize */
 /* called before trim_bios_range() to spare extra sanitize */
@@ -775,18 +752,18 @@ static void __init e820_add_kernel_range(void)
 	u64 size = __pa_symbol(_end) - start;
 	u64 size = __pa_symbol(_end) - start;
 
 
 	/*
 	/*
-	 * Complain if .text .data and .bss are not marked as E820_RAM and
+	 * Complain if .text .data and .bss are not marked as E820_TYPE_RAM and
 	 * attempt to fix it by adding the range. We may have a confused BIOS,
 	 * attempt to fix it by adding the range. We may have a confused BIOS,
 	 * or the user may have used memmap=exactmap or memmap=xxM$yyM to
 	 * or the user may have used memmap=exactmap or memmap=xxM$yyM to
 	 * exclude kernel range. If we really are running on top non-RAM,
 	 * exclude kernel range. If we really are running on top non-RAM,
 	 * we will crash later anyways.
 	 * we will crash later anyways.
 	 */
 	 */
-	if (e820_all_mapped(start, start + size, E820_RAM))
+	if (e820__mapped_all(start, start + size, E820_TYPE_RAM))
 		return;
 		return;
 
 
-	pr_warn(".text .data .bss are not marked as E820_RAM!\n");
-	e820_remove_range(start, size, E820_RAM, 0);
-	e820_add_region(start, size, E820_RAM);
+	pr_warn(".text .data .bss are not marked as E820_TYPE_RAM!\n");
+	e820__range_remove(start, size, E820_TYPE_RAM, 0);
+	e820__range_add(start, size, E820_TYPE_RAM);
 }
 }
 
 
 static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
 static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
@@ -939,7 +916,7 @@ void __init setup_arch(char **cmdline_p)
 	x86_init.oem.arch_setup();
 	x86_init.oem.arch_setup();
 
 
 	iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
 	iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
-	setup_memory_map();
+	e820__memory_setup();
 	parse_setup_data();
 	parse_setup_data();
 
 
 	copy_edd();
 	copy_edd();
@@ -1028,9 +1005,8 @@ void __init setup_arch(char **cmdline_p)
 		early_dump_pci_devices();
 		early_dump_pci_devices();
 #endif
 #endif
 
 
-	/* update the e820_saved too */
-	e820_reserve_setup_data();
-	finish_e820_parsing();
+	e820__reserve_setup_data();
+	e820__finish_early_params();
 
 
 	if (efi_enabled(EFI_BOOT))
 	if (efi_enabled(EFI_BOOT))
 		efi_init();
 		efi_init();
@@ -1056,11 +1032,11 @@ void __init setup_arch(char **cmdline_p)
 	trim_bios_range();
 	trim_bios_range();
 #ifdef CONFIG_X86_32
 #ifdef CONFIG_X86_32
 	if (ppro_with_ram_bug()) {
 	if (ppro_with_ram_bug()) {
-		e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
-				  E820_RESERVED);
-		sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
+		e820__range_update(0x70000000ULL, 0x40000ULL, E820_TYPE_RAM,
+				  E820_TYPE_RESERVED);
+		e820__update_table(e820_table);
 		printk(KERN_INFO "fixed physical RAM map:\n");
 		printk(KERN_INFO "fixed physical RAM map:\n");
-		e820_print_map("bad_ppro");
+		e820__print_table("bad_ppro");
 	}
 	}
 #else
 #else
 	early_gart_iommu_check();
 	early_gart_iommu_check();
@@ -1070,12 +1046,12 @@ void __init setup_arch(char **cmdline_p)
 	 * partially used pages are not usable - thus
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
 	 * we are rounding upwards:
 	 */
 	 */
-	max_pfn = e820_end_of_ram_pfn();
+	max_pfn = e820__end_of_ram_pfn();
 
 
 	/* update e820 for memory not covered by WB MTRRs */
 	/* update e820 for memory not covered by WB MTRRs */
 	mtrr_bp_init();
 	mtrr_bp_init();
 	if (mtrr_trim_uncached_memory(max_pfn))
 	if (mtrr_trim_uncached_memory(max_pfn))
-		max_pfn = e820_end_of_ram_pfn();
+		max_pfn = e820__end_of_ram_pfn();
 
 
 	max_possible_pfn = max_pfn;
 	max_possible_pfn = max_pfn;
 
 
@@ -1094,7 +1070,7 @@ void __init setup_arch(char **cmdline_p)
 	/* How many end-of-memory variables you have, grandma! */
 	/* How many end-of-memory variables you have, grandma! */
 	/* need this before calling reserve_initrd */
 	/* need this before calling reserve_initrd */
 	if (max_pfn > (1UL<<(32 - PAGE_SHIFT)))
 	if (max_pfn > (1UL<<(32 - PAGE_SHIFT)))
-		max_low_pfn = e820_end_of_low_ram_pfn();
+		max_low_pfn = e820__end_of_low_ram_pfn();
 	else
 	else
 		max_low_pfn = max_pfn;
 		max_low_pfn = max_pfn;
 
 
@@ -1111,7 +1087,7 @@ void __init setup_arch(char **cmdline_p)
 	early_alloc_pgt_buf();
 	early_alloc_pgt_buf();
 
 
 	/*
 	/*
-	 * Need to conclude brk, before memblock_x86_fill()
+	 * Need to conclude brk, before e820__memblock_setup()
 	 *  it could use memblock_find_in_range, could overlap with
 	 *  it could use memblock_find_in_range, could overlap with
 	 *  brk area.
 	 *  brk area.
 	 */
 	 */
@@ -1120,7 +1096,7 @@ void __init setup_arch(char **cmdline_p)
 	cleanup_highmap();
 	cleanup_highmap();
 
 
 	memblock_set_current_limit(ISA_END_ADDRESS);
 	memblock_set_current_limit(ISA_END_ADDRESS);
-	memblock_x86_fill();
+	e820__memblock_setup();
 
 
 	reserve_bios_regions();
 	reserve_bios_regions();
 
 
@@ -1137,7 +1113,7 @@ void __init setup_arch(char **cmdline_p)
 	}
 	}
 
 
 	/* preallocate 4k for mptable mpc */
 	/* preallocate 4k for mptable mpc */
-	early_reserve_e820_mpc_new();
+	e820__memblock_alloc_reserved_mpc_new();
 
 
 #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
 #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
 	setup_bios_corruption_check();
 	setup_bios_corruption_check();
@@ -1275,12 +1251,12 @@ void __init setup_arch(char **cmdline_p)
 
 
 	kvm_guest_init();
 	kvm_guest_init();
 
 
-	e820_reserve_resources();
-	e820_mark_nosave_regions(max_low_pfn);
+	e820__reserve_resources();
+	e820__register_nosave_regions(max_low_pfn);
 
 
 	x86_init.resources.reserve_resources();
 	x86_init.resources.reserve_resources();
 
 
-	e820_setup_gap();
+	e820__setup_pci_gap();
 
 
 #ifdef CONFIG_VT
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
 #if defined(CONFIG_VGA_CONSOLE)

+ 3 - 0
arch/x86/kernel/smp.c

@@ -33,6 +33,7 @@
 #include <asm/mce.h>
 #include <asm/mce.h>
 #include <asm/trace/irq_vectors.h>
 #include <asm/trace/irq_vectors.h>
 #include <asm/kexec.h>
 #include <asm/kexec.h>
+#include <asm/virtext.h>
 
 
 /*
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
  *	Some notes on x86 processor bugs affecting SMP operation:
@@ -162,6 +163,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
 	if (raw_smp_processor_id() == atomic_read(&stopping_cpu))
 	if (raw_smp_processor_id() == atomic_read(&stopping_cpu))
 		return NMI_HANDLED;
 		return NMI_HANDLED;
 
 
+	cpu_emergency_vmxoff();
 	stop_this_cpu(NULL);
 	stop_this_cpu(NULL);
 
 
 	return NMI_HANDLED;
 	return NMI_HANDLED;
@@ -174,6 +176,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
 asmlinkage __visible void smp_reboot_interrupt(void)
 asmlinkage __visible void smp_reboot_interrupt(void)
 {
 {
 	ipi_entering_ack_irq();
 	ipi_entering_ack_irq();
+	cpu_emergency_vmxoff();
 	stop_this_cpu(NULL);
 	stop_this_cpu(NULL);
 	irq_exit();
 	irq_exit();
 }
 }

+ 8 - 8
arch/x86/kernel/tboot.c

@@ -42,7 +42,7 @@
 #include <asm/fixmap.h>
 #include <asm/fixmap.h>
 #include <asm/proto.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
 #include "../realmode/rm/wakeup.h"
 #include "../realmode/rm/wakeup.h"
@@ -68,9 +68,9 @@ void __init tboot_probe(void)
 	 * also verify that it is mapped as we expect it before calling
 	 * also verify that it is mapped as we expect it before calling
 	 * set_fixmap(), to reduce chance of garbage value causing crash
 	 * set_fixmap(), to reduce chance of garbage value causing crash
 	 */
 	 */
-	if (!e820_any_mapped(boot_params.tboot_addr,
-			     boot_params.tboot_addr, E820_RESERVED)) {
-		pr_warning("non-0 tboot_addr but it is not of type E820_RESERVED\n");
+	if (!e820__mapped_any(boot_params.tboot_addr,
+			     boot_params.tboot_addr, E820_TYPE_RESERVED)) {
+		pr_warning("non-0 tboot_addr but it is not of type E820_TYPE_RESERVED\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -188,12 +188,12 @@ static int tboot_setup_sleep(void)
 
 
 	tboot->num_mac_regions = 0;
 	tboot->num_mac_regions = 0;
 
 
-	for (i = 0; i < e820->nr_map; i++) {
-		if ((e820->map[i].type != E820_RAM)
-		 && (e820->map[i].type != E820_RESERVED_KERN))
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		if ((e820_table->entries[i].type != E820_TYPE_RAM)
+		 && (e820_table->entries[i].type != E820_TYPE_RESERVED_KERN))
 			continue;
 			continue;
 
 
-		add_mac_region(e820->map[i].addr, e820->map[i].size);
+		add_mac_region(e820_table->entries[i].addr, e820_table->entries[i].size);
 	}
 	}
 
 
 	tboot->acpi_sinfo.kernel_s3_resume_vector =
 	tboot->acpi_sinfo.kernel_s3_resume_vector =

+ 2 - 2
arch/x86/kernel/x86_init.c

@@ -14,7 +14,7 @@
 #include <asm/mpspec.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/time.h>
 #include <asm/time.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
 #include <asm/io_apic.h>
 #include <asm/io_apic.h>
@@ -38,7 +38,7 @@ struct x86_init_ops x86_init __initdata = {
 	.resources = {
 	.resources = {
 		.probe_roms		= probe_roms,
 		.probe_roms		= probe_roms,
 		.reserve_resources	= reserve_standard_io_resources,
 		.reserve_resources	= reserve_standard_io_resources,
-		.memory_setup		= default_machine_specific_memory_setup,
+		.memory_setup		= e820__memory_setup_default,
 	},
 	},
 
 
 	.mpparse = {
 	.mpparse = {

+ 4 - 4
arch/x86/lguest/boot.c

@@ -67,7 +67,7 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/desc.h>
 #include <asm/desc.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mce.h>
 #include <asm/mce.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/fpu/api.h>
 #include <asm/fpu/api.h>
@@ -1180,9 +1180,9 @@ static __init char *lguest_memory_setup(void)
 	 * The Linux bootloader header contains an "e820" memory map: the
 	 * The Linux bootloader header contains an "e820" memory map: the
 	 * Launcher populated the first entry with our memory limit.
 	 * Launcher populated the first entry with our memory limit.
 	 */
 	 */
-	e820_add_region(boot_params.e820_map[0].addr,
-			  boot_params.e820_map[0].size,
-			  boot_params.e820_map[0].type);
+	e820__range_add(boot_params.e820_table[0].addr,
+			  boot_params.e820_table[0].size,
+			  boot_params.e820_table[0].type);
 
 
 	/* This string is for the boot messages. */
 	/* This string is for the boot messages. */
 	return "LGUEST";
 	return "LGUEST";

+ 1 - 1
arch/x86/lib/kaslr.c

@@ -8,7 +8,7 @@
 #include <asm/kaslr.h>
 #include <asm/kaslr.h>
 #include <asm/msr.h>
 #include <asm/msr.h>
 #include <asm/archrandom.h>
 #include <asm/archrandom.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
 /*
 /*

+ 1 - 1
arch/x86/mm/amdtopology.c

@@ -19,7 +19,7 @@
 #include <asm/types.h>
 #include <asm/types.h>
 #include <asm/mmzone.h>
 #include <asm/mmzone.h>
 #include <asm/proto.h>
 #include <asm/proto.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci-direct.h>
 #include <asm/pci-direct.h>
 #include <asm/numa.h>
 #include <asm/numa.h>
 #include <asm/mpspec.h>
 #include <asm/mpspec.h>

+ 53 - 6
arch/x86/mm/init.c

@@ -6,7 +6,7 @@
 #include <linux/bootmem.h>	/* for max_low_pfn */
 #include <linux/bootmem.h>	/* for max_low_pfn */
 
 
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/init.h>
 #include <asm/init.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/page_types.h>
 #include <asm/page_types.h>
@@ -373,14 +373,14 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
 	return nr_range;
 	return nr_range;
 }
 }
 
 
-struct range pfn_mapped[E820_X_MAX];
+struct range pfn_mapped[E820_MAX_ENTRIES];
 int nr_pfn_mapped;
 int nr_pfn_mapped;
 
 
 static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn)
 static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn)
 {
 {
-	nr_pfn_mapped = add_range_with_merge(pfn_mapped, E820_X_MAX,
+	nr_pfn_mapped = add_range_with_merge(pfn_mapped, E820_MAX_ENTRIES,
 					     nr_pfn_mapped, start_pfn, end_pfn);
 					     nr_pfn_mapped, start_pfn, end_pfn);
-	nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_X_MAX);
+	nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_MAX_ENTRIES);
 
 
 	max_pfn_mapped = max(max_pfn_mapped, end_pfn);
 	max_pfn_mapped = max(max_pfn_mapped, end_pfn);
 
 
@@ -430,7 +430,7 @@ unsigned long __ref init_memory_mapping(unsigned long start,
 
 
 /*
 /*
  * We need to iterate through the E820 memory map and create direct mappings
  * We need to iterate through the E820 memory map and create direct mappings
- * for only E820_RAM and E820_KERN_RESERVED regions. We cannot simply
+ * for only E820_TYPE_RAM and E820_KERN_RESERVED regions. We cannot simply
  * create direct mappings for all pfns from [0 to max_low_pfn) and
  * create direct mappings for all pfns from [0 to max_low_pfn) and
  * [4GB to max_pfn) because of possible memory holes in high addresses
  * [4GB to max_pfn) because of possible memory holes in high addresses
  * that cannot be marked as UC by fixed/variable range MTRRs.
  * that cannot be marked as UC by fixed/variable range MTRRs.
@@ -720,7 +720,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
 
 
 void __ref free_initmem(void)
 void __ref free_initmem(void)
 {
 {
-	e820_reallocate_tables();
+	e820__reallocate_tables();
 
 
 	free_init_pages("unused kernel",
 	free_init_pages("unused kernel",
 			(unsigned long)(&__init_begin),
 			(unsigned long)(&__init_begin),
@@ -743,6 +743,53 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
 }
 }
 #endif
 #endif
 
 
+/*
+ * Calculate the precise size of the DMA zone (first 16 MB of RAM),
+ * and pass it to the MM layer - to help it set zone watermarks more
+ * accurately.
+ *
+ * Done on 64-bit systems only for the time being, although 32-bit systems
+ * might benefit from this as well.
+ */
+void __init memblock_find_dma_reserve(void)
+{
+#ifdef CONFIG_X86_64
+	u64 nr_pages = 0, nr_free_pages = 0;
+	unsigned long start_pfn, end_pfn;
+	phys_addr_t start_addr, end_addr;
+	int i;
+	u64 u;
+
+	/*
+	 * Iterate over all memory ranges (free and reserved ones alike),
+	 * to calculate the total number of pages in the first 16 MB of RAM:
+	 */
+	nr_pages = 0;
+	for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) {
+		start_pfn = min(start_pfn, MAX_DMA_PFN);
+		end_pfn   = min(end_pfn,   MAX_DMA_PFN);
+
+		nr_pages += end_pfn - start_pfn;
+	}
+
+	/*
+	 * Iterate over free memory ranges to calculate the number of free
+	 * pages in the DMA zone, while not counting potential partial
+	 * pages at the beginning or the end of the range:
+	 */
+	nr_free_pages = 0;
+	for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start_addr, &end_addr, NULL) {
+		start_pfn = min_t(unsigned long, PFN_UP(start_addr), MAX_DMA_PFN);
+		end_pfn   = min_t(unsigned long, PFN_DOWN(end_addr), MAX_DMA_PFN);
+
+		if (start_pfn < end_pfn)
+			nr_free_pages += end_pfn - start_pfn;
+	}
+
+	set_dma_reserve(nr_pages - nr_free_pages);
+#endif
+}
+
 void __init zone_sizes_init(void)
 void __init zone_sizes_init(void)
 {
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
 	unsigned long max_zone_pfns[MAX_NR_ZONES];

+ 1 - 1
arch/x86/mm/init_32.c

@@ -38,7 +38,7 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/dma.h>
 #include <asm/dma.h>
 #include <asm/fixmap.h>
 #include <asm/fixmap.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
 #include <asm/bugs.h>
 #include <asm/bugs.h>
 #include <asm/tlb.h>
 #include <asm/tlb.h>

+ 13 - 13
arch/x86/mm/init_64.c

@@ -41,7 +41,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/dma.h>
 #include <asm/dma.h>
 #include <asm/fixmap.h>
 #include <asm/fixmap.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
 #include <asm/tlb.h>
 #include <asm/tlb.h>
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
@@ -337,10 +337,10 @@ phys_pte_init(pte_t *pte_page, unsigned long paddr, unsigned long paddr_end,
 		paddr_next = (paddr & PAGE_MASK) + PAGE_SIZE;
 		paddr_next = (paddr & PAGE_MASK) + PAGE_SIZE;
 		if (paddr >= paddr_end) {
 		if (paddr >= paddr_end) {
 			if (!after_bootmem &&
 			if (!after_bootmem &&
-			    !e820_any_mapped(paddr & PAGE_MASK, paddr_next,
-					     E820_RAM) &&
-			    !e820_any_mapped(paddr & PAGE_MASK, paddr_next,
-					     E820_RESERVED_KERN))
+			    !e820__mapped_any(paddr & PAGE_MASK, paddr_next,
+					     E820_TYPE_RAM) &&
+			    !e820__mapped_any(paddr & PAGE_MASK, paddr_next,
+					     E820_TYPE_RESERVED_KERN))
 				set_pte(pte, __pte(0));
 				set_pte(pte, __pte(0));
 			continue;
 			continue;
 		}
 		}
@@ -392,10 +392,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end,
 		paddr_next = (paddr & PMD_MASK) + PMD_SIZE;
 		paddr_next = (paddr & PMD_MASK) + PMD_SIZE;
 		if (paddr >= paddr_end) {
 		if (paddr >= paddr_end) {
 			if (!after_bootmem &&
 			if (!after_bootmem &&
-			    !e820_any_mapped(paddr & PMD_MASK, paddr_next,
-					     E820_RAM) &&
-			    !e820_any_mapped(paddr & PMD_MASK, paddr_next,
-					     E820_RESERVED_KERN))
+			    !e820__mapped_any(paddr & PMD_MASK, paddr_next,
+					     E820_TYPE_RAM) &&
+			    !e820__mapped_any(paddr & PMD_MASK, paddr_next,
+					     E820_TYPE_RESERVED_KERN))
 				set_pmd(pmd, __pmd(0));
 				set_pmd(pmd, __pmd(0));
 			continue;
 			continue;
 		}
 		}
@@ -478,10 +478,10 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end,
 
 
 		if (paddr >= paddr_end) {
 		if (paddr >= paddr_end) {
 			if (!after_bootmem &&
 			if (!after_bootmem &&
-			    !e820_any_mapped(paddr & PUD_MASK, paddr_next,
-					     E820_RAM) &&
-			    !e820_any_mapped(paddr & PUD_MASK, paddr_next,
-					     E820_RESERVED_KERN))
+			    !e820__mapped_any(paddr & PUD_MASK, paddr_next,
+					     E820_TYPE_RAM) &&
+			    !e820__mapped_any(paddr & PUD_MASK, paddr_next,
+					     E820_TYPE_RESERVED_KERN))
 				set_pud(pud, __pud(0));
 				set_pud(pud, __pud(0));
 			continue;
 			continue;
 		}
 		}

+ 2 - 1
arch/x86/mm/ioremap.c

@@ -9,12 +9,13 @@
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/mmiotrace.h>
 #include <linux/mmiotrace.h>
 
 
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/fixmap.h>
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>

+ 3 - 2
arch/x86/mm/kasan_init_64.c

@@ -8,11 +8,12 @@
 #include <linux/sched/task.h>
 #include <linux/sched/task.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 
 
+#include <asm/e820/types.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
 
 
 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
-extern struct range pfn_mapped[E820_X_MAX];
+extern struct range pfn_mapped[E820_MAX_ENTRIES];
 
 
 static int __init map_range(struct range *range)
 static int __init map_range(struct range *range)
 {
 {
@@ -104,7 +105,7 @@ void __init kasan_init(void)
 	kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
 	kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
 			kasan_mem_to_shadow((void *)PAGE_OFFSET));
 			kasan_mem_to_shadow((void *)PAGE_OFFSET));
 
 
-	for (i = 0; i < E820_X_MAX; i++) {
+	for (i = 0; i < E820_MAX_ENTRIES; i++) {
 		if (pfn_mapped[i].end == 0)
 		if (pfn_mapped[i].end == 0)
 			break;
 			break;
 
 

+ 1 - 1
arch/x86/mm/mmio-mod.c

@@ -32,7 +32,7 @@
 #include <linux/kallsyms.h>
 #include <linux/kallsyms.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <linux/mmiotrace.h>
 #include <linux/mmiotrace.h>
-#include <asm/e820.h> /* for ISA_START_ADDRESS */
+#include <asm/e820/api.h> /* for ISA_START_ADDRESS */
 #include <linux/atomic.h>
 #include <linux/atomic.h>
 #include <linux/percpu.h>
 #include <linux/percpu.h>
 #include <linux/cpu.h>
 #include <linux/cpu.h>

+ 1 - 1
arch/x86/mm/numa.c

@@ -12,7 +12,7 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/topology.h>
 #include <linux/topology.h>
 
 
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/proto.h>
 #include <asm/proto.h>
 #include <asm/dma.h>
 #include <asm/dma.h>
 #include <asm/amd_nb.h>
 #include <asm/amd_nb.h>

+ 1 - 1
arch/x86/mm/pageattr.c

@@ -15,7 +15,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 
 
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
 #include <asm/sections.h>

+ 2 - 1
arch/x86/mm/pat.c

@@ -10,6 +10,7 @@
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
 #include <linux/debugfs.h>
 #include <linux/debugfs.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/pfn_t.h>
 #include <linux/pfn_t.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
@@ -23,7 +24,7 @@
 #include <asm/x86_init.h>
 #include <asm/x86_init.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/fcntl.h>
 #include <asm/fcntl.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/mtrr.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/msr.h>
 #include <asm/msr.h>

+ 1 - 1
arch/x86/mm/pgtable_32.c

@@ -12,7 +12,7 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/fixmap.h>
 #include <asm/fixmap.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/tlb.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 #include <asm/io.h>
 #include <asm/io.h>

+ 1 - 1
arch/x86/mm/srat.c

@@ -18,7 +18,7 @@
 #include <linux/mm.h>
 #include <linux/mm.h>
 #include <asm/proto.h>
 #include <asm/proto.h>
 #include <asm/numa.h>
 #include <asm/numa.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/apic.h>
 #include <asm/apic.h>
 #include <asm/uv/uv.h>
 #include <asm/uv/uv.h>
 
 

+ 2 - 2
arch/x86/pci/i386.c

@@ -34,7 +34,7 @@
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
 
 
 #include <asm/pat.h>
 #include <asm/pat.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 #include <asm/io_apic.h>
 #include <asm/io_apic.h>
 
 
@@ -398,7 +398,7 @@ void __init pcibios_resource_survey(void)
 	list_for_each_entry(bus, &pci_root_buses, node)
 	list_for_each_entry(bus, &pci_root_buses, node)
 		pcibios_allocate_resources(bus, 1);
 		pcibios_allocate_resources(bus, 1);
 
 
-	e820_reserve_resources_late();
+	e820__reserve_resources_late();
 	/*
 	/*
 	 * Insert the IO APIC resources after PCI initialization has
 	 * Insert the IO APIC resources after PCI initialization has
 	 * occurred to handle IO APICS that are mapped in on a BAR in
 	 * occurred to handle IO APICS that are mapped in on a BAR in

+ 11 - 11
arch/x86/pci/mmconfig-shared.c

@@ -18,7 +18,7 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/rculist.h>
 #include <linux/rculist.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
 #include <asm/acpi.h>
 
 
@@ -423,7 +423,7 @@ static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl,
 	return AE_OK;
 	return AE_OK;
 }
 }
 
 
-static int is_acpi_reserved(u64 start, u64 end, unsigned not_used)
+static bool is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 {
 {
 	struct resource mcfg_res;
 	struct resource mcfg_res;
 
 
@@ -440,11 +440,11 @@ static int is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 	return mcfg_res.flags;
 	return mcfg_res.flags;
 }
 }
 
 
-typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
+typedef bool (*check_reserved_t)(u64 start, u64 end, unsigned type);
 
 
-static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
-				    struct pci_mmcfg_region *cfg,
-				    struct device *dev, int with_e820)
+static bool __ref is_mmconf_reserved(check_reserved_t is_reserved,
+				     struct pci_mmcfg_region *cfg,
+				     struct device *dev, int with_e820)
 {
 {
 	u64 addr = cfg->res.start;
 	u64 addr = cfg->res.start;
 	u64 size = resource_size(&cfg->res);
 	u64 size = resource_size(&cfg->res);
@@ -452,7 +452,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
 	int num_buses;
 	int num_buses;
 	char *method = with_e820 ? "E820" : "ACPI motherboard resources";
 	char *method = with_e820 ? "E820" : "ACPI motherboard resources";
 
 
-	while (!is_reserved(addr, addr + size, E820_RESERVED)) {
+	while (!is_reserved(addr, addr + size, E820_TYPE_RESERVED)) {
 		size >>= 1;
 		size >>= 1;
 		if (size < (16UL<<20))
 		if (size < (16UL<<20))
 			break;
 			break;
@@ -494,8 +494,8 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
 	return 1;
 	return 1;
 }
 }
 
 
-static int __ref pci_mmcfg_check_reserved(struct device *dev,
-		  struct pci_mmcfg_region *cfg, int early)
+static bool __ref
+pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int early)
 {
 {
 	if (!early && !acpi_disabled) {
 	if (!early && !acpi_disabled) {
 		if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
 		if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
@@ -514,7 +514,7 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev,
 	}
 	}
 
 
 	/*
 	/*
-	 * e820_all_mapped() is marked as __init.
+	 * e820__mapped_all() is marked as __init.
 	 * All entries from ACPI MCFG table have been checked at boot time.
 	 * All entries from ACPI MCFG table have been checked at boot time.
 	 * For MCFG information constructed from hotpluggable host bridge's
 	 * For MCFG information constructed from hotpluggable host bridge's
 	 * _CBA method, just assume it's reserved.
 	 * _CBA method, just assume it's reserved.
@@ -525,7 +525,7 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev,
 	/* Don't try to do this check unless configuration
 	/* Don't try to do this check unless configuration
 	   type 1 is available. how about type 2 ?*/
 	   type 1 is available. how about type 2 ?*/
 	if (raw_pci_ops)
 	if (raw_pci_ops)
-		return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1);
+		return is_mmconf_reserved(e820__mapped_all, cfg, dev, 1);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 1
arch/x86/pci/mmconfig_32.c

@@ -12,7 +12,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
 #include <linux/rcupdate.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 
 
 /* Assume systems with more busses have correct MCFG */
 /* Assume systems with more busses have correct MCFG */

+ 1 - 1
arch/x86/pci/mmconfig_64.c

@@ -10,7 +10,7 @@
 #include <linux/acpi.h>
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
 #include <linux/bitmap.h>
 #include <linux/rcupdate.h>
 #include <linux/rcupdate.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 
 
 #define PREFIX "PCI: "
 #define PREFIX "PCI: "

+ 2 - 0
arch/x86/pci/pcbios.c

@@ -7,7 +7,9 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
+
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
+#include <asm/e820/types.h>
 #include <asm/pci-functions.h>
 #include <asm/pci-functions.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 
 

+ 10 - 9
arch/x86/platform/efi/efi.c

@@ -47,6 +47,7 @@
 
 
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/efi.h>
 #include <asm/efi.h>
+#include <asm/e820/api.h>
 #include <asm/time.h>
 #include <asm/time.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
@@ -139,21 +140,21 @@ static void __init do_add_efi_memmap(void)
 		case EFI_BOOT_SERVICES_DATA:
 		case EFI_BOOT_SERVICES_DATA:
 		case EFI_CONVENTIONAL_MEMORY:
 		case EFI_CONVENTIONAL_MEMORY:
 			if (md->attribute & EFI_MEMORY_WB)
 			if (md->attribute & EFI_MEMORY_WB)
-				e820_type = E820_RAM;
+				e820_type = E820_TYPE_RAM;
 			else
 			else
-				e820_type = E820_RESERVED;
+				e820_type = E820_TYPE_RESERVED;
 			break;
 			break;
 		case EFI_ACPI_RECLAIM_MEMORY:
 		case EFI_ACPI_RECLAIM_MEMORY:
-			e820_type = E820_ACPI;
+			e820_type = E820_TYPE_ACPI;
 			break;
 			break;
 		case EFI_ACPI_MEMORY_NVS:
 		case EFI_ACPI_MEMORY_NVS:
-			e820_type = E820_NVS;
+			e820_type = E820_TYPE_NVS;
 			break;
 			break;
 		case EFI_UNUSABLE_MEMORY:
 		case EFI_UNUSABLE_MEMORY:
-			e820_type = E820_UNUSABLE;
+			e820_type = E820_TYPE_UNUSABLE;
 			break;
 			break;
 		case EFI_PERSISTENT_MEMORY:
 		case EFI_PERSISTENT_MEMORY:
-			e820_type = E820_PMEM;
+			e820_type = E820_TYPE_PMEM;
 			break;
 			break;
 		default:
 		default:
 			/*
 			/*
@@ -161,12 +162,12 @@ static void __init do_add_efi_memmap(void)
 			 * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO
 			 * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO
 			 * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE
 			 * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE
 			 */
 			 */
-			e820_type = E820_RESERVED;
+			e820_type = E820_TYPE_RESERVED;
 			break;
 			break;
 		}
 		}
-		e820_add_region(start, size, e820_type);
+		e820__range_add(start, size, e820_type);
 	}
 	}
-	sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
+	e820__update_table(e820_table);
 }
 }
 
 
 int __init efi_memblock_x86_reserve_range(void)
 int __init efi_memblock_x86_reserve_range(void)

+ 1 - 1
arch/x86/platform/efi/efi_64.c

@@ -35,7 +35,7 @@
 
 
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/page.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 #include <asm/proto.h>
 #include <asm/proto.h>

+ 5 - 3
arch/x86/platform/efi/quirks.c

@@ -11,6 +11,8 @@
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/dmi.h>
+
+#include <asm/e820/api.h>
 #include <asm/efi.h>
 #include <asm/efi.h>
 #include <asm/uv/uv.h>
 #include <asm/uv/uv.h>
 
 
@@ -244,14 +246,14 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
  * else. We must only reserve (and then free) regions:
  * else. We must only reserve (and then free) regions:
  *
  *
  * - Not within any part of the kernel
  * - Not within any part of the kernel
- * - Not the BIOS reserved area (E820_RESERVED, E820_NVS, etc)
+ * - Not the BIOS reserved area (E820_TYPE_RESERVED, E820_TYPE_NVS, etc)
  */
  */
 static bool can_free_region(u64 start, u64 size)
 static bool can_free_region(u64 start, u64 size)
 {
 {
 	if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end))
 	if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end))
 		return false;
 		return false;
 
 
-	if (!e820_all_mapped(start, start+size, E820_RAM))
+	if (!e820__mapped_all(start, start+size, E820_TYPE_RAM))
 		return false;
 		return false;
 
 
 	return true;
 	return true;
@@ -284,7 +286,7 @@ void __init efi_reserve_boot_services(void)
 		 * A good example of a critical region that must not be
 		 * A good example of a critical region that must not be
 		 * freed is page zero (first 4Kb of memory), which may
 		 * freed is page zero (first 4Kb of memory), which may
 		 * contain boot services code/data but is marked
 		 * contain boot services code/data but is marked
-		 * E820_RESERVED by trim_bios_range().
+		 * E820_TYPE_RESERVED by trim_bios_range().
 		 */
 		 */
 		if (!already_reserved) {
 		if (!already_reserved) {
 			memblock_reserve(start, size);
 			memblock_reserve(start, size);

+ 8 - 8
arch/x86/power/hibernate_64.c

@@ -16,6 +16,7 @@
 
 
 #include <crypto/hash.h>
 #include <crypto/hash.h>
 
 
+#include <asm/e820/api.h>
 #include <asm/init.h>
 #include <asm/init.h>
 #include <asm/proto.h>
 #include <asm/proto.h>
 #include <asm/page.h>
 #include <asm/page.h>
@@ -195,12 +196,12 @@ struct restore_data_record {
 
 
 #if IS_BUILTIN(CONFIG_CRYPTO_MD5)
 #if IS_BUILTIN(CONFIG_CRYPTO_MD5)
 /**
 /**
- * get_e820_md5 - calculate md5 according to given e820 map
+ * get_e820_md5 - calculate md5 according to given e820 table
  *
  *
- * @map: the e820 map to be calculated
+ * @table: the e820 table to be calculated
  * @buf: the md5 result to be stored to
  * @buf: the md5 result to be stored to
  */
  */
-static int get_e820_md5(struct e820map *map, void *buf)
+static int get_e820_md5(struct e820_table *table, void *buf)
 {
 {
 	struct scatterlist sg;
 	struct scatterlist sg;
 	struct crypto_ahash *tfm;
 	struct crypto_ahash *tfm;
@@ -213,10 +214,9 @@ static int get_e820_md5(struct e820map *map, void *buf)
 
 
 	{
 	{
 		AHASH_REQUEST_ON_STACK(req, tfm);
 		AHASH_REQUEST_ON_STACK(req, tfm);
-		size = offsetof(struct e820map, map)
-			+ sizeof(struct e820entry) * map->nr_map;
+		size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry) * table->nr_entries;
 		ahash_request_set_tfm(req, tfm);
 		ahash_request_set_tfm(req, tfm);
-		sg_init_one(&sg, (u8 *)map, size);
+		sg_init_one(&sg, (u8 *)table, size);
 		ahash_request_set_callback(req, 0, NULL, NULL);
 		ahash_request_set_callback(req, 0, NULL, NULL);
 		ahash_request_set_crypt(req, &sg, buf, size);
 		ahash_request_set_crypt(req, &sg, buf, size);
 
 
@@ -231,7 +231,7 @@ static int get_e820_md5(struct e820map *map, void *buf)
 
 
 static void hibernation_e820_save(void *buf)
 static void hibernation_e820_save(void *buf)
 {
 {
-	get_e820_md5(e820_saved, buf);
+	get_e820_md5(e820_table_firmware, buf);
 }
 }
 
 
 static bool hibernation_e820_mismatch(void *buf)
 static bool hibernation_e820_mismatch(void *buf)
@@ -244,7 +244,7 @@ static bool hibernation_e820_mismatch(void *buf)
 	if (!memcmp(result, buf, MD5_DIGEST_SIZE))
 	if (!memcmp(result, buf, MD5_DIGEST_SIZE))
 		return false;
 		return false;
 
 
-	ret = get_e820_md5(e820_saved, result);
+	ret = get_e820_md5(e820_table_firmware, result);
 	if (ret)
 	if (ret)
 		return true;
 		return true;
 
 

+ 13 - 14
arch/x86/xen/enlighten.c

@@ -76,6 +76,7 @@
 #include <asm/mwait.h>
 #include <asm/mwait.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 #include <asm/cpu.h>
 #include <asm/cpu.h>
+#include <asm/e820/api.h> 
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
 #include <linux/acpi.h>
 #include <linux/acpi.h>
@@ -1690,34 +1691,32 @@ static void __init init_pvh_bootparams(void)
 
 
 	memset(&pvh_bootparams, 0, sizeof(pvh_bootparams));
 	memset(&pvh_bootparams, 0, sizeof(pvh_bootparams));
 
 
-	memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_map);
-	set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_map);
+	memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_table);
+	set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_table);
 	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
 	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
 	if (rc) {
 	if (rc) {
 		xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc);
 		xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc);
 		BUG();
 		BUG();
 	}
 	}
 
 
-	if (memmap.nr_entries < E820MAX - 1) {
-		pvh_bootparams.e820_map[memmap.nr_entries].addr =
+	if (memmap.nr_entries < E820_MAX_ENTRIES_ZEROPAGE - 1) {
+		pvh_bootparams.e820_table[memmap.nr_entries].addr =
 			ISA_START_ADDRESS;
 			ISA_START_ADDRESS;
-		pvh_bootparams.e820_map[memmap.nr_entries].size =
+		pvh_bootparams.e820_table[memmap.nr_entries].size =
 			ISA_END_ADDRESS - ISA_START_ADDRESS;
 			ISA_END_ADDRESS - ISA_START_ADDRESS;
-		pvh_bootparams.e820_map[memmap.nr_entries].type =
-			E820_RESERVED;
+		pvh_bootparams.e820_table[memmap.nr_entries].type =
+			E820_TYPE_RESERVED;
 		memmap.nr_entries++;
 		memmap.nr_entries++;
 	} else
 	} else
 		xen_raw_printk("Warning: Can fit ISA range into e820\n");
 		xen_raw_printk("Warning: Can fit ISA range into e820\n");
 
 
-	sanitize_e820_map(pvh_bootparams.e820_map,
-			  ARRAY_SIZE(pvh_bootparams.e820_map),
-			  &memmap.nr_entries);
-
 	pvh_bootparams.e820_entries = memmap.nr_entries;
 	pvh_bootparams.e820_entries = memmap.nr_entries;
 	for (i = 0; i < pvh_bootparams.e820_entries; i++)
 	for (i = 0; i < pvh_bootparams.e820_entries; i++)
-		e820_add_region(pvh_bootparams.e820_map[i].addr,
-				pvh_bootparams.e820_map[i].size,
-				pvh_bootparams.e820_map[i].type);
+		e820__range_add(pvh_bootparams.e820_table[i].addr,
+				pvh_bootparams.e820_table[i].size,
+				pvh_bootparams.e820_table[i].type);
+
+	e820__update_table(e820_table);
 
 
 	pvh_bootparams.hdr.cmd_line_ptr =
 	pvh_bootparams.hdr.cmd_line_ptr =
 		pvh_start_info.cmdline_paddr;
 		pvh_start_info.cmdline_paddr;

+ 1 - 1
arch/x86/xen/mmu.c

@@ -58,7 +58,7 @@
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/paravirt.h>
 #include <asm/paravirt.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/linkage.h>
 #include <asm/linkage.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/init.h>
 #include <asm/init.h>

+ 73 - 45
arch/x86/xen/setup.c

@@ -14,7 +14,7 @@
 
 
 #include <asm/elf.h>
 #include <asm/elf.h>
 #include <asm/vdso.h>
 #include <asm/vdso.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/acpi.h>
 #include <asm/acpi.h>
 #include <asm/numa.h>
 #include <asm/numa.h>
@@ -41,8 +41,7 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
 unsigned long xen_released_pages;
 unsigned long xen_released_pages;
 
 
 /* E820 map used during setting up memory. */
 /* E820 map used during setting up memory. */
-static struct e820entry xen_e820_map[E820_X_MAX] __initdata;
-static u32 xen_e820_map_entries __initdata;
+static struct e820_table xen_e820_table __initdata;
 
 
 /*
 /*
  * Buffer used to remap identity mapped pages. We only need the virtual space.
  * Buffer used to remap identity mapped pages. We only need the virtual space.
@@ -198,15 +197,15 @@ void __init xen_inv_extra_mem(void)
  */
  */
 static unsigned long __init xen_find_pfn_range(unsigned long *min_pfn)
 static unsigned long __init xen_find_pfn_range(unsigned long *min_pfn)
 {
 {
-	const struct e820entry *entry = xen_e820_map;
+	const struct e820_entry *entry = xen_e820_table.entries;
 	unsigned int i;
 	unsigned int i;
 	unsigned long done = 0;
 	unsigned long done = 0;
 
 
-	for (i = 0; i < xen_e820_map_entries; i++, entry++) {
+	for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) {
 		unsigned long s_pfn;
 		unsigned long s_pfn;
 		unsigned long e_pfn;
 		unsigned long e_pfn;
 
 
-		if (entry->type != E820_RAM)
+		if (entry->type != E820_TYPE_RAM)
 			continue;
 			continue;
 
 
 		e_pfn = PFN_DOWN(entry->addr + entry->size);
 		e_pfn = PFN_DOWN(entry->addr + entry->size);
@@ -457,7 +456,7 @@ static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
 {
 {
 	phys_addr_t start = 0;
 	phys_addr_t start = 0;
 	unsigned long ret_val = 0;
 	unsigned long ret_val = 0;
-	const struct e820entry *entry = xen_e820_map;
+	const struct e820_entry *entry = xen_e820_table.entries;
 	int i;
 	int i;
 
 
 	/*
 	/*
@@ -471,13 +470,13 @@ static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
 	 * example) the DMI tables in a reserved region that begins on
 	 * example) the DMI tables in a reserved region that begins on
 	 * a non-page boundary.
 	 * a non-page boundary.
 	 */
 	 */
-	for (i = 0; i < xen_e820_map_entries; i++, entry++) {
+	for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) {
 		phys_addr_t end = entry->addr + entry->size;
 		phys_addr_t end = entry->addr + entry->size;
-		if (entry->type == E820_RAM || i == xen_e820_map_entries - 1) {
+		if (entry->type == E820_TYPE_RAM || i == xen_e820_table.nr_entries - 1) {
 			unsigned long start_pfn = PFN_DOWN(start);
 			unsigned long start_pfn = PFN_DOWN(start);
 			unsigned long end_pfn = PFN_UP(end);
 			unsigned long end_pfn = PFN_UP(end);
 
 
-			if (entry->type == E820_RAM)
+			if (entry->type == E820_TYPE_RAM)
 				end_pfn = PFN_UP(entry->addr);
 				end_pfn = PFN_UP(entry->addr);
 
 
 			if (start_pfn < end_pfn)
 			if (start_pfn < end_pfn)
@@ -591,28 +590,28 @@ static void __init xen_align_and_add_e820_region(phys_addr_t start,
 	phys_addr_t end = start + size;
 	phys_addr_t end = start + size;
 
 
 	/* Align RAM regions to page boundaries. */
 	/* Align RAM regions to page boundaries. */
-	if (type == E820_RAM) {
+	if (type == E820_TYPE_RAM) {
 		start = PAGE_ALIGN(start);
 		start = PAGE_ALIGN(start);
 		end &= ~((phys_addr_t)PAGE_SIZE - 1);
 		end &= ~((phys_addr_t)PAGE_SIZE - 1);
 	}
 	}
 
 
-	e820_add_region(start, end - start, type);
+	e820__range_add(start, end - start, type);
 }
 }
 
 
 static void __init xen_ignore_unusable(void)
 static void __init xen_ignore_unusable(void)
 {
 {
-	struct e820entry *entry = xen_e820_map;
+	struct e820_entry *entry = xen_e820_table.entries;
 	unsigned int i;
 	unsigned int i;
 
 
-	for (i = 0; i < xen_e820_map_entries; i++, entry++) {
-		if (entry->type == E820_UNUSABLE)
-			entry->type = E820_RAM;
+	for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) {
+		if (entry->type == E820_TYPE_UNUSABLE)
+			entry->type = E820_TYPE_RAM;
 	}
 	}
 }
 }
 
 
 bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 {
 {
-	struct e820entry *entry;
+	struct e820_entry *entry;
 	unsigned mapcnt;
 	unsigned mapcnt;
 	phys_addr_t end;
 	phys_addr_t end;
 
 
@@ -620,10 +619,10 @@ bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 		return false;
 		return false;
 
 
 	end = start + size;
 	end = start + size;
-	entry = xen_e820_map;
+	entry = xen_e820_table.entries;
 
 
-	for (mapcnt = 0; mapcnt < xen_e820_map_entries; mapcnt++) {
-		if (entry->type == E820_RAM && entry->addr <= start &&
+	for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
+		if (entry->type == E820_TYPE_RAM && entry->addr <= start &&
 		    (entry->addr + entry->size) >= end)
 		    (entry->addr + entry->size) >= end)
 			return false;
 			return false;
 
 
@@ -645,10 +644,10 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size)
 {
 {
 	unsigned mapcnt;
 	unsigned mapcnt;
 	phys_addr_t addr, start;
 	phys_addr_t addr, start;
-	struct e820entry *entry = xen_e820_map;
+	struct e820_entry *entry = xen_e820_table.entries;
 
 
-	for (mapcnt = 0; mapcnt < xen_e820_map_entries; mapcnt++, entry++) {
-		if (entry->type != E820_RAM || entry->size < size)
+	for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++, entry++) {
+		if (entry->type != E820_TYPE_RAM || entry->size < size)
 			continue;
 			continue;
 		start = entry->addr;
 		start = entry->addr;
 		for (addr = start; addr < start + size; addr += PAGE_SIZE) {
 		for (addr = start; addr < start + size; addr += PAGE_SIZE) {
@@ -750,8 +749,8 @@ char * __init xen_memory_setup(void)
 	max_pfn = min(max_pfn, xen_start_info->nr_pages);
 	max_pfn = min(max_pfn, xen_start_info->nr_pages);
 	mem_end = PFN_PHYS(max_pfn);
 	mem_end = PFN_PHYS(max_pfn);
 
 
-	memmap.nr_entries = ARRAY_SIZE(xen_e820_map);
-	set_xen_guest_handle(memmap.buffer, xen_e820_map);
+	memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries);
+	set_xen_guest_handle(memmap.buffer, xen_e820_table.entries);
 
 
 	op = xen_initial_domain() ?
 	op = xen_initial_domain() ?
 		XENMEM_machine_memory_map :
 		XENMEM_machine_memory_map :
@@ -760,16 +759,16 @@ char * __init xen_memory_setup(void)
 	if (rc == -ENOSYS) {
 	if (rc == -ENOSYS) {
 		BUG_ON(xen_initial_domain());
 		BUG_ON(xen_initial_domain());
 		memmap.nr_entries = 1;
 		memmap.nr_entries = 1;
-		xen_e820_map[0].addr = 0ULL;
-		xen_e820_map[0].size = mem_end;
+		xen_e820_table.entries[0].addr = 0ULL;
+		xen_e820_table.entries[0].size = mem_end;
 		/* 8MB slack (to balance backend allocations). */
 		/* 8MB slack (to balance backend allocations). */
-		xen_e820_map[0].size += 8ULL << 20;
-		xen_e820_map[0].type = E820_RAM;
+		xen_e820_table.entries[0].size += 8ULL << 20;
+		xen_e820_table.entries[0].type = E820_TYPE_RAM;
 		rc = 0;
 		rc = 0;
 	}
 	}
 	BUG_ON(rc);
 	BUG_ON(rc);
 	BUG_ON(memmap.nr_entries == 0);
 	BUG_ON(memmap.nr_entries == 0);
-	xen_e820_map_entries = memmap.nr_entries;
+	xen_e820_table.nr_entries = memmap.nr_entries;
 
 
 	/*
 	/*
 	 * Xen won't allow a 1:1 mapping to be created to UNUSABLE
 	 * Xen won't allow a 1:1 mapping to be created to UNUSABLE
@@ -783,8 +782,7 @@ char * __init xen_memory_setup(void)
 		xen_ignore_unusable();
 		xen_ignore_unusable();
 
 
 	/* Make sure the Xen-supplied memory map is well-ordered. */
 	/* Make sure the Xen-supplied memory map is well-ordered. */
-	sanitize_e820_map(xen_e820_map, ARRAY_SIZE(xen_e820_map),
-			  &xen_e820_map_entries);
+	e820__update_table(&xen_e820_table);
 
 
 	max_pages = xen_get_max_pages();
 	max_pages = xen_get_max_pages();
 
 
@@ -811,15 +809,15 @@ char * __init xen_memory_setup(void)
 	extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
 	extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
 			   extra_pages, max_pages - max_pfn);
 			   extra_pages, max_pages - max_pfn);
 	i = 0;
 	i = 0;
-	addr = xen_e820_map[0].addr;
-	size = xen_e820_map[0].size;
-	while (i < xen_e820_map_entries) {
+	addr = xen_e820_table.entries[0].addr;
+	size = xen_e820_table.entries[0].size;
+	while (i < xen_e820_table.nr_entries) {
 		bool discard = false;
 		bool discard = false;
 
 
 		chunk_size = size;
 		chunk_size = size;
-		type = xen_e820_map[i].type;
+		type = xen_e820_table.entries[i].type;
 
 
-		if (type == E820_RAM) {
+		if (type == E820_TYPE_RAM) {
 			if (addr < mem_end) {
 			if (addr < mem_end) {
 				chunk_size = min(size, mem_end - addr);
 				chunk_size = min(size, mem_end - addr);
 			} else if (extra_pages) {
 			} else if (extra_pages) {
@@ -840,9 +838,9 @@ char * __init xen_memory_setup(void)
 		size -= chunk_size;
 		size -= chunk_size;
 		if (size == 0) {
 		if (size == 0) {
 			i++;
 			i++;
-			if (i < xen_e820_map_entries) {
-				addr = xen_e820_map[i].addr;
-				size = xen_e820_map[i].size;
+			if (i < xen_e820_table.nr_entries) {
+				addr = xen_e820_table.entries[i].addr;
+				size = xen_e820_table.entries[i].size;
 			}
 			}
 		}
 		}
 	}
 	}
@@ -858,10 +856,9 @@ char * __init xen_memory_setup(void)
 	 * reserve ISA memory anyway because too many things poke
 	 * reserve ISA memory anyway because too many things poke
 	 * about in there.
 	 * about in there.
 	 */
 	 */
-	e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS,
-			E820_RESERVED);
+	e820__range_add(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_TYPE_RESERVED);
 
 
-	sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map);
+	e820__update_table(e820_table);
 
 
 	/*
 	/*
 	 * Check whether the kernel itself conflicts with the target E820 map.
 	 * Check whether the kernel itself conflicts with the target E820 map.
@@ -914,6 +911,37 @@ char * __init xen_memory_setup(void)
 	return "Xen";
 	return "Xen";
 }
 }
 
 
+/*
+ * Machine specific memory setup for auto-translated guests.
+ */
+char * __init xen_auto_xlated_memory_setup(void)
+{
+	struct xen_memory_map memmap;
+	int i;
+	int rc;
+
+	memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries);
+	set_xen_guest_handle(memmap.buffer, xen_e820_table.entries);
+
+	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
+	if (rc < 0)
+		panic("No memory map (%d)\n", rc);
+
+	xen_e820_table.nr_entries = memmap.nr_entries;
+
+	e820__update_table(&xen_e820_table);
+
+	for (i = 0; i < xen_e820_table.nr_entries; i++)
+		e820__range_add(xen_e820_table.entries[i].addr, xen_e820_table.entries[i].size, xen_e820_table.entries[i].type);
+
+	/* Remove p2m info, it is not needed. */
+	xen_start_info->mfn_list = 0;
+	xen_start_info->first_p2m_pfn = 0;
+	xen_start_info->nr_p2m_frames = 0;
+
+	return "Xen";
+}
+
 /*
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
  * Set the bit indicating "nosegneg" library variants should be used.
  * We only need to bother in pure 32-bit mode; compat 32-bit processes
  * We only need to bother in pure 32-bit mode; compat 32-bit processes
@@ -999,8 +1027,8 @@ void __init xen_pvmmu_arch_setup(void)
 void __init xen_arch_setup(void)
 void __init xen_arch_setup(void)
 {
 {
 	xen_panic_handler_init();
 	xen_panic_handler_init();
-
-	xen_pvmmu_arch_setup();
+	if (!xen_feature(XENFEAT_auto_translated_physmap))
+		xen_pvmmu_arch_setup();
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
 	if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
 	if (!(xen_start_info->flags & SIF_INITDOMAIN)) {

+ 1 - 1
drivers/acpi/tables.c

@@ -540,7 +540,7 @@ void __init acpi_table_upgrade(void)
 	 * But it's not enough on X86 because ioremap will
 	 * But it's not enough on X86 because ioremap will
 	 * complain later (used by acpi_os_map_memory) that the pages
 	 * complain later (used by acpi_os_map_memory) that the pages
 	 * that should get mapped are not marked "reserved".
 	 * that should get mapped are not marked "reserved".
-	 * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
+	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
 	 * works fine.
 	 * works fine.
 	 */
 	 */
 	memblock_reserve(acpi_tables_addr, all_tables_size);
 	memblock_reserve(acpi_tables_addr, all_tables_size);

+ 1 - 1
drivers/char/agp/amd64-agp.c

@@ -14,7 +14,7 @@
 #include <linux/agp_backend.h>
 #include <linux/agp_backend.h>
 #include <linux/mmzone.h>
 #include <linux/mmzone.h>
 #include <asm/page.h>		/* PAGE_SIZE */
 #include <asm/page.h>		/* PAGE_SIZE */
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/amd_nb.h>
 #include <asm/amd_nb.h>
 #include <asm/gart.h>
 #include <asm/gart.h>
 #include "agp.h"
 #include "agp.h"

+ 1 - 0
include/linux/kernel.h

@@ -438,6 +438,7 @@ extern int get_option(char **str, int *pint);
 extern char *get_options(const char *str, int nints, int *ints);
 extern char *get_options(const char *str, int nints, int *ints);
 extern unsigned long long memparse(const char *ptr, char **retptr);
 extern unsigned long long memparse(const char *ptr, char **retptr);
 extern bool parse_option_str(const char *str, const char *option);
 extern bool parse_option_str(const char *str, const char *option);
+extern char *next_arg(char *args, char **param, char **val);
 
 
 extern int core_kernel_text(unsigned long addr);
 extern int core_kernel_text(unsigned long addr);
 extern int core_kernel_data(unsigned long addr);
 extern int core_kernel_data(unsigned long addr);

+ 1 - 1
include/xen/page.h

@@ -38,7 +38,7 @@ struct xen_memory_region {
 	unsigned long n_pfns;
 	unsigned long n_pfns;
 };
 };
 
 
-#define XEN_EXTRA_MEM_MAX_REGIONS 128 /* == E820MAX */
+#define XEN_EXTRA_MEM_MAX_REGIONS 128 /* == E820_MAX_ENTRIES_ZEROPAGE */
 
 
 extern __initdata
 extern __initdata
 struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS];
 struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS];

+ 0 - 52
kernel/params.c

@@ -160,58 +160,6 @@ static int parse_one(char *param,
 	return -ENOENT;
 	return -ENOENT;
 }
 }
 
 
-/* You can use " around spaces, but can't escape ". */
-/* Hyphens and underscores equivalent in parameter names. */
-static char *next_arg(char *args, char **param, char **val)
-{
-	unsigned int i, equals = 0;
-	int in_quote = 0, quoted = 0;
-	char *next;
-
-	if (*args == '"') {
-		args++;
-		in_quote = 1;
-		quoted = 1;
-	}
-
-	for (i = 0; args[i]; i++) {
-		if (isspace(args[i]) && !in_quote)
-			break;
-		if (equals == 0) {
-			if (args[i] == '=')
-				equals = i;
-		}
-		if (args[i] == '"')
-			in_quote = !in_quote;
-	}
-
-	*param = args;
-	if (!equals)
-		*val = NULL;
-	else {
-		args[equals] = '\0';
-		*val = args + equals + 1;
-
-		/* Don't include quotes in value. */
-		if (**val == '"') {
-			(*val)++;
-			if (args[i-1] == '"')
-				args[i-1] = '\0';
-		}
-	}
-	if (quoted && args[i-1] == '"')
-		args[i-1] = '\0';
-
-	if (args[i]) {
-		args[i] = '\0';
-		next = args + i + 1;
-	} else
-		next = args + i;
-
-	/* Chew up trailing spaces. */
-	return skip_spaces(next);
-}
-
 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
 char *parse_args(const char *doing,
 char *parse_args(const char *doing,
 		 char *args,
 		 char *args,

+ 57 - 0
lib/cmdline.c

@@ -15,6 +15,7 @@
 #include <linux/export.h>
 #include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/string.h>
+#include <linux/ctype.h>
 
 
 /*
 /*
  *	If a hyphen was found in get_option, this will handle the
  *	If a hyphen was found in get_option, this will handle the
@@ -189,3 +190,59 @@ bool parse_option_str(const char *str, const char *option)
 
 
 	return false;
 	return false;
 }
 }
+
+/*
+ * Parse a string to get a param value pair.
+ * You can use " around spaces, but can't escape ".
+ * Hyphens and underscores equivalent in parameter names.
+ */
+char *next_arg(char *args, char **param, char **val)
+{
+	unsigned int i, equals = 0;
+	int in_quote = 0, quoted = 0;
+	char *next;
+
+	if (*args == '"') {
+		args++;
+		in_quote = 1;
+		quoted = 1;
+	}
+
+	for (i = 0; args[i]; i++) {
+		if (isspace(args[i]) && !in_quote)
+			break;
+		if (equals == 0) {
+			if (args[i] == '=')
+				equals = i;
+		}
+		if (args[i] == '"')
+			in_quote = !in_quote;
+	}
+
+	*param = args;
+	if (!equals)
+		*val = NULL;
+	else {
+		args[equals] = '\0';
+		*val = args + equals + 1;
+
+		/* Don't include quotes in value. */
+		if (**val == '"') {
+			(*val)++;
+			if (args[i-1] == '"')
+				args[i-1] = '\0';
+		}
+	}
+	if (quoted && args[i-1] == '"')
+		args[i-1] = '\0';
+
+	if (args[i]) {
+		args[i] = '\0';
+		next = args + i + 1;
+	} else
+		next = args + i;
+
+	/* Chew up trailing spaces. */
+	return skip_spaces(next);
+	//return next;
+}

+ 1 - 1
tools/lguest/lguest.c

@@ -3339,7 +3339,7 @@ int main(int argc, char *argv[])
 	 * simple, single region.
 	 * simple, single region.
 	 */
 	 */
 	boot->e820_entries = 1;
 	boot->e820_entries = 1;
-	boot->e820_map[0] = ((struct e820entry) { 0, mem, E820_RAM });
+	boot->e820_table[0] = ((struct e820_entry) { 0, mem, E820_TYPE_RAM });
 	/*
 	/*
 	 * The boot header contains a command line pointer: we put the command
 	 * The boot header contains a command line pointer: we put the command
 	 * line after the boot header.
 	 * line after the boot header.