From: Ackerley Tng Unhandled errors from xa_store_range() means kvm_gmem_bind() might falsely reporting success, leading to false assumptions in guest_memfd's lifecycle later. On error, restore the unbound state and return the error to userspace. Fixes: a7800aa80ea4d ("KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory") Signed-off-by: Ackerley Tng --- virt/kvm/guest_memfd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index d203135969d13..5b4911ffa208a 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -648,6 +648,7 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, struct inode *inode; struct file *file; int r = -EINVAL; + void *result; BUILD_BUG_ON(sizeof(gfn_t) != sizeof(slot->gmem.pgoff)); @@ -688,7 +689,14 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, if (kvm_gmem_supports_mmap(inode)) slot->flags |= KVM_MEMSLOT_GMEM_ONLY; - xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNEL); + result = xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNEL); + if (xa_is_err(result)) { + r = xa_err(result); + xa_store_range(&f->bindings, start, end - 1, NULL, GFP_KERNEL); + } else { + r = 0; + } + filemap_invalidate_unlock(inode->i_mapping); /* @@ -696,7 +704,6 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, * not the other way 'round. Active bindings are invalidated if the * file is closed before memslots are destroyed. */ - r = 0; err: fput(file); return r; -- 2.54.0.794.g4f17f83d09-goog