powerpc: Implement and use pgprot_nx()
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Mon, 25 Sep 2023 18:31:35 +0000 (20:31 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 19 Oct 2023 06:12:45 +0000 (17:12 +1100)
ioremap_page_range() calls pgprot_nx() vmap() and vmap_pfn()
clear execute permission by calling pgprot_nx().

When pgprot_nx() is not defined it falls back to a nop.

Implement it for powerpc then use it in early_ioremap_range().

Then the call to pte_exprotect() can be removed from ioremap_prot().

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/5993a7a097e989af1c97fc4a6c011fefc67dbe6e.1695659959.git.christophe.leroy@csgroup.eu
arch/powerpc/include/asm/pgtable.h
arch/powerpc/mm/ioremap.c

index 966e7c5119f63aed44489938727999da7d30d6d9..2bfb7dd3b49e6ccae334de4ccb0064a6b47b1845 100644 (file)
@@ -71,6 +71,12 @@ static inline pgprot_t pte_pgprot(pte_t pte)
        return __pgprot(pte_flags);
 }
 
+static inline pgprot_t pgprot_nx(pgprot_t prot)
+{
+       return pte_pgprot(pte_exprotect(__pte(pgprot_val(prot))));
+}
+#define pgprot_nx pgprot_nx
+
 #ifndef pmd_page_vaddr
 static inline const void *pmd_page_vaddr(pmd_t pmd)
 {
index 705e8e8ffde4d7e653edc42c18aaf2c2788fb363..d5159f20538006ece4a9263d12b49d8352f32899 100644 (file)
@@ -50,8 +50,7 @@ void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long flags)
        if (pte_write(pte))
                pte = pte_mkdirty(pte);
 
-       /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
-       pte = pte_exprotect(pte);
+       /* we don't want to let _PAGE_USER leak out */
        pte = pte_mkprivileged(pte);
 
        if (iowa_is_active())
@@ -66,7 +65,7 @@ int early_ioremap_range(unsigned long ea, phys_addr_t pa,
        unsigned long i;
 
        for (i = 0; i < size; i += PAGE_SIZE) {
-               int err = map_kernel_page(ea + i, pa + i, prot);
+               int err = map_kernel_page(ea + i, pa + i, pgprot_nx(prot));
 
                if (WARN_ON_ONCE(err))  /* Should clean up */
                        return err;