|  | @@ -19,6 +19,7 @@
 | 
		
	
		
			
			| 19 | 19 |  FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 20 | 20 |  
 | 
		
	
		
			
			| 21 | 21 |  #include <stdint.h>
 | 
		
	
		
			
			|  | 22 | +#include <strings.h>
 | 
		
	
		
			
			| 22 | 23 |  #include <errno.h>
 | 
		
	
		
			
			| 23 | 24 |  #include <ipxe/malloc.h>
 | 
		
	
		
			
			| 24 | 25 |  #include <ipxe/iobuf.h>
 | 
		
	
	
		
			
			|  | @@ -40,18 +41,24 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 40 | 41 |   */
 | 
		
	
		
			
			| 41 | 42 |  struct io_buffer * alloc_iob ( size_t len ) {
 | 
		
	
		
			
			| 42 | 43 |  	struct io_buffer *iobuf = NULL;
 | 
		
	
		
			
			|  | 44 | +	size_t align;
 | 
		
	
		
			
			| 43 | 45 |  	void *data;
 | 
		
	
		
			
			| 44 | 46 |  
 | 
		
	
		
			
			| 45 | 47 |  	/* Pad to minimum length */
 | 
		
	
		
			
			| 46 | 48 |  	if ( len < IOB_ZLEN )
 | 
		
	
		
			
			| 47 | 49 |  		len = IOB_ZLEN;
 | 
		
	
		
			
			| 48 | 50 |  
 | 
		
	
		
			
			| 49 |  | -	/* Align buffer length */
 | 
		
	
		
			
			| 50 |  | -	len = ( len + __alignof__( *iobuf ) - 1 ) &
 | 
		
	
		
			
			| 51 |  | -		~( __alignof__( *iobuf ) - 1 );
 | 
		
	
		
			
			| 52 |  | -	
 | 
		
	
		
			
			|  | 51 | +	/* Align buffer length to ensure that struct io_buffer is aligned */
 | 
		
	
		
			
			|  | 52 | +	len = ( len + __alignof__ ( *iobuf ) - 1 ) &
 | 
		
	
		
			
			|  | 53 | +		~( __alignof__ ( *iobuf ) - 1 );
 | 
		
	
		
			
			|  | 54 | +
 | 
		
	
		
			
			|  | 55 | +	/* Align buffer on its own size to avoid potential problems
 | 
		
	
		
			
			|  | 56 | +	 * with boundary-crossing DMA.
 | 
		
	
		
			
			|  | 57 | +	 */
 | 
		
	
		
			
			|  | 58 | +	align = ( 1 << fls ( len - 1 ) );
 | 
		
	
		
			
			|  | 59 | +
 | 
		
	
		
			
			| 53 | 60 |  	/* Allocate memory for buffer plus descriptor */
 | 
		
	
		
			
			| 54 |  | -	data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN );
 | 
		
	
		
			
			|  | 61 | +	data = malloc_dma ( len + sizeof ( *iobuf ), align );
 | 
		
	
		
			
			| 55 | 62 |  	if ( ! data )
 | 
		
	
		
			
			| 56 | 63 |  		return NULL;
 | 
		
	
		
			
			| 57 | 64 |  
 | 
		
	
	
		
			
			|  | @@ -61,6 +68,7 @@ struct io_buffer * alloc_iob ( size_t len ) {
 | 
		
	
		
			
			| 61 | 68 |  	return iobuf;
 | 
		
	
		
			
			| 62 | 69 |  }
 | 
		
	
		
			
			| 63 | 70 |  
 | 
		
	
		
			
			|  | 71 | +
 | 
		
	
		
			
			| 64 | 72 |  /**
 | 
		
	
		
			
			| 65 | 73 |   * Free I/O buffer
 | 
		
	
		
			
			| 66 | 74 |   *
 |