[PATCH v2 04/13] arm64: decouple early fixmap init from linear mapping
From: Ard Biesheuvel <hidden>
Date: 2016-01-08 12:05:17
Also in:
lkml
On 8 January 2016 at 13:00, Catalin Marinas [off-list ref] wrote:
On Wed, Dec 30, 2015 at 04:26:03PM +0100, Ard Biesheuvel wrote:quoted
@@ -583,33 +555,42 @@ void __init early_fixmap_init(void) unsigned long addr = FIXADDR_START; pgd = pgd_offset_k(addr); - pgd_populate(&init_mm, pgd, bm_pud); - pud = pud_offset(pgd, addr); - pud_populate(&init_mm, pud, bm_pmd); - pmd = pmd_offset(pud, addr); - pmd_populate_kernel(&init_mm, pmd, bm_pte); +#if CONFIG_PGTABLE_LEVELS > 3 + if (pgd_none(*pgd)) { + static pud_t bm_pud[PTRS_PER_PUD] __pgdir; + + pgd_populate(&init_mm, pgd, bm_pud); + memblock_reserve(__pa(bm_pud), sizeof(bm_pud)); + } + pud = (pud_t *)__phys_to_kimg(pud_offset_phys(pgd, addr)); +#else + pud = (pud_t *)pgd; +#endif +#if CONFIG_PGTABLE_LEVELS > 2 + if (pud_none(*pud)) { + static pmd_t bm_pmd[PTRS_PER_PMD] __pgdir; + + pud_populate(&init_mm, pud, bm_pmd); + memblock_reserve(__pa(bm_pmd), sizeof(bm_pmd)); + } + pmd = (pmd_t *)__phys_to_kimg(pmd_offset_phys(pud, addr)); +#else + pmd = (pmd_t *)pud; +#endif + if (pmd_none(*pmd)) { + static pte_t bm_pte[PTRS_PER_PTE] __pgdir; + + pmd_populate_kernel(&init_mm, pmd, bm_pte); + memblock_reserve(__pa(bm_pte), sizeof(bm_pte)); + } + __fixmap_pte = (pte_t *)__phys_to_kimg(pmd_page_paddr(*pmd));I haven't tried but could you not avoid the #if and just rely on the pud_none() etc. definitions to be 0 and the compiler+linker optimising the irrelevant code out?
I tried but it requires some tinkering so I gave up. I can have another go based on the latest version (which will look a bit different)