aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-11-13 08:01:13 -0500
committerThanos Makatos <thanos.makatos@nutanix.com>2020-11-13 09:30:57 -0500
commitf0b7e72a73fb65eac354e3322f5e7b63aaa28e8a (patch)
tree4ba923b68126a45610811bbbf3554865453812d7 /lib
parentea51c80d8ba4d0abf0cb8ec6dac8ebe4a1c38aa1 (diff)
downloadlibvfio-user-f0b7e72a73fb65eac354e3322f5e7b63aaa28e8a.zip
libvfio-user-f0b7e72a73fb65eac354e3322f5e7b63aaa28e8a.tar.gz
libvfio-user-f0b7e72a73fb65eac354e3322f5e7b63aaa28e8a.tar.bz2
only allow accessing the migration region in stop-and-copy state
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/muser_ctx.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/lib/muser_ctx.c b/lib/muser_ctx.c
index defc46d..92a8475 100644
--- a/lib/muser_ctx.c
+++ b/lib/muser_ctx.c
@@ -1907,6 +1907,23 @@ handle_device_reset(lm_ctx_t *lm_ctx)
return device_reset(lm_ctx);
}
+static bool
+migration_available(lm_ctx_t *lm_ctx)
+{
+ assert(lm_ctx != NULL);
+
+ return lm_ctx->pci_info.reg_info[LM_DEV_MIGRATION_REG_IDX].size > 0;
+}
+
+static bool
+migration_is_stop_and_copy(lm_ctx_t *lm_ctx)
+{
+ assert(lm_ctx != NULL);
+
+ return migration_available(lm_ctx) &&
+ lm_ctx->migration.info.device_state == VFIO_DEVICE_STATE_SAVING;
+}
+
static int
handle_region_access(lm_ctx_t *lm_ctx, struct vfio_user_header *hdr,
void **data, size_t *len)
@@ -1949,6 +1966,15 @@ handle_region_access(lm_ctx_t *lm_ctx, struct vfio_user_header *hdr,
region_access.region, region_access.count);
return -EINVAL;
}
+
+ if (migration_is_stop_and_copy(lm_ctx) &&
+ region_access.region != LM_DEV_MIGRATION_REG_IDX) {
+ lm_log(lm_ctx, LM_ERR,
+ "cannot access region %d while device in stop-and-copy state",
+ region_access.region);
+ return -EINVAL;
+ }
+
count = region_access.count;
offset = region_to_offset(region_access.region) + region_access.offset;
@@ -2093,7 +2119,7 @@ process_request(lm_ctx_t *lm_ctx)
assert(lm_ctx != NULL);
- if (lm_ctx->pci_info.reg_info[LM_DEV_MIGRATION_REG_IDX].size > 0 &&
+ if (migration_available(lm_ctx) &&
lm_ctx->migration.info.device_state == VFIO_DEVICE_STATE_STOP) {
return -ESHUTDOWN;
}
@@ -2154,6 +2180,13 @@ process_request(lm_ctx_t *lm_ctx)
* here.
*/
+ if (migration_is_stop_and_copy(lm_ctx)
+ && !(hdr.cmd == VFIO_USER_REGION_READ || hdr.cmd == VFIO_USER_REGION_WRITE)) {
+ lm_log(lm_ctx, LM_ERR,
+ "bad command %d while device in stop-and-copy state", hdr.cmd);
+ return -EINVAL;
+ }
+
switch (hdr.cmd) {
case VFIO_USER_DMA_MAP:
case VFIO_USER_DMA_UNMAP: