diff options
author | Russell King | 2010-11-21 17:27:49 +0100 |
---|---|---|
committer | Russell King | 2011-02-21 20:24:14 +0100 |
commit | 516295e5ab4bf986865cfff856d484ec678e3b0b (patch) | |
tree | 2125f49635462fca18ac6d36ebf7363d3cc6d521 /arch/arm/mm/idmap.c | |
parent | ARM: 6673/1: LPAE: use phys_addr_t instead of unsigned long for start of memb... (diff) | |
download | kernel-qcow2-linux-516295e5ab4bf986865cfff856d484ec678e3b0b.tar.gz kernel-qcow2-linux-516295e5ab4bf986865cfff856d484ec678e3b0b.tar.xz kernel-qcow2-linux-516295e5ab4bf986865cfff856d484ec678e3b0b.zip |
ARM: pgtable: add pud-level code
Add pud_offset() et.al. between the pgd and pmd code in preparation of
using pgtable-nopud.h rather than 4level-fixup.h.
This incorporates a fix from Jamie Iles <jamie@jamieiles.com> for
uaccess_with_memcpy.c.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/idmap.c')
-rw-r--r-- | arch/arm/mm/idmap.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 57299446f787..2be9139a4ef3 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -4,10 +4,10 @@ #include <asm/pgalloc.h> #include <asm/pgtable.h> -static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, +static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, unsigned long prot) { - pmd_t *pmd = pmd_offset(pgd, addr); + pmd_t *pmd = pmd_offset(pud, addr); addr = (addr & PMD_MASK) | prot; pmd[0] = __pmd(addr); @@ -16,6 +16,18 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, flush_pmd_entry(pmd); } +static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end, + unsigned long prot) +{ + pud_t *pud = pud_offset(pgd, addr); + unsigned long next; + + do { + next = pud_addr_end(addr, end); + idmap_add_pmd(pud, addr, next, prot); + } while (pud++, addr = next, addr != end); +} + void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) { unsigned long prot, next; @@ -27,17 +39,28 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) pgd += pgd_index(addr); do { next = pgd_addr_end(addr, end); - idmap_add_pmd(pgd, addr, next, prot); + idmap_add_pud(pgd, addr, next, prot); } while (pgd++, addr = next, addr != end); } #ifdef CONFIG_SMP -static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end) +static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end) { - pmd_t *pmd = pmd_offset(pgd, addr); + pmd_t *pmd = pmd_offset(pud, addr); pmd_clear(pmd); } +static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + pud_t *pud = pud_offset(pgd, addr); + unsigned long next; + + do { + next = pud_addr_end(addr, end); + idmap_del_pmd(pud, addr, next); + } while (pud++, addr = next, addr != end); +} + void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) { unsigned long next; @@ -45,7 +68,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) pgd += pgd_index(addr); do { next = pgd_addr_end(addr, end); - idmap_del_pmd(pgd, addr, next); + idmap_del_pud(pgd, addr, next); } while (pgd++, addr = next, addr != end); } #endif |