]> git.ipfire.org Git - people/arne_f/kernel.git/commitdiff
Merge branch 'WIP.x86/boot' into x86/boot, to pick up ready branch
authorIngo Molnar <mingo@kernel.org>
Tue, 11 Apr 2017 06:49:31 +0000 (08:49 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 11 Apr 2017 06:49:31 +0000 (08:49 +0200)
The E820 rework in WIP.x86/boot has gone through a couple of weeks
of exposure in -tip, merge it in a wider fashion.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
66 files changed:
Documentation/x86/zero-page.txt
arch/x86/boot/compressed/eboot.c
arch/x86/boot/compressed/kaslr.c
arch/x86/boot/header.S
arch/x86/boot/memory.c
arch/x86/include/asm/acpi.h
arch/x86/include/asm/e820.h [deleted file]
arch/x86/include/asm/e820/api.h [new file with mode: 0644]
arch/x86/include/asm/e820/types.h [new file with mode: 0644]
arch/x86/include/asm/gart.h
arch/x86/include/asm/mpspec.h
arch/x86/include/asm/pci_x86.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/xen/page.h
arch/x86/include/uapi/asm/bootparam.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/apic_noop.c
arch/x86/kernel/apic/probe_32.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/centaur.c
arch/x86/kernel/cpu/mtrr/cleanup.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/crash.c
arch/x86/kernel/e820.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/head32.c
arch/x86/kernel/head64.c
arch/x86/kernel/kexec-bzimage64.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/probe_roms.c
arch/x86/kernel/resource.c
arch/x86/kernel/setup.c
arch/x86/kernel/tboot.c
arch/x86/kernel/x86_init.c
arch/x86/lguest/boot.c
arch/x86/lib/kaslr.c
arch/x86/mm/amdtopology.c
arch/x86/mm/init.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/kasan_init_64.c
arch/x86/mm/mmio-mod.c
arch/x86/mm/numa.c
arch/x86/mm/pageattr.c
arch/x86/mm/pat.c
arch/x86/mm/pgtable_32.c
arch/x86/mm/srat.c
arch/x86/pci/i386.c
arch/x86/pci/mmconfig-shared.c
arch/x86/pci/mmconfig_32.c
arch/x86/pci/mmconfig_64.c
arch/x86/pci/pcbios.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/efi/quirks.c
arch/x86/power/hibernate_64.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/setup.c
drivers/acpi/tables.c
drivers/char/agp/amd64-agp.c
include/xen/page.h
tools/lguest/lguest.c

index b8527c6b76461c7ee9446630c5acb4cc65867671..97b7adbceda4828ab217301a305a3b20892d0603 100644 (file)
@@ -27,7 +27,7 @@ Offset        Proto   Name            Meaning
 1C0/020        ALL     efi_info        EFI 32 information (struct efi_info)
 1E0/004        ALL     alk_mem_k       Alternative mem check, in KB
 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)
 1EA/001        ALL     edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
                                (below)
@@ -35,6 +35,6 @@ Offset        Proto   Name            Meaning
 1EC/001        ALL     secure_boot     Secure boot is enabled in the firmware
 1EF/001        ALL     sentinel        Used to detect broken bootloaders
 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)
index 801c7a158e55938a830e709578be069f3b649c19..cbf4b87f55b9e9da244754d343401b5374dd49d1 100644 (file)
@@ -9,7 +9,9 @@
 
 #include <linux/efi.h>
 #include <linux/pci.h>
+
 #include <asm/efi.h>
+#include <asm/e820/types.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
 
@@ -729,7 +731,7 @@ static void add_e820ext(struct boot_params *params,
        unsigned long size;
 
        e820ext->type = SETUP_E820_EXT;
-       e820ext->len = nr_entries * sizeof(struct e820entry);
+       e820ext->len = nr_entries * sizeof(struct boot_e820_entry);
        e820ext->next = 0;
 
        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,
                               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 e820entry *prev = NULL;
+       struct boot_e820_entry *prev = NULL;
        u32 nr_entries;
        u32 nr_desc;
        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_PORT_SPACE:
                case EFI_PAL_CODE:
-                       e820_type = E820_RESERVED;
+                       e820_type = E820_TYPE_RESERVED;
                        break;
 
                case EFI_UNUSABLE_MEMORY:
-                       e820_type = E820_UNUSABLE;
+                       e820_type = E820_TYPE_UNUSABLE;
                        break;
 
                case EFI_ACPI_RECLAIM_MEMORY:
-                       e820_type = E820_ACPI;
+                       e820_type = E820_TYPE_ACPI;
                        break;
 
                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_DATA:
                case EFI_CONVENTIONAL_MEMORY:
-                       e820_type = E820_RAM;
+                       e820_type = E820_TYPE_RAM;
                        break;
 
                case EFI_ACPI_MEMORY_NVS:
-                       e820_type = E820_NVS;
+                       e820_type = E820_TYPE_NVS;
                        break;
 
                case EFI_PERSISTENT_MEMORY:
-                       e820_type = E820_PMEM;
+                       e820_type = E820_TYPE_PMEM;
                        break;
 
                default:
@@ -811,26 +813,26 @@ static efi_status_t setup_e820(struct boot_params *params,
                        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);
 
                        if (!e820ext || e820ext_size < need)
                                return EFI_BUFFER_TOO_SMALL;
 
                        /* 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++;
        }
 
-       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);
                nr_entries -= nr_e820ext;
@@ -848,7 +850,7 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
        unsigned long size;
 
        size = sizeof(struct setup_data) +
-               sizeof(struct e820entry) * nr_desc;
+               sizeof(struct e820_entry) * nr_desc;
 
        if (*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) {
                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 -
-                                       ARRAY_SIZE(p->boot_params->e820_map);
+                                       ARRAY_SIZE(p->boot_params->e820_table);
 
                        status = alloc_e820ext(nr_e820ext, &p->e820ext,
                                               &p->e820ext_size);
index 8b7c9e75edcbf5a397c968d441a34369553f7870..6d9a546ec7ae1d75dbcbf3dbd0d6891c2675b0f8 100644 (file)
@@ -426,7 +426,7 @@ static unsigned long slots_fetch_random(void)
        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 image_size)
 {
@@ -435,7 +435,7 @@ static void process_e820_entry(struct e820entry *entry,
        unsigned long start_orig;
 
        /* Skip non-RAM entries. */
-       if (entry->type != E820_RAM)
+       if (entry->type != E820_TYPE_RAM)
                return;
 
        /* 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. */
        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);
                if (slot_area_index == MAX_SLOT_AREA) {
                        debug_putstr("Aborted e820 scan (slot_areas full)!\n");
index 3dd5be33aaa7b091fce5c21c3c8105cbbef5f707..2ed8f0c25def4b01dd50107425c5b6e54d60f2eb 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/segment.h>
 #include <generated/utsrelease.h>
 #include <asm/boot.h>
-#include <asm/e820.h>
 #include <asm/page_types.h>
 #include <asm/setup.h>
 #include <asm/bootparam.h>
index db75d07c3645c0375090596ae29d1085f0f8a38a..d9c28c87e4771ffadf68091800b50142417389ba 100644 (file)
@@ -21,8 +21,8 @@ static int detect_memory_e820(void)
 {
        int count = 0;
        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);
        ireg.ax  = 0xe820;
@@ -66,7 +66,7 @@ static int detect_memory_e820(void)
 
                *desc++ = buf;
                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;
 }
index 395b69551fce8172ab1938ab730eee034154c638..2efc768e43627a48118d28729c380c0fbcaa7681 100644 (file)
@@ -52,6 +52,8 @@ extern u8 acpi_sci_flags;
 extern int acpi_sci_override_gsi;
 void acpi_pic_sci_set_trigger(unsigned int, u16);
 
+struct device;
+
 extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
                                  int trigger, int polarity);
 extern void (*__acpi_unregister_gsi)(u32 gsi);
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
deleted file mode 100644 (file)
index 67313f3..0000000
+++ /dev/null
@@ -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 */
diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/api.h
new file mode 100644 (file)
index 0000000..8e0f8b8
--- /dev/null
@@ -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 */
diff --git a/arch/x86/include/asm/e820/types.h b/arch/x86/include/asm/e820/types.h
new file mode 100644 (file)
index 0000000..4adeed0
--- /dev/null
@@ -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 */
index 156cd5d18d2abeabb26a0587cfffd15c52aa6f13..1d268098ac2ec54fd6a1da226ae057282a8eb3cf 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _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);
 
@@ -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");
                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");
                return 0;
        }
index 32007041ef8c14d5ad90b914dbccb4cbf40ba034..831eb78955352bcded4422a8584d7becaf6ba15c 100644 (file)
@@ -64,7 +64,7 @@ static inline void find_smp_config(void)
 }
 
 #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 default_mpc_apic_id(struct mpc_cpu *m);
 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_get_smp_config(unsigned int early);
 #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 default_mpc_apic_id NULL
 #define default_smp_read_mpc_oem NULL
index d08eacd298c2f4b2436b9841203dd5c90f295697..9f1b21f372fedbb24328a887f44550a49f242ef3 100644 (file)
@@ -4,6 +4,8 @@
  *     (c) 1999 Martin Mares <mj@ucw.cz>
  */
 
+#include <linux/ioport.h>
+
 #undef DEBUG
 
 #ifdef DEBUG
index 1cfb36b8c024ab07b8334121fc56ac79f2a35371..eef5fbc7c67437ae40f5a8788069e3e9c3361813 100644 (file)
@@ -2,8 +2,6 @@
 #define _ASM_X86_PGTABLE_H
 
 #include <asm/page.h>
-#include <asm/e820.h>
-
 #include <asm/pgtable_types.h>
 
 /*
@@ -845,6 +843,7 @@ static inline int pgd_none(pgd_t pgd)
 extern int direct_gbpages;
 void init_mem_mapping(void);
 void early_alloc_pgt_buf(void);
+extern void memblock_find_dma_reserve(void);
 
 #ifdef CONFIG_X86_64
 /* Realmode trampoline initialization. */
index 33cbd3db97b93d4449d29dfd1a79e1875ebfb1dc..64c5e745ebadb90425e50bea5ce16e34ebf68f03 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/pfn.h>
 #include <linux/mm.h>
+#include <linux/device.h>
 
 #include <linux/uaccess.h>
 #include <asm/page.h>
index 5138dacf8bb8360511f7b3514f8ab0ac1a1e88f8..41af92e473cfe8bd50f6352178dc1966893f3363 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/screen_info.h>
 #include <linux/apm_bios.h>
 #include <linux/edd.h>
-#include <asm/e820.h>
 #include <asm/ist.h>
 #include <video/edid.h>
 
@@ -111,6 +110,21 @@ struct efi_info {
        __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" */
 struct boot_params {
        struct screen_info screen_info;                 /* 0x000 */
@@ -153,7 +167,7 @@ struct boot_params {
        struct setup_header hdr;    /* setup header */  /* 0x1f1 */
        __u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
        __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 */
        struct edd_info eddbuf[EDDMAXNR];               /* 0xd00 */
        __u8  _pad9[276];                               /* 0xeec */
index ae32838cac5fd2251e1ffa0bbb8b8c629e399a84..a468f0fdc9075bbdc04d75f5105620c97d0ddf48 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/pci.h>
 #include <linux/efi-bgrt.h>
 
+#include <asm/e820/api.h>
 #include <asm/irqdomain.h>
 #include <asm/pci_x86.h>
 #include <asm/pgtable.h>
@@ -1724,6 +1725,6 @@ int __acpi_release_global_lock(unsigned int *lock)
 
 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();
 }
index 0a2bb1f62e724d5820632eb59bbdaea18acdc659..ef2859f9fccefca9cc48b22410b51c88c0e29ca2 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 #include <linux/bitops.h>
 #include <linux/suspend.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/io.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
@@ -306,13 +306,13 @@ void __init early_gart_iommu_check(void)
                fix = 1;
 
        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 */
                        pr_info("e820: reserve [mem %#010Lx-%#010Lx] for GART\n",
                                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();
                }
        }
 
index 4261b3282ad99dd87799683e33b2945bcfb20746..4eca103a1e01d3473e57413530a08b0d64fe5b3a 100644 (file)
@@ -2648,7 +2648,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
  */
 late_initcall(lapic_insert_resource);
index b109e4389c928d2efcc2df0b83df3c4b7872fe28..2262eb6df796df01aaa4c5c2cf932c0c01547555 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <linux/interrupt.h>
 #include <asm/acpi.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 static void noop_init_apic_ldr(void) { }
 static void noop_send_IPI(int cpu, int vector) { }
index c48264e202fd17ab87043db486f06fc069617f8b..2e8f7f048f4f38fbb4134192cb4cd28aef269281 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <linux/interrupt.h>
 #include <asm/acpi.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 #ifdef CONFIG_HOTPLUG_CPU
 #define DEFAULT_SEND_IPI       (1)
index e9f8f8cdd57085db85dee8247b67150250308a42..7f179f1c467cba9fd12125b6161689d58f7f50d6 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/uv/bios.h>
 #include <asm/uv/uv.h>
 #include <asm/apic.h>
+#include <asm/e820/api.h>
 #include <asm/ipi.h>
 #include <asm/smp.h>
 #include <asm/x86_init.h>
index adc0ebd8bed0e17be1716f3fb7c3eab51b7fa0c4..106bd3318121ae8a57758b1e4ca57606a6d87e93 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/sched/clock.h>
 
 #include <asm/cpufeature.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 
index 3b442b64c72de95152cfdfdc4ea2d6e9cb0a52fe..765afd5990398c9ef687d1cfe8b3b97b6fc46335 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/range.h>
 
 #include <asm/processor.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.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 -= 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);
 
                pr_info("update e820 for mtrr\n");
-               update_e820();
+               e820__update_table_print();
 
                return 1;
        }
index 24e87e74990df40d6ed8d18dbb51439e7dd4286a..2bce84d91c2b6adba00a678a683843b2e47b485a 100644 (file)
@@ -48,7 +48,7 @@
 #include <linux/syscore_ops.h>
 
 #include <asm/cpufeature.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 #include <asm/pat.h>
index 3741461c63a0cfc56cbc8cf88e3011260ba82018..22217ece26c8807a2747d8396a171c7a6b952842 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/nmi.h>
 #include <asm/hw_irq.h>
 #include <asm/apic.h>
+#include <asm/e820/types.h>
 #include <asm/io_apic.h>
 #include <asm/hpet.h>
 #include <linux/kdebug.h>
@@ -503,16 +504,16 @@ static int prepare_elf_headers(struct kimage *image, void **addr,
        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;
 
        nr_e820_entries = params->e820_entries;
-       if (nr_e820_entries >= E820MAX)
+       if (nr_e820_entries >= E820_MAX_ENTRIES_ZEROPAGE)
                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++;
        return 0;
 }
@@ -521,7 +522,7 @@ static int memmap_entry_callback(u64 start, u64 end, void *arg)
 {
        struct crash_memmap_data *cmd = arg;
        struct boot_params *params = cmd->params;
-       struct e820entry ei;
+       struct e820_entry ei;
 
        ei.addr = start;
        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;
        unsigned long flags;
-       struct e820entry ei;
+       struct e820_entry ei;
        struct crash_memmap_data cmd;
        struct crash_mem *cmem;
 
@@ -574,17 +575,17 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
        /* Add first 640K segment */
        ei.addr = image->arch.backup_src_start;
        ei.size = image->arch.backup_src_sz;
-       ei.type = E820_RAM;
+       ei.type = E820_TYPE_RAM;
        add_e820_entry(params, &ei);
 
        /* Add ACPI tables */
-       cmd.type = E820_ACPI;
+       cmd.type = E820_TYPE_ACPI;
        flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, &cmd,
                       memmap_entry_callback);
 
        /* 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,
                        memmap_entry_callback);
 
@@ -592,7 +593,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
        if (crashk_low_res.end) {
                ei.addr = crashk_low_res.start;
                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);
        }
 
@@ -609,7 +610,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
                if (ei.size < PAGE_SIZE)
                        continue;
                ei.addr = cmem->ranges[i].start;
-               ei.type = E820_RAM;
+               ei.type = E820_TYPE_RAM;
                add_e820_entry(params, &ei);
        }
 
index b2bbad6ebe4d8c5c822965134ea1daf4a6fe8adc..6e9b26fa6d05767784858f8dae821f4c89c31480 100644 (file)
@@ -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/export.h>
 #include <linux/bootmem.h>
-#include <linux/pfn.h>
 #include <linux/suspend.h>
 #include <linux/acpi.h>
 #include <linux/firmware-map.h>
 #include <linux/memblock.h>
 #include <linux/sort.h>
 
-#include <asm/e820.h>
-#include <asm/proto.h>
+#include <asm/e820/api.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 */
 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
  * 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;
 
-       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;
-               if (ei->addr >= end || ei->addr + ei->size <= start)
+               if (entry->addr >= end || entry->addr + entry->size <= start)
                        continue;
                return 1;
        }
        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;
 
-       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;
-               /* 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;
 
-               /* 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)
                        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;
        }
 
-       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) {
-       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;
 
-       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
  * 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
  * 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
@@ -238,10 +229,17 @@ void __init e820_print_map(char *who)
  *        ______________________4_
  */
 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)
 {
        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
-        * 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
         * to be greater than one that does not.
         */
        if (ap->addr != bp->addr)
                return ap->addr > bp->addr ? 1 : -1;
 
-       return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
+       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;
-       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;
 
-       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;
+       }
 
-       /* 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];
 
-       /* 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 {
-                       /*
-                        * 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++) {
-                               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--;
                }
                /*
-                * if there are overlapping entries, decide which
+                * If there are overlapping entries, decide which
                 * "type" to use (larger value takes precedence --
                 * 1=usable, 2,3,4,4+=unusable)
                 */
                current_type = 0;
-               for (i = 0; i < overlap_entries; i++)
+               for (i = 0; i < overlap_entries; i++) {
                        if (overlap_list[i]->type > current_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)      {
-                               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;
                        }
                        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;
                }
        }
-       /* 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;
 }
 
-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;
-               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))
                        return -1;
 
-               e820_add_region(start, size, type);
+               e820__range_add(start, size, type);
 
-               biosmap++;
-               nr_map--;
+               entry++;
+               nr_entries--;
        }
        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..
  *
@@ -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
  * 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 */
-       if (nr_map < 2)
+       if (nr_entries < 2)
                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;
        unsigned int i;
@@ -437,77 +411,73 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
                size = ULLONG_MAX - start;
 
        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);
-       printk(KERN_CONT " ==> ");
+       pr_cont(" ==> ");
        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 ei_end;
+               u64 entry_end;
 
-               if (ei->type != old_type)
+               if (entry->type != old_type)
                        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;
                }
 
-               /* 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;
                        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)
                        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;
 
                /*
-                * 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;
-               ei->addr = final_end;
+
+               entry->addr = final_end;
        }
        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;
        u64 end;
@@ -517,85 +487,89 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
                size = ULLONG_MAX - start;
 
        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);
-       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 ei_end;
+               u64 entry_end;
 
-               if (checktype && ei->type != old_type)
+               if (check_type && entry->type != old_type)
                        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;
                }
 
-               /* 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;
                        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)
                        continue;
+
                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;
-               ei->addr = final_end;
+
+               entry->addr = final_end;
        }
        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;
-       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
+
 /*
- * 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;
-       int i = e820->nr_map;
+       int i = e820_table->nr_entries;
        int found = 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
-                * fit in 32 bits if this condition is true
+                * fit in 32 bits if this condition is true:
                 */
                if (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.
  */
-__init void e820_setup_gap(void)
+__init void e820__setup_pci_gap(void)
 {
        unsigned long gapstart, gapsize;
        int found;
@@ -629,138 +605,143 @@ __init void e820_setup_gap(void)
        if (!found) {
 #ifdef CONFIG_X86_64
                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
                gapstart = 0x10000000;
 #endif
        }
 
        /*
-        * e820_reserve_resources_late protect stolen RAM already
+        * e820__reserve_resources_late() protects stolen RAM already:
         */
        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().
  *
- * 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;
 
-       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);
        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);
        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;
-       struct e820entry *extmap;
+       struct boot_e820_entry *extmap;
        struct setup_data *sdata;
 
        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);
-       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
- * 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.
  */
-void __init e820_mark_nosave_regions(unsigned long limit_pfn)
+void __init e820__register_nosave_regions(unsigned long limit_pfn)
 {
        int i;
        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)
                        break;
        }
 }
-#endif
 
 #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;
 
-       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;
 }
-core_initcall(e820_mark_nvs_memory);
+core_initcall(e820__register_nvs_regions);
 #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;
 
        addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
        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;
@@ -779,22 +760,22 @@ u64 __init early_reserve_e820(u64 size, u64 align)
 /*
  * 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;
        unsigned long last_pfn = 0;
        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 end_pfn;
 
-               if (ei->type != type)
+               if (entry->type != type)
                        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)
                        continue;
@@ -809,18 +790,19 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
        if (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);
        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)
@@ -831,7 +813,7 @@ static void __init early_panic(char *msg)
 
 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)
 {
        u64 mem_size;
@@ -844,17 +826,19 @@ static int __init parse_memopt(char *p)
                setup_clear_cpu_cap(X86_FEATURE_PSE);
                return 0;
 #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;
 #endif
        }
 
        userdef = 1;
        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)
                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;
 }
@@ -872,12 +856,12 @@ static int __init parse_memmap_one(char *p)
 #ifdef CONFIG_CRASH_DUMP
                /*
                 * 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.
                 */
-               saved_max_pfn = e820_end_of_ram_pfn();
+               saved_max_pfn = e820__end_of_ram_pfn();
 #endif
-               e820->nr_map = 0;
+               e820_table->nr_entries = 0;
                userdef = 1;
                return 0;
        }
@@ -890,21 +874,23 @@ static int __init parse_memmap_one(char *p)
        userdef = 1;
        if (*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 == '#') {
                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 == '$') {
                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 == '!') {
                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;
 }
+
 static int __init parse_memmap_opt(char *str)
 {
        while (str) {
@@ -921,68 +907,97 @@ static int __init parse_memmap_opt(char *str)
 }
 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 (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");
 
-               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 */
        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
         */
        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;
+       case E820_TYPE_RESERVED_KERN:
+       case E820_TYPE_RAM:
+       case E820_TYPE_ACPI:
+       case E820_TYPE_NVS:
+       case E820_TYPE_UNUSABLE:
        default:
                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;
-void __init e820_reserve_resources(void)
+
+void __init e820__reserve_resources(void)
 {
        int i;
        struct resource *res;
        u64 end;
 
-       res = alloc_bootmem(sizeof(struct resource) * e820->nr_map);
+       res = alloc_bootmem(sizeof(*res) * e820_table->nr_entries);
        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) {
                        res++;
                        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;
                        insert_resource(&iomem_resource, 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)
 {
        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)
 
-void __init e820_reserve_resources_late(void)
+void __init e820__reserve_resources_late(void)
 {
        int i;
        struct resource *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)
                        insert_resource_expand_to_fit(&iomem_resource, 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:
         */
-       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;
 
-               if (entry->type != E820_RAM)
+               if (entry->type != E820_TYPE_RAM)
                        continue;
+
                start = entry->addr + entry->size;
                end = round_up(start, ram_alignment(start)) - 1;
                if (end > MAX_RESOURCE_SIZE)
                        end = MAX_RESOURCE_SIZE;
                if (start >= end)
                        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";
-       u32 new_nr;
+
        /*
         * Try to copy the BIOS-supplied E820-map.
         *
         * Otherwise fake a memory map; one section from 0k->640k,
         * 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;
 
-               /* 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;
                        who = "BIOS-88";
                } else {
@@ -1131,84 +1151,68 @@ char *__init default_machine_specific_memory_setup(void)
                        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;
 }
 
-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;
 
+       /* 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();
-       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;
        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();
 
-       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)
                        continue;
 
-               if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
+               if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
                        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_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
-}
index 6a08e25a48d8dc46ee01efc809fe7a4f6ff3db2d..ff7e4b3988ed9da3f3f6e26d3c31708a4fe936ef 100644 (file)
@@ -546,8 +546,8 @@ intel_graphics_stolen(int num, int slot, int func,
               &base, &end);
 
        /* 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)
index e5fb436a6548a9111f95ce3afacf787f5bec278c..538ec012b3717c6c73f2deb45423322cecc649d5 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <asm/setup.h>
 #include <asm/sections.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/page.h>
 #include <asm/apic.h>
 #include <asm/io_apic.h>
index 54a2372f5dbb1eb0598788e944ad28708b638671..baa0e7b78d80f7d803400642d0eabce82f25ccf5 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
 #include <asm/kdebug.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/bios_ebda.h>
 #include <asm/bootparam_utils.h>
 #include <asm/microcode.h>
index d0a814a9d96ac5412b1216060169d53a69133aea..9d7fd5e6689acb1a1bfeb9b8afd6255dc613b05a 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/setup.h>
 #include <asm/crash.h>
 #include <asm/efi.h>
+#include <asm/e820/api.h>
 #include <asm/kexec-bzimage64.h>
 
 #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;
 
-       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;
-       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;
 }
@@ -232,10 +232,10 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
        nr_e820_entries = params->e820_entries;
 
        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;
-               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) {
                        mem_k = (end >> 10) - (0x100000 >> 10);
index 0f8d204973838071d5ce936a97b7f5a0b524055e..0d904d759ff1d42c97e57a7ef5e126bd961b8b03 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/io_apic.h>
 #include <asm/proto.h>
 #include <asm/bios_ebda.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/setup.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);
 
-void __init early_reserve_e820_mpc_new(void)
+void __init e820__memblock_alloc_reserved_mpc_new(void)
 {
        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)
index d5f15c3f7b25e11996bcaf41826d46fc4645bc8f..963e3fb564377d1c9aca9cab11cdcb2b78e9b20f 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <asm/probe_roms.h>
 #include <asm/pci-direct.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mmzone.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
index 2408c1603438ca360a72c0fe6434427d1295beb4..5ab3895516ac14966a80d53f3e331c576db8c463 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/ioport.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 
 static void resource_clip(struct resource *res, resource_size_t start,
                          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)
 {
        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,
                              entry->addr + entry->size - 1);
index 4bf0c8926a1c061bb22c1973962a0d668bfa3d98..cab13f75908b63e43d8bb139441d6c8ca01a18ae 100644 (file)
@@ -75,7 +75,7 @@
 #include <asm/mtrr.h>
 #include <asm/apic.h>
 #include <asm/realmode.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
 #include <asm/efi.h>
  * max_low_pfn_mapped: highest direct mapped pfn under 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
  */
 unsigned long max_low_pfn_mapped;
@@ -426,7 +426,7 @@ static void __init parse_setup_data(void)
 
                switch (data_type) {
                case SETUP_E820_EXT:
-                       parse_e820_ext(pa_data, data_len);
+                       e820__memory_setup_extended(pa_data, data_len);
                        break;
                case SETUP_DTB:
                        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)
 {
        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
         * 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
         * area (640->1Mb) as ram even though it is not.
         * 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 */
@@ -775,18 +752,18 @@ static void __init e820_add_kernel_range(void)
        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,
         * 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,
         * 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;
 
-       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;
@@ -939,7 +916,7 @@ void __init setup_arch(char **cmdline_p)
        x86_init.oem.arch_setup();
 
        iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
-       setup_memory_map();
+       e820__memory_setup();
        parse_setup_data();
 
        copy_edd();
@@ -1028,9 +1005,8 @@ void __init setup_arch(char **cmdline_p)
                early_dump_pci_devices();
 #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))
                efi_init();
@@ -1056,11 +1032,11 @@ void __init setup_arch(char **cmdline_p)
        trim_bios_range();
 #ifdef CONFIG_X86_32
        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");
-               e820_print_map("bad_ppro");
+               e820__print_table("bad_ppro");
        }
 #else
        early_gart_iommu_check();
@@ -1070,12 +1046,12 @@ void __init setup_arch(char **cmdline_p)
         * partially used pages are not usable - thus
         * 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 */
        mtrr_bp_init();
        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;
 
@@ -1094,7 +1070,7 @@ void __init setup_arch(char **cmdline_p)
        /* How many end-of-memory variables you have, grandma! */
        /* need this before calling reserve_initrd */
        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
                max_low_pfn = max_pfn;
 
@@ -1111,7 +1087,7 @@ void __init setup_arch(char **cmdline_p)
        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
         *  brk area.
         */
@@ -1120,7 +1096,7 @@ void __init setup_arch(char **cmdline_p)
        cleanup_highmap();
 
        memblock_set_current_limit(ISA_END_ADDRESS);
-       memblock_x86_fill();
+       e820__memblock_setup();
 
        reserve_bios_regions();
 
@@ -1137,7 +1113,7 @@ void __init setup_arch(char **cmdline_p)
        }
 
        /* preallocate 4k for mptable mpc */
-       early_reserve_e820_mpc_new();
+       e820__memblock_alloc_reserved_mpc_new();
 
 #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
        setup_bios_corruption_check();
@@ -1275,12 +1251,12 @@ void __init setup_arch(char **cmdline_p)
 
        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();
 
-       e820_setup_gap();
+       e820__setup_pci_gap();
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
index b868fa1b812b3a82713e0556c39900bced73f338..ccccd335ae01223810440250f48b3faeafe2c4bb 100644 (file)
@@ -42,7 +42,7 @@
 #include <asm/fixmap.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/io.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
         * 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;
        }
 
@@ -188,12 +188,12 @@ static int tboot_setup_sleep(void)
 
        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;
 
-               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 =
index 11a93f005268b731de6fea9d8fa42775f46f1c2a..a088b2c47f7396dbfa9bd070ebc8f3c544a33d07 100644 (file)
@@ -14,7 +14,7 @@
 #include <asm/mpspec.h>
 #include <asm/setup.h>
 #include <asm/apic.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/time.h>
 #include <asm/irq.h>
 #include <asm/io_apic.h>
@@ -38,7 +38,7 @@ struct x86_init_ops x86_init __initdata = {
        .resources = {
                .probe_roms             = probe_roms,
                .reserve_resources      = reserve_standard_io_resources,
-               .memory_setup           = default_machine_specific_memory_setup,
+               .memory_setup           = e820__memory_setup_default,
        },
 
        .mpparse = {
index d3289d7e78fac8ac98a40e3b62b9dcd406402910..7aa6336862951a9529a9a33e9acebdf73e7f68b7 100644 (file)
@@ -67,7 +67,7 @@
 #include <asm/pgtable.h>
 #include <asm/desc.h>
 #include <asm/setup.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mce.h>
 #include <asm/io.h>
 #include <asm/fpu/api.h>
@@ -1178,9 +1178,9 @@ static __init char *lguest_memory_setup(void)
         * The Linux bootloader header contains an "e820" memory map: the
         * 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. */
        return "LGUEST";
index 121f59c6ee54e0159aab44889274f3bdf0b1041a..5761a4f19455cd1a7a3d6678857c8aef2277a353 100644 (file)
@@ -8,7 +8,7 @@
 #include <asm/kaslr.h>
 #include <asm/msr.h>
 #include <asm/archrandom.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/io.h>
 
 /*
index d1c7de0958086f6ca3901fccf179fbd9873aac44..91f501b2da3bb2d8d2fe4a24b2b83e8bb6d7c3e4 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/types.h>
 #include <asm/mmzone.h>
 #include <asm/proto.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci-direct.h>
 #include <asm/numa.h>
 #include <asm/mpspec.h>
index 22af912d66d258f413414c7355ac82da2814b074..2193799ca800982ad9713fd03ba70fc86fce3d9a 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/bootmem.h>     /* for max_low_pfn */
 
 #include <asm/cacheflush.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/init.h>
 #include <asm/page.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;
 }
 
-struct range pfn_mapped[E820_X_MAX];
+struct range pfn_mapped[E820_MAX_ENTRIES];
 int nr_pfn_mapped;
 
 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 = 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);
 
@@ -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
- * 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
  * [4GB to max_pfn) because of possible memory holes in high addresses
  * that cannot be marked as UC by fixed/variable range MTRRs.
@@ -701,7 +701,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
 
 void __ref free_initmem(void)
 {
-       e820_reallocate_tables();
+       e820__reallocate_tables();
 
        free_init_pages("unused kernel",
                        (unsigned long)(&__init_begin),
@@ -724,6 +724,53 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
 }
 #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)
 {
        unsigned long max_zone_pfns[MAX_NR_ZONES];
index 2b4b53e6793f16b24d2e96199166c724d068f339..1fa97c941abe1cba99bac48ee27f8f4b242a56d4 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/pgtable.h>
 #include <asm/dma.h>
 #include <asm/fixmap.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/apic.h>
 #include <asm/bugs.h>
 #include <asm/tlb.h>
index 15173d37f399610caf8969fa942b17b175dd466b..f6da869810a805ecc3cc975684737b100a34e647 100644 (file)
@@ -41,7 +41,7 @@
 #include <asm/pgalloc.h>
 #include <asm/dma.h>
 #include <asm/fixmap.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/apic.h>
 #include <asm/tlb.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;
                if (paddr >= paddr_end) {
                        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));
                        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;
                if (paddr >= paddr_end) {
                        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));
                        continue;
                }
@@ -478,10 +478,10 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end,
 
                if (paddr >= paddr_end) {
                        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));
                        continue;
                }
index 7aaa2635862d7771797b38cfcc553bcf955e0531..c43b6b33463ab2ce51a50148838603029bcc6c56 100644 (file)
@@ -9,12 +9,13 @@
 #include <linux/bootmem.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mmiotrace.h>
 
 #include <asm/cacheflush.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
index 8d63d7a104c3c445805dcf24a59fff2756a17b01..66d20174e35f5222a29be27553a78c54b257ca88 100644 (file)
@@ -7,11 +7,12 @@
 #include <linux/sched/task.h>
 #include <linux/vmalloc.h>
 
+#include <asm/e820/types.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
 
 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)
 {
@@ -103,7 +104,7 @@ void __init kasan_init(void)
        kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
                        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)
                        break;
 
index bef36622e4087b98eaee4409607320e2c71b38d6..4d434ddb75dbe6307be3b0ca13638a94094935c6 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/kallsyms.h>
 #include <asm/pgtable.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/percpu.h>
 #include <linux/cpu.h>
index 12dcad7297a5b70ac34a7a1ca7711aca13e9d9cc..f9d99535f233bf74c1631b1af02c36b6446e3c5f 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/sched.h>
 #include <linux/topology.h>
 
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/proto.h>
 #include <asm/dma.h>
 #include <asm/amd_nb.h>
index 28d42130243c0fdd463e7c2221af83115cce6bec..a57e8e02f4571d68cb3bb35df07d8915971fb55e 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
index efc32bc6862b3f53271719ae90bb8304634cbb59..9b78685b66e663c80ec3a68986a39024fd372b3c 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/seq_file.h>
 #include <linux/bootmem.h>
 #include <linux/debugfs.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/pfn_t.h>
 #include <linux/slab.h>
@@ -23,7 +24,7 @@
 #include <asm/x86_init.h>
 #include <asm/pgtable.h>
 #include <asm/fcntl.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/mtrr.h>
 #include <asm/page.h>
 #include <asm/msr.h>
index 9adce776852be885cff56c59b07cec98b64f4dde..de53c52551a5ee3e02ecf972bc61bebf3c6fd99a 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/fixmap.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/io.h>
index 35fe69529bc1675f7336caa1413c4a7e4cb84a83..3ea20d61b5236a67ec521c52cc85a5f96d92b766 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/mm.h>
 #include <asm/proto.h>
 #include <asm/numa.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/apic.h>
 #include <asm/uv/uv.h>
 
index 0a9f2caf358ff7230e6afa569219234127490c1a..6fa84d531f4feabb5d695dae191b61d1f79cd6b3 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/bootmem.h>
 
 #include <asm/pat.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.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)
                pcibios_allocate_resources(bus, 1);
 
-       e820_reserve_resources_late();
+       e820__reserve_resources_late();
        /*
         * Insert the IO APIC resources after PCI initialization has
         * occurred to handle IO APICS that are mapped in on a BAR in
index dd30b7e08bc2c8e703c1f91f7f8b60894d36f6eb..d1b47d5bc9c33f8869357f04cc7def1f83eb271e 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/rculist.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
 
@@ -423,7 +423,7 @@ static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl,
        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;
 
@@ -440,11 +440,11 @@ static int is_acpi_reserved(u64 start, u64 end, unsigned not_used)
        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 size = resource_size(&cfg->res);
@@ -452,7 +452,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
        int num_buses;
        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;
                if (size < (16UL<<20))
                        break;
@@ -494,8 +494,8 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
        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 (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.
         * For MCFG information constructed from hotpluggable host bridge's
         * _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
           type 1 is available. how about type 2 ?*/
        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;
 }
index 43984bc1665a917303ae574b27345138cc9560b6..3e9e166f640841f9d282f43236e80a7dcef30128 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 
 /* Assume systems with more busses have correct MCFG */
index bea52496aea682f0b2c86e152d23ca52aae31662..f1c1aa0430ae365712d6105d2574006f2e098545 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
 #include <linux/rcupdate.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 
 #define PREFIX "PCI: "
index 1d97cea3b3a44efb3152e32278573970c2c0c2c3..29e9ba6ace9d71a000fc46133863caec101d8bff 100644 (file)
@@ -7,7 +7,9 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
+
 #include <asm/pci_x86.h>
+#include <asm/e820/types.h>
 #include <asm/pci-functions.h>
 #include <asm/cacheflush.h>
 
index 565dff3c9a12cf1f042fae494d1bdb3a55d032b3..a15cf815ac4ead121415f6565f522d5578df1325 100644 (file)
@@ -47,6 +47,7 @@
 
 #include <asm/setup.h>
 #include <asm/efi.h>
+#include <asm/e820/api.h>
 #include <asm/time.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
@@ -139,21 +140,21 @@ static void __init do_add_efi_memmap(void)
                case EFI_BOOT_SERVICES_DATA:
                case EFI_CONVENTIONAL_MEMORY:
                        if (md->attribute & EFI_MEMORY_WB)
-                               e820_type = E820_RAM;
+                               e820_type = E820_TYPE_RAM;
                        else
-                               e820_type = E820_RESERVED;
+                               e820_type = E820_TYPE_RESERVED;
                        break;
                case EFI_ACPI_RECLAIM_MEMORY:
-                       e820_type = E820_ACPI;
+                       e820_type = E820_TYPE_ACPI;
                        break;
                case EFI_ACPI_MEMORY_NVS:
-                       e820_type = E820_NVS;
+                       e820_type = E820_TYPE_NVS;
                        break;
                case EFI_UNUSABLE_MEMORY:
-                       e820_type = E820_UNUSABLE;
+                       e820_type = E820_TYPE_UNUSABLE;
                        break;
                case EFI_PERSISTENT_MEMORY:
-                       e820_type = E820_PMEM;
+                       e820_type = E820_TYPE_PMEM;
                        break;
                default:
                        /*
@@ -161,12 +162,12 @@ static void __init do_add_efi_memmap(void)
                         * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO
                         * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE
                         */
-                       e820_type = E820_RESERVED;
+                       e820_type = E820_TYPE_RESERVED;
                        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)
index a4695da42d77b39cec3b65083c7b7115b1faa32d..2ee7694362a5028d6e4ecbb530444d648b58c6a6 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <asm/setup.h>
 #include <asm/page.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/proto.h>
index 30031d5293c483202c526d5045cda23be6617359..3c8d8e511fd495243f360f52e96674d80345a648 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
 #include <linux/dmi.h>
+
+#include <asm/e820/api.h>
 #include <asm/efi.h>
 #include <asm/uv/uv.h>
 
@@ -240,14 +242,14 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
  * else. We must only reserve (and then free) regions:
  *
  * - 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)
 {
        if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end))
                return false;
 
-       if (!e820_all_mapped(start, start+size, E820_RAM))
+       if (!e820__mapped_all(start, start+size, E820_TYPE_RAM))
                return false;
 
        return true;
@@ -280,7 +282,7 @@ void __init efi_reserve_boot_services(void)
                 * A good example of a critical region that must not be
                 * freed is page zero (first 4Kb of memory), which may
                 * contain boot services code/data but is marked
-                * E820_RESERVED by trim_bios_range().
+                * E820_TYPE_RESERVED by trim_bios_range().
                 */
                if (!already_reserved) {
                        memblock_reserve(start, size);
index ded2e82723829b7d74b2a771c6426cae06168cc8..053801b022dd0df27b1687603896f63c179f9b5d 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <crypto/hash.h>
 
+#include <asm/e820/api.h>
 #include <asm/init.h>
 #include <asm/proto.h>
 #include <asm/page.h>
@@ -195,12 +196,12 @@ struct restore_data_record {
 
 #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
  */
-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 crypto_ahash *tfm;
@@ -213,10 +214,9 @@ static int get_e820_md5(struct e820map *map, void *buf)
 
        {
                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);
-               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_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)
 {
-       get_e820_md5(e820_saved, buf);
+       get_e820_md5(e820_table_firmware, 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))
                return false;
 
-       ret = get_e820_md5(e820_saved, result);
+       ret = get_e820_md5(e820_table_firmware, result);
        if (ret)
                return true;
 
index ec1d5c46e58f7cd0719c84686b627e10b7b18dcd..78243454f5e66dbe30c8f473ce9895f47c57610d 100644 (file)
@@ -76,6 +76,7 @@
 #include <asm/mwait.h>
 #include <asm/pci_x86.h>
 #include <asm/cpu.h>
+#include <asm/e820/api.h> 
 
 #ifdef CONFIG_ACPI
 #include <linux/acpi.h>
@@ -1690,34 +1691,32 @@ static void __init init_pvh_bootparams(void)
 
        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);
        if (rc) {
                xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc);
                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;
-               pvh_bootparams.e820_map[memmap.nr_entries].size =
+               pvh_bootparams.e820_table[memmap.nr_entries].size =
                        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++;
        } else
                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;
        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_start_info.cmdline_paddr;
index 37cb5aad71de364fa50974e236e2d001f51ea687..1d68be6e3ff172205f3d0a1bcd53a6778b855491 100644 (file)
@@ -58,7 +58,7 @@
 #include <asm/mmu_context.h>
 #include <asm/setup.h>
 #include <asm/paravirt.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/linkage.h>
 #include <asm/page.h>
 #include <asm/init.h>
index a8c306cf88683e6c19e32f483e50dfcc0ca681ac..a5bf7c4514357e1e89d2703df5cb2052aeabcc12 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <asm/elf.h>
 #include <asm/vdso.h>
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/setup.h>
 #include <asm/acpi.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;
 
 /* 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.
@@ -198,15 +197,15 @@ void __init xen_inv_extra_mem(void)
  */
 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 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 e_pfn;
 
-               if (entry->type != E820_RAM)
+               if (entry->type != E820_TYPE_RAM)
                        continue;
 
                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;
        unsigned long ret_val = 0;
-       const struct e820entry *entry = xen_e820_map;
+       const struct e820_entry *entry = xen_e820_table.entries;
        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
         * 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;
-               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 end_pfn = PFN_UP(end);
 
-                       if (entry->type == E820_RAM)
+                       if (entry->type == E820_TYPE_RAM)
                                end_pfn = PFN_UP(entry->addr);
 
                        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;
 
        /* Align RAM regions to page boundaries. */
-       if (type == E820_RAM) {
+       if (type == E820_TYPE_RAM) {
                start = PAGE_ALIGN(start);
                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)
 {
-       struct e820entry *entry = xen_e820_map;
+       struct e820_entry *entry = xen_e820_table.entries;
        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)
 {
-       struct e820entry *entry;
+       struct e820_entry *entry;
        unsigned mapcnt;
        phys_addr_t end;
 
@@ -620,10 +619,10 @@ bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
                return false;
 
        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)
                        return false;
 
@@ -645,10 +644,10 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size)
 {
        unsigned mapcnt;
        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;
                start = entry->addr;
                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);
        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() ?
                XENMEM_machine_memory_map :
@@ -760,16 +759,16 @@ char * __init xen_memory_setup(void)
        if (rc == -ENOSYS) {
                BUG_ON(xen_initial_domain());
                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). */
-               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;
        }
        BUG_ON(rc);
        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
@@ -783,8 +782,7 @@ char * __init xen_memory_setup(void)
                xen_ignore_unusable();
 
        /* 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();
 
@@ -811,15 +809,15 @@ char * __init xen_memory_setup(void)
        extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
                           extra_pages, max_pages - max_pfn);
        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;
 
                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) {
                                chunk_size = min(size, mem_end - addr);
                        } else if (extra_pages) {
@@ -840,9 +838,9 @@ char * __init xen_memory_setup(void)
                size -= chunk_size;
                if (size == 0) {
                        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
         * 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.
@@ -914,6 +911,37 @@ char * __init xen_memory_setup(void)
        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.
  * 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)
 {
        xen_panic_handler_init();
-
-       xen_pvmmu_arch_setup();
+       if (!xen_feature(XENFEAT_auto_translated_physmap))
+               xen_pvmmu_arch_setup();
 
 #ifdef CONFIG_ACPI
        if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
index 2604189d6cd156e5449c7dd071d63120ea000a0e..9b9ac04593fb5134e8b03f2ad5ebf9e75276b7e5 100644 (file)
@@ -556,7 +556,7 @@ void __init acpi_table_upgrade(void)
         * But it's not enough on X86 because ioremap will
         * complain later (used by acpi_os_map_memory) that the pages
         * 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.
         */
        memblock_reserve(acpi_tables_addr, all_tables_size);
index 0ef350010766355c933ebe7e48ce41a78656b0ac..c99cd19d91479ce62ca1871925fc046f9efa16fe 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/agp_backend.h>
 #include <linux/mmzone.h>
 #include <asm/page.h>          /* PAGE_SIZE */
-#include <asm/e820.h>
+#include <asm/e820/api.h>
 #include <asm/amd_nb.h>
 #include <asm/gart.h>
 #include "agp.h"
index 9dc46cb8a0fd79be7f4bdae7ae8f5f4dbdcdb7f4..064194f6453ebccc04ffc3cda9e1c1901b7c1728 100644 (file)
@@ -38,7 +38,7 @@ struct xen_memory_region {
        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
 struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS];
index 11c8d9bc762ef0c4bde99dec4292e84ff00d3477..4e38ea02ef0fac1e3365d1963079fa478b5c6ae2 100644 (file)
@@ -3339,7 +3339,7 @@ int main(int argc, char *argv[])
         * simple, single region.
         */
        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
         * line after the boot header.