aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Mayle <fmayle@google.com>2023-10-23 19:12:23 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-10-23 19:12:23 +0000
commit7419327eb616ecc0e82a46baf64e6fab1a37abbb (patch)
tree6a879b0424eb6a99800caff1d602b670a3f4a5fc
parent33c3daeb098faf57c00441fb0351b8319e666636 (diff)
parent51387394334843ebff79dc7db94ad19d71f98bb9 (diff)
downloadwmediumd-7419327eb616ecc0e82a46baf64e6fab1a37abbb.tar.gz
snapshot/restore the vrings am: 5138739433
Original change: https://android-review.googlesource.com/c/platform/external/wmediumd/+/2794978 Change-Id: Iacf36001d732e1b2e2ec69724ede235e3085afca Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--wmediumd/inc/usfstl/vhost.h7
-rw-r--r--wmediumd/inc/usfstl/vhostproto.h15
-rw-r--r--wmediumd/lib/vhost.c61
3 files changed, 79 insertions, 4 deletions
diff --git a/wmediumd/inc/usfstl/vhost.h b/wmediumd/inc/usfstl/vhost.h
index 017d0b5..85a76d9 100644
--- a/wmediumd/inc/usfstl/vhost.h
+++ b/wmediumd/inc/usfstl/vhost.h
@@ -141,6 +141,13 @@ void usfstl_vhost_user_config_changed(struct usfstl_vhost_user_dev *dev);
void *usfstl_vhost_user_to_va(struct usfstl_vhost_user_dev *dev, uint64_t addr);
/**
+ * usfstl_vhost_user_to_va - translate address
+ * @dev: device to translate address for
+ * @addr: host-side virtual addr
+ */
+uint64_t usfstl_vhost_user_to_phys(struct usfstl_vhost_user_dev *dev, uint64_t addr);
+
+/**
* usfstl_vhost_phys_to_va - translate address
* @dev: device to translate address for
* @addr: guest-side physical addr
diff --git a/wmediumd/inc/usfstl/vhostproto.h b/wmediumd/inc/usfstl/vhostproto.h
index 579af54..28756fa 100644
--- a/wmediumd/inc/usfstl/vhostproto.h
+++ b/wmediumd/inc/usfstl/vhostproto.h
@@ -33,10 +33,23 @@ struct vhost_user_region {
uint64_t mmap_offset;
};
+struct vring_snapshot {
+ int8_t enabled;
+ int8_t sleeping;
+ int8_t triggered;
+
+ unsigned int num;
+ uint64_t desc_guest_addr;
+ uint64_t avail_guest_addr;
+ uint64_t used_guest_addr;
+ uint16_t last_avail_idx;
+};
+
struct vhost_user_snapshot {
- int8_t sleeping[NUM_SNAPSHOT_QUEUES];
+ struct vring_snapshot vrings[NUM_SNAPSHOT_QUEUES];
};
+
struct vhost_user_msg {
struct vhost_user_msg_hdr hdr;
union {
diff --git a/wmediumd/lib/vhost.c b/wmediumd/lib/vhost.c
index 7e177ac..4e13012 100644
--- a/wmediumd/lib/vhost.c
+++ b/wmediumd/lib/vhost.c
@@ -43,6 +43,9 @@ struct usfstl_vhost_user_dev_int {
bool enabled;
bool sleeping;
bool triggered;
+ uint64_t desc_guest_addr;
+ uint64_t avail_guest_addr;
+ uint64_t used_guest_addr;
struct vring virtq;
int call_fd;
uint16_t last_avail_idx;
@@ -579,6 +582,15 @@ static void usfstl_vhost_user_handle_msg(struct usfstl_loop_entry *entry)
dev->ext.server->max_queues);
USFSTL_ASSERT_EQ(msg.payload.vring_addr.flags, (uint32_t)0, "0x%x");
USFSTL_ASSERT(!dev->virtqs[msg.payload.vring_addr.idx].enabled);
+
+ // Save the guest physical addresses to make snapshotting more convenient.
+ dev->virtqs[msg.payload.vring_addr.idx].desc_guest_addr =
+ usfstl_vhost_user_to_phys(&dev->ext, msg.payload.vring_addr.descriptor);
+ dev->virtqs[msg.payload.vring_addr.idx].used_guest_addr =
+ usfstl_vhost_user_to_phys(&dev->ext, msg.payload.vring_addr.used);
+ dev->virtqs[msg.payload.vring_addr.idx].avail_guest_addr =
+ usfstl_vhost_user_to_phys(&dev->ext, msg.payload.vring_addr.avail);
+
dev->virtqs[msg.payload.vring_addr.idx].last_avail_idx = 0;
dev->virtqs[msg.payload.vring_addr.idx].virtq.desc =
usfstl_vhost_user_to_va(&dev->ext,
@@ -703,7 +715,15 @@ static void usfstl_vhost_user_handle_msg(struct usfstl_loop_entry *entry)
USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd");
USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d");
for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
- msg.payload.snapshot_response.snapshot.sleeping[virtq] = dev->virtqs[virtq].sleeping;
+ struct vring_snapshot* snapshot = &msg.payload.snapshot_response.snapshot.vrings[virtq];
+ snapshot->enabled = dev->virtqs[virtq].enabled;
+ snapshot->sleeping = dev->virtqs[virtq].sleeping;
+ snapshot->triggered = dev->virtqs[virtq].triggered;
+ snapshot->num = dev->virtqs[virtq].virtq.num;
+ snapshot->desc_guest_addr = dev->virtqs[virtq].desc_guest_addr;
+ snapshot->avail_guest_addr = dev->virtqs[virtq].avail_guest_addr;
+ snapshot->used_guest_addr = dev->virtqs[virtq].used_guest_addr;
+ snapshot->last_avail_idx = dev->virtqs[virtq].last_avail_idx;
}
msg.payload.snapshot_response.bool_store = 1;
reply_len = (int)sizeof(msg.payload.snapshot_response);
@@ -721,8 +741,25 @@ static void usfstl_vhost_user_handle_msg(struct usfstl_loop_entry *entry)
usfstl_vhost_user_get_msg_fds(&msghdr, fds, 2);
for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) {
- dev->virtqs[virtq].sleeping = msg.payload.restore_request.snapshot.sleeping[virtq];
+ const struct vring_snapshot* snapshot = &msg.payload.snapshot_response.snapshot.vrings[virtq];
+ dev->virtqs[virtq].enabled = snapshot->enabled;
+ dev->virtqs[virtq].sleeping = snapshot->sleeping;
+ dev->virtqs[virtq].triggered = snapshot->triggered;
+ dev->virtqs[virtq].virtq.num = snapshot->num;
+ dev->virtqs[virtq].desc_guest_addr = snapshot->desc_guest_addr;
+ dev->virtqs[virtq].avail_guest_addr = snapshot->avail_guest_addr;
+ dev->virtqs[virtq].used_guest_addr = snapshot->used_guest_addr;
+ dev->virtqs[virtq].last_avail_idx = snapshot->last_avail_idx;
+
dev->virtqs[virtq].entry.fd = fds[virtq];
+
+ // Translate vring guest physical addresses.
+ dev->virtqs[virtq].virtq.desc = usfstl_vhost_phys_to_va(&dev->ext, dev->virtqs[virtq].desc_guest_addr);
+ dev->virtqs[virtq].virtq.used = usfstl_vhost_phys_to_va(&dev->ext, dev->virtqs[virtq].used_guest_addr);
+ dev->virtqs[virtq].virtq.avail = usfstl_vhost_phys_to_va(&dev->ext, dev->virtqs[virtq].avail_guest_addr);
+ USFSTL_ASSERT(dev->virtqs[virtq].virtq.avail &&
+ dev->virtqs[virtq].virtq.desc &&
+ dev->virtqs[virtq].virtq.used);
}
free(fds);
@@ -901,11 +938,29 @@ void *usfstl_vhost_user_to_va(struct usfstl_vhost_user_dev *extdev, uint64_t add
dev->regions[region].user_addr +
dev->regions[region].mmap_offset);
}
-
USFSTL_ASSERT(0, "cannot translate user address %"PRIx64"\n", addr);
return NULL;
}
+uint64_t usfstl_vhost_user_to_phys(struct usfstl_vhost_user_dev *extdev, uint64_t addr)
+{
+ struct usfstl_vhost_user_dev_int *dev;
+ unsigned int region;
+
+ dev = container_of(extdev, struct usfstl_vhost_user_dev_int, ext);
+
+ for (region = 0; region < dev->n_regions; region++) {
+ if (addr >= dev->regions[region].user_addr &&
+ addr < dev->regions[region].user_addr +
+ dev->regions[region].size)
+ return addr -
+ dev->regions[region].user_addr +
+ dev->regions[region].guest_phys_addr;
+ }
+ USFSTL_ASSERT(0, "cannot translate user address %"PRIx64"\n", addr);
+ return 0;
+}
+
void *usfstl_vhost_phys_to_va(struct usfstl_vhost_user_dev *extdev, uint64_t addr)
{
struct usfstl_vhost_user_dev_int *dev;