^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <asm/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "efistub.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) static inline bool mmap_has_headroom(unsigned long buff_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) unsigned long map_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) unsigned long desc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) unsigned long slack = buff_size - map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * efi_get_memory_map() - get memory map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @map: on return pointer to memory map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Retrieve the UEFI memory map. The allocated memory leaves room for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Return: status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) efi_memory_desc_t *m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned long key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u32 desc_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *map->desc_size = sizeof(*m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *map->map_size = *map->desc_size * 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *map->buff_size = *map->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *map->map_size, (void **)&m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (status != EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *map->desc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) status = efi_bs_call(get_memory_map, map->map_size, m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) &key, map->desc_size, &desc_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (status == EFI_BUFFER_TOO_SMALL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) !mmap_has_headroom(*map->buff_size, *map->map_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *map->desc_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) efi_bs_call(free_pool, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Make sure there is some entries of headroom so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * buffer can be reused for a new map after allocations are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * no longer permitted. Its unlikely that the map will grow to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * exceed this headroom once we are ready to trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * ExitBootServices()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *map->buff_size = *map->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (status == EFI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (map->key_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *map->key_ptr = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (map->desc_ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *map->desc_ver = desc_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) efi_bs_call(free_pool, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *map->map = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * efi_allocate_pages() - Allocate memory pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @size: minimum number of bytes to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @addr: On return the address of the first allocated page. The first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * allocated page has alignment EFI_ALLOC_ALIGN which is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * architecture dependent multiple of the page size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @max: the address that the last allocated memory page shall not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * exceed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * to EFI_ALLOC_ALIGN. The last allocated page will not exceed the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * given by @max.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Return: status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned long max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) efi_physical_addr_t alloc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (EFI_ALLOC_ALIGN > EFI_PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return efi_allocate_pages_aligned(size, addr, max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) EFI_ALLOC_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) alloc_addr = ALIGN_DOWN(max + 1, EFI_ALLOC_ALIGN) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) EFI_LOADER_DATA, DIV_ROUND_UP(size, EFI_PAGE_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) &alloc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (status != EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *addr = alloc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return EFI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * efi_free() - free memory pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @size: size of the memory area to free in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @addr: start of the memory area to free (must be EFI_PAGE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * aligned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @size is rounded up to a multiple of EFI_ALLOC_ALIGN which is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * architecture specific multiple of EFI_PAGE_SIZE. So this function should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * only be used to return pages allocated with efi_allocate_pages() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * efi_low_alloc_above().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void efi_free(unsigned long size, unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned long nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) efi_bs_call(free_pages, addr, nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }