Re: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap

From: James Houghton
Date: Fri Dec 06 2024 - 17:47:12 EST


> arch/x86/kvm/../../../virt/kvm/kvm_main.c: In function '__kvm_set_memory_region':
> >> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2049:41: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
> 2049 | new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
> | ^

I realize that, not only have I done this cast slightly wrong, I'm
missing a few checks on userfault_bitmap that I should have. Applying
this diff, or at least something like it, to fix it:

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index b552cdef2850..30f09141df64 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1977,6 +1977,12 @@ int __kvm_set_memory_region(struct kvm *kvm,
return -EINVAL;
if ((mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES)
return -EINVAL;
+ if (mem->flags & KVM_MEM_USERFAULT &&
+ ((mem->userfault_bitmap != untagged_addr(mem->userfault_bitmap)) ||
+ !access_ok((void __user *)(unsigned long)mem->userfault_bitmap,
+ DIV_ROUND_UP(mem->memory_size >> PAGE_SHIFT, BITS_PER_LONG)
+ * sizeof(long))))
+ return -EINVAL;

slots = __kvm_memslots(kvm, as_id);

@@ -2053,7 +2059,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
goto out;
}
if (mem->flags & KVM_MEM_USERFAULT)
- new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
+ new->userfault_bitmap =
+ (unsigned long __user *)(unsigned long)mem->userfault_bitmap;

r = kvm_set_memslot(kvm, old, new, change);
if (r)