Example #1
0
/**
 * Reallocate external memory
 *
 * @v old_ptr		Memory previously allocated by umalloc(), or UNULL
 * @v new_size		Requested size
 * @ret new_ptr		Allocated memory, or UNULL
 *
 * Calling realloc() with a new size of zero is a valid way to free a
 * memory block.
 */
static userptr_t efi_urealloc ( userptr_t old_ptr, size_t new_size ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_PHYSICAL_ADDRESS phys_addr;
	unsigned int new_pages, old_pages;
	userptr_t new_ptr = UNOWHERE;
	size_t old_size;
	EFI_STATUS efirc;
	int rc;

	/* Allocate new memory if necessary.  If allocation fails,
	 * return without touching the old block.
	 */
	if ( new_size ) {
		new_pages = ( EFI_SIZE_TO_PAGES ( new_size ) + 1 );
		if ( ( efirc = bs->AllocatePages ( AllocateAnyPages,
						   EfiBootServicesData,
						   new_pages,
						   &phys_addr ) ) != 0 ) {
			rc = -EEFI ( efirc );
			DBG ( "EFI could not allocate %d pages: %s\n",
			      new_pages, strerror ( rc ) );
			return UNULL;
		}
		assert ( phys_addr != 0 );
		new_ptr = phys_to_user ( phys_addr + EFI_PAGE_SIZE );
		copy_to_user ( new_ptr, -EFI_PAGE_SIZE,
			       &new_size, sizeof ( new_size ) );
		DBG ( "EFI allocated %d pages at %llx\n",
		      new_pages, phys_addr );
	}

	/* Copy across relevant part of the old data region (if any),
	 * then free it.  Note that at this point either (a) new_ptr
	 * is valid, or (b) new_size is 0; either way, the memcpy() is
	 * valid.
	 */
	if ( old_ptr && ( old_ptr != UNOWHERE ) ) {
		copy_from_user ( &old_size, old_ptr, -EFI_PAGE_SIZE,
				 sizeof ( old_size ) );
		memcpy_user ( new_ptr, 0, old_ptr, 0,
			      ( (old_size < new_size) ? old_size : new_size ));
		old_pages = ( EFI_SIZE_TO_PAGES ( old_size ) + 1 );
		phys_addr = user_to_phys ( old_ptr, -EFI_PAGE_SIZE );
		if ( ( efirc = bs->FreePages ( phys_addr, old_pages ) ) != 0 ){
			rc = -EEFI ( efirc );
			DBG ( "EFI could not free %d pages at %llx: %s\n",
			      old_pages, phys_addr, strerror ( rc ) );
			/* Not fatal; we have leaked memory but successfully
			 * allocated (if asked to do so).
			 */
		}
		DBG ( "EFI freed %d pages at %llx\n", old_pages, phys_addr );
	}

	return new_ptr;
}
Example #2
0
EFI_STATUS EFIAPI
OvrFreePages(
	IN EFI_PHYSICAL_ADDRESS Memory,
	IN UINTN Pages
)  
{
	EFI_STATUS			Status;
	
	Status = gOrgBS.FreePages(Memory, Pages);
//	PRINT("->FreePages(0x%lx, 0x%x) = %r\n", Memory, Pages, Status);
	return Status;
}