2 * Copyright 2005, Paul Mackerras, IBM Corporation.
3 * Copyright 2009, Benjamin Herrenschmidt, IBM Corporation.
4 * Copyright 2015-2016, Aneesh Kumar K.V, IBM Corporation.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
12 #include <linux/sched.h>
13 #include <asm/pgalloc.h>
18 #ifdef CONFIG_SPARSEMEM_VMEMMAP
20 * On hash-based CPUs, the vmemmap is bolted in the hash table.
23 int __meminit vmemmap_create_mapping(unsigned long start,
24 unsigned long page_size,
27 int rc = htab_bolt_mapping(start, start + page_size, phys,
28 pgprot_val(PAGE_KERNEL),
29 mmu_vmemmap_psize, mmu_kernel_ssize);
31 int rc2 = htab_remove_mapping(start, start + page_size,
34 BUG_ON(rc2 && (rc2 != -ENOENT));
39 #ifdef CONFIG_MEMORY_HOTPLUG
40 void vmemmap_remove_mapping(unsigned long start,
41 unsigned long page_size)
43 int rc = htab_remove_mapping(start, start + page_size,
46 BUG_ON((rc < 0) && (rc != -ENOENT));
47 WARN_ON(rc == -ENOENT);
50 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
53 * map_kernel_page currently only called by __ioremap
54 * map_kernel_page adds an entry to the ioremap page table
55 * and adds an entry to the HPT, possibly bolting it
57 int map_kernel_page(unsigned long ea, unsigned long pa, unsigned long flags)
64 if (slab_is_available()) {
65 pgdp = pgd_offset_k(ea);
66 pudp = pud_alloc(&init_mm, pgdp, ea);
69 pmdp = pmd_alloc(&init_mm, pudp, ea);
72 ptep = pte_alloc_kernel(pmdp, ea);
75 set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
79 * If the mm subsystem is not fully up, we cannot create a
80 * linux page table entry for this mapping. Simply bolt an
81 * entry in the hardware page table.
84 if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
85 mmu_io_psize, mmu_kernel_ssize)) {
86 printk(KERN_ERR "Failed to do bolted mapping IO "
87 "memory at %016lx !\n", pa);