@@ -167,13 +167,29 @@
return ptr;
}
+static void __init *table_alloc(phys_addr_t limit, unsigned long sz)
+{
+ void *ptr = early_alloc(sz);
+
+ if (!ptr) {
+ /*
+ * Mapping created, extend the current memblock limit.
+ */
+ memblock_set_current_limit(limit);
+
+ ptr = early_alloc(sz);
+ }
+
+ return ptr;
+}
+
static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn)
{
pte_t *pte;
if (pmd_none(*pmd)) {
- pte = early_alloc(PTRS_PER_PTE * sizeof(pte_t));
+ pte = table_alloc(__pfn_to_phys(pfn), PTRS_PER_PTE * sizeof(pte_t));
__pmd_populate(pmd, __pa(pte), PMD_TYPE_TABLE);
}
BUG_ON(pmd_bad(*pmd));
@@ -195,7 +211,7 @@
* Check for initial section mappings in the pgd/pud and remove them.
*/
if (pud_none(*pud) || pud_bad(*pud)) {
- pmd = early_alloc(PTRS_PER_PMD * sizeof(pmd_t));
+ pmd = table_alloc(phys, PTRS_PER_PMD * sizeof(pmd_t));
pud_populate(&init_mm, pud, pmd);
}
@@ -307,6 +323,24 @@
*/
memblock_set_current_limit((PHYS_OFFSET & PGDIR_MASK) + PGDIR_SIZE);
+#ifndef CONFIG_ARM64_64K_PAGES
+{
+ phys_addr_t table;
+ phys_addr_t tablesize = PMD_SIZE;
+
+ table = memblock_alloc(tablesize, PMD_SIZE);
+
+ if (table) {
+ create_mapping(table, __phys_to_virt(table), tablesize);
+
+ memblock_free(table, tablesize);
+ memblock_add(table, tablesize);
+
+ memblock_set_current_limit(table + tablesize);
+ }
+}
+#endif
+
/* map all the memory banks */
for_each_memblock(memory, reg) {
phys_addr_t start = reg->base;