[PATCH] x86-64: fix mapping updates across pmd boundary

From: Colin Watson
Date: Wed Sep 15 2010 - 08:47:36 EST


A Dell Precision M4500 booted in UEFI mode shows the following warning
at boot:

[ 0.040003] init_memory_mapping: 00000000bb5df000-00000000bb637000
[ 0.046182] EFI: ioremap of 0xBB5DF000 failed!

The range in question corresponds to an entry in the UEFI memory map,
which is always aligned on 4096-byte pages but not necessarily any more
than that. init_memory_mapping passes the start address to
kernel_physical_mapping_init which passes it on to phys_pud_update, etc.
phys_pud_init takes care that if the address crosses a pud boundary then
it's set to the start of the pud, but phys_pmd_init simply increased the
address by PMD_SIZE, which in this case meant that it would jump from
0xbb600000 to 0xbb7df000 and immediately stop since that was after the
end address, not setting any of the remaining pte entries.

Bringing phys_pmd_init into line with phys_pud_init fixes this.

Signed-off-by: Colin Watson <cjwatson@xxxxxxxxxxxxx>
---
arch/x86/mm/init_64.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 9a66746..2f386de 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -368,7 +368,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,

int i = pmd_index(address);

- for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) {
+ for (; i < PTRS_PER_PMD;
+ i++, address = (address & PMD_MASK) + PMD_SIZE) {
unsigned long pte_phys;
pmd_t *pmd = pmd_page + pmd_index(address);
pte_t *pte;
--
1.7.1
--
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/