* Page alignment is not checked as this is not a requirement of
* efi_free_pool().
*
- * @addr: address of page to be freed
- * Return: status code
+ * @addr: address of page to be freed
+ * @must_be_allocated: return success if the page is allocated
+ * Return: status code
*/
-static efi_status_t efi_check_allocated(u64 addr)
+static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated)
{
struct efi_mem_list *item;
u64 end = start + (item->desc.num_pages << EFI_PAGE_SHIFT);
if (addr >= start && addr < end) {
- if (item->desc.type != EFI_CONVENTIONAL_MEMORY)
+ if (must_be_allocated ^
+ (item->desc.type == EFI_CONVENTIONAL_MEMORY))
return EFI_SUCCESS;
else
return EFI_NOT_FOUND;
efi_uintn_t pages, uint64_t *memory)
{
u64 len = pages << EFI_PAGE_SHIFT;
- efi_status_t r = EFI_SUCCESS;
+ efi_status_t ret;
uint64_t addr;
/* Check import parameters */
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
addr = efi_find_free_memory(len, -1ULL);
- if (!addr) {
- r = EFI_OUT_OF_RESOURCES;
- break;
- }
+ if (!addr)
+ return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_MAX_ADDRESS:
/* Max address */
addr = efi_find_free_memory(len, *memory);
- if (!addr) {
- r = EFI_OUT_OF_RESOURCES;
- break;
- }
+ if (!addr)
+ return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_ADDRESS:
/* Exact address, reserve it. The addr is already in *memory. */
+ ret = efi_check_allocated(*memory, false);
+ if (ret != EFI_SUCCESS)
+ return EFI_NOT_FOUND;
addr = *memory;
break;
default:
/* UEFI doesn't specify other allocation types */
- r = EFI_INVALID_PARAMETER;
- break;
+ return EFI_INVALID_PARAMETER;
}
- if (r == EFI_SUCCESS) {
- uint64_t ret;
+ /* Reserve that map in our memory maps */
+ if (efi_add_memory_map(addr, pages, memory_type, true) != addr)
+ /* Map would overlap, bail out */
+ return EFI_OUT_OF_RESOURCES;
- /* Reserve that map in our memory maps */
- ret = efi_add_memory_map(addr, pages, memory_type, true);
- if (ret == addr) {
- *memory = addr;
- } else {
- /* Map would overlap, bail out */
- r = EFI_OUT_OF_RESOURCES;
- }
- }
+ *memory = addr;
- return r;
+ return EFI_SUCCESS;
}
void *efi_alloc(uint64_t len, int memory_type)
uint64_t r = 0;
efi_status_t ret;
- ret = efi_check_allocated(memory);
+ ret = efi_check_allocated(memory, true);
if (ret != EFI_SUCCESS)
return ret;
efi_status_t ret;
struct efi_pool_allocation *alloc;
- ret = efi_check_allocated((uintptr_t)buffer);
+ ret = efi_check_allocated((uintptr_t)buffer, true);
if (ret != EFI_SUCCESS)
return ret;