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

ARM: LPAE: Introduce the 3-level page table format definitions

This patch introduces the pgtable-3level*.h files with definitions
specific to the LPAE page table format (3 levels of page tables).

Each table is 4KB and has 512 64-bit entries. An entry can point to a
40-bit physical address. The young, write and exec software bits share
the corresponding hardware bits (negated). Other software bits use spare
bits in the PTE.

The patch also changes some variable types from unsigned long or int to
pteval_t or pgprot_t.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

+261
+4
arch/arm/include/asm/page.h
··· 151 151 #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) 152 152 extern void copy_page(void *to, const void *from); 153 153 154 + #ifdef CONFIG_ARM_LPAE 155 + #include <asm/pgtable-3level-types.h> 156 + #else 154 157 #include <asm/pgtable-2level-types.h> 158 + #endif 155 159 156 160 #endif /* CONFIG_MMU */ 157 161
+77
arch/arm/include/asm/pgtable-3level-hwdef.h
··· 1 + /* 2 + * arch/arm/include/asm/pgtable-3level-hwdef.h 3 + * 4 + * Copyright (C) 2011 ARM Ltd. 5 + * Author: Catalin Marinas <catalin.marinas@arm.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef _ASM_PGTABLE_3LEVEL_HWDEF_H 21 + #define _ASM_PGTABLE_3LEVEL_HWDEF_H 22 + 23 + /* 24 + * Hardware page table definitions. 25 + * 26 + * + Level 1/2 descriptor 27 + * - common 28 + */ 29 + #define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0) 30 + #define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) 31 + #define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0) 32 + #define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0) 33 + #define PMD_BIT4 (_AT(pmdval_t, 0)) 34 + #define PMD_DOMAIN(x) (_AT(pmdval_t, 0)) 35 + 36 + /* 37 + * - section 38 + */ 39 + #define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) 40 + #define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) 41 + #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) 42 + #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) 43 + #define PMD_SECT_nG (_AT(pmdval_t, 1) << 11) 44 + #define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) 45 + #define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0)) 46 + #define PMD_SECT_AP_READ (_AT(pmdval_t, 0)) 47 + #define PMD_SECT_TEX(x) (_AT(pmdval_t, 0)) 48 + 49 + /* 50 + * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). 51 + */ 52 + #define PMD_SECT_UNCACHED (_AT(pmdval_t, 0) << 2) /* strongly ordered */ 53 + #define PMD_SECT_BUFFERED (_AT(pmdval_t, 1) << 2) /* normal non-cacheable */ 54 + #define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */ 55 + #define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */ 56 + #define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */ 57 + 58 + /* 59 + * + Level 3 descriptor (PTE) 60 + */ 61 + #define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0) 62 + #define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0) 63 + #define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0) 64 + #define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ 65 + #define PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ 66 + #define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ 67 + #define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ 68 + #define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ 69 + #define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ 70 + 71 + /* 72 + * 40-bit physical address supported. 73 + */ 74 + #define PHYS_MASK_SHIFT (40) 75 + #define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1) 76 + 77 + #endif
+70
arch/arm/include/asm/pgtable-3level-types.h
··· 1 + /* 2 + * arch/arm/include/asm/pgtable-3level-types.h 3 + * 4 + * Copyright (C) 2011 ARM Ltd. 5 + * Author: Catalin Marinas <catalin.marinas@arm.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef _ASM_PGTABLE_3LEVEL_TYPES_H 21 + #define _ASM_PGTABLE_3LEVEL_TYPES_H 22 + 23 + #include <asm/types.h> 24 + 25 + typedef u64 pteval_t; 26 + typedef u64 pmdval_t; 27 + typedef u64 pgdval_t; 28 + 29 + #undef STRICT_MM_TYPECHECKS 30 + 31 + #ifdef STRICT_MM_TYPECHECKS 32 + 33 + /* 34 + * These are used to make use of C type-checking.. 35 + */ 36 + typedef struct { pteval_t pte; } pte_t; 37 + typedef struct { pmdval_t pmd; } pmd_t; 38 + typedef struct { pgdval_t pgd; } pgd_t; 39 + typedef struct { pteval_t pgprot; } pgprot_t; 40 + 41 + #define pte_val(x) ((x).pte) 42 + #define pmd_val(x) ((x).pmd) 43 + #define pgd_val(x) ((x).pgd) 44 + #define pgprot_val(x) ((x).pgprot) 45 + 46 + #define __pte(x) ((pte_t) { (x) } ) 47 + #define __pmd(x) ((pmd_t) { (x) } ) 48 + #define __pgd(x) ((pgd_t) { (x) } ) 49 + #define __pgprot(x) ((pgprot_t) { (x) } ) 50 + 51 + #else /* !STRICT_MM_TYPECHECKS */ 52 + 53 + typedef pteval_t pte_t; 54 + typedef pmdval_t pmd_t; 55 + typedef pgdval_t pgd_t; 56 + typedef pteval_t pgprot_t; 57 + 58 + #define pte_val(x) (x) 59 + #define pmd_val(x) (x) 60 + #define pgd_val(x) (x) 61 + #define pgprot_val(x) (x) 62 + 63 + #define __pte(x) (x) 64 + #define __pmd(x) (x) 65 + #define __pgd(x) (x) 66 + #define __pgprot(x) (x) 67 + 68 + #endif /* STRICT_MM_TYPECHECKS */ 69 + 70 + #endif /* _ASM_PGTABLE_3LEVEL_TYPES_H */
+102
arch/arm/include/asm/pgtable-3level.h
··· 1 + /* 2 + * arch/arm/include/asm/pgtable-3level.h 3 + * 4 + * Copyright (C) 2011 ARM Ltd. 5 + * Author: Catalin Marinas <catalin.marinas@arm.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef _ASM_PGTABLE_3LEVEL_H 21 + #define _ASM_PGTABLE_3LEVEL_H 22 + 23 + /* 24 + * With LPAE, there are 3 levels of page tables. Each level has 512 entries of 25 + * 8 bytes each, occupying a 4K page. The first level table covers a range of 26 + * 512GB, each entry representing 1GB. Since we are limited to 4GB input 27 + * address range, only 4 entries in the PGD are used. 28 + * 29 + * There are enough spare bits in a page table entry for the kernel specific 30 + * state. 31 + */ 32 + #define PTRS_PER_PTE 512 33 + #define PTRS_PER_PMD 512 34 + #define PTRS_PER_PGD 4 35 + 36 + #define PTE_HWTABLE_PTRS (PTRS_PER_PTE) 37 + #define PTE_HWTABLE_OFF (0) 38 + #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) 39 + 40 + /* 41 + * PGDIR_SHIFT determines the size a top-level page table entry can map. 42 + */ 43 + #define PGDIR_SHIFT 30 44 + 45 + /* 46 + * PMD_SHIFT determines the size a middle-level page table entry can map. 47 + */ 48 + #define PMD_SHIFT 21 49 + 50 + #define PMD_SIZE (1UL << PMD_SHIFT) 51 + #define PMD_MASK (~(PMD_SIZE-1)) 52 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT) 53 + #define PGDIR_MASK (~(PGDIR_SIZE-1)) 54 + 55 + /* 56 + * section address mask and size definitions. 57 + */ 58 + #define SECTION_SHIFT 21 59 + #define SECTION_SIZE (1UL << SECTION_SHIFT) 60 + #define SECTION_MASK (~(SECTION_SIZE-1)) 61 + 62 + #define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE) 63 + 64 + /* 65 + * "Linux" PTE definitions for LPAE. 66 + * 67 + * These bits overlap with the hardware bits but the naming is preserved for 68 + * consistency with the classic page table format. 69 + */ 70 + #define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */ 71 + #define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ 72 + #define L_PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ 73 + #define L_PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ 74 + #define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */ 75 + #define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */ 76 + #define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ 77 + #define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */ 78 + #define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ 79 + #define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */ 80 + #define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */ 81 + 82 + /* 83 + * To be used in assembly code with the upper page attributes. 84 + */ 85 + #define L_PTE_XN_HIGH (1 << (54 - 32)) 86 + #define L_PTE_DIRTY_HIGH (1 << (55 - 32)) 87 + 88 + /* 89 + * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). 90 + */ 91 + #define L_PTE_MT_UNCACHED (_AT(pteval_t, 0) << 2) /* strongly ordered */ 92 + #define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 1) << 2) /* normal non-cacheable */ 93 + #define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 2) << 2) /* normal inner write-through */ 94 + #define L_PTE_MT_WRITEBACK (_AT(pteval_t, 3) << 2) /* normal inner write-back */ 95 + #define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 7) << 2) /* normal inner write-alloc */ 96 + #define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 4) << 2) /* device */ 97 + #define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 4) << 2) /* device */ 98 + #define L_PTE_MT_DEV_WC (_AT(pteval_t, 1) << 2) /* normal non-cacheable */ 99 + #define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 3) << 2) /* normal inner write-back */ 100 + #define L_PTE_MT_MASK (_AT(pteval_t, 7) << 2) 101 + 102 + #endif /* _ASM_PGTABLE_3LEVEL_H */
+4
arch/arm/include/asm/pgtable-hwdef.h
··· 10 10 #ifndef _ASMARM_PGTABLE_HWDEF_H 11 11 #define _ASMARM_PGTABLE_HWDEF_H 12 12 13 + #ifdef CONFIG_ARM_LPAE 14 + #include <asm/pgtable-3level-hwdef.h> 15 + #else 13 16 #include <asm/pgtable-2level-hwdef.h> 17 + #endif 14 18 15 19 #endif
+4
arch/arm/include/asm/pgtable.h
··· 25 25 #include <mach/vmalloc.h> 26 26 #include <asm/pgtable-hwdef.h> 27 27 28 + #ifdef CONFIG_ARM_LPAE 29 + #include <asm/pgtable-3level.h> 30 + #else 28 31 #include <asm/pgtable-2level.h> 32 + #endif 29 33 30 34 /* 31 35 * Just any arbitrary offset to the start of the vmalloc VM area: the