12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 270d64ceaSPaul Mackerras /* 3f381d571SChristophe Leroy * This file contains pgtable related functions for 64-bit machines. 470d64ceaSPaul Mackerras * 570d64ceaSPaul Mackerras * Derived from arch/ppc64/mm/init.c 670d64ceaSPaul Mackerras * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 770d64ceaSPaul Mackerras * 870d64ceaSPaul Mackerras * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org) 970d64ceaSPaul Mackerras * and Cort Dougan (PReP) (cort@cs.nmt.edu) 1070d64ceaSPaul Mackerras * Copyright (C) 1996 Paul Mackerras 1170d64ceaSPaul Mackerras * 1270d64ceaSPaul Mackerras * Derived from "arch/i386/mm/init.c" 1370d64ceaSPaul Mackerras * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 1470d64ceaSPaul Mackerras * 1570d64ceaSPaul Mackerras * Dave Engebretsen <engebret@us.ibm.com> 1670d64ceaSPaul Mackerras * Rework for PPC64 port. 1770d64ceaSPaul Mackerras */ 1870d64ceaSPaul Mackerras 1970d64ceaSPaul Mackerras #include <linux/signal.h> 2070d64ceaSPaul Mackerras #include <linux/sched.h> 2170d64ceaSPaul Mackerras #include <linux/kernel.h> 2270d64ceaSPaul Mackerras #include <linux/errno.h> 2370d64ceaSPaul Mackerras #include <linux/string.h> 2466b15db6SPaul Gortmaker #include <linux/export.h> 2570d64ceaSPaul Mackerras #include <linux/types.h> 2670d64ceaSPaul Mackerras #include <linux/mman.h> 2770d64ceaSPaul Mackerras #include <linux/mm.h> 2870d64ceaSPaul Mackerras #include <linux/swap.h> 2970d64ceaSPaul Mackerras #include <linux/stddef.h> 3070d64ceaSPaul Mackerras #include <linux/vmalloc.h> 315a0e3ad6STejun Heo #include <linux/slab.h> 3206743521SAneesh Kumar K.V #include <linux/hugetlb.h> 3370d64ceaSPaul Mackerras 3470d64ceaSPaul Mackerras #include <asm/page.h> 3570d64ceaSPaul Mackerras #include <asm/mmu_context.h> 3670d64ceaSPaul Mackerras #include <asm/mmu.h> 3770d64ceaSPaul Mackerras #include <asm/smp.h> 3870d64ceaSPaul Mackerras #include <asm/machdep.h> 3970d64ceaSPaul Mackerras #include <asm/tlb.h> 4070d64ceaSPaul Mackerras #include <asm/processor.h> 4170d64ceaSPaul Mackerras #include <asm/cputable.h> 4270d64ceaSPaul Mackerras #include <asm/sections.h> 435e203d68SStephen Rothwell #include <asm/firmware.h> 4468cf0d64SAnton Blanchard #include <asm/dma.h> 45800fc3eeSDavid Gibson 469d9f2cccSChristophe Leroy #include <mm/mmu_decl.h> 4770d64ceaSPaul Mackerras 4878f1dbdeSAneesh Kumar K.V 4950de596dSAneesh Kumar K.V #ifdef CONFIG_PPC_BOOK3S_64 5050de596dSAneesh Kumar K.V /* 5150de596dSAneesh Kumar K.V * partition table and process table for ISA 3.0 5250de596dSAneesh Kumar K.V */ 5350de596dSAneesh Kumar K.V struct prtb_entry *process_tb; 5450de596dSAneesh Kumar K.V struct patb_entry *partition_tb; 55dd1842a2SAneesh Kumar K.V /* 56dd1842a2SAneesh Kumar K.V * page table size 57dd1842a2SAneesh Kumar K.V */ 58dd1842a2SAneesh Kumar K.V unsigned long __pte_index_size; 59dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pte_index_size); 60dd1842a2SAneesh Kumar K.V unsigned long __pmd_index_size; 61dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pmd_index_size); 62dd1842a2SAneesh Kumar K.V unsigned long __pud_index_size; 63dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pud_index_size); 64dd1842a2SAneesh Kumar K.V unsigned long __pgd_index_size; 65dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pgd_index_size); 66fae22116SAneesh Kumar K.V unsigned long __pud_cache_index; 67fae22116SAneesh Kumar K.V EXPORT_SYMBOL(__pud_cache_index); 68dd1842a2SAneesh Kumar K.V unsigned long __pte_table_size; 69dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pte_table_size); 70dd1842a2SAneesh Kumar K.V unsigned long __pmd_table_size; 71dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pmd_table_size); 72dd1842a2SAneesh Kumar K.V unsigned long __pud_table_size; 73dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pud_table_size); 74dd1842a2SAneesh Kumar K.V unsigned long __pgd_table_size; 75dd1842a2SAneesh Kumar K.V EXPORT_SYMBOL(__pgd_table_size); 76a2f41eb9SAneesh Kumar K.V unsigned long __pmd_val_bits; 77a2f41eb9SAneesh Kumar K.V EXPORT_SYMBOL(__pmd_val_bits); 78a2f41eb9SAneesh Kumar K.V unsigned long __pud_val_bits; 79a2f41eb9SAneesh Kumar K.V EXPORT_SYMBOL(__pud_val_bits); 80a2f41eb9SAneesh Kumar K.V unsigned long __pgd_val_bits; 81a2f41eb9SAneesh Kumar K.V EXPORT_SYMBOL(__pgd_val_bits); 82d6a9996eSAneesh Kumar K.V unsigned long __kernel_virt_start; 83d6a9996eSAneesh Kumar K.V EXPORT_SYMBOL(__kernel_virt_start); 84d6a9996eSAneesh Kumar K.V unsigned long __vmalloc_start; 85d6a9996eSAneesh Kumar K.V EXPORT_SYMBOL(__vmalloc_start); 86d6a9996eSAneesh Kumar K.V unsigned long __vmalloc_end; 87d6a9996eSAneesh Kumar K.V EXPORT_SYMBOL(__vmalloc_end); 8863ee9b2fSMichael Ellerman unsigned long __kernel_io_start; 8963ee9b2fSMichael Ellerman EXPORT_SYMBOL(__kernel_io_start); 90a35a3c6fSAneesh Kumar K.V unsigned long __kernel_io_end; 91d6a9996eSAneesh Kumar K.V struct page *vmemmap; 92d6a9996eSAneesh Kumar K.V EXPORT_SYMBOL(vmemmap); 935ed7ecd0SAneesh Kumar K.V unsigned long __pte_frag_nr; 945ed7ecd0SAneesh Kumar K.V EXPORT_SYMBOL(__pte_frag_nr); 955ed7ecd0SAneesh Kumar K.V unsigned long __pte_frag_size_shift; 965ed7ecd0SAneesh Kumar K.V EXPORT_SYMBOL(__pte_frag_size_shift); 97d6a9996eSAneesh Kumar K.V #endif 98a245067eSBenjamin Herrenschmidt 9906743521SAneesh Kumar K.V #ifndef __PAGETABLE_PUD_FOLDED 10006743521SAneesh Kumar K.V /* 4 level page table */ p4d_page(p4d_t p4d)1012fb47060SMike Rapoportstruct page *p4d_page(p4d_t p4d) 10206743521SAneesh Kumar K.V { 1032fb47060SMike Rapoport if (p4d_is_leaf(p4d)) { 104*467ba14eSNicholas Piggin if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) 1052fb47060SMike Rapoport VM_WARN_ON(!p4d_huge(p4d)); 1062fb47060SMike Rapoport return pte_page(p4d_pte(p4d)); 107d6eaceddSAneesh Kumar K.V } 108dc4875f0SAneesh Kumar K.V return virt_to_page(p4d_pgtable(p4d)); 10906743521SAneesh Kumar K.V } 11006743521SAneesh Kumar K.V #endif 11106743521SAneesh Kumar K.V pud_page(pud_t pud)11206743521SAneesh Kumar K.Vstruct page *pud_page(pud_t pud) 11306743521SAneesh Kumar K.V { 114d6eaceddSAneesh Kumar K.V if (pud_is_leaf(pud)) { 115*467ba14eSNicholas Piggin if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) 116d6eaceddSAneesh Kumar K.V VM_WARN_ON(!pud_huge(pud)); 11706743521SAneesh Kumar K.V return pte_page(pud_pte(pud)); 118d6eaceddSAneesh Kumar K.V } 1199cf6fa24SAneesh Kumar K.V return virt_to_page(pud_pgtable(pud)); 12006743521SAneesh Kumar K.V } 12106743521SAneesh Kumar K.V 122074c2eaeSAneesh Kumar K.V /* 123074c2eaeSAneesh Kumar K.V * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags 124074c2eaeSAneesh Kumar K.V * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address. 125074c2eaeSAneesh Kumar K.V */ pmd_page(pmd_t pmd)126074c2eaeSAneesh Kumar K.Vstruct page *pmd_page(pmd_t pmd) 127074c2eaeSAneesh Kumar K.V { 128d6eaceddSAneesh Kumar K.V if (pmd_is_leaf(pmd)) { 129*467ba14eSNicholas Piggin /* 130*467ba14eSNicholas Piggin * vmalloc_to_page may be called on any vmap address (not only 131*467ba14eSNicholas Piggin * vmalloc), and it uses pmd_page() etc., when huge vmap is 132*467ba14eSNicholas Piggin * enabled so these checks can't be used. 133*467ba14eSNicholas Piggin */ 134*467ba14eSNicholas Piggin if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) 1351ecf2cdcSAneesh Kumar K.V VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd))); 136e34aa03cSAneesh Kumar K.V return pte_page(pmd_pte(pmd)); 137d6eaceddSAneesh Kumar K.V } 138074c2eaeSAneesh Kumar K.V return virt_to_page(pmd_page_vaddr(pmd)); 139074c2eaeSAneesh Kumar K.V } 140074c2eaeSAneesh Kumar K.V 141cd65d697SBalbir Singh #ifdef CONFIG_STRICT_KERNEL_RWX mark_rodata_ro(void)142cd65d697SBalbir Singhvoid mark_rodata_ro(void) 143cd65d697SBalbir Singh { 144cd65d697SBalbir Singh if (!mmu_has_feature(MMU_FTR_KERNEL_RO)) { 145cd65d697SBalbir Singh pr_warn("Warning: Unable to mark rodata read only on this CPU.\n"); 146cd65d697SBalbir Singh return; 147cd65d697SBalbir Singh } 148cd65d697SBalbir Singh 1497614ff32SBalbir Singh if (radix_enabled()) 1507614ff32SBalbir Singh radix__mark_rodata_ro(); 1517614ff32SBalbir Singh else 152cd65d697SBalbir Singh hash__mark_rodata_ro(); 153453d87f6SRussell Currey 154453d87f6SRussell Currey // mark_initmem_nx() should have already run by now 155453d87f6SRussell Currey ptdump_check_wx(); 156cd65d697SBalbir Singh } 157029d9252SMichael Ellerman mark_initmem_nx(void)158029d9252SMichael Ellermanvoid mark_initmem_nx(void) 159029d9252SMichael Ellerman { 160029d9252SMichael Ellerman if (radix_enabled()) 161029d9252SMichael Ellerman radix__mark_initmem_nx(); 162029d9252SMichael Ellerman else 163029d9252SMichael Ellerman hash__mark_initmem_nx(); 164029d9252SMichael Ellerman } 165cd65d697SBalbir Singh #endif 166