~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/mm/init-common.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *  PowerPC version
  4  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  5  *
  6  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  7  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  8  *    Copyright (C) 1996 Paul Mackerras
  9  *
 10  *  Derived from "arch/i386/mm/init.c"
 11  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
 12  *
 13  *  Dave Engebretsen <engebret@us.ibm.com>
 14  *      Rework for PPC64 port.
 15  */
 16 
 17 #undef DEBUG
 18 
 19 #include <linux/string.h>
 20 #include <linux/pgtable.h>
 21 #include <asm/pgalloc.h>
 22 #include <asm/kup.h>
 23 #include <asm/smp.h>
 24 
 25 phys_addr_t memstart_addr __ro_after_init = (phys_addr_t)~0ull;
 26 EXPORT_SYMBOL_GPL(memstart_addr);
 27 phys_addr_t kernstart_addr __ro_after_init;
 28 EXPORT_SYMBOL_GPL(kernstart_addr);
 29 unsigned long kernstart_virt_addr __ro_after_init = KERNELBASE;
 30 EXPORT_SYMBOL_GPL(kernstart_virt_addr);
 31 
 32 bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP);
 33 bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP);
 34 #ifdef CONFIG_KFENCE
 35 bool __ro_after_init kfence_disabled;
 36 #endif
 37 
 38 static int __init parse_nosmep(char *p)
 39 {
 40         if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64))
 41                 return 0;
 42 
 43         disable_kuep = true;
 44         pr_warn("Disabling Kernel Userspace Execution Prevention\n");
 45         return 0;
 46 }
 47 early_param("nosmep", parse_nosmep);
 48 
 49 static int __init parse_nosmap(char *p)
 50 {
 51         disable_kuap = true;
 52         pr_warn("Disabling Kernel Userspace Access Protection\n");
 53         return 0;
 54 }
 55 early_param("nosmap", parse_nosmap);
 56 
 57 void __weak setup_kuep(bool disabled)
 58 {
 59         if (!IS_ENABLED(CONFIG_PPC_KUEP) || disabled)
 60                 return;
 61 
 62         if (smp_processor_id() != boot_cpuid)
 63                 return;
 64 
 65         pr_info("Activating Kernel Userspace Execution Prevention\n");
 66 }
 67 
 68 void setup_kup(void)
 69 {
 70         setup_kuap(disable_kuap);
 71         setup_kuep(disable_kuep);
 72 }
 73 
 74 #define CTOR(shift) static void ctor_##shift(void *addr) \
 75 {                                                       \
 76         memset(addr, 0, sizeof(pgd_t) << (shift));      \
 77 }
 78 
 79 CTOR(0); CTOR(1); CTOR(2); CTOR(3); CTOR(4); CTOR(5); CTOR(6); CTOR(7);
 80 CTOR(8); CTOR(9); CTOR(10); CTOR(11); CTOR(12); CTOR(13); CTOR(14); CTOR(15);
 81 
 82 static inline void (*ctor(int shift))(void *)
 83 {
 84         BUILD_BUG_ON(MAX_PGTABLE_INDEX_SIZE != 15);
 85 
 86         switch (shift) {
 87         case 0: return ctor_0;
 88         case 1: return ctor_1;
 89         case 2: return ctor_2;
 90         case 3: return ctor_3;
 91         case 4: return ctor_4;
 92         case 5: return ctor_5;
 93         case 6: return ctor_6;
 94         case 7: return ctor_7;
 95         case 8: return ctor_8;
 96         case 9: return ctor_9;
 97         case 10: return ctor_10;
 98         case 11: return ctor_11;
 99         case 12: return ctor_12;
100         case 13: return ctor_13;
101         case 14: return ctor_14;
102         case 15: return ctor_15;
103         }
104         return NULL;
105 }
106 
107 struct kmem_cache *pgtable_cache[MAX_PGTABLE_INDEX_SIZE + 1];
108 EXPORT_SYMBOL_GPL(pgtable_cache);       /* used by kvm_hv module */
109 
110 /*
111  * Create a kmem_cache() for pagetables.  This is not used for PTE
112  * pages - they're linked to struct page, come from the normal free
113  * pages pool and have a different entry size (see real_pte_t) to
114  * everything else.  Caches created by this function are used for all
115  * the higher level pagetables, and for hugepage pagetables.
116  */
117 void pgtable_cache_add(unsigned int shift)
118 {
119         char *name;
120         unsigned long table_size = sizeof(pgd_t) << shift;
121         unsigned long align = table_size;
122 
123         /* When batching pgtable pointers for RCU freeing, we store
124          * the index size in the low bits.  Table alignment must be
125          * big enough to fit it.
126          */
127         unsigned long minalign = MAX_PGTABLE_INDEX_SIZE + 1;
128         struct kmem_cache *new = NULL;
129 
130         /* It would be nice if this was a BUILD_BUG_ON(), but at the
131          * moment, gcc doesn't seem to recognize is_power_of_2 as a
132          * constant expression, so so much for that. */
133         BUG_ON(!is_power_of_2(minalign));
134         BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
135 
136         if (PGT_CACHE(shift))
137                 return; /* Already have a cache of this size */
138 
139         align = max_t(unsigned long, align, minalign);
140         name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift);
141         if (name)
142                 new = kmem_cache_create(name, table_size, align, 0, ctor(shift));
143         if (!new)
144                 panic("Could not allocate pgtable cache for order %d", shift);
145 
146         kfree(name);
147         pgtable_cache[shift] = new;
148 
149         pr_debug("Allocated pgtable cache for order %d\n", shift);
150 }
151 EXPORT_SYMBOL_GPL(pgtable_cache_add);   /* used by kvm_hv module */
152 
153 void pgtable_cache_init(void)
154 {
155         pgtable_cache_add(PGD_INDEX_SIZE);
156 
157         if (PMD_CACHE_INDEX)
158                 pgtable_cache_add(PMD_CACHE_INDEX);
159         /*
160          * In all current configs, when the PUD index exists it's the
161          * same size as either the pgd or pmd index except with THP enabled
162          * on book3s 64
163          */
164         if (PUD_CACHE_INDEX)
165                 pgtable_cache_add(PUD_CACHE_INDEX);
166 }
167 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php