summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorArtiom Myaskouvskey <artiom.myaskouvskey@intel.com>2006-12-07 02:14:11 +0100
committerAndi Kleen <andi@basil.nowhere.org>2006-12-07 02:14:11 +0100
commitbf7e6a196318316e921f357557fca9d11d15f486 (patch)
tree7484602fdde8eab3b750b4e9bd3f3d9a2edc628e /arch
parentf990fff427d68af3e4e1d16fe799c106abc0bf53 (diff)
downloadlinux-3.10-bf7e6a196318316e921f357557fca9d11d15f486.tar.gz
linux-3.10-bf7e6a196318316e921f357557fca9d11d15f486.tar.bz2
linux-3.10-bf7e6a196318316e921f357557fca9d11d15f486.zip
[PATCH] i386: Preserve EFI run time regions with memmap parameter
When using memmap kernel parameter in EFI boot we should also add to memory map memory regions of runtime services to enable their mapping later. AK: merged and cleaned up the patch Signed-off-by: Artiom Myaskouvskey <artiom.myaskouvskey@intel.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/e820.c60
-rw-r--r--arch/i386/mm/init.c2
2 files changed, 43 insertions, 19 deletions
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index b704790f796..2f7d0a92fd7 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -742,29 +742,55 @@ void __init print_memory_map(char *who)
}
}
-void __init limit_regions(unsigned long long size)
+static __init __always_inline void efi_limit_regions(unsigned long long size)
{
unsigned long long current_addr = 0;
+ efi_memory_desc_t *md, *next_md;
+ void *p, *p1;
+ int i, j;
+
+ j = 0;
+ p1 = memmap.map;
+ for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
+ md = p;
+ next_md = p1;
+ current_addr = md->phys_addr +
+ PFN_PHYS(md->num_pages);
+ if (is_available_memory(md)) {
+ if (md->phys_addr >= size) continue;
+ memcpy(next_md, md, memmap.desc_size);
+ if (current_addr >= size) {
+ next_md->num_pages -=
+ PFN_UP(current_addr-size);
+ }
+ p1 += memmap.desc_size;
+ next_md = p1;
+ j++;
+ } else if ((md->attribute & EFI_MEMORY_RUNTIME) ==
+ EFI_MEMORY_RUNTIME) {
+ /* In order to make runtime services
+ * available we have to include runtime
+ * memory regions in memory map */
+ memcpy(next_md, md, memmap.desc_size);
+ p1 += memmap.desc_size;
+ next_md = p1;
+ j++;
+ }
+ }
+ memmap.nr_map = j;
+ memmap.map_end = memmap.map +
+ (memmap.nr_map * memmap.desc_size);
+}
+
+void __init limit_regions(unsigned long long size)
+{
+ unsigned long long current_addr;
int i;
print_memory_map("limit_regions start");
if (efi_enabled) {
- efi_memory_desc_t *md;
- void *p;
-
- for (p = memmap.map, i = 0; p < memmap.map_end;
- p += memmap.desc_size, i++) {
- md = p;
- current_addr = md->phys_addr + (md->num_pages << 12);
- if (md->type == EFI_CONVENTIONAL_MEMORY) {
- if (current_addr >= size) {
- md->num_pages -=
- (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
- memmap.nr_map = i + 1;
- return;
- }
- }
- }
+ efi_limit_regions(size);
+ return;
}
for (i = 0; i < e820.nr_map; i++) {
current_addr = e820.map[i].addr + e820.map[i].size;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 167416155ee..f4dd048187f 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -192,8 +192,6 @@ static inline int page_kills_ppro(unsigned long pagenr)
return 0;
}
-extern int is_available_memory(efi_memory_desc_t *);
-
int page_is_ram(unsigned long pagenr)
{
int i;