1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
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
10 * Derived from "arch/i386/mm/init.c"
11 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
13 * Dave Engebretsen <engebret@us.ibm.com>
14 * Rework for PPC64 port.
19 #include <linux/signal.h>
20 #include <linux/sched.h>
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/string.h>
24 #include <linux/types.h>
25 #include <linux/mman.h>
27 #include <linux/swap.h>
28 #include <linux/stddef.h>
29 #include <linux/vmalloc.h>
30 #include <linux/init.h>
31 #include <linux/delay.h>
32 #include <linux/highmem.h>
33 #include <linux/idr.h>
34 #include <linux/nodemask.h>
35 #include <linux/module.h>
36 #include <linux/poison.h>
37 #include <linux/memblock.h>
38 #include <linux/hugetlb.h>
39 #include <linux/slab.h>
40 #include <linux/of_fdt.h>
41 #include <linux/libfdt.h>
42 #include <linux/memremap.h>
44 #include <asm/pgalloc.h>
49 #include <asm/mmu_context.h>
51 #include <linux/uaccess.h>
53 #include <asm/machdep.h>
56 #include <asm/processor.h>
57 #include <asm/mmzone.h>
58 #include <asm/cputable.h>
59 #include <asm/sections.h>
60 #include <asm/iommu.h>
63 #include <mm/mmu_decl.h>
65 #ifdef CONFIG_SPARSEMEM_VMEMMAP
67 * Given an address within the vmemmap, determine the page that
68 * represents the start of the subsection it is within. Note that we have to
69 * do this by hand as the proffered address may not be correctly aligned.
70 * Subtraction of non-aligned pointers produces undefined results.
72 static struct page
* __meminit
vmemmap_subsection_start(unsigned long vmemmap_addr
)
74 unsigned long start_pfn
;
75 unsigned long offset
= vmemmap_addr
- ((unsigned long)(vmemmap
));
77 /* Return the pfn of the start of the section. */
78 start_pfn
= (offset
/ sizeof(struct page
)) & PAGE_SUBSECTION_MASK
;
79 return pfn_to_page(start_pfn
);
83 * Since memory is added in sub-section chunks, before creating a new vmemmap
84 * mapping, the kernel should check whether there is an existing memmap mapping
85 * covering the new subsection added. This is needed because kernel can map
86 * vmemmap area using 16MB pages which will cover a memory range of 16G. Such
87 * a range covers multiple subsections (2M)
89 * If any subsection in the 16G range mapped by vmemmap is valid we consider the
90 * vmemmap populated (There is a page table entry already present). We can't do
91 * a page table lookup here because with the hash translation we don't keep
92 * vmemmap details in linux page table.
94 static int __meminit
vmemmap_populated(unsigned long vmemmap_addr
, int vmemmap_map_size
)
97 unsigned long vmemmap_end
= vmemmap_addr
+ vmemmap_map_size
;
98 start
= vmemmap_subsection_start(vmemmap_addr
);
100 for (; (unsigned long)start
< vmemmap_end
; start
+= PAGES_PER_SUBSECTION
)
102 * pfn valid check here is intended to really check
103 * whether we have any subsection already initialized
106 if (pfn_valid(page_to_pfn(start
)))
113 * vmemmap virtual address space management does not have a traditonal page
114 * table to track which virtual struct pages are backed by physical mapping.
115 * The virtual to physical mappings are tracked in a simple linked list
116 * format. 'vmemmap_list' maintains the entire vmemmap physical mapping at
117 * all times where as the 'next' list maintains the available
118 * vmemmap_backing structures which have been deleted from the
119 * 'vmemmap_global' list during system runtime (memory hotplug remove
120 * operation). The freed 'vmemmap_backing' structures are reused later when
121 * new requests come in without allocating fresh memory. This pointer also
122 * tracks the allocated 'vmemmap_backing' structures as we allocate one
123 * full page memory at a time when we dont have any.
125 struct vmemmap_backing
*vmemmap_list
;
126 static struct vmemmap_backing
*next
;
129 * The same pointer 'next' tracks individual chunks inside the allocated
130 * full page during the boot time and again tracks the freeed nodes during
131 * runtime. It is racy but it does not happen as they are separated by the
132 * boot process. Will create problem if some how we have memory hotplug
133 * operation during boot !!
136 static int num_freed
;
138 static __meminit
struct vmemmap_backing
* vmemmap_list_alloc(int node
)
140 struct vmemmap_backing
*vmem_back
;
141 /* get from freed entries first */
150 /* allocate a page when required and hand out chunks */
152 next
= vmemmap_alloc_block(PAGE_SIZE
, node
);
153 if (unlikely(!next
)) {
157 num_left
= PAGE_SIZE
/ sizeof(struct vmemmap_backing
);
165 static __meminit
void vmemmap_list_populate(unsigned long phys
,
169 struct vmemmap_backing
*vmem_back
;
171 vmem_back
= vmemmap_list_alloc(node
);
172 if (unlikely(!vmem_back
)) {
177 vmem_back
->phys
= phys
;
178 vmem_back
->virt_addr
= start
;
179 vmem_back
->list
= vmemmap_list
;
181 vmemmap_list
= vmem_back
;
184 static bool altmap_cross_boundary(struct vmem_altmap
*altmap
, unsigned long start
,
185 unsigned long page_size
)
187 unsigned long nr_pfn
= page_size
/ sizeof(struct page
);
188 unsigned long start_pfn
= page_to_pfn((struct page
*)start
);
190 if ((start_pfn
+ nr_pfn
) > altmap
->end_pfn
)
193 if (start_pfn
< altmap
->base_pfn
)
199 int __meminit
vmemmap_populate(unsigned long start
, unsigned long end
, int node
,
200 struct vmem_altmap
*altmap
)
202 unsigned long page_size
= 1 << mmu_psize_defs
[mmu_vmemmap_psize
].shift
;
204 /* Align to the page size of the linear mapping. */
205 start
= ALIGN_DOWN(start
, page_size
);
207 pr_debug("vmemmap_populate %lx..%lx, node %d\n", start
, end
, node
);
209 for (; start
< end
; start
+= page_size
) {
214 * This vmemmap range is backing different subsections. If any
215 * of that subsection is marked valid, that means we already
216 * have initialized a page table covering this range and hence
217 * the vmemmap range is populated.
219 if (vmemmap_populated(start
, page_size
))
223 * Allocate from the altmap first if we have one. This may
224 * fail due to alignment issues when using 16MB hugepages, so
225 * fall back to system memory if the altmap allocation fail.
227 if (altmap
&& !altmap_cross_boundary(altmap
, start
, page_size
)) {
228 p
= vmemmap_alloc_block_buf(page_size
, node
, altmap
);
230 pr_debug("altmap block allocation failed, falling back to system memory");
233 p
= vmemmap_alloc_block_buf(page_size
, node
, NULL
);
237 vmemmap_list_populate(__pa(p
), start
, node
);
239 pr_debug(" * %016lx..%016lx allocated at %p\n",
240 start
, start
+ page_size
, p
);
242 rc
= vmemmap_create_mapping(start
, page_size
, __pa(p
));
244 pr_warn("%s: Unable to create vmemmap mapping: %d\n",
253 #ifdef CONFIG_MEMORY_HOTPLUG
254 static unsigned long vmemmap_list_free(unsigned long start
)
256 struct vmemmap_backing
*vmem_back
, *vmem_back_prev
;
258 vmem_back_prev
= vmem_back
= vmemmap_list
;
260 /* look for it with prev pointer recorded */
261 for (; vmem_back
; vmem_back
= vmem_back
->list
) {
262 if (vmem_back
->virt_addr
== start
)
264 vmem_back_prev
= vmem_back
;
267 if (unlikely(!vmem_back
)) {
272 /* remove it from vmemmap_list */
273 if (vmem_back
== vmemmap_list
) /* remove head */
274 vmemmap_list
= vmem_back
->list
;
276 vmem_back_prev
->list
= vmem_back
->list
;
278 /* next point to this freed entry */
279 vmem_back
->list
= next
;
283 return vmem_back
->phys
;
286 void __ref
vmemmap_free(unsigned long start
, unsigned long end
,
287 struct vmem_altmap
*altmap
)
289 unsigned long page_size
= 1 << mmu_psize_defs
[mmu_vmemmap_psize
].shift
;
290 unsigned long page_order
= get_order(page_size
);
291 unsigned long alt_start
= ~0, alt_end
= ~0;
292 unsigned long base_pfn
;
294 start
= ALIGN_DOWN(start
, page_size
);
296 alt_start
= altmap
->base_pfn
;
297 alt_end
= altmap
->base_pfn
+ altmap
->reserve
+
298 altmap
->free
+ altmap
->alloc
+ altmap
->align
;
301 pr_debug("vmemmap_free %lx...%lx\n", start
, end
);
303 for (; start
< end
; start
+= page_size
) {
304 unsigned long nr_pages
, addr
;
308 * We have already marked the subsection we are trying to remove
309 * invalid. So if we want to remove the vmemmap range, we
310 * need to make sure there is no subsection marked valid
313 if (vmemmap_populated(start
, page_size
))
316 addr
= vmemmap_list_free(start
);
320 page
= pfn_to_page(addr
>> PAGE_SHIFT
);
321 nr_pages
= 1 << page_order
;
322 base_pfn
= PHYS_PFN(addr
);
324 if (base_pfn
>= alt_start
&& base_pfn
< alt_end
) {
325 vmem_altmap_free(altmap
, nr_pages
);
326 } else if (PageReserved(page
)) {
327 /* allocated from bootmem */
328 if (page_size
< PAGE_SIZE
) {
330 * this shouldn't happen, but if it is
331 * the case, leave the memory there
336 free_reserved_page(page
++);
339 free_pages((unsigned long)(__va(addr
)), page_order
);
342 vmemmap_remove_mapping(start
, page_size
);
346 void register_page_bootmem_memmap(unsigned long section_nr
,
347 struct page
*start_page
, unsigned long size
)
351 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
353 #ifdef CONFIG_PPC_BOOK3S_64
354 static bool disable_radix
= !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT
);
356 static int __init
parse_disable_radix(char *p
)
362 else if (kstrtobool(p
, &val
))
369 early_param("disable_radix", parse_disable_radix
);
372 * If we're running under a hypervisor, we need to check the contents of
373 * /chosen/ibm,architecture-vec-5 to see if the hypervisor is willing to do
374 * radix. If not, we clear the radix feature bit so we fall back to hash.
376 static void __init
early_check_vec5(void)
378 unsigned long root
, chosen
;
383 root
= of_get_flat_dt_root();
384 chosen
= of_get_flat_dt_subnode_by_name(root
, "chosen");
385 if (chosen
== -FDT_ERR_NOTFOUND
) {
386 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_TYPE_RADIX
;
389 vec5
= of_get_flat_dt_prop(chosen
, "ibm,architecture-vec-5", &size
);
391 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_TYPE_RADIX
;
394 if (size
<= OV5_INDX(OV5_MMU_SUPPORT
)) {
395 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_TYPE_RADIX
;
399 /* Check for supported configuration */
400 mmu_supported
= vec5
[OV5_INDX(OV5_MMU_SUPPORT
)] &
401 OV5_FEAT(OV5_MMU_SUPPORT
);
402 if (mmu_supported
== OV5_FEAT(OV5_MMU_RADIX
)) {
403 /* Hypervisor only supports radix - check enabled && GTSE */
404 if (!early_radix_enabled()) {
405 pr_warn("WARNING: Ignoring cmdline option disable_radix\n");
407 if (!(vec5
[OV5_INDX(OV5_RADIX_GTSE
)] &
408 OV5_FEAT(OV5_RADIX_GTSE
))) {
409 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_GTSE
;
411 cur_cpu_spec
->mmu_features
|= MMU_FTR_GTSE
;
412 /* Do radix anyway - the hypervisor said we had to */
413 cur_cpu_spec
->mmu_features
|= MMU_FTR_TYPE_RADIX
;
414 } else if (mmu_supported
== OV5_FEAT(OV5_MMU_HASH
)) {
415 /* Hypervisor only supports hash - disable radix */
416 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_TYPE_RADIX
;
417 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_GTSE
;
421 void __init
mmu_early_init_devtree(void)
423 /* Disable radix mode based on kernel command line. */
425 cur_cpu_spec
->mmu_features
&= ~MMU_FTR_TYPE_RADIX
;
428 * Check /chosen/ibm,architecture-vec-5 if running as a guest.
429 * When running bare-metal, we can use radix if we like
430 * even though the ibm,architecture-vec-5 property created by
431 * skiboot doesn't have the necessary bits set.
433 if (!(mfmsr() & MSR_HV
))
436 if (early_radix_enabled())
437 radix__early_init_devtree();
439 hash__early_init_devtree();
441 #endif /* CONFIG_PPC_BOOK3S_64 */