aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-11-02 04:16:08 -0500
committerThanos Makatos <thanos.makatos@nutanix.com>2020-11-13 09:30:57 -0500
commitea51c80d8ba4d0abf0cb8ec6dac8ebe4a1c38aa1 (patch)
treec08e800790006e020331ff1d734a2ec9c6c0f321 /lib
parentbc14a86815855af69141d4c6a44dbda24c270757 (diff)
downloadlibvfio-user-ea51c80d8ba4d0abf0cb8ec6dac8ebe4a1c38aa1.zip
libvfio-user-ea51c80d8ba4d0abf0cb8ec6dac8ebe4a1c38aa1.tar.gz
libvfio-user-ea51c80d8ba4d0abf0cb8ec6dac8ebe4a1c38aa1.tar.bz2
fixes in migration iteration code
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/muser_ctx.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/lib/muser_ctx.c b/lib/muser_ctx.c
index 92155d7..defc46d 100644
--- a/lib/muser_ctx.c
+++ b/lib/muser_ctx.c
@@ -1370,32 +1370,33 @@ handle_migration_data_offset(lm_ctx_t *lm_ctx, __u64 *offset, bool is_write)
assert(offset != NULL);
if (is_write) {
+ /* FIXME RO register means that we simply ignore the write, right? */
return -EINVAL;
}
switch (lm_ctx->migration.iter.state) {
- case VFIO_USER_MIGRATION_ITERATION_STATE_STARTED:
- break;
- default:
- /*
- * FIXME it's not clear whether these registers can be accessed in
- * other parts of the iteration, need clarification on the
- * following:
- *
- * Read on data_offset and data_size should return the offset and
- * size of the current buffer if the user application reads
- * data_offset and data_size more than once here.
- */
- return -EINVAL;
- }
-
- ret = lm_ctx->migration.callbacks.prepare_data(lm_ctx->pvt,
- &lm_ctx->migration.iter.offset,
- &lm_ctx->migration.iter.size);
- if (ret < 0) {
- return ret;
+ case VFIO_USER_MIGRATION_ITERATION_STATE_STARTED:
+ ret = lm_ctx->migration.callbacks.prepare_data(lm_ctx->pvt,
+ &lm_ctx->migration.iter.offset,
+ &lm_ctx->migration.iter.size);
+ if (ret < 0) {
+ return ret;
+ }
+ break;
+ case VFIO_USER_MIGRATION_ITERATION_STATE_DATA_PREPARED:
+ /*
+ * data_offset is invariant during an iteration.
+ */
+ break;
+ default:
+ /*
+ * reading data_offset is undefined out of sequence
+ */
+ *offset = ULLONG_MAX;
+ return -EINVAL;
}
+
*offset = lm_ctx->migration.iter.offset + sizeof(struct vfio_device_migration_info);
return ret;
@@ -1408,15 +1409,20 @@ handle_migration_data_size(lm_ctx_t *lm_ctx, __u64 *size, bool is_write)
assert(size != NULL);
if (is_write) {
+ /* FIXME RO register means that we simply ignore the write, right? */
return -EINVAL;
}
switch (lm_ctx->migration.iter.state) {
- case VFIO_USER_MIGRATION_ITERATION_STATE_STARTED:
- break;
- default:
- /* FIXME see comment in handle_migration_data_offset */
- return -EINVAL;
+ case VFIO_USER_MIGRATION_ITERATION_STATE_STARTED:
+ case VFIO_USER_MIGRATION_ITERATION_STATE_DATA_PREPARED:
+ break;
+ default:
+ /*
+ * reading data_size is undefined out of sequence
+ */
+ *size = ULLONG_MAX;
+ return -EINVAL;
}
*size = lm_ctx->migration.iter.size;
@@ -2092,6 +2098,15 @@ process_request(lm_ctx_t *lm_ctx)
return -ESHUTDOWN;
}
+ /*
+ * FIXME if migration device state is VFIO_DEVICE_STATE_STOP then only
+ * migration-related operations should execute. However, some operations
+ * are harmless (e.g. get region info). At the minimum we should fail
+ * accesses to device regions other than the migration region. I'd expect
+ * DMA unmap and get dirty pages to be required even in the stop-and-copy
+ * state.
+ */
+
nr_fds = lm_ctx->client_max_fds;
fds = alloca(nr_fds * sizeof(int));