2 * Virtual Memory Map support
4 * (C) 2007 sgi. Christoph Lameter.
6 * Virtual memory maps allow VM primitives pfn_to_page, page_to_pfn,
7 * virt_to_page, page_address() to be implemented as a base offset
8 * calculation without memory access.
10 * However, virtual mappings need a page table and TLBs. Many Linux
11 * architectures already map their physical space using 1-1 mappings
12 * via TLBs. For those arches the virtual memory map is essentially
13 * for free if we use the same page size as the 1-1 mappings. In that
14 * case the overhead consists of a few additional pages that are
15 * allocated to create a view of memory for vmemmap.
17 * The architecture is expected to provide a vmemmap_populate() function
18 * to instantiate the mapping.
21 #include <linux/mmzone.h>
22 #include <linux/bootmem.h>
23 #include <linux/memremap.h>
24 #include <linux/highmem.h>
25 #include <linux/slab.h>
26 #include <linux/spinlock.h>
27 #include <linux/vmalloc.h>
28 #include <linux/sched.h>
30 #include <asm/pgalloc.h>
31 #include <asm/pgtable.h>
34 * Allocate a block of memory to be used to back the virtual memory map
35 * or to back the page tables that are used to create the mapping.
36 * Uses the main allocators if they are available, else bootmem.
39 static void * __ref
__earlyonly_bootmem_alloc(int node
,
44 return memblock_virt_alloc_try_nid(size
, align
, goal
,
45 BOOTMEM_ALLOC_ACCESSIBLE
, node
);
48 static void *vmemmap_buf
;
49 static void *vmemmap_buf_end
;
51 void * __meminit
vmemmap_alloc_block(unsigned long size
, int node
)
53 /* If the main allocator is up use that, fallback to bootmem. */
54 if (slab_is_available()) {
57 if (node_state(node
, N_HIGH_MEMORY
))
58 page
= alloc_pages_node(
59 node
, GFP_KERNEL
| __GFP_ZERO
| __GFP_REPEAT
,
63 GFP_KERNEL
| __GFP_ZERO
| __GFP_REPEAT
,
66 return page_address(page
);
69 return __earlyonly_bootmem_alloc(node
, size
, size
,
70 __pa(MAX_DMA_ADDRESS
));
73 /* need to make sure size is all the same during early stage */
74 static void * __meminit
alloc_block_buf(unsigned long size
, int node
)
79 return vmemmap_alloc_block(size
, node
);
81 /* take the from buf */
82 ptr
= (void *)ALIGN((unsigned long)vmemmap_buf
, size
);
83 if (ptr
+ size
> vmemmap_buf_end
)
84 return vmemmap_alloc_block(size
, node
);
86 vmemmap_buf
= ptr
+ size
;
91 static unsigned long __meminit
vmem_altmap_next_pfn(struct vmem_altmap
*altmap
)
93 return altmap
->base_pfn
+ altmap
->reserve
+ altmap
->alloc
97 static unsigned long __meminit
vmem_altmap_nr_free(struct vmem_altmap
*altmap
)
99 unsigned long allocated
= altmap
->alloc
+ altmap
->align
;
101 if (altmap
->free
> allocated
)
102 return altmap
->free
- allocated
;
107 * vmem_altmap_alloc - allocate pages from the vmem_altmap reservation
108 * @altmap - reserved page pool for the allocation
109 * @nr_pfns - size (in pages) of the allocation
111 * Allocations are aligned to the size of the request
113 static unsigned long __meminit
vmem_altmap_alloc(struct vmem_altmap
*altmap
,
114 unsigned long nr_pfns
)
116 unsigned long pfn
= vmem_altmap_next_pfn(altmap
);
117 unsigned long nr_align
;
119 nr_align
= 1UL << find_first_bit(&nr_pfns
, BITS_PER_LONG
);
120 nr_align
= ALIGN(pfn
, nr_align
) - pfn
;
122 if (nr_pfns
+ nr_align
> vmem_altmap_nr_free(altmap
))
124 altmap
->alloc
+= nr_pfns
;
125 altmap
->align
+= nr_align
;
126 return pfn
+ nr_align
;
129 static void * __meminit
altmap_alloc_block_buf(unsigned long size
,
130 struct vmem_altmap
*altmap
)
132 unsigned long pfn
, nr_pfns
;
135 if (size
& ~PAGE_MASK
) {
136 pr_warn_once("%s: allocations must be multiple of PAGE_SIZE (%ld)\n",
141 nr_pfns
= size
>> PAGE_SHIFT
;
142 pfn
= vmem_altmap_alloc(altmap
, nr_pfns
);
144 ptr
= __va(__pfn_to_phys(pfn
));
147 pr_debug("%s: pfn: %#lx alloc: %ld align: %ld nr: %#lx\n",
148 __func__
, pfn
, altmap
->alloc
, altmap
->align
, nr_pfns
);
153 /* need to make sure size is all the same during early stage */
154 void * __meminit
__vmemmap_alloc_block_buf(unsigned long size
, int node
,
155 struct vmem_altmap
*altmap
)
158 return altmap_alloc_block_buf(size
, altmap
);
159 return alloc_block_buf(size
, node
);
162 void __meminit
vmemmap_verify(pte_t
*pte
, int node
,
163 unsigned long start
, unsigned long end
)
165 unsigned long pfn
= pte_pfn(*pte
);
166 int actual_node
= early_pfn_to_nid(pfn
);
168 if (node_distance(actual_node
, node
) > LOCAL_DISTANCE
)
169 pr_warn("[%lx-%lx] potential offnode page_structs\n",
173 pte_t
* __meminit
vmemmap_pte_populate(pmd_t
*pmd
, unsigned long addr
, int node
)
175 pte_t
*pte
= pte_offset_kernel(pmd
, addr
);
176 if (pte_none(*pte
)) {
178 void *p
= alloc_block_buf(PAGE_SIZE
, node
);
181 entry
= pfn_pte(__pa(p
) >> PAGE_SHIFT
, PAGE_KERNEL
);
182 set_pte_at(&init_mm
, addr
, pte
, entry
);
187 pmd_t
* __meminit
vmemmap_pmd_populate(pud_t
*pud
, unsigned long addr
, int node
)
189 pmd_t
*pmd
= pmd_offset(pud
, addr
);
190 if (pmd_none(*pmd
)) {
191 void *p
= vmemmap_alloc_block(PAGE_SIZE
, node
);
194 pmd_populate_kernel(&init_mm
, pmd
, p
);
199 pud_t
* __meminit
vmemmap_pud_populate(pgd_t
*pgd
, unsigned long addr
, int node
)
201 pud_t
*pud
= pud_offset(pgd
, addr
);
202 if (pud_none(*pud
)) {
203 void *p
= vmemmap_alloc_block(PAGE_SIZE
, node
);
206 pud_populate(&init_mm
, pud
, p
);
211 pgd_t
* __meminit
vmemmap_pgd_populate(unsigned long addr
, int node
)
213 pgd_t
*pgd
= pgd_offset_k(addr
);
214 if (pgd_none(*pgd
)) {
215 void *p
= vmemmap_alloc_block(PAGE_SIZE
, node
);
218 pgd_populate(&init_mm
, pgd
, p
);
223 int __meminit
vmemmap_populate_basepages(unsigned long start
,
224 unsigned long end
, int node
)
226 unsigned long addr
= start
;
232 for (; addr
< end
; addr
+= PAGE_SIZE
) {
233 pgd
= vmemmap_pgd_populate(addr
, node
);
236 pud
= vmemmap_pud_populate(pgd
, addr
, node
);
239 pmd
= vmemmap_pmd_populate(pud
, addr
, node
);
242 pte
= vmemmap_pte_populate(pmd
, addr
, node
);
245 vmemmap_verify(pte
, node
, addr
, addr
+ PAGE_SIZE
);
251 struct page
* __meminit
sparse_mem_map_populate(unsigned long pnum
, int nid
)
257 map
= pfn_to_page(pnum
* PAGES_PER_SECTION
);
258 start
= (unsigned long)map
;
259 end
= (unsigned long)(map
+ PAGES_PER_SECTION
);
261 if (vmemmap_populate(start
, end
, nid
))
267 void __init
sparse_mem_maps_populate_node(struct page
**map_map
,
268 unsigned long pnum_begin
,
269 unsigned long pnum_end
,
270 unsigned long map_count
, int nodeid
)
273 unsigned long size
= sizeof(struct page
) * PAGES_PER_SECTION
;
274 void *vmemmap_buf_start
;
276 size
= ALIGN(size
, PMD_SIZE
);
277 vmemmap_buf_start
= __earlyonly_bootmem_alloc(nodeid
, size
* map_count
,
278 PMD_SIZE
, __pa(MAX_DMA_ADDRESS
));
280 if (vmemmap_buf_start
) {
281 vmemmap_buf
= vmemmap_buf_start
;
282 vmemmap_buf_end
= vmemmap_buf_start
+ size
* map_count
;
285 for (pnum
= pnum_begin
; pnum
< pnum_end
; pnum
++) {
286 struct mem_section
*ms
;
288 if (!present_section_nr(pnum
))
291 map_map
[pnum
] = sparse_mem_map_populate(pnum
, nodeid
);
294 ms
= __nr_to_section(pnum
);
295 pr_err("%s: sparsemem memory map backing failed some memory will not be available\n",
297 ms
->section_mem_map
= 0;
300 if (vmemmap_buf_start
) {
301 /* need to free left buf */
302 memblock_free_early(__pa(vmemmap_buf
),
303 vmemmap_buf_end
- vmemmap_buf
);
305 vmemmap_buf_end
= NULL
;