git: 95303c0646c4 - stable/13 - hyperv storvsc: Don't abuse struct sglist to hold virtual addresses.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 11 May 2022 00:30:01 UTC
The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=95303c0646c45a7288c82fbba3ad88589fd1d641 commit 95303c0646c45a7288c82fbba3ad88589fd1d641 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2022-02-01 01:11:27 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2022-05-11 00:03:58 +0000 hyperv storvsc: Don't abuse struct sglist to hold virtual addresses. struct sglist is intended for holding S/G lists of physical address ranges, not virtual address ranges. GCC 9.x issues several warnings due to casts between pointers and integers of different sizes as a result (vm_paddr_t is 64-bits on i386). Instead, add a local 'struct hv_sglist' which uses an array of 'struct iovec' to hold the S/G list of virtual address ranges. Differential Revision: https://reviews.freebsd.org/D31933 (cherry picked from commit 53e938e408be78a45c82012ca7a7be50b216159b) --- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c | 64 ++++++++++++------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c index 702308e26a1d..8764eaa379c9 100644 --- a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c +++ b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c @@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> #include <sys/lock.h> #include <sys/sema.h> -#include <sys/sglist.h> #include <sys/eventhandler.h> #include <machine/bus.h> @@ -110,9 +109,15 @@ __FBSDID("$FreeBSD$"); struct storvsc_softc; +struct hv_sglist { + struct iovec sg_iov[STORVSC_DATA_SEGCNT_MAX]; + u_short sg_nseg; + u_short sg_maxseg; +}; + struct hv_sgl_node { LIST_ENTRY(hv_sgl_node) link; - struct sglist *sgl_data; + struct hv_sglist *sgl_data; }; struct hv_sgl_page_pool{ @@ -186,7 +191,7 @@ struct hv_storvsc_request { struct storvsc_softc *softc; struct callout callout; struct sema synch_sema; /*Synchronize the request/response if needed */ - struct sglist *bounce_sgl; + struct hv_sglist *bounce_sgl; unsigned int bounce_sgl_count; uint64_t not_aligned_seg_bits; bus_dmamap_t data_dmap; @@ -344,13 +349,13 @@ static void hv_storvsc_on_iocompletion( struct storvsc_softc *sc, struct hv_storvsc_request *request); static int hv_storvsc_connect_vsp(struct storvsc_softc *); static void storvsc_io_done(struct hv_storvsc_request *reqp); -static void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, +static void storvsc_copy_sgl_to_bounce_buf(struct hv_sglist *bounce_sgl, bus_dma_segment_t *orig_sgl, unsigned int orig_sgl_count, uint64_t seg_bits); void storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl, unsigned int dest_sgl_count, - struct sglist* src_sgl, + struct hv_sglist *src_sgl, uint64_t seg_bits); static device_method_t storvsc_methods[] = { @@ -1109,16 +1114,15 @@ storvsc_attach(device_t dev) sgl_node = malloc(sizeof(struct hv_sgl_node), M_DEVBUF, M_WAITOK|M_ZERO); - sgl_node->sgl_data = - sglist_alloc(STORVSC_DATA_SEGCNT_MAX, - M_WAITOK|M_ZERO); + sgl_node->sgl_data = malloc(sizeof(struct hv_sglist), + M_DEVBUF, M_WAITOK|M_ZERO); for (j = 0; j < STORVSC_DATA_SEGCNT_MAX; j++) { tmp_buff = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK|M_ZERO); - sgl_node->sgl_data->sg_segs[j].ss_paddr = - (vm_paddr_t)tmp_buff; + sgl_node->sgl_data->sg_iov[j].iov_base = + tmp_buff; } LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, @@ -1207,12 +1211,9 @@ cleanup: sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); LIST_REMOVE(sgl_node, link); for (j = 0; j < STORVSC_DATA_SEGCNT_MAX; j++) { - if (NULL != - (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { - free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); - } + free(sgl_node->sgl_data->sg_iov[j].iov_base, M_DEVBUF); } - sglist_free(sgl_node->sgl_data); + free(sgl_node->sgl_data, M_DEVBUF); free(sgl_node, M_DEVBUF); } @@ -1270,12 +1271,9 @@ storvsc_detach(device_t dev) sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); LIST_REMOVE(sgl_node, link); for (j = 0; j < STORVSC_DATA_SEGCNT_MAX; j++){ - if (NULL != - (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { - free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); - } + free(sgl_node->sgl_data->sg_iov[j].iov_base, M_DEVBUF); } - sglist_free(sgl_node->sgl_data); + free(sgl_node->sgl_data, M_DEVBUF); free(sgl_node, M_DEVBUF); } @@ -1618,7 +1616,7 @@ storvsc_action(struct cam_sim *sim, union ccb *ccb) * */ static void -storvsc_destroy_bounce_buffer(struct sglist *sgl) +storvsc_destroy_bounce_buffer(struct hv_sglist *sgl) { struct hv_sgl_node *sgl_node = NULL; if (LIST_EMPTY(&g_hv_sgl_page_pool.in_use_sgl_list)) { @@ -1643,15 +1641,15 @@ storvsc_destroy_bounce_buffer(struct sglist *sgl) * * return NULL if create failed */ -static struct sglist * +static struct hv_sglist * storvsc_create_bounce_buffer(uint16_t seg_count, int write) { int i = 0; - struct sglist *bounce_sgl = NULL; + struct hv_sglist *bounce_sgl = NULL; unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE); struct hv_sgl_node *sgl_node = NULL; - /* get struct sglist from free_sgl_list */ + /* get struct hv_sglist from free_sgl_list */ if (LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { printf("storvsc error: not enough free sgl\n"); return NULL; @@ -1669,7 +1667,7 @@ storvsc_create_bounce_buffer(uint16_t seg_count, int write) bounce_sgl->sg_nseg = seg_count; for (i = 0; i < seg_count; i++) - bounce_sgl->sg_segs[i].ss_len = buf_len; + bounce_sgl->sg_iov[i].iov_len = buf_len; return bounce_sgl; } @@ -1688,7 +1686,7 @@ storvsc_create_bounce_buffer(uint16_t seg_count, int write) * */ static void -storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, +storvsc_copy_sgl_to_bounce_buf(struct hv_sglist *bounce_sgl, bus_dma_segment_t *orig_sgl, unsigned int orig_sgl_count, uint64_t seg_bits) @@ -1697,11 +1695,11 @@ storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, for (src_sgl_idx = 0; src_sgl_idx < orig_sgl_count; src_sgl_idx++) { if (seg_bits & (1 << src_sgl_idx)) { - memcpy((void*)bounce_sgl->sg_segs[src_sgl_idx].ss_paddr, + memcpy(bounce_sgl->sg_iov[src_sgl_idx].iov_base, (void*)orig_sgl[src_sgl_idx].ds_addr, orig_sgl[src_sgl_idx].ds_len); - bounce_sgl->sg_segs[src_sgl_idx].ss_len = + bounce_sgl->sg_iov[src_sgl_idx].iov_len = orig_sgl[src_sgl_idx].ds_len; } } @@ -1722,7 +1720,7 @@ storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, void storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl, unsigned int dest_sgl_count, - struct sglist* src_sgl, + struct hv_sglist* src_sgl, uint64_t seg_bits) { int sgl_idx = 0; @@ -1730,8 +1728,8 @@ storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl, for (sgl_idx = 0; sgl_idx < dest_sgl_count; sgl_idx++) { if (seg_bits & (1 << sgl_idx)) { memcpy((void*)(dest_sgl[sgl_idx].ds_addr), - (void*)(src_sgl->sg_segs[sgl_idx].ss_paddr), - src_sgl->sg_segs[sgl_idx].ss_len); + src_sgl->sg_iov[sgl_idx].iov_base, + src_sgl->sg_iov[sgl_idx].iov_len); } } } @@ -2021,7 +2019,7 @@ create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp) /* transfer virtual address to physical frame number */ if (reqp->not_aligned_seg_bits & 0x1){ phys_addr = - vtophys(reqp->bounce_sgl->sg_segs[0].ss_paddr); + vtophys(reqp->bounce_sgl->sg_iov[0].iov_base); }else{ phys_addr = vtophys(storvsc_sglist[0].ds_addr); @@ -2034,7 +2032,7 @@ create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp) for (i = 1; i < storvsc_sg_count; i++) { if (reqp->not_aligned_seg_bits & (1 << i)) { phys_addr = - vtophys(reqp->bounce_sgl->sg_segs[i].ss_paddr); + vtophys(reqp->bounce_sgl->sg_iov[i].iov_base); } else { phys_addr = vtophys(storvsc_sglist[i].ds_addr);