[PATCH 3 of 8] x86_64/setup: preserve existing PUD mappings

From: Jeremy Fitzhardinge
Date: Tue Jul 01 2008 - 21:02:37 EST


When constructing the physical mapping, reuse any existing PUD pages
rather than starting afresh. This preserves any special mappings the
earlier boot code may have created.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
---
arch/x86/mm/init_64.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -493,6 +493,14 @@
}
#endif

+static unsigned long __meminit
+phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ pud_t *pud = (pud_t *)pgd_page_vaddr(*pgd);
+
+ return phys_pud_init(pud, addr, end);
+}
+
/*
* Setup the direct mapping of the physical memory at PAGE_OFFSET.
* This runs before bootmem is initialized and gets pages directly from
@@ -525,14 +533,20 @@
unsigned long pud_phys;
pud_t *pud;

+ next = start + PGDIR_SIZE;
+ if (next > end)
+ next = end;
+
+ if (pgd_val(*pgd)) {
+ last_map_addr = phys_pud_update(pgd, __pa(start), __pa(end));
+ continue;
+ }
+
if (after_bootmem)
pud = pud_offset(pgd, start & PGDIR_MASK);
else
pud = alloc_low_page(&pud_phys);

- next = start + PGDIR_SIZE;
- if (next > end)
- next = end;
last_map_addr = phys_pud_init(pud, __pa(start), __pa(next));
unmap_low_page(pud);
if (!after_bootmem)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/