memmap.c (10101B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Common EFI memory map functions. 4 */ 5 6#define pr_fmt(fmt) "efi: " fmt 7 8#include <linux/init.h> 9#include <linux/kernel.h> 10#include <linux/efi.h> 11#include <linux/io.h> 12#include <asm/early_ioremap.h> 13#include <linux/memblock.h> 14#include <linux/slab.h> 15 16static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size) 17{ 18 return memblock_phys_alloc(size, SMP_CACHE_BYTES); 19} 20 21static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size) 22{ 23 unsigned int order = get_order(size); 24 struct page *p = alloc_pages(GFP_KERNEL, order); 25 26 if (!p) 27 return 0; 28 29 return PFN_PHYS(page_to_pfn(p)); 30} 31 32void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags) 33{ 34 if (flags & EFI_MEMMAP_MEMBLOCK) { 35 if (slab_is_available()) 36 memblock_free_late(phys, size); 37 else 38 memblock_phys_free(phys, size); 39 } else if (flags & EFI_MEMMAP_SLAB) { 40 struct page *p = pfn_to_page(PHYS_PFN(phys)); 41 unsigned int order = get_order(size); 42 43 free_pages((unsigned long) page_address(p), order); 44 } 45} 46 47static void __init efi_memmap_free(void) 48{ 49 __efi_memmap_free(efi.memmap.phys_map, 50 efi.memmap.desc_size * efi.memmap.nr_map, 51 efi.memmap.flags); 52} 53 54/** 55 * efi_memmap_alloc - Allocate memory for the EFI memory map 56 * @num_entries: Number of entries in the allocated map. 57 * @data: efi memmap installation parameters 58 * 59 * Depending on whether mm_init() has already been invoked or not, 60 * either memblock or "normal" page allocation is used. 61 * 62 * Returns the physical address of the allocated memory map on 63 * success, zero on failure. 64 */ 65int __init efi_memmap_alloc(unsigned int num_entries, 66 struct efi_memory_map_data *data) 67{ 68 /* Expect allocation parameters are zero initialized */ 69 WARN_ON(data->phys_map || data->size); 70 71 data->size = num_entries * efi.memmap.desc_size; 72 data->desc_version = efi.memmap.desc_version; 73 data->desc_size = efi.memmap.desc_size; 74 data->flags &= ~(EFI_MEMMAP_SLAB | EFI_MEMMAP_MEMBLOCK); 75 data->flags |= efi.memmap.flags & EFI_MEMMAP_LATE; 76 77 if (slab_is_available()) { 78 data->flags |= EFI_MEMMAP_SLAB; 79 data->phys_map = __efi_memmap_alloc_late(data->size); 80 } else { 81 data->flags |= EFI_MEMMAP_MEMBLOCK; 82 data->phys_map = __efi_memmap_alloc_early(data->size); 83 } 84 85 if (!data->phys_map) 86 return -ENOMEM; 87 return 0; 88} 89 90/** 91 * __efi_memmap_init - Common code for mapping the EFI memory map 92 * @data: EFI memory map data 93 * 94 * This function takes care of figuring out which function to use to 95 * map the EFI memory map in efi.memmap based on how far into the boot 96 * we are. 97 * 98 * During bootup EFI_MEMMAP_LATE in data->flags should be clear since we 99 * only have access to the early_memremap*() functions as the vmalloc 100 * space isn't setup. Once the kernel is fully booted we can fallback 101 * to the more robust memremap*() API. 102 * 103 * Returns zero on success, a negative error code on failure. 104 */ 105static int __init __efi_memmap_init(struct efi_memory_map_data *data) 106{ 107 struct efi_memory_map map; 108 phys_addr_t phys_map; 109 110 if (efi_enabled(EFI_PARAVIRT)) 111 return 0; 112 113 phys_map = data->phys_map; 114 115 if (data->flags & EFI_MEMMAP_LATE) 116 map.map = memremap(phys_map, data->size, MEMREMAP_WB); 117 else 118 map.map = early_memremap(phys_map, data->size); 119 120 if (!map.map) { 121 pr_err("Could not map the memory map!\n"); 122 return -ENOMEM; 123 } 124 125 /* NOP if data->flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB) == 0 */ 126 efi_memmap_free(); 127 128 map.phys_map = data->phys_map; 129 map.nr_map = data->size / data->desc_size; 130 map.map_end = map.map + data->size; 131 132 map.desc_version = data->desc_version; 133 map.desc_size = data->desc_size; 134 map.flags = data->flags; 135 136 set_bit(EFI_MEMMAP, &efi.flags); 137 138 efi.memmap = map; 139 140 return 0; 141} 142 143/** 144 * efi_memmap_init_early - Map the EFI memory map data structure 145 * @data: EFI memory map data 146 * 147 * Use early_memremap() to map the passed in EFI memory map and assign 148 * it to efi.memmap. 149 */ 150int __init efi_memmap_init_early(struct efi_memory_map_data *data) 151{ 152 /* Cannot go backwards */ 153 WARN_ON(efi.memmap.flags & EFI_MEMMAP_LATE); 154 155 data->flags = 0; 156 return __efi_memmap_init(data); 157} 158 159void __init efi_memmap_unmap(void) 160{ 161 if (!efi_enabled(EFI_MEMMAP)) 162 return; 163 164 if (!(efi.memmap.flags & EFI_MEMMAP_LATE)) { 165 unsigned long size; 166 167 size = efi.memmap.desc_size * efi.memmap.nr_map; 168 early_memunmap(efi.memmap.map, size); 169 } else { 170 memunmap(efi.memmap.map); 171 } 172 173 efi.memmap.map = NULL; 174 clear_bit(EFI_MEMMAP, &efi.flags); 175} 176 177/** 178 * efi_memmap_init_late - Map efi.memmap with memremap() 179 * @phys_addr: Physical address of the new EFI memory map 180 * @size: Size in bytes of the new EFI memory map 181 * 182 * Setup a mapping of the EFI memory map using ioremap_cache(). This 183 * function should only be called once the vmalloc space has been 184 * setup and is therefore not suitable for calling during early EFI 185 * initialise, e.g. in efi_init(). Additionally, it expects 186 * efi_memmap_init_early() to have already been called. 187 * 188 * The reason there are two EFI memmap initialisation 189 * (efi_memmap_init_early() and this late version) is because the 190 * early EFI memmap should be explicitly unmapped once EFI 191 * initialisation is complete as the fixmap space used to map the EFI 192 * memmap (via early_memremap()) is a scarce resource. 193 * 194 * This late mapping is intended to persist for the duration of 195 * runtime so that things like efi_mem_desc_lookup() and 196 * efi_mem_attributes() always work. 197 * 198 * Returns zero on success, a negative error code on failure. 199 */ 200int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size) 201{ 202 struct efi_memory_map_data data = { 203 .phys_map = addr, 204 .size = size, 205 .flags = EFI_MEMMAP_LATE, 206 }; 207 208 /* Did we forget to unmap the early EFI memmap? */ 209 WARN_ON(efi.memmap.map); 210 211 /* Were we already called? */ 212 WARN_ON(efi.memmap.flags & EFI_MEMMAP_LATE); 213 214 /* 215 * It makes no sense to allow callers to register different 216 * values for the following fields. Copy them out of the 217 * existing early EFI memmap. 218 */ 219 data.desc_version = efi.memmap.desc_version; 220 data.desc_size = efi.memmap.desc_size; 221 222 return __efi_memmap_init(&data); 223} 224 225/** 226 * efi_memmap_install - Install a new EFI memory map in efi.memmap 227 * @ctx: map allocation parameters (address, size, flags) 228 * 229 * Unlike efi_memmap_init_*(), this function does not allow the caller 230 * to switch from early to late mappings. It simply uses the existing 231 * mapping function and installs the new memmap. 232 * 233 * Returns zero on success, a negative error code on failure. 234 */ 235int __init efi_memmap_install(struct efi_memory_map_data *data) 236{ 237 efi_memmap_unmap(); 238 239 return __efi_memmap_init(data); 240} 241 242/** 243 * efi_memmap_split_count - Count number of additional EFI memmap entries 244 * @md: EFI memory descriptor to split 245 * @range: Address range (start, end) to split around 246 * 247 * Returns the number of additional EFI memmap entries required to 248 * accomodate @range. 249 */ 250int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) 251{ 252 u64 m_start, m_end; 253 u64 start, end; 254 int count = 0; 255 256 start = md->phys_addr; 257 end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; 258 259 /* modifying range */ 260 m_start = range->start; 261 m_end = range->end; 262 263 if (m_start <= start) { 264 /* split into 2 parts */ 265 if (start < m_end && m_end < end) 266 count++; 267 } 268 269 if (start < m_start && m_start < end) { 270 /* split into 3 parts */ 271 if (m_end < end) 272 count += 2; 273 /* split into 2 parts */ 274 if (end <= m_end) 275 count++; 276 } 277 278 return count; 279} 280 281/** 282 * efi_memmap_insert - Insert a memory region in an EFI memmap 283 * @old_memmap: The existing EFI memory map structure 284 * @buf: Address of buffer to store new map 285 * @mem: Memory map entry to insert 286 * 287 * It is suggested that you call efi_memmap_split_count() first 288 * to see how large @buf needs to be. 289 */ 290void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, 291 struct efi_mem_range *mem) 292{ 293 u64 m_start, m_end, m_attr; 294 efi_memory_desc_t *md; 295 u64 start, end; 296 void *old, *new; 297 298 /* modifying range */ 299 m_start = mem->range.start; 300 m_end = mem->range.end; 301 m_attr = mem->attribute; 302 303 /* 304 * The EFI memory map deals with regions in EFI_PAGE_SIZE 305 * units. Ensure that the region described by 'mem' is aligned 306 * correctly. 307 */ 308 if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) || 309 !IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) { 310 WARN_ON(1); 311 return; 312 } 313 314 for (old = old_memmap->map, new = buf; 315 old < old_memmap->map_end; 316 old += old_memmap->desc_size, new += old_memmap->desc_size) { 317 318 /* copy original EFI memory descriptor */ 319 memcpy(new, old, old_memmap->desc_size); 320 md = new; 321 start = md->phys_addr; 322 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; 323 324 if (m_start <= start && end <= m_end) 325 md->attribute |= m_attr; 326 327 if (m_start <= start && 328 (start < m_end && m_end < end)) { 329 /* first part */ 330 md->attribute |= m_attr; 331 md->num_pages = (m_end - md->phys_addr + 1) >> 332 EFI_PAGE_SHIFT; 333 /* latter part */ 334 new += old_memmap->desc_size; 335 memcpy(new, old, old_memmap->desc_size); 336 md = new; 337 md->phys_addr = m_end + 1; 338 md->num_pages = (end - md->phys_addr + 1) >> 339 EFI_PAGE_SHIFT; 340 } 341 342 if ((start < m_start && m_start < end) && m_end < end) { 343 /* first part */ 344 md->num_pages = (m_start - md->phys_addr) >> 345 EFI_PAGE_SHIFT; 346 /* middle part */ 347 new += old_memmap->desc_size; 348 memcpy(new, old, old_memmap->desc_size); 349 md = new; 350 md->attribute |= m_attr; 351 md->phys_addr = m_start; 352 md->num_pages = (m_end - m_start + 1) >> 353 EFI_PAGE_SHIFT; 354 /* last part */ 355 new += old_memmap->desc_size; 356 memcpy(new, old, old_memmap->desc_size); 357 md = new; 358 md->phys_addr = m_end + 1; 359 md->num_pages = (end - m_end) >> 360 EFI_PAGE_SHIFT; 361 } 362 363 if ((start < m_start && m_start < end) && 364 (end <= m_end)) { 365 /* first part */ 366 md->num_pages = (m_start - md->phys_addr) >> 367 EFI_PAGE_SHIFT; 368 /* latter part */ 369 new += old_memmap->desc_size; 370 memcpy(new, old, old_memmap->desc_size); 371 md = new; 372 md->phys_addr = m_start; 373 md->num_pages = (end - md->phys_addr + 1) >> 374 EFI_PAGE_SHIFT; 375 md->attribute |= m_attr; 376 } 377 } 378}