diff options
author | William Henderson <william.henderson@nutanix.com> | 2023-07-21 09:39:11 +0000 |
---|---|---|
committer | John Levon <john.levon@nutanix.com> | 2023-09-15 12:59:39 +0100 |
commit | 9476ee2de7a60c7576bb0242720098aa334a0a88 (patch) | |
tree | 0e2c9c5a7ff70c4c20bdb7212583dc19ba2e0060 | |
parent | 951f92270d94e5cc7e688625283c2a293f2f0399 (diff) | |
download | libvfio-user-9476ee2de7a60c7576bb0242720098aa334a0a88.zip libvfio-user-9476ee2de7a60c7576bb0242720098aa334a0a88.tar.gz libvfio-user-9476ee2de7a60c7576bb0242720098aa334a0a88.tar.bz2 |
fix: dirty page logging bug fixes
Signed-off-by: William Henderson <william.henderson@nutanix.com>
-rw-r--r-- | lib/dma.c | 41 |
1 files changed, 33 insertions, 8 deletions
@@ -358,6 +358,8 @@ ssize_t dma_feature_set(vfu_ctx_t *vfu_ctx, uint32_t feature, void *buf) { assert(vfu_ctx != NULL); + assert(feature == VFIO_DEVICE_FEATURE_DMA_LOGGING_START || + feature == VFIO_DEVICE_FEATURE_DMA_LOGGING_STOP); struct dma_controller *dma = vfu_ctx->dma; @@ -365,6 +367,17 @@ dma_feature_set(vfu_ctx_t *vfu_ctx, uint32_t feature, void *buf) struct vfio_user_device_feature_dma_logging_control *req = buf; + size_t num_regions = req->num_ranges; + bool is_all_regions = false; + + // If num_ranges is zero, we consider every region to be selected. + if (num_regions == 0) { + num_regions = dma->nregions; + is_all_regions = true; + } + + dma_memory_region_t *region; + if (feature == VFIO_DEVICE_FEATURE_DMA_LOGGING_START) { if (req->page_size == 0) { return ERROR_INT(EINVAL); @@ -377,9 +390,13 @@ dma_feature_set(vfu_ctx_t *vfu_ctx, uint32_t feature, void *buf) return 0; } - for (size_t i = 0; i < req->num_ranges; i++) { - dma_memory_region_t *region = find_region(dma, req->ranges[i].iova, - req->ranges[i].length); + for (size_t i = 0; i < num_regions; i++) { + if (is_all_regions) { + region = &dma->regions[i]; + } else { + region = find_region(dma, req->ranges[i].iova, + req->ranges[i].length); + } if (region == NULL) { return ERROR_INT(EINVAL); @@ -391,8 +408,12 @@ dma_feature_set(vfu_ctx_t *vfu_ctx, uint32_t feature, void *buf) size_t j; for (j = 0; j < i; j++) { - region = find_region(dma, req->ranges[i].iova, - req->ranges[i].length); + if (is_all_regions) { + region = &dma->regions[j]; + } else { + region = find_region(dma, req->ranges[j].iova, + req->ranges[j].length); + } free(region->dirty_bitmap); region->dirty_bitmap = NULL; } @@ -409,9 +430,13 @@ dma_feature_set(vfu_ctx_t *vfu_ctx, uint32_t feature, void *buf) return 0; } - for (size_t i = 0; i < req->num_ranges; i++) { - dma_memory_region_t *region = find_region(dma, req->ranges[i].iova, - req->ranges[i].length); + for (size_t i = 0; i < num_regions; i++) { + if (is_all_regions) { + region = &dma->regions[i]; + } else { + region = find_region(dma, req->ranges[i].iova, + req->ranges[i].length); + } if (region == NULL || region->dirty_bitmap == NULL) { return ERROR_INT(EINVAL); |