aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Henderson <william.henderson@nutanix.com>2023-07-21 09:39:11 +0000
committerJohn Levon <john.levon@nutanix.com>2023-09-15 12:59:39 +0100
commit9476ee2de7a60c7576bb0242720098aa334a0a88 (patch)
tree0e2c9c5a7ff70c4c20bdb7212583dc19ba2e0060
parent951f92270d94e5cc7e688625283c2a293f2f0399 (diff)
downloadlibvfio-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.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/lib/dma.c b/lib/dma.c
index 8000406..a323b4e 100644
--- a/lib/dma.c
+++ b/lib/dma.c
@@ -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);