diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2015-01-13 22:42:31 +0000 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2015-01-13 22:42:31 +0000 |
commit | c26a535b747a56298000c42cdd669514456dfc2d (patch) | |
tree | 1456199ed7f9038ffc664cebb31bad9e0c35414d /arch/arm64/mm | |
parent | eaa27f34e91a14cdceed26ed6c6793ec1d186115 (diff) | |
parent | 9679be103108926cfe9e6fd2f6829cefa77e47b0 (diff) | |
download | op-kernel-dev-c26a535b747a56298000c42cdd669514456dfc2d.zip op-kernel-dev-c26a535b747a56298000c42cdd669514456dfc2d.tar.gz |
Merge tag 'for-3.20' of http://git.linaro.org/people/ard.biesheuvel/linux-arm into upstream
UEFI updates for arm64
This series consists of a reimplementation of the virtual remapping of
UEFI Runtime Services in a way that is stable across kexec, including
the required preparatory refactoring and other work to set the stage,
and some cleaning up afterwards to remove boot services memory and
identitity map handling that has now become redundant.
* tag 'for-3.20' of http://git.linaro.org/people/ard.biesheuvel/linux-arm:
arm64/efi: remove idmap manipulations from UEFI code
arm64/efi: remove free_boot_services() and friends
arm64/efi: move SetVirtualAddressMap() to UEFI stub
arm64/efi: set EFI_ALLOC_ALIGN to 64 KB
efi: efistub: allow allocation alignment larger than EFI_PAGE_SIZE
efi: split off remapping code from efi_config_init()
arm64/mm: add create_pgd_mapping() to create private page tables
arm64/mm: add explicit struct_mm argument to __create_mapping()
Diffstat (limited to 'arch/arm64/mm')
-rw-r--r-- | arch/arm64/mm/mmu.c | 60 |
1 files changed, 25 insertions, 35 deletions
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 6032f3e..3286385 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -156,29 +156,19 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, } while (pte++, addr += PAGE_SIZE, addr != end); } -static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, - unsigned long end, phys_addr_t phys, - int map_io) +static void __init alloc_init_pmd(struct mm_struct *mm, pud_t *pud, + unsigned long addr, unsigned long end, + phys_addr_t phys, pgprot_t prot) { pmd_t *pmd; unsigned long next; - pmdval_t prot_sect; - pgprot_t prot_pte; - - if (map_io) { - prot_sect = PROT_SECT_DEVICE_nGnRE; - prot_pte = __pgprot(PROT_DEVICE_nGnRE); - } else { - prot_sect = PROT_SECT_NORMAL_EXEC; - prot_pte = PAGE_KERNEL_EXEC; - } /* * 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)); - pud_populate(&init_mm, pud, pmd); + pud_populate(mm, pud, pmd); } pmd = pmd_offset(pud, addr); @@ -187,7 +177,8 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, /* try section mapping first */ if (((addr | next | phys) & ~SECTION_MASK) == 0) { pmd_t old_pmd =*pmd; - set_pmd(pmd, __pmd(phys | prot_sect)); + set_pmd(pmd, __pmd(phys | + pgprot_val(mk_sect_prot(prot)))); /* * Check for previous table entries created during * boot (__create_page_tables) and flush them. @@ -196,22 +187,22 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, flush_tlb_all(); } else { alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), - prot_pte); + prot); } phys += next - addr; } while (pmd++, addr = next, addr != end); } -static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, - unsigned long end, phys_addr_t phys, - int map_io) +static void __init alloc_init_pud(struct mm_struct *mm, pgd_t *pgd, + unsigned long addr, unsigned long end, + phys_addr_t phys, pgprot_t prot) { pud_t *pud; unsigned long next; if (pgd_none(*pgd)) { pud = early_alloc(PTRS_PER_PUD * sizeof(pud_t)); - pgd_populate(&init_mm, pgd, pud); + pgd_populate(mm, pgd, pud); } BUG_ON(pgd_bad(*pgd)); @@ -222,10 +213,11 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, /* * For 4K granule only, attempt to put down a 1GB block */ - if (!map_io && (PAGE_SHIFT == 12) && + if ((PAGE_SHIFT == 12) && ((addr | next | phys) & ~PUD_MASK) == 0) { pud_t old_pud = *pud; - set_pud(pud, __pud(phys | PROT_SECT_NORMAL_EXEC)); + set_pud(pud, __pud(phys | + pgprot_val(mk_sect_prot(prot)))); /* * If we have an old value for a pud, it will @@ -240,7 +232,7 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, flush_tlb_all(); } } else { - alloc_init_pmd(pud, addr, next, phys, map_io); + alloc_init_pmd(mm, pud, addr, next, phys, prot); } phys += next - addr; } while (pud++, addr = next, addr != end); @@ -250,9 +242,9 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, * Create the page directory entries and any necessary page tables for the * mapping specified by 'md'. */ -static void __init __create_mapping(pgd_t *pgd, phys_addr_t phys, - unsigned long virt, phys_addr_t size, - int map_io) +static void __init __create_mapping(struct mm_struct *mm, pgd_t *pgd, + phys_addr_t phys, unsigned long virt, + phys_addr_t size, pgprot_t prot) { unsigned long addr, length, end, next; @@ -262,7 +254,7 @@ static void __init __create_mapping(pgd_t *pgd, phys_addr_t phys, end = addr + length; do { next = pgd_addr_end(addr, end); - alloc_init_pud(pgd, addr, next, phys, map_io); + alloc_init_pud(mm, pgd, addr, next, phys, prot); phys += next - addr; } while (pgd++, addr = next, addr != end); } @@ -275,17 +267,15 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt, &phys, virt); return; } - __create_mapping(pgd_offset_k(virt & PAGE_MASK), phys, virt, size, 0); + __create_mapping(&init_mm, pgd_offset_k(virt & PAGE_MASK), phys, virt, + size, PAGE_KERNEL_EXEC); } -void __init create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io) +void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, + unsigned long virt, phys_addr_t size, + pgprot_t prot) { - if ((addr >> PGDIR_SHIFT) >= ARRAY_SIZE(idmap_pg_dir)) { - pr_warn("BUG: not creating id mapping for %pa\n", &addr); - return; - } - __create_mapping(&idmap_pg_dir[pgd_index(addr)], - addr, addr, size, map_io); + __create_mapping(mm, pgd_offset(mm, virt), phys, virt, size, prot); } static void __init map_mem(void) |