Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Remove fixmap include fragility

The asm-generic fixmap.h depends on each architecture's fixmap.h to pull
in the definition of PAGE_KERNEL_RO, if this exists. In the absence of
this, FIXMAP_PAGE_RO will not be defined. In mm/early_ioremap.c the
definition of early_memremap_ro is predicated on FIXMAP_PAGE_RO being
defined.

Currently, the arm64 fixmap.h doesn't include pgtable.h for the
definition of PAGE_KERNEL_RO, and as a knock-on effect early_memremap_ro
is not always defined, leading to link-time failures when it is used.
This has been observed with defconfig on next-20160226.

Unfortunately, as pgtable.h includes fixmap.h, adding the include
introduces a circular dependency, which is just as fragile.

Instead, this patch factors out PAGE_KERNEL_RO and other prot
definitions into a new pgtable-prot header which can be included by poth
pgtable.h and fixmap.h, avoiding the circular dependency, and ensuring
that early_memremap_ro is alwyas defined where it is used.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Mark Rutland and committed by
Catalin Marinas
3eca86e7 104a0c02

+94 -62
+1
arch/arm64/include/asm/fixmap.h
··· 20 20 #include <linux/sizes.h> 21 21 #include <asm/boot.h> 22 22 #include <asm/page.h> 23 + #include <asm/pgtable-prot.h> 23 24 24 25 /* 25 26 * Here we define all the compile-time 'special' virtual
+92
arch/arm64/include/asm/pgtable-prot.h
··· 1 + /* 2 + * Copyright (C) 2016 ARM Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + #ifndef __ASM_PGTABLE_PROT_H 17 + #define __ASM_PGTABLE_PROT_H 18 + 19 + #include <asm/memory.h> 20 + #include <asm/pgtable-hwdef.h> 21 + 22 + #include <linux/const.h> 23 + 24 + /* 25 + * Software defined PTE bits definition. 26 + */ 27 + #define PTE_VALID (_AT(pteval_t, 1) << 0) 28 + #define PTE_WRITE (PTE_DBM) /* same as DBM (51) */ 29 + #define PTE_DIRTY (_AT(pteval_t, 1) << 55) 30 + #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) 31 + #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ 32 + 33 + #ifndef __ASSEMBLY__ 34 + 35 + #include <asm/pgtable-types.h> 36 + 37 + #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) 38 + #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) 39 + 40 + #define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) 41 + #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE)) 42 + #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) 43 + #define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) 44 + #define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) 45 + 46 + #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) 47 + #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) 48 + #define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) 49 + 50 + #define _PAGE_DEFAULT (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) 51 + 52 + #define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE) 53 + #define PAGE_KERNEL_RO __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY) 54 + #define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) 55 + #define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE) 56 + #define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT) 57 + 58 + #define PAGE_HYP __pgprot(_PAGE_DEFAULT | PTE_HYP) 59 + #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) 60 + 61 + #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) 62 + #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) 63 + 64 + #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) 65 + #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) 66 + #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) 67 + #define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 68 + #define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 69 + #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 70 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 71 + 72 + #define __P000 PAGE_NONE 73 + #define __P001 PAGE_READONLY 74 + #define __P010 PAGE_COPY 75 + #define __P011 PAGE_COPY 76 + #define __P100 PAGE_READONLY_EXEC 77 + #define __P101 PAGE_READONLY_EXEC 78 + #define __P110 PAGE_COPY_EXEC 79 + #define __P111 PAGE_COPY_EXEC 80 + 81 + #define __S000 PAGE_NONE 82 + #define __S001 PAGE_READONLY 83 + #define __S010 PAGE_SHARED 84 + #define __S011 PAGE_SHARED 85 + #define __S100 PAGE_READONLY_EXEC 86 + #define __S101 PAGE_READONLY_EXEC 87 + #define __S110 PAGE_SHARED_EXEC 88 + #define __S111 PAGE_SHARED_EXEC 89 + 90 + #endif /* __ASSEMBLY__ */ 91 + 92 + #endif /* __ASM_PGTABLE_PROT_H */
+1 -62
arch/arm64/include/asm/pgtable.h
··· 21 21 22 22 #include <asm/memory.h> 23 23 #include <asm/pgtable-hwdef.h> 24 - 25 - /* 26 - * Software defined PTE bits definition. 27 - */ 28 - #define PTE_VALID (_AT(pteval_t, 1) << 0) 29 - #define PTE_WRITE (PTE_DBM) /* same as DBM (51) */ 30 - #define PTE_DIRTY (_AT(pteval_t, 1) << 55) 31 - #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) 32 - #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ 24 + #include <asm/pgtable-prot.h> 33 25 34 26 /* 35 27 * VMALLOC and SPARSEMEM_VMEMMAP ranges. ··· 50 58 extern void __pmd_error(const char *file, int line, unsigned long val); 51 59 extern void __pud_error(const char *file, int line, unsigned long val); 52 60 extern void __pgd_error(const char *file, int line, unsigned long val); 53 - 54 - #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) 55 - #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) 56 - 57 - #define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) 58 - #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE)) 59 - #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) 60 - #define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) 61 - #define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) 62 - 63 - #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) 64 - #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) 65 - #define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) 66 - 67 - #define _PAGE_DEFAULT (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) 68 - 69 - #define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE) 70 - #define PAGE_KERNEL_RO __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY) 71 - #define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) 72 - #define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE) 73 - #define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT) 74 - 75 - #define PAGE_HYP __pgprot(_PAGE_DEFAULT | PTE_HYP) 76 - #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) 77 - 78 - #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) 79 - #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) 80 - 81 - #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) 82 - #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) 83 - #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) 84 - #define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 85 - #define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 86 - #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 87 - #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 88 - 89 - #define __P000 PAGE_NONE 90 - #define __P001 PAGE_READONLY 91 - #define __P010 PAGE_COPY 92 - #define __P011 PAGE_COPY 93 - #define __P100 PAGE_READONLY_EXEC 94 - #define __P101 PAGE_READONLY_EXEC 95 - #define __P110 PAGE_COPY_EXEC 96 - #define __P111 PAGE_COPY_EXEC 97 - 98 - #define __S000 PAGE_NONE 99 - #define __S001 PAGE_READONLY 100 - #define __S010 PAGE_SHARED 101 - #define __S011 PAGE_SHARED 102 - #define __S100 PAGE_READONLY_EXEC 103 - #define __S101 PAGE_READONLY_EXEC 104 - #define __S110 PAGE_SHARED_EXEC 105 - #define __S111 PAGE_SHARED_EXEC 106 61 107 62 /* 108 63 * ZERO_PAGE is a global shared page that is always zero: used