QEMU needs to perform memslots operations like merging and splitting, and each operation requires more than a single ioctl. Therefore if a vcpu is concurrently reading the same memslots, it could end up reading something that was temporarly deleted. For example, merging two memslots into one would imply: DELETE(m1) DELETE(m2) CREATE(m1+m2) And a vcpu could attempt to read m2 right after it is deleted, but before the new one is created. To solve this problem, use the newly introduced kvm API: KVM_KICK_ALL_RUNNING_VCPUS and KVM_RESUME_ALL_KICKED_VCPUS. This new API allows the userspace to respectively stop and resume all running vcpus. A "running" vcpu is a vcpu that is executing the KVM_RUN ioctl. While KVM already handles the case of KVM_RUN being called after KVM_KICK_ALL_RUNNING_VCPUS is invoked but before KVM_RESUME_ALL_KICKED_VCPUS by simply returning immediately, QEMU also avoids that using the event API. This is the simplest solution, pausing all vcpus in the kvm side, so that: - QEMU just needs to call the new API before making memslots changes, keeping modifications to the minimum - dirty page updates are also performed when vcpus are blocked, so there is no time window between the dirty page ioctl and memslots modifications, since vcpus are all stopped. - no need to modify the existing memslots API This series requires the KVM serie "KVM: API to block and resume all running vcpus in a vm". Emanuele Giuseppe Esposito (2): linux-headers/linux/kvm.h: introduce kvm_userspace_memory_region_list ioctl accel/kvm: introduce begin/commit listener callbacks accel/kvm/kvm-all.c | 50 +++++++++++++++++++++++++++++++++++++++ linux-headers/linux/kvm.h | 3 +++ 2 files changed, 53 insertions(+) -- 2.31.1