[gve] Replace uses of userptr_t with direct pointer dereferences

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-04-23 18:24:18 +01:00
parent 839540cb95
commit 945df9b429
2 changed files with 67 additions and 64 deletions

View File

@@ -578,7 +578,8 @@ static void gve_create_tx_param ( struct gve_queue *queue,
/* Construct request parameters */ /* Construct request parameters */
create->res = cpu_to_be64 ( dma ( &queue->res_map, queue->res ) ); create->res = cpu_to_be64 ( dma ( &queue->res_map, queue->res ) );
create->desc = cpu_to_be64 ( dma ( &queue->desc_map, queue->desc ) ); create->desc =
cpu_to_be64 ( dma ( &queue->desc_map, queue->desc.tx ) );
create->qpl_id = cpu_to_be32 ( type->qpl ); create->qpl_id = cpu_to_be32 ( type->qpl );
create->notify_id = cpu_to_be32 ( type->irq ); create->notify_id = cpu_to_be32 ( type->irq );
} }
@@ -597,8 +598,10 @@ static void gve_create_rx_param ( struct gve_queue *queue,
/* Construct request parameters */ /* Construct request parameters */
create->notify_id = cpu_to_be32 ( type->irq ); create->notify_id = cpu_to_be32 ( type->irq );
create->res = cpu_to_be64 ( dma ( &queue->res_map, queue->res ) ); create->res = cpu_to_be64 ( dma ( &queue->res_map, queue->res ) );
create->desc = cpu_to_be64 ( dma ( &queue->desc_map, queue->desc ) ); create->desc =
create->cmplt = cpu_to_be64 ( dma ( &queue->cmplt_map, queue->cmplt )); cpu_to_be64 ( dma ( &queue->desc_map, queue->desc.rx ) );
create->cmplt =
cpu_to_be64 ( dma ( &queue->cmplt_map, queue->cmplt.rx ) );
create->qpl_id = cpu_to_be32 ( type->qpl ); create->qpl_id = cpu_to_be32 ( type->qpl );
create->bufsz = cpu_to_be16 ( GVE_BUF_SIZE ); create->bufsz = cpu_to_be16 ( GVE_BUF_SIZE );
} }
@@ -800,7 +803,7 @@ gve_address ( struct gve_queue *queue, unsigned int index ) {
* @v index Buffer index * @v index Buffer index
* @ret addr Buffer address * @ret addr Buffer address
*/ */
static inline __attribute__ (( always_inline )) userptr_t static inline __attribute__ (( always_inline )) void *
gve_buffer ( struct gve_queue *queue, unsigned int index ) { gve_buffer ( struct gve_queue *queue, unsigned int index ) {
/* Pages are currently allocated as a single contiguous block */ /* Pages are currently allocated as a single contiguous block */
@@ -845,8 +848,7 @@ static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
size_t desc_len = ( queue->count * type->desc_len ); size_t desc_len = ( queue->count * type->desc_len );
size_t cmplt_len = ( queue->count * type->cmplt_len ); size_t cmplt_len = ( queue->count * type->cmplt_len );
size_t res_len = sizeof ( *queue->res ); size_t res_len = sizeof ( *queue->res );
struct gve_buffer buf; struct gve_buffer *buf;
size_t offset;
unsigned int i; unsigned int i;
int rc; int rc;
@@ -873,27 +875,27 @@ static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
goto err_qpl; goto err_qpl;
/* Allocate descriptors */ /* Allocate descriptors */
queue->desc = dma_umalloc ( dma, &queue->desc_map, desc_len, queue->desc.raw = dma_umalloc ( dma, &queue->desc_map, desc_len,
GVE_ALIGN ); GVE_ALIGN );
if ( ! queue->desc ) { if ( ! queue->desc.raw ) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_desc; goto err_desc;
} }
DBGC ( gve, "GVE %p %s descriptors at [%08lx,%08lx)\n", DBGC ( gve, "GVE %p %s descriptors at [%08lx,%08lx)\n",
gve, type->name, virt_to_phys ( queue->desc ), gve, type->name, virt_to_phys ( queue->desc.raw ),
( virt_to_phys ( queue->desc ) + desc_len ) ); ( virt_to_phys ( queue->desc.raw ) + desc_len ) );
/* Allocate completions */ /* Allocate completions */
if ( cmplt_len ) { if ( cmplt_len ) {
queue->cmplt = dma_umalloc ( dma, &queue->cmplt_map, cmplt_len, queue->cmplt.raw = dma_umalloc ( dma, &queue->cmplt_map,
GVE_ALIGN ); cmplt_len, GVE_ALIGN );
if ( ! queue->cmplt ) { if ( ! queue->cmplt.raw ) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_cmplt; goto err_cmplt;
} }
DBGC ( gve, "GVE %p %s completions at [%08lx,%08lx)\n", DBGC ( gve, "GVE %p %s completions at [%08lx,%08lx)\n",
gve, type->name, virt_to_phys ( queue->cmplt ), gve, type->name, virt_to_phys ( queue->cmplt.raw ),
( virt_to_phys ( queue->cmplt ) + cmplt_len ) ); ( virt_to_phys ( queue->cmplt.raw ) + cmplt_len ) );
} }
/* Allocate queue resources */ /* Allocate queue resources */
@@ -905,11 +907,10 @@ static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
memset ( queue->res, 0, res_len ); memset ( queue->res, 0, res_len );
/* Populate descriptor offsets */ /* Populate descriptor offsets */
offset = ( type->desc_len - sizeof ( buf ) ); buf = ( queue->desc.raw + type->desc_len - sizeof ( *buf ) );
for ( i = 0 ; i < queue->count ; i++ ) { for ( i = 0 ; i < queue->count ; i++ ) {
buf.addr = cpu_to_be64 ( gve_address ( queue, i ) ); buf->addr = cpu_to_be64 ( gve_address ( queue, i ) );
copy_to_user ( queue->desc, offset, &buf, sizeof ( buf ) ); buf = ( ( ( void * ) buf ) + type->desc_len );
offset += type->desc_len;
} }
return 0; return 0;
@@ -917,9 +918,9 @@ static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
dma_free ( &queue->res_map, queue->res, res_len ); dma_free ( &queue->res_map, queue->res, res_len );
err_res: err_res:
if ( cmplt_len ) if ( cmplt_len )
dma_ufree ( &queue->cmplt_map, queue->cmplt, cmplt_len ); dma_ufree ( &queue->cmplt_map, queue->cmplt.raw, cmplt_len );
err_cmplt: err_cmplt:
dma_ufree ( &queue->desc_map, queue->desc, desc_len ); dma_ufree ( &queue->desc_map, queue->desc.raw, desc_len );
err_desc: err_desc:
gve_free_qpl ( gve, &queue->qpl ); gve_free_qpl ( gve, &queue->qpl );
err_qpl: err_qpl:
@@ -944,10 +945,10 @@ static void gve_free_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
/* Free completions, if applicable */ /* Free completions, if applicable */
if ( cmplt_len ) if ( cmplt_len )
dma_ufree ( &queue->cmplt_map, queue->cmplt, cmplt_len ); dma_ufree ( &queue->cmplt_map, queue->cmplt.raw, cmplt_len );
/* Free descriptors */ /* Free descriptors */
dma_ufree ( &queue->desc_map, queue->desc, desc_len ); dma_ufree ( &queue->desc_map, queue->desc.raw, desc_len );
/* Free queue page list */ /* Free queue page list */
gve_free_qpl ( gve, &queue->qpl ); gve_free_qpl ( gve, &queue->qpl );
@@ -977,7 +978,7 @@ static int gve_start ( struct gve_nic *gve ) {
} }
/* Invalidate receive completions */ /* Invalidate receive completions */
memset ( rx->cmplt, 0, ( rx->count * rx->type->cmplt_len ) ); memset ( rx->cmplt.raw, 0, ( rx->count * rx->type->cmplt_len ) );
/* Reset receive sequence */ /* Reset receive sequence */
gve->seq = gve_next ( 0 ); gve->seq = gve_next ( 0 );
@@ -1209,7 +1210,7 @@ static void gve_close ( struct net_device *netdev ) {
static int gve_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { static int gve_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
struct gve_nic *gve = netdev->priv; struct gve_nic *gve = netdev->priv;
struct gve_queue *tx = &gve->tx; struct gve_queue *tx = &gve->tx;
struct gve_tx_descriptor desc; struct gve_tx_descriptor *desc;
unsigned int count; unsigned int count;
unsigned int index; unsigned int index;
size_t frag_len; size_t frag_len;
@@ -1238,26 +1239,25 @@ static int gve_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
frag_len = ( len - offset ); frag_len = ( len - offset );
if ( frag_len > GVE_BUF_SIZE ) if ( frag_len > GVE_BUF_SIZE )
frag_len = GVE_BUF_SIZE; frag_len = GVE_BUF_SIZE;
copy_to_user ( gve_buffer ( tx, tx->prod ), 0, memcpy ( gve_buffer ( tx, tx->prod ),
( iobuf->data + offset ), frag_len ); ( iobuf->data + offset ), frag_len );
/* Populate descriptor */ /* Populate descriptor */
index = ( tx->prod++ & ( tx->count - 1 ) ); index = ( tx->prod++ & ( tx->count - 1 ) );
memset ( &desc.pkt, 0, sizeof ( desc.pkt ) ); desc = &tx->desc.tx[index];
memset ( &desc->pkt, 0, sizeof ( desc->pkt ) );
if ( offset ) { if ( offset ) {
desc.pkt.type = GVE_TX_TYPE_CONT; desc->pkt.type = GVE_TX_TYPE_CONT;
} else { } else {
desc.pkt.type = GVE_TX_TYPE_START; desc->pkt.type = GVE_TX_TYPE_START;
desc.pkt.count = count; desc->pkt.count = count;
desc.pkt.total = cpu_to_be16 ( len ); desc->pkt.total = cpu_to_be16 ( len );
} }
desc.pkt.len = cpu_to_be16 ( frag_len ); desc->pkt.len = cpu_to_be16 ( frag_len );
copy_to_user ( tx->desc, ( index * sizeof ( desc ) ), &desc,
sizeof ( desc.pkt ) );
DBGC2 ( gve, "GVE %p TX %#04x %#02x:%#02x len %#04x/%#04x at " DBGC2 ( gve, "GVE %p TX %#04x %#02x:%#02x len %#04x/%#04x at "
"%#08zx\n", gve, index, desc.pkt.type, desc.pkt.count, "%#08zx\n", gve, index, desc->pkt.type,
be16_to_cpu ( desc.pkt.len ), desc->pkt.count, be16_to_cpu ( desc->pkt.len ),
be16_to_cpu ( desc.pkt.total ), be16_to_cpu ( desc->pkt.total ),
gve_address ( tx, index ) ); gve_address ( tx, index ) );
} }
assert ( ( tx->prod - tx->cons ) <= tx->fill ); assert ( ( tx->prod - tx->cons ) <= tx->fill );
@@ -1305,12 +1305,11 @@ static void gve_poll_tx ( struct net_device *netdev ) {
static void gve_poll_rx ( struct net_device *netdev ) { static void gve_poll_rx ( struct net_device *netdev ) {
struct gve_nic *gve = netdev->priv; struct gve_nic *gve = netdev->priv;
struct gve_queue *rx = &gve->rx; struct gve_queue *rx = &gve->rx;
struct gve_rx_completion cmplt; struct gve_rx_completion *cmplt;
struct io_buffer *iobuf; struct io_buffer *iobuf;
unsigned int index; unsigned int index;
unsigned int seq; unsigned int seq;
uint32_t cons; uint32_t cons;
size_t offset;
size_t total; size_t total;
size_t len; size_t len;
int rc; int rc;
@@ -1323,28 +1322,25 @@ static void gve_poll_rx ( struct net_device *netdev ) {
/* Read next possible completion */ /* Read next possible completion */
index = ( cons++ & ( rx->count - 1 ) ); index = ( cons++ & ( rx->count - 1 ) );
offset = ( ( index * sizeof ( cmplt ) ) + cmplt = &rx->cmplt.rx[index];
offsetof ( typeof ( cmplt ), pkt ) );
copy_from_user ( &cmplt.pkt, rx->cmplt, offset,
sizeof ( cmplt.pkt ) );
/* Check sequence number */ /* Check sequence number */
if ( ( cmplt.pkt.seq & GVE_RX_SEQ_MASK ) != seq ) if ( ( cmplt->pkt.seq & GVE_RX_SEQ_MASK ) != seq )
break; break;
seq = gve_next ( seq ); seq = gve_next ( seq );
/* Parse completion */ /* Parse completion */
len = be16_to_cpu ( cmplt.pkt.len ); len = be16_to_cpu ( cmplt->pkt.len );
DBGC2 ( gve, "GVE %p RX %#04x %#02x:%#02x len %#04zx at " DBGC2 ( gve, "GVE %p RX %#04x %#02x:%#02x len %#04zx at "
"%#08zx\n", gve, index, cmplt.pkt.seq, cmplt.pkt.flags, "%#08zx\n", gve, index, cmplt->pkt.seq,
len, gve_address ( rx, index ) ); cmplt->pkt.flags, len, gve_address ( rx, index ) );
/* Accumulate a complete packet */ /* Accumulate a complete packet */
if ( cmplt.pkt.flags & GVE_RXF_ERROR ) { if ( cmplt->pkt.flags & GVE_RXF_ERROR ) {
total = 0; total = 0;
} else { } else {
total += len; total += len;
if ( cmplt.pkt.flags & GVE_RXF_MORE ) if ( cmplt->pkt.flags & GVE_RXF_MORE )
continue; continue;
} }
gve->seq = seq; gve->seq = seq;
@@ -1355,17 +1351,13 @@ static void gve_poll_rx ( struct net_device *netdev ) {
/* Re-read completion length */ /* Re-read completion length */
index = ( rx->cons & ( rx->count - 1 ) ); index = ( rx->cons & ( rx->count - 1 ) );
offset = ( ( index * sizeof ( cmplt ) ) + cmplt = &rx->cmplt.rx[index];
offsetof ( typeof ( cmplt ), pkt.len ) );
copy_from_user ( &cmplt.pkt, rx->cmplt, offset,
sizeof ( cmplt.pkt.len ) );
/* Copy data */ /* Copy data */
if ( iobuf ) { if ( iobuf ) {
len = be16_to_cpu ( cmplt.pkt.len ); len = be16_to_cpu ( cmplt->pkt.len );
copy_from_user ( iob_put ( iobuf, len ), memcpy ( iob_put ( iobuf, len ),
gve_buffer ( rx, rx->cons ), gve_buffer ( rx, rx->cons ), len );
0, len );
} }
} }
assert ( ( iobuf == NULL ) || ( iob_len ( iobuf ) == total ) ); assert ( ( iobuf == NULL ) || ( iob_len ( iobuf ) == total ) );
@@ -1376,7 +1368,7 @@ static void gve_poll_rx ( struct net_device *netdev ) {
iob_pull ( iobuf, GVE_RX_PAD ); iob_pull ( iobuf, GVE_RX_PAD );
netdev_rx ( netdev, iobuf ); netdev_rx ( netdev, iobuf );
} else { } else {
rc = ( ( cmplt.pkt.flags & GVE_RXF_ERROR ) ? rc = ( ( cmplt->pkt.flags & GVE_RXF_ERROR ) ?
-EIO : -ENOMEM ); -EIO : -ENOMEM );
netdev_rx_err ( netdev, NULL, rc ); netdev_rx_err ( netdev, NULL, rc );
} }

View File

@@ -17,7 +17,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dma.h> #include <ipxe/dma.h>
#include <ipxe/pci.h> #include <ipxe/pci.h>
#include <ipxe/in.h> #include <ipxe/in.h>
#include <ipxe/uaccess.h>
#include <ipxe/process.h> #include <ipxe/process.h>
#include <ipxe/retry.h> #include <ipxe/retry.h>
@@ -459,7 +458,7 @@ struct gve_resources {
*/ */
struct gve_qpl { struct gve_qpl {
/** Page addresses */ /** Page addresses */
userptr_t data; void *data;
/** Page mapping */ /** Page mapping */
struct dma_mapping map; struct dma_mapping map;
/** Number of pages */ /** Number of pages */
@@ -569,9 +568,21 @@ struct gve_rx_completion {
/** A descriptor queue */ /** A descriptor queue */
struct gve_queue { struct gve_queue {
/** Descriptor ring */ /** Descriptor ring */
userptr_t desc; union {
/** Transmit descriptors */
struct gve_tx_descriptor *tx;
/** Receive descriptors */
struct gve_rx_descriptor *rx;
/** Raw data */
void *raw;
} desc;
/** Completion ring */ /** Completion ring */
userptr_t cmplt; union {
/** Receive completions */
struct gve_rx_completion *rx;
/** Raw data */
void *raw;
} cmplt;
/** Queue resources */ /** Queue resources */
struct gve_resources *res; struct gve_resources *res;