Set .owner for guest_memfd file operations so that the KVM module(s) is is pinned until any files with callbacks back into KVM are completely freed. Note, file types that can call into sub-module code, e.g. kvm-intel.ko or kvm-amd.ko on x86, must use the module pointer passed to kvm_init(), not THIS_MODULE (which points at kvm.ko). KVM assumes that if /dev/kvm is reachable, e.g. VMs are active, then the vendor module is loaded. Opportunistically clean up the kvm_gmem_{init,exit}() mess that got left behind by commit 0f7e60a5f42a ("kvm: guestmem: do not use a file system"). Link: https://lore.kernel.org/all/20231018204624.1905300-2-seanjc@xxxxxxxxxx Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- See the link for details. I'm going to eventually squash this so I put the bare minimum copy+paste effort into the changelog. virt/kvm/guest_memfd.c | 7 ++++++- virt/kvm/kvm_main.c | 2 ++ virt/kvm/kvm_mm.h | 10 ++-------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 9ffce54555ae..94bc478c26f3 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -285,12 +285,17 @@ static struct file *kvm_gmem_get_file(struct kvm_memory_slot *slot) return file; } -static const struct file_operations kvm_gmem_fops = { +static struct file_operations kvm_gmem_fops = { .open = generic_file_open, .release = kvm_gmem_release, .fallocate = kvm_gmem_fallocate, }; +void kvm_gmem_init(struct module *module) +{ + kvm_gmem_fops.owner = module; +} + static int kvm_gmem_migrate_folio(struct address_space *mapping, struct folio *dst, struct folio *src, enum migrate_mode mode) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 959e866c84f0..357b9d9d0225 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -6459,6 +6459,8 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module) if (WARN_ON_ONCE(r)) goto err_vfio; + kvm_gmem_init(module); + /* * Registration _must_ be the very last thing done, as this exposes * /dev/kvm to userspace, i.e. all infrastructure must be setup! diff --git a/virt/kvm/kvm_mm.h b/virt/kvm/kvm_mm.h index 798f20d612bb..cca5372b9d5d 100644 --- a/virt/kvm/kvm_mm.h +++ b/virt/kvm/kvm_mm.h @@ -38,19 +38,13 @@ static inline void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, #endif /* HAVE_KVM_PFNCACHE */ #ifdef CONFIG_KVM_PRIVATE_MEM -int kvm_gmem_init(void); -void kvm_gmem_exit(void); +void kvm_gmem_init(struct module *module); int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args); int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, unsigned int fd, loff_t offset); void kvm_gmem_unbind(struct kvm_memory_slot *slot); #else -static inline int kvm_gmem_init(void) -{ - return 0; -} - -static inline void kvm_gmem_exit(void) +static inline void kvm_gmem_init(struct module *module) { } base-commit: 911b515af3ec5f53992b9cc162cf7d3893c2fbe2 -- 2.42.0.758.gaed0368e0e-goog