diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 3b2089092..7c3d4e402 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -86,9 +86,19 @@ const struct vhost_device_ops g_spdk_vhost_ops = { static struct spdk_vhost_dev *g_spdk_vhost_devices[MAX_VHOST_DEVICES]; static pthread_mutex_t g_spdk_vhost_mutex = PTHREAD_MUTEX_INITIALIZER; -void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr) +void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr, uint64_t len) { - return (void *)rte_vhost_gpa_to_vva(vdev->mem, addr); + void *vva; + uint64_t newlen; + + newlen = len; + vva = (void *)rte_vhost_va_from_guest_pa(vdev->mem, addr, &newlen); + if (newlen != len) { + return NULL; + } + + return vva; + } static void @@ -213,8 +223,9 @@ spdk_vhost_vq_get_desc(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue if (spdk_vhost_vring_desc_is_indirect(*desc)) { assert(spdk_vhost_dev_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC)); - *desc_table = spdk_vhost_gpa_to_vva(vdev, (*desc)->addr); *desc_table_size = (*desc)->len / sizeof(**desc); + *desc_table = spdk_vhost_gpa_to_vva(vdev, (*desc)->addr, + sizeof(**desc) * *desc_table_size); *desc = *desc_table; if (*desc == NULL) { return -1; @@ -429,7 +440,7 @@ spdk_vhost_vring_desc_to_iov(struct spdk_vhost_dev *vdev, struct iovec *iov, SPDK_ERRLOG("SPDK_VHOST_IOVS_MAX(%d) reached\n", SPDK_VHOST_IOVS_MAX); return -1; } - vva = (uintptr_t)spdk_vhost_gpa_to_vva(vdev, payload); + vva = (uintptr_t)rte_vhost_gpa_to_vva(vdev->mem, payload); if (vva == 0) { SPDK_ERRLOG("gpa_to_vva(%p) == NULL\n", (void *)payload); return -1; @@ -448,7 +459,7 @@ spdk_vhost_vring_desc_to_iov(struct spdk_vhost_dev *vdev, struct iovec *iov, */ len = to_boundary; while (len < remaining) { - if (vva + len != (uintptr_t)spdk_vhost_gpa_to_vva(vdev, payload + len)) { + if (vva + len != (uintptr_t)rte_vhost_gpa_to_vva(vdev->mem, payload + len)) { break; } len += spdk_min(remaining - len, 0x200000); diff --git a/lib/vhost/vhost_internal.h b/lib/vhost/vhost_internal.h index 453dd385e..871f7c4be 100644 --- a/lib/vhost/vhost_internal.h +++ b/lib/vhost/vhost_internal.h @@ -172,7 +172,7 @@ struct spdk_vhost_dev *spdk_vhost_dev_find(const char *ctrlr_name); void spdk_vhost_dev_mem_register(struct spdk_vhost_dev *vdev); void spdk_vhost_dev_mem_unregister(struct spdk_vhost_dev *vdev); -void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr); +void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr, uint64_t len); uint16_t spdk_vhost_vq_avail_ring_get(struct spdk_vhost_virtqueue *vq, uint16_t *reqs, uint16_t reqs_len); diff --git a/lib/vhost/vhost_scsi.c b/lib/vhost/vhost_scsi.c index 47e188a75..1b76ba2ae 100644 --- a/lib/vhost/vhost_scsi.c +++ b/lib/vhost/vhost_scsi.c @@ -185,7 +185,7 @@ eventq_enqueue(struct spdk_vhost_scsi_dev *svdev, unsigned scsi_dev_num, uint32_ goto out; } - desc_ev = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr); + desc_ev = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr, sizeof(*desc_ev)); if (desc_ev == NULL) { SPDK_ERRLOG("Controller %s: Eventq descriptor at index %"PRIu16" points to unmapped guest memory address %p.\n", svdev->vdev.name, req, (void *)(uintptr_t)desc->addr); @@ -319,7 +319,7 @@ process_ctrl_request(struct spdk_vhost_scsi_task *task) goto out; } - ctrl_req = spdk_vhost_gpa_to_vva(vdev, desc->addr); + ctrl_req = spdk_vhost_gpa_to_vva(vdev, desc->addr, sizeof(*ctrl_req)); SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n", @@ -340,7 +340,7 @@ process_ctrl_request(struct spdk_vhost_scsi_task *task) /* Process the TMF request */ switch (ctrl_req->type) { case VIRTIO_SCSI_T_TMF: - task->tmf_resp = spdk_vhost_gpa_to_vva(vdev, desc->addr); + task->tmf_resp = spdk_vhost_gpa_to_vva(vdev, desc->addr, sizeof(*task->tmf_resp)); if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_tmf_resp) || task->tmf_resp == NULL)) { SPDK_ERRLOG("%s: TMF response descriptor at index %d points to invalid guest memory region\n", vdev->name, task->req_idx); @@ -369,7 +369,7 @@ process_ctrl_request(struct spdk_vhost_scsi_task *task) break; case VIRTIO_SCSI_T_AN_QUERY: case VIRTIO_SCSI_T_AN_SUBSCRIBE: { - an_resp = spdk_vhost_gpa_to_vva(vdev, desc->addr); + an_resp = spdk_vhost_gpa_to_vva(vdev, desc->addr, sizeof(*an_resp)); if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_an_resp) || an_resp == NULL)) { SPDK_WARNLOG("%s: Asynchronous response descriptor points to invalid guest memory region\n", vdev->name); @@ -418,7 +418,7 @@ task_data_setup(struct spdk_vhost_scsi_task *task, goto invalid_task; } - *req = spdk_vhost_gpa_to_vva(vdev, desc->addr); + *req = spdk_vhost_gpa_to_vva(vdev, desc->addr, sizeof(**req)); if (spdk_unlikely(*req == NULL)) { SPDK_WARNLOG("%s: Request descriptor at index %d points to invalid guest memory region\n", vdev->name, task->req_idx); @@ -440,7 +440,7 @@ task_data_setup(struct spdk_vhost_scsi_task *task, /* * FROM_DEV (READ): [RD_req][WR_resp][WR_buf0]...[WR_bufN] */ - task->resp = spdk_vhost_gpa_to_vva(vdev, desc->addr); + task->resp = spdk_vhost_gpa_to_vva(vdev, desc->addr, sizeof(*task->resp)); if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) { SPDK_WARNLOG("%s: Response descriptor at index %d points to invalid guest memory region\n", vdev->name, task->req_idx); @@ -510,7 +510,7 @@ task_data_setup(struct spdk_vhost_scsi_task *task, } } - task->resp = spdk_vhost_gpa_to_vva(vdev, desc->addr); + task->resp = spdk_vhost_gpa_to_vva(vdev, desc->addr, sizeof(*task->resp)); if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) { SPDK_WARNLOG("%s: Response descriptor at index %d points to invalid guest memory region\n", vdev->name, task->req_idx); diff --git a/test/unit/lib/vhost/test_vhost.c b/test/unit/lib/vhost/test_vhost.c index 4e4387921..ec02fc1d2 100644 --- a/test/unit/lib/vhost/test_vhost.c +++ b/test/unit/lib/vhost/test_vhost.c @@ -87,7 +87,8 @@ DEFINE_STUB_V(spdk_vhost_call_external_event, (const char *ctrlr_name, spdk_vhos DEFINE_STUB(spdk_vhost_dev_has_feature, bool, (struct spdk_vhost_dev *vdev, unsigned feature_id), false); DEFINE_STUB(spdk_vhost_vring_desc_has_next, bool, (struct vring_desc *cur_desc), false); -DEFINE_STUB_VP(spdk_vhost_gpa_to_vva, (struct spdk_vhost_dev *vdev, uint64_t addr), {0}); +DEFINE_STUB_VP(spdk_vhost_gpa_to_vva, (struct spdk_vhost_dev *vdev, uint64_t addr, uint64_t len), +{0}); DEFINE_STUB(spdk_scsi_dev_get_id, int, (const struct spdk_scsi_dev *dev), {0}); DEFINE_STUB(spdk_json_write_null, int, (struct spdk_json_write_ctx *w), 0); DEFINE_STUB(spdk_json_write_bool, int, (struct spdk_json_write_ctx *w, bool val), 0);