git: 95303c0646c4 - stable/13 - hyperv storvsc: Don't abuse struct sglist to hold virtual addresses.

From: John Baldwin <jhb_at_FreeBSD.org>
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);