diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-06-18 10:09:38 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-06-21 06:33:01 +0200 |
commit | dcf3c3696b5529873231410b4db1334c8c7144c5 (patch) | |
tree | 4c2d34c579c364b732971b2fce635b7fb4d9d4f9 /arch/arm/cpu/mmu.c | |
parent | 59f9a95b1697b92c5e0752a1475dd92f1d7b4434 (diff) | |
download | barebox-dcf3c3696b5529873231410b4db1334c8c7144c5.tar.gz barebox-dcf3c3696b5529873231410b4db1334c8c7144c5.tar.xz |
ARM: mmu: inherit pte flags from pmd
When creating a 2nd level page table from a section inherit the flags
from the section rather than assuming the section was mapped cached
previously. This fixes creating a 2nd level pagetable when the section
was mapped differently than we expected.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Link: https://lore.barebox.org/20210618080939.15343-1-s.trumtrar@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/cpu/mmu.c')
-rw-r--r-- | arch/arm/cpu/mmu.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 6af228505d..6388e1bf14 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -138,6 +138,29 @@ static u32 *arm_create_pte(unsigned long virt, uint32_t flags) return table; } +static u32 pmd_flags_to_pte(u32 pmd) +{ + u32 pte = 0; + + if (pmd & PMD_SECT_BUFFERABLE) + pte |= PTE_BUFFERABLE; + if (pmd & PMD_SECT_CACHEABLE) + pte |= PTE_CACHEABLE; + if (pmd & PMD_SECT_nG) + pte |= PTE_EXT_NG; + if (pmd & PMD_SECT_XN) + pte |= PTE_EXT_XN; + + /* TEX[2:0] */ + pte |= PTE_EXT_TEX((pmd >> 12) & 7); + /* AP[1:0] */ + pte |= ((pmd >> 10) & 0x3) << 4; + /* AP[2] */ + pte |= ((pmd >> 15) & 0x1) << 9; + + return pte; +} + int arch_remap_range(void *start, size_t size, unsigned flags) { u32 addr = (u32)start; @@ -206,11 +229,8 @@ int arch_remap_range(void *start, size_t size, unsigned flags) * If PTE is not found it means that * we needs to split this section and * create a new page table for it - * - * NOTE: Here we assume that section - * we just split was mapped as cached */ - table = arm_create_pte(addr, pte_flags_cached); + table = arm_create_pte(addr, pmd_flags_to_pte(*pgd)); pte = find_pte(addr); BUG_ON(!pte); } |