diff options
author | Frederick Mayle <fmayle@google.com> | 2023-10-23 19:12:23 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-10-23 19:12:23 +0000 |
commit | 7419327eb616ecc0e82a46baf64e6fab1a37abbb (patch) | |
tree | 6a879b0424eb6a99800caff1d602b670a3f4a5fc | |
parent | 33c3daeb098faf57c00441fb0351b8319e666636 (diff) | |
parent | 51387394334843ebff79dc7db94ad19d71f98bb9 (diff) | |
download | wmediumd-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.h | 7 | ||||
-rw-r--r-- | wmediumd/inc/usfstl/vhostproto.h | 15 | ||||
-rw-r--r-- | wmediumd/lib/vhost.c | 61 |
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; |