Skip to content

Commit ae2de10

Browse files
committed
ARM: LPAE: Add identity mapping support for the 3-level page table format
With LPAE, the pgd is a separate page table with entries pointing to the pmd. The identity_mapping_add() function needs to ensure that the pgd is populated before populating the pmd level. The do..while blocks now loop over the pmd in order to have the same implementation for the two page table formats. The pmd_addr_end() definition has been removed and the generic one used instead. The pmd clean-up is done in the pgd_free() function. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 14d8c95 commit ae2de10

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

arch/arm/mm/idmap.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,31 @@
88

99
pgd_t *idmap_pgd;
1010

11+
#ifdef CONFIG_ARM_LPAE
12+
static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
13+
unsigned long prot)
14+
{
15+
pmd_t *pmd;
16+
unsigned long next;
17+
18+
if (pud_none_or_clear_bad(pud) || (pud_val(*pud) & L_PGD_SWAPPER)) {
19+
pmd = pmd_alloc_one(&init_mm, addr);
20+
if (!pmd) {
21+
pr_warning("Failed to allocate identity pmd.\n");
22+
return;
23+
}
24+
pud_populate(&init_mm, pud, pmd);
25+
pmd += pmd_index(addr);
26+
} else
27+
pmd = pmd_offset(pud, addr);
28+
29+
do {
30+
next = pmd_addr_end(addr, end);
31+
*pmd = __pmd((addr & PMD_MASK) | prot);
32+
flush_pmd_entry(pmd);
33+
} while (pmd++, addr = next, addr != end);
34+
}
35+
#else /* !CONFIG_ARM_LPAE */
1136
static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
1237
unsigned long prot)
1338
{
@@ -19,6 +44,7 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
1944
pmd[1] = __pmd(addr);
2045
flush_pmd_entry(pmd);
2146
}
47+
#endif /* CONFIG_ARM_LPAE */
2248

2349
static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
2450
unsigned long prot)
@@ -36,7 +62,7 @@ static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long e
3662
{
3763
unsigned long prot, next;
3864

39-
prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
65+
prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
4066
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
4167
prot |= PMD_BIT4;
4268

0 commit comments

Comments
 (0)