diff options
author | Thanos Makatos <thanos.makatos@nutanix.com> | 2020-11-13 08:01:13 -0500 |
---|---|---|
committer | Thanos Makatos <thanos.makatos@nutanix.com> | 2020-11-13 09:30:57 -0500 |
commit | f0b7e72a73fb65eac354e3322f5e7b63aaa28e8a (patch) | |
tree | 4ba923b68126a45610811bbbf3554865453812d7 /lib | |
parent | ea51c80d8ba4d0abf0cb8ec6dac8ebe4a1c38aa1 (diff) | |
download | libvfio-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.c | 35 |
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: |