^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This file contains pgtable related functions for 64-bit machines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Derived from arch/ppc64/mm/init.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * and Cort Dougan (PReP) (cort@cs.nmt.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 1996 Paul Mackerras
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Derived from "arch/i386/mm/init.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Dave Engebretsen <engebret@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Rework for PPC64 port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/hugetlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/tlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/cputable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <asm/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <mm/mmu_decl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #ifdef CONFIG_PPC_BOOK3S_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * partition table and process table for ISA 3.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct prtb_entry *process_tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct patb_entry *partition_tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * page table size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long __pte_index_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) EXPORT_SYMBOL(__pte_index_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned long __pmd_index_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) EXPORT_SYMBOL(__pmd_index_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned long __pud_index_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) EXPORT_SYMBOL(__pud_index_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long __pgd_index_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) EXPORT_SYMBOL(__pgd_index_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long __pud_cache_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) EXPORT_SYMBOL(__pud_cache_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long __pte_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) EXPORT_SYMBOL(__pte_table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned long __pmd_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) EXPORT_SYMBOL(__pmd_table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned long __pud_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) EXPORT_SYMBOL(__pud_table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned long __pgd_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) EXPORT_SYMBOL(__pgd_table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned long __pmd_val_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) EXPORT_SYMBOL(__pmd_val_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned long __pud_val_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) EXPORT_SYMBOL(__pud_val_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned long __pgd_val_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) EXPORT_SYMBOL(__pgd_val_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long __kernel_virt_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) EXPORT_SYMBOL(__kernel_virt_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned long __vmalloc_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) EXPORT_SYMBOL(__vmalloc_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long __vmalloc_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) EXPORT_SYMBOL(__vmalloc_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long __kernel_io_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) EXPORT_SYMBOL(__kernel_io_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned long __kernel_io_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct page *vmemmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) EXPORT_SYMBOL(vmemmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned long __pte_frag_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) EXPORT_SYMBOL(__pte_frag_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned long __pte_frag_size_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) EXPORT_SYMBOL(__pte_frag_size_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #ifndef __PAGETABLE_PUD_FOLDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* 4 level page table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct page *p4d_page(p4d_t p4d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (p4d_is_leaf(p4d)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) VM_WARN_ON(!p4d_huge(p4d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return pte_page(p4d_pte(p4d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return virt_to_page(p4d_page_vaddr(p4d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct page *pud_page(pud_t pud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (pud_is_leaf(pud)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) VM_WARN_ON(!pud_huge(pud));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return pte_page(pud_pte(pud));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return virt_to_page(pud_page_vaddr(pud));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct page *pmd_page(pmd_t pmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (pmd_is_leaf(pmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * vmalloc_to_page may be called on any vmap address (not only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * vmalloc), and it uses pmd_page() etc., when huge vmap is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * enabled so these checks can't be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return pte_page(pmd_pte(pmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return virt_to_page(pmd_page_vaddr(pmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #ifdef CONFIG_STRICT_KERNEL_RWX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void mark_rodata_ro(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!mmu_has_feature(MMU_FTR_KERNEL_RO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) pr_warn("Warning: Unable to mark rodata read only on this CPU.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (radix_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) radix__mark_rodata_ro();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) hash__mark_rodata_ro();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) // mark_initmem_nx() should have already run by now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ptdump_check_wx();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) void mark_initmem_nx(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (radix_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) radix__mark_initmem_nx();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) hash__mark_initmem_nx();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #endif