diff --git a/src/arch/riscv/interface/sbi/sbi_umalloc.c b/src/arch/riscv/interface/sbi/sbi_umalloc.c index 2f9935adb..0e351748b 100644 --- a/src/arch/riscv/interface/sbi/sbi_umalloc.c +++ b/src/arch/riscv/interface/sbi/sbi_umalloc.c @@ -32,23 +32,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ -/** Equivalent of NOWHERE for user pointers */ -#define UNOWHERE ( ~UNULL ) - /** * Reallocate external memory * - * @v old_ptr Memory previously allocated by umalloc(), or UNULL + * @v old_ptr Memory previously allocated by umalloc(), or NULL * @v new_size Requested size - * @ret new_ptr Allocated memory, or UNULL + * @ret new_ptr Allocated memory, or NULL * * Calling realloc() with a new size of zero is a valid way to free a * memory block. */ -static userptr_t sbi_urealloc ( userptr_t old_ptr, size_t new_size ) { +static void * sbi_urealloc ( void * old_ptr, size_t new_size ) { /* External allocation not yet implemented: allocate from heap */ - return ( ( userptr_t ) realloc ( ( ( void * ) old_ptr ), new_size ) ); + return ( realloc ( old_ptr, new_size ) ); } PROVIDE_UMALLOC ( sbi, urealloc, sbi_urealloc ); diff --git a/src/arch/x86/interface/pcbios/memtop_umalloc.c b/src/arch/x86/interface/pcbios/memtop_umalloc.c index b87d22516..d4489fb01 100644 --- a/src/arch/x86/interface/pcbios/memtop_umalloc.c +++ b/src/arch/x86/interface/pcbios/memtop_umalloc.c @@ -44,9 +44,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** Alignment of external allocated memory */ #define EM_ALIGN ( 4 * 1024 ) -/** Equivalent of NOWHERE for user pointers */ -#define UNOWHERE ( ( userptr_t ) ~( ( intptr_t ) 0 ) ) - /** An external memory block */ struct external_memory { /** Size of this memory block (excluding this header) */ @@ -56,10 +53,10 @@ struct external_memory { }; /** Top of heap */ -static userptr_t top = UNULL; +static void *top = NULL; /** Bottom of heap (current lowest allocated block) */ -static userptr_t bottom = UNULL; +static void *bottom = NULL; /** Remaining space on heap */ static size_t heap_size; @@ -70,7 +67,7 @@ static size_t heap_size; * @ret start Start of region * @ret len Length of region */ -size_t largest_memblock ( userptr_t *start ) { +size_t largest_memblock ( void **start ) { struct memory_map memmap; struct memory_region *region; physaddr_t max = EM_MAX_ADDRESS; @@ -81,7 +78,7 @@ size_t largest_memblock ( userptr_t *start ) { size_t len = 0; /* Avoid returning uninitialised data on error */ - *start = UNULL; + *start = NULL; /* Scan through all memory regions */ get_memmap ( &memmap ); @@ -119,7 +116,7 @@ size_t largest_memblock ( userptr_t *start ) { * */ static void init_eheap ( void ) { - userptr_t base; + void *base; heap_size = largest_memblock ( &base ); bottom = top = ( base + heap_size ); @@ -137,8 +134,8 @@ static void ecollect_free ( void ) { /* Walk the free list and collect empty blocks */ while ( bottom != top ) { - copy_from_user ( &extmem, bottom, -sizeof ( extmem ), - sizeof ( extmem ) ); + memcpy ( &extmem, ( bottom - sizeof ( extmem ) ), + sizeof ( extmem ) ); if ( extmem.used ) break; DBG ( "EXTMEM freeing [%lx,%lx)\n", virt_to_phys ( bottom ), @@ -152,16 +149,16 @@ static void ecollect_free ( void ) { /** * Reallocate external memory * - * @v old_ptr Memory previously allocated by umalloc(), or UNULL + * @v old_ptr Memory previously allocated by umalloc(), or NULL * @v new_size Requested size - * @ret new_ptr Allocated memory, or UNULL + * @ret new_ptr Allocated memory, or NULL * * Calling realloc() with a new size of zero is a valid way to free a * memory block. */ -static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { +static void * memtop_urealloc ( void *ptr, size_t new_size ) { struct external_memory extmem; - userptr_t new = ptr; + void *new = ptr; size_t align; /* (Re)initialise external memory allocator if necessary */ @@ -169,15 +166,15 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { init_eheap(); /* Get block properties into extmem */ - if ( ptr && ( ptr != UNOWHERE ) ) { + if ( ptr && ( ptr != NOWHERE ) ) { /* Determine old size */ - copy_from_user ( &extmem, ptr, -sizeof ( extmem ), - sizeof ( extmem ) ); + memcpy ( &extmem, ( ptr - sizeof ( extmem ) ), + sizeof ( extmem ) ); } else { /* Create a zero-length block */ if ( heap_size < sizeof ( extmem ) ) { DBG ( "EXTMEM out of space\n" ); - return UNULL; + return NULL; } ptr = bottom = ( bottom - sizeof ( extmem ) ); heap_size -= sizeof ( extmem ); @@ -196,7 +193,7 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { new -= align; if ( new_size > ( heap_size + extmem.size ) ) { DBG ( "EXTMEM out of space\n" ); - return UNULL; + return NULL; } DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n", virt_to_phys ( ptr ), @@ -215,13 +212,12 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { DBG ( "EXTMEM cannot expand [%lx,%lx)\n", virt_to_phys ( ptr ), ( virt_to_phys ( ptr ) + extmem.size ) ); - return UNULL; + return NULL; } } /* Write back block properties */ - copy_to_user ( new, -sizeof ( extmem ), &extmem, - sizeof ( extmem ) ); + memcpy ( ( new - sizeof ( extmem ) ), &extmem, sizeof ( extmem ) ); /* Collect any free blocks and update hidden memory region */ ecollect_free(); @@ -229,7 +225,7 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { ( ( bottom == top ) ? 0 : sizeof ( extmem ) ) ), virt_to_phys ( top ) ); - return ( new_size ? new : UNOWHERE ); + return ( new_size ? new : NOWHERE ); } PROVIDE_UMALLOC ( memtop, urealloc, memtop_urealloc ); diff --git a/src/core/dma.c b/src/core/dma.c index 5d6868216..1f3c1d8a6 100644 --- a/src/core/dma.c +++ b/src/core/dma.c @@ -130,9 +130,9 @@ static void dma_op_free ( struct dma_mapping *map, void *addr, size_t len ) { * @v align Physical alignment * @ret addr Buffer address, or NULL on error */ -static userptr_t dma_op_umalloc ( struct dma_device *dma, - struct dma_mapping *map, - size_t len, size_t align ) { +static void * dma_op_umalloc ( struct dma_device *dma, + struct dma_mapping *map, + size_t len, size_t align ) { struct dma_operations *op = dma->op; if ( ! op ) @@ -147,8 +147,7 @@ static userptr_t dma_op_umalloc ( struct dma_device *dma, * @v addr Buffer address * @v len Length of buffer */ -static void dma_op_ufree ( struct dma_mapping *map, userptr_t addr, - size_t len ) { +static void dma_op_ufree ( struct dma_mapping *map, void *addr, size_t len ) { struct dma_device *dma = map->dma; assert ( dma != NULL ); diff --git a/src/core/malloc.c b/src/core/malloc.c index c499ce6fd..ec29513ef 100644 --- a/src/core/malloc.c +++ b/src/core/malloc.c @@ -71,23 +71,6 @@ struct autosized_block { char data[0]; }; -/** - * Address for zero-length memory blocks - * - * @c malloc(0) or @c realloc(ptr,0) will return the special value @c - * NOWHERE. Calling @c free(NOWHERE) will have no effect. - * - * This is consistent with the ANSI C standards, which state that - * "either NULL or a pointer suitable to be passed to free()" must be - * returned in these cases. Using a special non-NULL value means that - * the caller can take a NULL return value to indicate failure, - * without first having to check for a requested size of zero. - * - * Code outside of malloc.c do not ever need to refer to the actual - * value of @c NOWHERE; this is an internal definition. - */ -#define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) - /** List of free memory blocks */ static LIST_HEAD ( free_blocks ); diff --git a/src/core/xferbuf.c b/src/core/xferbuf.c index 240118557..1c08f8bc3 100644 --- a/src/core/xferbuf.c +++ b/src/core/xferbuf.c @@ -237,8 +237,8 @@ struct xfer_buffer_operations xferbuf_malloc_operations = { * @ret rc Return status code */ static int xferbuf_umalloc_realloc ( struct xfer_buffer *xferbuf, size_t len ) { - userptr_t *udata = xferbuf->data; - userptr_t new_udata; + void **udata = xferbuf->data; + void *new_udata; new_udata = urealloc ( *udata, len ); if ( ! new_udata ) @@ -257,9 +257,9 @@ static int xferbuf_umalloc_realloc ( struct xfer_buffer *xferbuf, size_t len ) { */ static void xferbuf_umalloc_write ( struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len ) { - userptr_t *udata = xferbuf->data; + void **udata = xferbuf->data; - copy_to_user ( *udata, offset, data, len ); + memcpy ( ( *udata + offset ), data, len ); } /** @@ -272,9 +272,9 @@ static void xferbuf_umalloc_write ( struct xfer_buffer *xferbuf, size_t offset, */ static void xferbuf_umalloc_read ( struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len ) { - userptr_t *udata = xferbuf->data; + void **udata = xferbuf->data; - copy_from_user ( data, *udata, offset, len ); + memcpy ( data, ( *udata + offset ), len ); } /** umalloc()-based data buffer operations */ diff --git a/src/include/ipxe/dma.h b/src/include/ipxe/dma.h index 385e4baf7..6e5c43289 100644 --- a/src/include/ipxe/dma.h +++ b/src/include/ipxe/dma.h @@ -106,9 +106,9 @@ struct dma_operations { * @v align Physical alignment * @ret addr Buffer address, or NULL on error */ - userptr_t ( * umalloc ) ( struct dma_device *dma, - struct dma_mapping *map, - size_t len, size_t align ); + void * ( * umalloc ) ( struct dma_device *dma, + struct dma_mapping *map, + size_t len, size_t align ); /** * Unmap and free DMA-coherent buffer from external (user) memory * @@ -118,7 +118,7 @@ struct dma_operations { * @v len Length of buffer */ void ( * ufree ) ( struct dma_device *dma, struct dma_mapping *map, - userptr_t addr, size_t len ); + void *addr, size_t len ); /** * Set addressable space mask * @@ -265,11 +265,11 @@ DMAAPI_INLINE ( flat, dma_free ) ( struct dma_mapping *map, * @v align Physical alignment * @ret addr Buffer address, or NULL on error */ -static inline __always_inline userptr_t +static inline __always_inline void * DMAAPI_INLINE ( flat, dma_umalloc ) ( struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align __unused ) { - userptr_t addr; + void *addr; /* Allocate buffer */ addr = umalloc ( len ); @@ -292,7 +292,7 @@ DMAAPI_INLINE ( flat, dma_umalloc ) ( struct dma_device *dma, */ static inline __always_inline void DMAAPI_INLINE ( flat, dma_ufree ) ( struct dma_mapping *map, - userptr_t addr, size_t len __unused ) { + void *addr, size_t len __unused ) { /* Free buffer */ ufree ( addr ); @@ -397,8 +397,8 @@ void dma_free ( struct dma_mapping *map, void *addr, size_t len ); * @v align Physical alignment * @ret addr Buffer address, or NULL on error */ -userptr_t dma_umalloc ( struct dma_device *dma, struct dma_mapping *map, - size_t len, size_t align ); +void * dma_umalloc ( struct dma_device *dma, struct dma_mapping *map, + size_t len, size_t align ); /** * Unmap and free DMA-coherent buffer from external (user) memory @@ -407,7 +407,7 @@ userptr_t dma_umalloc ( struct dma_device *dma, struct dma_mapping *map, * @v addr Buffer address * @v len Length of buffer */ -void dma_ufree ( struct dma_mapping *map, userptr_t addr, size_t len ); +void dma_ufree ( struct dma_mapping *map, void *addr, size_t len ); /** * Set addressable space mask diff --git a/src/include/ipxe/malloc.h b/src/include/ipxe/malloc.h index f0fde0bc3..8c3a7769d 100644 --- a/src/include/ipxe/malloc.h +++ b/src/include/ipxe/malloc.h @@ -21,6 +21,24 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include +/** + * Address for zero-length memory blocks + * + * @c malloc(0) or @c realloc(ptr,0) will return the special value @c + * NOWHERE. Calling @c free(NOWHERE) will have no effect. + * + * This is consistent with the ANSI C standards, which state that + * "either NULL or a pointer suitable to be passed to free()" must be + * returned in these cases. Using a special non-NULL value means that + * the caller can take a NULL return value to indicate failure, + * without first having to check for a requested size of zero. + * + * Code outside of the memory allocators themselves does not ever need + * to refer to the actual value of @c NOWHERE; this is an internal + * definition. + */ +#define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) + extern size_t freemem; extern size_t usedmem; extern size_t maxusedmem; diff --git a/src/include/ipxe/umalloc.h b/src/include/ipxe/umalloc.h index 3892ef53b..a6476a390 100644 --- a/src/include/ipxe/umalloc.h +++ b/src/include/ipxe/umalloc.h @@ -10,9 +10,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include #include +#include #include -#include /** * Provide a user memory allocation API implementation @@ -34,36 +35,36 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * Reallocate external memory * - * @v userptr Memory previously allocated by umalloc(), or UNULL + * @v old_ptr Memory previously allocated by umalloc(), or NULL * @v new_size Requested size - * @ret userptr Allocated memory, or UNULL + * @ret new_ptr Allocated memory, or NULL * * Calling realloc() with a new size of zero is a valid way to free a * memory block. */ -userptr_t urealloc ( userptr_t userptr, size_t new_size ); +void * urealloc ( void *ptr, size_t new_size ); /** * Allocate external memory * * @v size Requested size - * @ret userptr Memory, or UNULL + * @ret ptr Memory, or NULL * * Memory is guaranteed to be aligned to a page boundary. */ -static inline __always_inline userptr_t umalloc ( size_t size ) { - return urealloc ( UNULL, size ); +static inline __always_inline void * umalloc ( size_t size ) { + return urealloc ( NULL, size ); } /** * Free external memory * - * @v userptr Memory allocated by umalloc(), or UNULL + * @v ptr Memory allocated by umalloc(), or NULL * - * If @c ptr is UNULL, no action is taken. + * If @c ptr is NULL, no action is taken. */ -static inline __always_inline void ufree ( userptr_t userptr ) { - urealloc ( userptr, 0 ); +static inline __always_inline void ufree ( void *ptr ) { + urealloc ( ptr, 0 ); } #endif /* _IPXE_UMALLOC_H */ diff --git a/src/include/ipxe/xferbuf.h b/src/include/ipxe/xferbuf.h index cb0b1a0e8..04635999d 100644 --- a/src/include/ipxe/xferbuf.h +++ b/src/include/ipxe/xferbuf.h @@ -11,7 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include -#include #include #include @@ -84,7 +83,7 @@ xferbuf_malloc_init ( struct xfer_buffer *xferbuf ) { * @v data User pointer */ static inline __attribute__ (( always_inline )) void -xferbuf_umalloc_init ( struct xfer_buffer *xferbuf, userptr_t *data ) { +xferbuf_umalloc_init ( struct xfer_buffer *xferbuf, void **data ) { xferbuf->data = data; xferbuf->op = &xferbuf_umalloc_operations; } diff --git a/src/interface/efi/efi_pci.c b/src/interface/efi/efi_pci.c index 01351df51..b8c7df38d 100644 --- a/src/interface/efi/efi_pci.c +++ b/src/interface/efi/efi_pci.c @@ -640,38 +640,6 @@ static void efipci_dma_free ( struct dma_device *dma, struct dma_mapping *map, dma->allocated--; } -/** - * Allocate and map DMA-coherent buffer from external (user) memory - * - * @v dma DMA device - * @v map DMA mapping to fill in - * @v len Length of buffer - * @v align Physical alignment - * @ret addr Buffer address, or NULL on error - */ -static userptr_t efipci_dma_umalloc ( struct dma_device *dma, - struct dma_mapping *map, - size_t len, size_t align ) { - void *addr; - - addr = efipci_dma_alloc ( dma, map, len, align ); - return virt_to_user ( addr ); -} - -/** - * Unmap and free DMA-coherent buffer from external (user) memory - * - * @v dma DMA device - * @v map DMA mapping - * @v addr Buffer address - * @v len Length of buffer - */ -static void efipci_dma_ufree ( struct dma_device *dma, struct dma_mapping *map, - userptr_t addr, size_t len ) { - - efipci_dma_free ( dma, map, addr, len ); -} - /** * Set addressable space mask * @@ -710,8 +678,8 @@ static struct dma_operations efipci_dma_operations = { .unmap = efipci_dma_unmap, .alloc = efipci_dma_alloc, .free = efipci_dma_free, - .umalloc = efipci_dma_umalloc, - .ufree = efipci_dma_ufree, + .umalloc = efipci_dma_alloc, + .ufree = efipci_dma_free, .set_mask = efipci_dma_set_mask, }; diff --git a/src/interface/efi/efi_umalloc.c b/src/interface/efi/efi_umalloc.c index 0636cb7fd..419d9b294 100644 --- a/src/interface/efi/efi_umalloc.c +++ b/src/interface/efi/efi_umalloc.c @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include @@ -35,25 +36,23 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ -/** Equivalent of NOWHERE for user pointers */ -#define UNOWHERE ( ( userptr_t ) ~( ( intptr_t ) 0 ) ) - /** * Reallocate external memory * - * @v old_ptr Memory previously allocated by umalloc(), or UNULL + * @v old_ptr Memory previously allocated by umalloc(), or NULL * @v new_size Requested size - * @ret new_ptr Allocated memory, or UNULL + * @ret new_ptr Allocated memory, or NULL * * 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 ) { +static void * efi_urealloc ( void *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; + void *new_ptr = NOWHERE; size_t old_size; + size_t *info; EFI_STATUS efirc; int rc; @@ -69,12 +68,12 @@ static userptr_t efi_urealloc ( userptr_t old_ptr, size_t new_size ) { rc = -EEFI ( efirc ); DBG ( "EFI could not allocate %d pages: %s\n", new_pages, strerror ( rc ) ); - return UNULL; + return NULL; } assert ( phys_addr != 0 ); new_ptr = phys_to_virt ( phys_addr + EFI_PAGE_SIZE ); - copy_to_user ( new_ptr, -EFI_PAGE_SIZE, - &new_size, sizeof ( new_size ) ); + info = ( new_ptr - EFI_PAGE_SIZE ); + *info = new_size; DBG ( "EFI allocated %d pages at %llx\n", new_pages, phys_addr ); } @@ -84,9 +83,9 @@ static userptr_t efi_urealloc ( userptr_t old_ptr, size_t new_size ) { * 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 ) ); + if ( old_ptr && ( old_ptr != NOWHERE ) ) { + info = ( old_ptr - EFI_PAGE_SIZE ); + old_size = *info; memcpy ( new_ptr, old_ptr, ( (old_size < new_size) ? old_size : new_size ) ); old_pages = ( EFI_SIZE_TO_PAGES ( old_size ) + 1 ); diff --git a/src/interface/linux/linux_umalloc.c b/src/interface/linux/linux_umalloc.c index a7250fa5b..ab5770e9c 100644 --- a/src/interface/linux/linux_umalloc.c +++ b/src/interface/linux/linux_umalloc.c @@ -31,9 +31,6 @@ FILE_LICENCE(GPL2_OR_LATER); #include -/** Special address returned for empty allocations */ -#define NOWHERE ((void *)-1) - /** Poison to make the metadata more unique */ #define POISON 0xa5a5a5a5 #define min(a,b) (((a)<(b))?(a):(b)) @@ -47,7 +44,16 @@ struct metadata #define SIZE_MD (sizeof(struct metadata)) -/** Simple realloc which passes most of the work to mmap(), mremap() and munmap() */ +/** + * Reallocate external memory + * + * @v old_ptr Memory previously allocated by umalloc(), or NULL + * @v new_size Requested size + * @ret new_ptr Allocated memory, or NULL + * + * Calling realloc() with a new size of zero is a valid way to free a + * memory block. + */ static void * linux_realloc(void *ptr, size_t size) { struct metadata md = {0, 0}; @@ -136,19 +142,4 @@ static void * linux_realloc(void *ptr, size_t size) return ptr; } -/** - * 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 linux_urealloc(userptr_t old_ptr, size_t new_size) -{ - return (userptr_t)linux_realloc((void *)old_ptr, new_size); -} - -PROVIDE_UMALLOC(linux, urealloc, linux_urealloc); +PROVIDE_UMALLOC(linux, urealloc, linux_realloc); diff --git a/src/tests/umalloc_test.c b/src/tests/umalloc_test.c index 53810833c..1a32a0531 100644 --- a/src/tests/umalloc_test.c +++ b/src/tests/umalloc_test.c @@ -1,12 +1,11 @@ #include -#include #include #include void umalloc_test ( void ) { struct memory_map memmap; - userptr_t bob; - userptr_t fred; + void *bob; + void *fred; printf ( "Before allocation:\n" ); get_memmap ( &memmap );