|
@@ -480,9 +480,14 @@ void __init native_pagetable_init(void)
|
|
|
|
|
|
/*
|
|
|
* Remove any mappings which extend past the end of physical
|
|
|
- * memory from the boot time page table:
|
|
|
+ * memory from the boot time page table.
|
|
|
+ * In virtual address space, we should have at least two pages
|
|
|
+ * from VMALLOC_END to pkmap or fixmap according to VMALLOC_END
|
|
|
+ * definition. And max_low_pfn is set to VMALLOC_END physical
|
|
|
+ * address. If initial memory mapping is doing right job, we
|
|
|
+ * should have pte used near max_low_pfn or one pmd is not present.
|
|
|
*/
|
|
|
- for (pfn = max_low_pfn + 1; pfn < 1<<(32-PAGE_SHIFT); pfn++) {
|
|
|
+ for (pfn = max_low_pfn; pfn < 1<<(32-PAGE_SHIFT); pfn++) {
|
|
|
va = PAGE_OFFSET + (pfn<<PAGE_SHIFT);
|
|
|
pgd = base + pgd_index(va);
|
|
|
if (!pgd_present(*pgd))
|
|
@@ -493,10 +498,19 @@ void __init native_pagetable_init(void)
|
|
|
if (!pmd_present(*pmd))
|
|
|
break;
|
|
|
|
|
|
+ /* should not be large page here */
|
|
|
+ if (pmd_large(*pmd)) {
|
|
|
+ pr_warn("try to clear pte for ram above max_low_pfn: pfn: %lx pmd: %p pmd phys: %lx, but pmd is big page and is not using pte !\n",
|
|
|
+ pfn, pmd, __pa(pmd));
|
|
|
+ BUG_ON(1);
|
|
|
+ }
|
|
|
+
|
|
|
pte = pte_offset_kernel(pmd, va);
|
|
|
if (!pte_present(*pte))
|
|
|
break;
|
|
|
|
|
|
+ printk(KERN_DEBUG "clearing pte for ram above max_low_pfn: pfn: %lx pmd: %p pmd phys: %lx pte: %p pte phys: %lx\n",
|
|
|
+ pfn, pmd, __pa(pmd), pte, __pa(pte));
|
|
|
pte_clear(NULL, va, pte);
|
|
|
}
|
|
|
paravirt_alloc_pmd(&init_mm, __pa(base) >> PAGE_SHIFT);
|