aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Henderson <william.henderson@nutanix.com>2023-09-04 10:21:54 +0000
committerJohn Levon <john.levon@nutanix.com>2023-09-15 12:59:39 +0100
commit5562eb7ca9971ca9ad895519e2ee834e721545d8 (patch)
tree7b264f33e7d79d424c17d5d1e762104f5e4be5bd
parent4b42857bfcc61a3cc3b7c23e7db8235182492e0c (diff)
downloadlibvfio-user-5562eb7ca9971ca9ad895519e2ee834e721545d8.zip
libvfio-user-5562eb7ca9971ca9ad895519e2ee834e721545d8.tar.gz
libvfio-user-5562eb7ca9971ca9ad895519e2ee834e721545d8.tar.bz2
fix: migration quiesce and short write
Signed-off-by: William Henderson <william.henderson@nutanix.com>
-rw-r--r--lib/libvfio-user.c17
-rw-r--r--lib/migration.c14
-rw-r--r--lib/migration.h3
3 files changed, 31 insertions, 3 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 01c520e..0cf4b13 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -1522,6 +1522,7 @@ static bool
command_needs_quiesce(vfu_ctx_t *vfu_ctx, const vfu_msg_t *msg)
{
struct vfio_user_region_access *reg;
+ struct vfio_user_device_feature *feature;
if (vfu_ctx->quiesce == NULL) {
return false;
@@ -1540,7 +1541,6 @@ command_needs_quiesce(vfu_ctx_t *vfu_ctx, const vfu_msg_t *msg)
/*
* bad request, it will be eventually failed by
* handle_region_access
- *
*/
return false;
}
@@ -1549,8 +1549,23 @@ command_needs_quiesce(vfu_ctx_t *vfu_ctx, const vfu_msg_t *msg)
return true;
}
break;
+
+ case VFIO_USER_DEVICE_FEATURE:
+ if (msg->in.iov.iov_len < sizeof(*feature)) {
+ /*
+ * bad request, it will be eventually failed by
+ * handle_region_access
+ */
+ return false;
+ }
+ feature = msg->in.iov.iov_base;
+ if (migration_feature_needs_quiesce(feature)) {
+ return true;
+ }
+ break;
}
+
return false;
}
diff --git a/lib/migration.c b/lib/migration.c
index cc6d271..6148e9e 100644
--- a/lib/migration.c
+++ b/lib/migration.c
@@ -385,6 +385,12 @@ handle_mig_data_write(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
return ERROR_INT(EINVAL);
}
+ if (msg->in.iov.iov_len < sizeof(struct vfio_user_mig_data) + req->size) {
+ vfu_log(vfu_ctx, LOG_ERR, "short write (%d < %ld)",
+ req->argsz, sizeof(struct vfio_user_mig_data) + req->size);
+ return ERROR_INT(EINVAL);
+ }
+
ssize_t ret = migr->callbacks.write_data(vfu_ctx, &req->data, req->size);
if (ret < 0) {
@@ -434,4 +440,12 @@ migration_set_pgsize(struct migration *migr, size_t pgsize)
return 0;
}
+bool
+migration_feature_needs_quiesce(struct vfio_user_device_feature *feature)
+{
+ return ((feature->flags &
+ (VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE)) != 0)
+ && !(feature->flags & VFIO_DEVICE_FEATURE_PROBE);
+}
+
/* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/lib/migration.h b/lib/migration.h
index 0d0dd76..928a7e5 100644
--- a/lib/migration.h
+++ b/lib/migration.h
@@ -85,8 +85,7 @@ MOCK_DECLARE(ssize_t, handle_device_state, vfu_ctx_t *vfu_ctx,
struct migration *migr, uint32_t device_state, bool notify);
bool
-access_migration_needs_quiesce(const vfu_ctx_t *vfu_ctx, size_t region_index,
- uint64_t offset);
+migration_feature_needs_quiesce(struct vfio_user_device_feature *feature);
#endif /* LIB_VFIO_USER_MIGRATION_H */