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);