| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/29 15:23 | flow | patch-triage |
11mArgs:null Results: {
"EnableConfigs": [
"KVM",
"KVM_AMD",
"VFIO",
"KVM_VFIO",
"DRM_I915_GVT_KVMGT"
],
"FocusSymbols": [
"kvm_vfio_file_add",
"vfio_file_set_kvm",
"vfio_group_set_kvm",
"vfio_device_get_kvm_safe",
"vfio_device_put_kvm",
"file_to_kvm_x86",
"sev_vm_move_enc_context_from",
"sev_vm_copy_enc_context_from",
"kvm_page_track_register_notifier",
"kvm_page_track_unregister_notifier",
"kvm_write_track_add_gfn",
"kvm_write_track_remove_gfn"
],
"KMSANReasoning": "The patch refactors the interface between KVM and external subsystems (VFIO, page tracking, s390 PCI / vfio_ap) so that external subsystems hold references to the KVM VM `struct file` (using `get_file()` and `fput()`) rather than directly holding references to `struct kvm` (using `kvm_get_kvm()` / `kvm_put_kvm()`), and resolves the VM instance using arch-namespaced helpers (`file_to_kvm_\u003carch\u003e`).\n\nThis refactoring touches object reference management, pointer passing, and lifecycle coordination. All newly introduced local variables and struct members are explicitly initialized before use. No kernel-to-user memory copy operations (e.g. copy_to_user, put_user), uninitialized struct allocations, or buffer length calculations are introduced or modified. Any risks introduced by these changes are limited to object lifetimes, use-after-free, reference leaks, or NULL pointer dereferences, which are covered by standard KASAN, LOCKDEP, and built-in kernel diagnostics. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies reachable KVM and VFIO subsystem code on amd64. It refactors external subsystem integration (VFIO, SEV, and x86 page tracking) to track KVM instances by 'struct file *' instead of direct 'struct kvm *' pointers. This refactoring alters object lifetime management and reference counting (introducing get_file_active(), get_file(), fput(), and clearing kvm-\u003efile in kvm_vm_release()), as well as type-safe arch-namespaced file-to-kvm resolution (file_to_kvm_x86). These paths are reachable via standard KVM and VFIO ioctls and warrant fuzzing to uncover potential race conditions, UAFs, or refcount imbalances during concurrent VM lifecycle operations.",
"WorthFuzzing": true
} |
| 1/1 | 2026/09/29 15:23 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 11fd22d39468642a418c5aacd0251911ee9247dc\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Sep 29 15:23:10 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/s390/include/asm/kvm_host_s390.h b/arch/s390/include/asm/kvm_host_s390.h\nindex cd692f8fb7643..9519b8028b104 100644\n--- a/arch/s390/include/asm/kvm_host_s390.h\n+++ b/arch/s390/include/asm/kvm_host_s390.h\n@@ -27,6 +27,8 @@\n #include \u003casm/isc.h\u003e\n #include \u003casm/guarded_storage.h\u003e\n \n+#define kvm_file_to_kvm_arch s390\n+\n #define KVM_HAVE_MMU_RWLOCK\n #define KVM_MAX_VCPUS 255\n \n@@ -720,7 +722,7 @@ static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}\n void kvm_arch_free_vm(struct kvm *kvm);\n \n struct zpci_kvm_hook {\n-\tint (*kvm_register)(void *opaque, struct kvm *kvm);\n+\tint (*kvm_register)(void *opaque, struct file *kvm_file);\n \tvoid (*kvm_unregister)(void *opaque);\n };\n \ndiff --git a/arch/s390/kvm/s390/pci.c b/arch/s390/kvm/s390/pci.c\nindex 82892e1e03d94..d79bd3bdc68e9 100644\n--- a/arch/s390/kvm/s390/pci.c\n+++ b/arch/s390/kvm/s390/pci.c\n@@ -498,17 +498,22 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)\n * available, enable them and let userspace indicate whether or not they will\n * be used (specify SHM bit to disable).\n */\n-static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)\n+static int kvm_s390_pci_register_kvm(void *opaque, struct file *kvm_file)\n {\n \tstruct zpci_dev *zdev = opaque;\n+\tstruct kvm *kvm;\n \tint rc;\n \n \tif (!zdev)\n \t\treturn -EINVAL;\n \n+\tkvm = file_to_kvm_s390(kvm_file);\n+\tif (!kvm)\n+\t\treturn -ENOENT;\n+\n \tmutex_lock(\u0026zdev-\u003ekzdev_lock);\n \n-\tif (zdev-\u003ekzdev || zdev-\u003egisa != 0 || !kvm) {\n+\tif (zdev-\u003ekzdev || zdev-\u003egisa != 0) {\n \t\tmutex_unlock(\u0026zdev-\u003ekzdev_lock);\n \t\treturn -EINVAL;\n \t}\ndiff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h\nindex 683bb8bf43a94..e460073ff176d 100644\n--- a/arch/x86/include/asm/kvm_host.h\n+++ b/arch/x86/include/asm/kvm_host.h\n@@ -44,6 +44,8 @@\n \n #include \u003chyperv/hvhdk.h\u003e\n \n+#define kvm_file_to_kvm_arch x86\n+\n #define __KVM_HAVE_ARCH_VCPU_DEBUGFS\n \n /*\ndiff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h\nindex 3d040741044b4..ea885dd5c9aff 100644\n--- a/arch/x86/include/asm/kvm_page_track.h\n+++ b/arch/x86/include/asm/kvm_page_track.h\n@@ -44,13 +44,15 @@ struct kvm_page_track_notifier_node {\n \t\t\t\t struct kvm_page_track_notifier_node *node);\n };\n \n-int kvm_page_track_register_notifier(struct kvm *kvm,\n+struct file;\n+\n+int kvm_page_track_register_notifier(struct file *file,\n \t\t\t\t struct kvm_page_track_notifier_node *n);\n-void kvm_page_track_unregister_notifier(struct kvm *kvm,\n+void kvm_page_track_unregister_notifier(struct file *file,\n \t\t\t\t\tstruct kvm_page_track_notifier_node *n);\n \n-int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);\n-int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);\n+int kvm_write_track_add_gfn(struct file *file, gfn_t gfn);\n+int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn);\n #else\n /*\n * Allow defining a node in a structure even if page tracking is disabled, e.g.\ndiff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile\nindex 0474604ab8a14..c6bf463f50327 100644\n--- a/arch/x86/kvm/Makefile\n+++ b/arch/x86/kvm/Makefile\n@@ -61,9 +61,7 @@ exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/a\n \t\t\t\t-e kvm_page_track_unregister_notifier \\\n \t\t\t\t-e kvm_write_track_add_gfn \\\n \t\t\t\t-e kvm_write_track_remove_gfn \\\n-\t\t\t\t-e kvm_get_kvm \\\n-\t\t\t\t-e kvm_get_kvm_safe \\\n-\t\t\t\t-e kvm_put_kvm\n+\t\t\t\t-e kvm_file_to_kvm_fn\n \n # Force grep to emit a goofy group separator that can in turn be replaced with\n # the above newline macro (newlines in Make are a nightmare). Note, grep only\ndiff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c\nindex 7e8195a311bb0..f12558dfcd812 100644\n--- a/arch/x86/kvm/mmu/page_track.c\n+++ b/arch/x86/kvm/mmu/page_track.c\n@@ -16,6 +16,8 @@\n #include \u003clinux/kvm_host.h\u003e\n #include \u003clinux/rculist.h\u003e\n \n+#include \u003casm/kvm_page_track.h\u003e\n+\n #include \"mmu.h\"\n #include \"mmu_internal.h\"\n #include \"page_track.h\"\n@@ -237,10 +239,11 @@ static int kvm_enable_external_write_tracking(struct kvm *kvm)\n * register the notifier so that event interception for the tracked guest\n * pages can be received.\n */\n-int kvm_page_track_register_notifier(struct kvm *kvm,\n+int kvm_page_track_register_notifier(struct file *file,\n \t\t\t\t struct kvm_page_track_notifier_node *n)\n {\n \tstruct kvm_page_track_notifier_head *head;\n+\tstruct kvm *kvm = file_to_kvm_x86(file);\n \tint r;\n \n \tif (!kvm || kvm-\u003emm != current-\u003emm)\n@@ -252,7 +255,7 @@ int kvm_page_track_register_notifier(struct kvm *kvm,\n \t\t\treturn r;\n \t}\n \n-\tkvm_get_kvm(kvm);\n+\tget_file(file);\n \n \thead = \u0026kvm-\u003earch.track_notifier_head;\n \n@@ -267,10 +270,11 @@ EXPORT_SYMBOL_GPL(kvm_page_track_register_notifier);\n * stop receiving the event interception. It is the opposed operation of\n * kvm_page_track_register_notifier().\n */\n-void kvm_page_track_unregister_notifier(struct kvm *kvm,\n+void kvm_page_track_unregister_notifier(struct file *file,\n \t\t\t\t\tstruct kvm_page_track_notifier_node *n)\n {\n \tstruct kvm_page_track_notifier_head *head;\n+\tstruct kvm *kvm = file_to_kvm_x86(file);\n \n \thead = \u0026kvm-\u003earch.track_notifier_head;\n \n@@ -279,7 +283,7 @@ void kvm_page_track_unregister_notifier(struct kvm *kvm,\n \twrite_unlock(\u0026kvm-\u003emmu_lock);\n \tsynchronize_srcu(\u0026head-\u003etrack_srcu);\n \n-\tkvm_put_kvm(kvm);\n+\tfput(file);\n }\n EXPORT_SYMBOL_GPL(kvm_page_track_unregister_notifier);\n \n@@ -336,11 +340,12 @@ void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot)\n * add guest page to the tracking pool so that corresponding access on that\n * page will be intercepted.\n *\n- * @kvm: the guest instance we are interested in.\n+ * @file: the VM file of the guest instance we are interested in.\n * @gfn: the guest page.\n */\n-int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn)\n+int kvm_write_track_add_gfn(struct file *file, gfn_t gfn)\n {\n+\tstruct kvm *kvm = file_to_kvm_x86(file);\n \tstruct kvm_memory_slot *slot;\n \tint idx;\n \n@@ -366,11 +371,12 @@ EXPORT_SYMBOL_GPL(kvm_write_track_add_gfn);\n * remove the guest page from the tracking pool which stops the interception\n * of corresponding access on that page.\n *\n- * @kvm: the guest instance we are interested in.\n+ * @file: the VM file of the guest instance we are interested in.\n * @gfn: the guest page.\n */\n-int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn)\n+int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn)\n {\n+\tstruct kvm *kvm = file_to_kvm_x86(file);\n \tstruct kvm_memory_slot *slot;\n \tint idx;\n \ndiff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c\nindex 63eb2155a7749..db7ed11e9056f 100644\n--- a/arch/x86/kvm/svm/sev.c\n+++ b/arch/x86/kvm/svm/sev.c\n@@ -2151,10 +2151,10 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)\n \tif (fd_empty(f))\n \t\treturn -EBADF;\n \n-\tif (!file_is_kvm(fd_file(f)))\n+\tsource_kvm = file_to_kvm_x86(fd_file(f));\n+\tif (!source_kvm)\n \t\treturn -EBADF;\n \n-\tsource_kvm = fd_file(f)-\u003eprivate_data;\n \tret = sev_lock_two_vms(kvm, source_kvm);\n \tif (ret)\n \t\treturn ret;\n@@ -2876,10 +2876,10 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)\n \tif (fd_empty(f))\n \t\treturn -EBADF;\n \n-\tif (!file_is_kvm(fd_file(f)))\n+\tsource_kvm = file_to_kvm_x86(fd_file(f));\n+\tif (!source_kvm)\n \t\treturn -EBADF;\n \n-\tsource_kvm = fd_file(f)-\u003eprivate_data;\n \tret = sev_lock_two_vms(kvm, source_kvm);\n \tif (ret)\n \t\treturn ret;\ndiff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c\nindex 4db878c18f41c..373ce574c4319 100644\n--- a/drivers/s390/crypto/vfio_ap_ops.c\n+++ b/drivers/s390/crypto/vfio_ap_ops.c\n@@ -1822,17 +1822,27 @@ static const struct attribute_group *vfio_ap_mdev_attr_groups[] = {\n \n /**\n * vfio_ap_mdev_set_kvm - sets all data for @matrix_mdev that are needed\n- * to manage AP resources for the guest whose state is represented by @kvm\n+ * to manage AP resources for the guest whose state is represented by\n+ * @kvm_file\n *\n * @matrix_mdev: a mediated matrix device\n- * @kvm: reference to KVM instance\n+ * @kvm_file: the KVM VM file this vfio device is associated with\n *\n- * Return: 0 if no other mediated matrix device has a reference to @kvm;\n+ * Return: 0 if no other mediated matrix device has a reference to the VM;\n * otherwise, returns an -EPERM.\n */\n static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,\n-\t\t\t\tstruct kvm *kvm)\n+\t\t\t\tstruct file *kvm_file)\n {\n+\tstruct kvm *kvm;\n+\n+\tif (!kvm_file)\n+\t\treturn -ENOENT;\n+\n+\tkvm = file_to_kvm_s390(kvm_file);\n+\tif (!kvm)\n+\t\treturn -ENOENT;\n+\n \tif (kvm-\u003earch.crypto.crycbd) {\n \t\tget_update_locks_for_kvm(kvm);\n \t\tif (kvm-\u003earch.crypto.pqap_hook) {\n@@ -1841,7 +1851,6 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,\n \t\t}\n \t\tkvm-\u003earch.crypto.pqap_hook = \u0026matrix_mdev-\u003epqap_hook;\n \n-\t\tkvm_get_kvm(kvm);\n \t\tmatrix_mdev-\u003ekvm = kvm;\n \t\tvfio_ap_mdev_update_guest_apcb(matrix_mdev);\n \t\trelease_update_locks_for_kvm(kvm);\n@@ -1894,7 +1903,6 @@ static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)\n \t\tmatrix_mdev-\u003ekvm = NULL;\n \n \t\trelease_update_locks_for_kvm(kvm);\n-\t\tkvm_put_kvm(kvm);\n \t}\n }\n \ndiff --git a/drivers/vfio/group.c b/drivers/vfio/group.c\nindex b2299e5bc6df3..5bf8cbdff377c 100644\n--- a/drivers/vfio/group.c\n+++ b/drivers/vfio/group.c\n@@ -860,11 +860,20 @@ bool vfio_group_enforced_coherent(struct vfio_group *group)\n \treturn ret;\n }\n \n-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)\n+void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\n {\n+\tstruct file *old;\n+\n+\tif (kvm)\n+\t\tget_file(kvm);\n+\n \tspin_lock(\u0026group-\u003ekvm_ref_lock);\n+\told = group-\u003ekvm;\n \tgroup-\u003ekvm = kvm;\n \tspin_unlock(\u0026group-\u003ekvm_ref_lock);\n+\n+\tif (old)\n+\t\tfput(old);\n }\n \n /**\ndiff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h\nindex 7728bc99b63d1..9b619951a5d0c 100644\n--- a/drivers/vfio/vfio.h\n+++ b/drivers/vfio/vfio.h\n@@ -23,7 +23,7 @@ struct vfio_device_file {\n \tu8 access_granted;\n \tu32 devid; /* only valid when iommufd is valid */\n \tspinlock_t kvm_ref_lock; /* protect kvm field */\n-\tstruct kvm *kvm;\n+\tstruct file *kvm;\n \tstruct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */\n };\n \n@@ -88,7 +88,7 @@ struct vfio_group {\n #endif\n \tenum vfio_group_type\t\ttype;\n \tstruct mutex\t\t\tgroup_lock;\n-\tstruct kvm\t\t\t*kvm;\n+\tstruct file\t\t\t*kvm;\n \tstruct file\t\t\t*opened_file;\n \tstruct iommufd_ctx\t\t*iommufd;\n \tspinlock_t\t\t\tkvm_ref_lock;\n@@ -107,7 +107,7 @@ void vfio_device_group_unuse_iommu(struct vfio_device *device);\n void vfio_df_group_close(struct vfio_device_file *df);\n struct vfio_group *vfio_group_from_file(struct file *file);\n bool vfio_group_enforced_coherent(struct vfio_group *group);\n-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);\n+void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm);\n bool vfio_device_has_container(struct vfio_device *device);\n int __init vfio_group_init(void);\n void vfio_group_cleanup(void);\n@@ -165,7 +165,7 @@ static inline bool vfio_group_enforced_coherent(struct vfio_group *group)\n \treturn true;\n }\n \n-static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)\n+static inline void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\n {\n }\n \n@@ -429,11 +429,11 @@ static inline void vfio_virqfd_exit(void)\n #endif\n \n #if IS_ENABLED(CONFIG_KVM)\n-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);\n+void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm);\n void vfio_device_put_kvm(struct vfio_device *device);\n #else\n static inline void vfio_device_get_kvm_safe(struct vfio_device *device,\n-\t\t\t\t\t struct kvm *kvm)\n+\t\t\t\t\t struct file *kvm)\n {\n }\n \ndiff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c\nindex 423ead48aafe3..ed96acfa86358 100644\n--- a/drivers/vfio/vfio_main.c\n+++ b/drivers/vfio/vfio_main.c\n@@ -472,36 +472,14 @@ void vfio_unregister_group_dev(struct vfio_device *device)\n EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);\n \n #if IS_ENABLED(CONFIG_KVM)\n-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)\n+void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)\n {\n-\tvoid (*pfn)(struct kvm *kvm);\n-\tbool (*fn)(struct kvm *kvm);\n-\tbool ret;\n-\n \tlockdep_assert_held(\u0026device-\u003edev_set-\u003elock);\n \n \tif (!kvm)\n \t\treturn;\n \n-\tpfn = symbol_get(kvm_put_kvm);\n-\tif (WARN_ON(!pfn))\n-\t\treturn;\n-\n-\tfn = symbol_get(kvm_get_kvm_safe);\n-\tif (WARN_ON(!fn)) {\n-\t\tsymbol_put(kvm_put_kvm);\n-\t\treturn;\n-\t}\n-\n-\tret = fn(kvm);\n-\tsymbol_put(kvm_get_kvm_safe);\n-\tif (!ret) {\n-\t\tsymbol_put(kvm_put_kvm);\n-\t\treturn;\n-\t}\n-\n-\tdevice-\u003eput_kvm = pfn;\n-\tdevice-\u003ekvm = kvm;\n+\tdevice-\u003ekvm = get_file(kvm);\n }\n \n void vfio_device_put_kvm(struct vfio_device *device)\n@@ -511,14 +489,7 @@ void vfio_device_put_kvm(struct vfio_device *device)\n \tif (!device-\u003ekvm)\n \t\treturn;\n \n-\tif (WARN_ON(!device-\u003eput_kvm))\n-\t\tgoto clear;\n-\n-\tdevice-\u003eput_kvm(device-\u003ekvm);\n-\tdevice-\u003eput_kvm = NULL;\n-\tsymbol_put(kvm_put_kvm);\n-\n-clear:\n+\tfput(device-\u003ekvm);\n \tdevice-\u003ekvm = NULL;\n }\n #endif\n@@ -1544,9 +1515,13 @@ bool vfio_file_enforced_coherent(struct file *file)\n }\n EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);\n \n-static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)\n+static void vfio_device_file_set_kvm(struct file *file, struct file *kvm)\n {\n \tstruct vfio_device_file *df = file-\u003eprivate_data;\n+\tstruct file *old;\n+\n+\tif (kvm)\n+\t\tget_file(kvm);\n \n \t/*\n \t * The kvm is first recorded in the vfio_device_file, and will\n@@ -1554,28 +1529,32 @@ static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)\n \t * iommufd successfully in the vfio device cdev path.\n \t */\n \tspin_lock(\u0026df-\u003ekvm_ref_lock);\n+\told = df-\u003ekvm;\n \tdf-\u003ekvm = kvm;\n \tspin_unlock(\u0026df-\u003ekvm_ref_lock);\n+\n+\tif (old)\n+\t\tfput(old);\n }\n \n /**\n * vfio_file_set_kvm - Link a kvm with VFIO drivers\n- * @file: VFIO group file or VFIO device file\n- * @kvm: KVM to link\n+ * @vfio_file: VFIO group file or VFIO device file\n+ * @kvm: KVM file to link\n *\n * When a VFIO device is first opened the KVM will be available in\n * device-\u003ekvm if one was associated with the file.\n */\n-void vfio_file_set_kvm(struct file *file, struct kvm *kvm)\n+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)\n {\n \tstruct vfio_group *group;\n \n-\tgroup = vfio_group_from_file(file);\n+\tgroup = vfio_group_from_file(vfio_file);\n \tif (group)\n \t\tvfio_group_set_kvm(group, kvm);\n \n-\tif (vfio_device_from_file(file))\n-\t\tvfio_device_file_set_kvm(file, kvm);\n+\tif (vfio_device_from_file(vfio_file))\n+\t\tvfio_device_file_set_kvm(vfio_file, kvm);\n }\n EXPORT_SYMBOL_GPL(vfio_file_set_kvm);\n \ndiff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h\nindex cf7fe835c4ad2..586f6e8bb81b3 100644\n--- a/include/linux/kvm_host.h\n+++ b/include/linux/kvm_host.h\n@@ -784,6 +784,12 @@ struct kvm {\n \t * kvm_swap_active_memslots().\n \t */\n \tstruct mutex slots_arch_lock;\n+\t/*\n+\t * Back-reference to the VM file for subsystems (e.g., VFIO). Holds no\n+\t * reference to avoid pinning the VM. Callers storing the file must\n+\t * take their own reference.\n+\t */\n+\tstruct file *file;\n \tstruct mm_struct *mm; /* userspace tied to this vm */\n \tunsigned long nr_memslot_pages;\n \t/* The two memslot sets - active and inactive (per address space) */\n@@ -1081,7 +1087,18 @@ void kvm_exit(void);\n void kvm_get_kvm(struct kvm *kvm);\n bool kvm_get_kvm_safe(struct kvm *kvm);\n void kvm_put_kvm(struct kvm *kvm);\n-bool file_is_kvm(struct file *file);\n+\n+/*\n+ * Architectures define kvm_file_to_kvm_arch to \u003carch\u003e\n+ * to get a typed, arch-namespaced helper:\n+ *\n+ * struct kvm *file_to_kvm_\u003carch\u003e(struct file *file)\n+ */\n+#ifdef kvm_file_to_kvm_arch\n+#define kvm_file_to_kvm_fn CONCATENATE(file_to_kvm_, kvm_file_to_kvm_arch)\n+struct kvm *kvm_file_to_kvm_fn(struct file *file);\n+#endif /* kvm_file_to_kvm_arch */\n+\n void kvm_put_kvm_no_destroy(struct kvm *kvm);\n \n static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)\ndiff --git a/include/linux/vfio.h b/include/linux/vfio.h\nindex 45f08986359e4..0cc91c6f96d2b 100644\n--- a/include/linux/vfio.h\n+++ b/include/linux/vfio.h\n@@ -54,7 +54,7 @@ struct vfio_device {\n \tstruct list_head dev_set_list;\n \tunsigned int migration_flags;\n \tu8 precopy_info_v2;\n-\tstruct kvm *kvm;\n+\tstruct file *kvm;\n \n \t/* Members below here are private, not for driver use */\n \tunsigned int index;\n@@ -66,7 +66,6 @@ struct vfio_device {\n \tunsigned int open_count;\n \tstruct completion comp;\n \tstruct iommufd_access *iommufd_access;\n-\tvoid (*put_kvm)(struct kvm *kvm);\n \tstruct inode *inode;\n #if IS_ENABLED(CONFIG_IOMMUFD)\n \tstruct iommufd_device *iommufd_device;\n@@ -378,7 +377,7 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi\n #endif\n bool vfio_file_is_valid(struct file *file);\n bool vfio_file_enforced_coherent(struct file *file);\n-void vfio_file_set_kvm(struct file *file, struct kvm *kvm);\n+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm);\n \n #define VFIO_PIN_PAGES_MAX_ENTRIES\t(PAGE_SIZE/sizeof(unsigned long))\n \ndiff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c\nindex 85f42289748dc..60e614795a36c 100644\n--- a/virt/kvm/kvm_main.c\n+++ b/virt/kvm/kvm_main.c\n@@ -1314,7 +1314,7 @@ void kvm_get_kvm(struct kvm *kvm)\n {\n \trefcount_inc(\u0026kvm-\u003eusers_count);\n }\n-EXPORT_SYMBOL_GPL(kvm_get_kvm);\n+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_kvm);\n \n /*\n * Make sure the vm is not during destruction, which is a safe version of\n@@ -1324,14 +1324,14 @@ bool kvm_get_kvm_safe(struct kvm *kvm)\n {\n \treturn refcount_inc_not_zero(\u0026kvm-\u003eusers_count);\n }\n-EXPORT_SYMBOL_GPL(kvm_get_kvm_safe);\n+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_kvm_safe);\n \n void kvm_put_kvm(struct kvm *kvm)\n {\n \tif (refcount_dec_and_test(\u0026kvm-\u003eusers_count))\n \t\tkvm_destroy_vm(kvm);\n }\n-EXPORT_SYMBOL_GPL(kvm_put_kvm);\n+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_put_kvm);\n \n /*\n * Used to put a reference that was taken on behalf of an object associated\n@@ -1352,6 +1352,8 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)\n \n \tkvm_irqfd_release(kvm);\n \n+\tWRITE_ONCE(kvm-\u003efile, NULL);\n+\n \tkvm_put_kvm(kvm);\n \treturn 0;\n }\n@@ -5513,11 +5515,16 @@ static struct file_operations kvm_vm_fops = {\n \tKVM_COMPAT(kvm_vm_compat_ioctl),\n };\n \n-bool file_is_kvm(struct file *file)\n+#ifdef kvm_file_to_kvm_arch\n+struct kvm *kvm_file_to_kvm_fn(struct file *file)\n {\n-\treturn file \u0026\u0026 file-\u003ef_op == \u0026kvm_vm_fops;\n+\tif (!file || file-\u003ef_op != \u0026kvm_vm_fops)\n+\t\treturn NULL;\n+\n+\treturn file-\u003eprivate_data;\n }\n-EXPORT_SYMBOL_FOR_KVM_INTERNAL(file_is_kvm);\n+EXPORT_SYMBOL_GPL(kvm_file_to_kvm_fn);\n+#endif\n \n static int kvm_dev_ioctl_create_vm(unsigned long type)\n {\n@@ -5544,6 +5551,8 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)\n \t\tgoto put_kvm;\n \t}\n \n+\tkvm-\u003efile = file;\n+\n \t/*\n \t * Don't call kvm_put_kvm anymore at this point; file-\u003ef_op is\n \t * already set, with -\u003erelease() being kvm_vm_release(). In error\ndiff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c\nindex 6cdc4e9a333a3..19548a4309426 100644\n--- a/virt/kvm/vfio.c\n+++ b/virt/kvm/vfio.c\n@@ -35,15 +35,15 @@ struct kvm_vfio {\n \tbool noncoherent;\n };\n \n-static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm)\n+static void kvm_vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)\n {\n-\tvoid (*fn)(struct file *file, struct kvm *kvm);\n+\tvoid (*fn)(struct file *vfio_file, struct file *kvm);\n \n \tfn = symbol_get(vfio_file_set_kvm);\n \tif (!fn)\n \t\treturn;\n \n-\tfn(file, kvm);\n+\tfn(vfio_file, kvm);\n \n \tsymbol_put(vfio_file_set_kvm);\n }\n@@ -144,6 +144,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\n {\n \tstruct kvm_vfio *kv = dev-\u003eprivate;\n \tstruct kvm_vfio_file *kvf;\n+\tstruct file *kvm_file __free(fput) = NULL;\n \tstruct file *filp __free(fput) = NULL;\n \n \tfilp = fget(fd);\n@@ -154,6 +155,10 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\n \tif (!kvm_vfio_file_is_valid(filp))\n \t\treturn -EINVAL;\n \n+\tkvm_file = get_file_active(\u0026dev-\u003ekvm-\u003efile);\n+\tif (!kvm_file)\n+\t\treturn -ENOENT;\n+\n \tguard(mutex)(\u0026kv-\u003elock);\n \n \tlist_for_each_entry(kvf, \u0026kv-\u003efile_list, node) {\n@@ -168,7 +173,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\n \tkvf-\u003efile = get_file(filp);\n \tlist_add_tail(\u0026kvf-\u003enode, \u0026kv-\u003efile_list);\n \n-\tkvm_vfio_file_set_kvm(kvf-\u003efile, dev-\u003ekvm);\n+\tkvm_vfio_file_set_kvm(kvf-\u003efile, kvm_file);\n \tkvm_vfio_update_coherency(dev);\n \n \treturn 0;\n"
} |
| 2/1 | 2026/09/29 15:23 | agent | patch-evaluator |
9mModel:core Args: null Results: {
"EnableConfigs": [
"KVM",
"KVM_AMD",
"VFIO",
"KVM_VFIO",
"DRM_I915_GVT_KVMGT"
],
"FocusSymbols": [
"kvm_vfio_file_add",
"vfio_file_set_kvm",
"vfio_group_set_kvm",
"vfio_device_get_kvm_safe",
"vfio_device_put_kvm",
"file_to_kvm_x86",
"sev_vm_move_enc_context_from",
"sev_vm_copy_enc_context_from",
"kvm_page_track_register_notifier",
"kvm_page_track_unregister_notifier",
"kvm_write_track_add_gfn",
"kvm_write_track_remove_gfn"
],
"Reasoning": "The patch modifies reachable KVM and VFIO subsystem code on amd64. It refactors external subsystem integration (VFIO, SEV, and x86 page tracking) to track KVM instances by 'struct file *' instead of direct 'struct kvm *' pointers. This refactoring alters object lifetime management and reference counting (introducing get_file_active(), get_file(), fput(), and clearing kvm-\u003efile in kvm_vm_release()), as well as type-safe arch-namespaced file-to-kvm resolution (file_to_kvm_x86). These paths are reachable via standard KVM and VFIO ioctls and warrant fuzzing to uncover potential race conditions, UAFs, or refcount imbalances during concurrent VM lifecycle operations.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 11fd22d39468642a418c5aacd0251911ee9247dc
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Sep 29 15:23:10 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/s390/include/asm/kvm_host_s390.h b/arch/s390/include/asm/kvm_host_s390.h
index cd692f8fb7643..9519b8028b104 100644
--- a/arch/s390/include/asm/kvm_host_s390.h
+++ b/arch/s390/include/asm/kvm_host_s390.h
@@ -27,6 +27,8 @@
#include <asm/isc.h>
#include <asm/guarded_storage.h>
+#define kvm_file_to_kvm_arch s390
+
#define KVM_HAVE_MMU_RWLOCK
#define KVM_MAX_VCPUS 255
@@ -720,7 +722,7 @@ static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
void kvm_arch_free_vm(struct kvm *kvm);
struct zpci_kvm_hook {
- int (*kvm_register)(void *opaque, struct kvm *kvm);
+ int (*kvm_register)(void *opaque, struct file *kvm_file);
void (*kvm_unregister)(void *opaque);
};
diff --git a/arch/s390/kvm/s390/pci.c b/arch/s390/kvm/s390/pci.c
index 82892e1e03d94..d79bd3bdc68e9 100644
--- a/arch/s390/kvm/s390/pci.c
+++ b/arch/s390/kvm/s390/pci.c
@@ -498,17 +498,22 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)
* available, enable them and let userspace indicate whether or not they will
* be used (specify SHM bit to disable).
*/
-static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
+static int kvm_s390_pci_register_kvm(void *opaque, struct file *kvm_file)
{
struct zpci_dev *zdev = opaque;
+ struct kvm *kvm;
int rc;
if (!zdev)
return -EINVAL;
+ kvm = file_to_kvm_s390(kvm_file);
+ if (!kvm)
+ return -ENOENT;
+
mutex_lock(&zdev->kzdev_lock);
- if (zdev->kzdev || zdev->gisa != 0 || !kvm) {
+ if (zdev->kzdev || zdev->gisa != 0) {
mutex_unlock(&zdev->kzdev_lock);
return -EINVAL;
}
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 683bb8bf43a94..e460073ff176d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -44,6 +44,8 @@
#include <hyperv/hvhdk.h>
+#define kvm_file_to_kvm_arch x86
+
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
/*
diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h
index 3d040741044b4..ea885dd5c9aff 100644
--- a/arch/x86/include/asm/kvm_page_track.h
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -44,13 +44,15 @@ struct kvm_page_track_notifier_node {
struct kvm_page_track_notifier_node *node);
};
-int kvm_page_track_register_notifier(struct kvm *kvm,
+struct file;
+
+int kvm_page_track_register_notifier(struct file *file,
struct kvm_page_track_notifier_node *n);
-void kvm_page_track_unregister_notifier(struct kvm *kvm,
+void kvm_page_track_unregister_notifier(struct file *file,
struct kvm_page_track_notifier_node *n);
-int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);
-int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);
+int kvm_write_track_add_gfn(struct file *file, gfn_t gfn);
+int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn);
#else
/*
* Allow defining a node in a structure even if page tracking is disabled, e.g.
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 0474604ab8a14..c6bf463f50327 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -61,9 +61,7 @@ exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/a
-e kvm_page_track_unregister_notifier \
-e kvm_write_track_add_gfn \
-e kvm_write_track_remove_gfn \
- -e kvm_get_kvm \
- -e kvm_get_kvm_safe \
- -e kvm_put_kvm
+ -e kvm_file_to_kvm_fn
# Force grep to emit a goofy group separator that can in turn be replaced with
# the above newline macro (newlines in Make are a nightmare). Note, grep only
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 7e8195a311bb0..f12558dfcd812 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -16,6 +16,8 @@
#include <linux/kvm_host.h>
#include <linux/rculist.h>
+#include <asm/kvm_page_track.h>
+
#include "mmu.h"
#include "mmu_internal.h"
#include "page_track.h"
@@ -237,10 +239,11 @@ static int kvm_enable_external_write_tracking(struct kvm *kvm)
* register the notifier so that event interception for the tracked guest
* pages can be received.
*/
-int kvm_page_track_register_notifier(struct kvm *kvm,
+int kvm_page_track_register_notifier(struct file *file,
struct kvm_page_track_notifier_node *n)
{
struct kvm_page_track_notifier_head *head;
+ struct kvm *kvm = file_to_kvm_x86(file);
int r;
if (!kvm || kvm->mm != current->mm)
@@ -252,7 +255,7 @@ int kvm_page_track_register_notifier(struct kvm *kvm,
return r;
}
- kvm_get_kvm(kvm);
+ get_file(file);
head = &kvm->arch.track_notifier_head;
@@ -267,10 +270,11 @@ EXPORT_SYMBOL_GPL(kvm_page_track_register_notifier);
* stop receiving the event interception. It is the opposed operation of
* kvm_page_track_register_notifier().
*/
-void kvm_page_track_unregister_notifier(struct kvm *kvm,
+void kvm_page_track_unregister_notifier(struct file *file,
struct kvm_page_track_notifier_node *n)
{
struct kvm_page_track_notifier_head *head;
+ struct kvm *kvm = file_to_kvm_x86(file);
head = &kvm->arch.track_notifier_head;
@@ -279,7 +283,7 @@ void kvm_page_track_unregister_notifier(struct kvm *kvm,
write_unlock(&kvm->mmu_lock);
synchronize_srcu(&head->track_srcu);
- kvm_put_kvm(kvm);
+ fput(file);
}
EXPORT_SYMBOL_GPL(kvm_page_track_unregister_notifier);
@@ -336,11 +340,12 @@ void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
* add guest page to the tracking pool so that corresponding access on that
* page will be intercepted.
*
- * @kvm: the guest instance we are interested in.
+ * @file: the VM file of the guest instance we are interested in.
* @gfn: the guest page.
*/
-int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn)
+int kvm_write_track_add_gfn(struct file *file, gfn_t gfn)
{
+ struct kvm *kvm = file_to_kvm_x86(file);
struct kvm_memory_slot *slot;
int idx;
@@ -366,11 +371,12 @@ EXPORT_SYMBOL_GPL(kvm_write_track_add_gfn);
* remove the guest page from the tracking pool which stops the interception
* of corresponding access on that page.
*
- * @kvm: the guest instance we are interested in.
+ * @file: the VM file of the guest instance we are interested in.
* @gfn: the guest page.
*/
-int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn)
+int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn)
{
+ struct kvm *kvm = file_to_kvm_x86(file);
struct kvm_memory_slot *slot;
int idx;
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 63eb2155a7749..db7ed11e9056f 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -2151,10 +2151,10 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
if (fd_empty(f))
return -EBADF;
- if (!file_is_kvm(fd_file(f)))
+ source_kvm = file_to_kvm_x86(fd_file(f));
+ if (!source_kvm)
return -EBADF;
- source_kvm = fd_file(f)->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
return ret;
@@ -2876,10 +2876,10 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
if (fd_empty(f))
return -EBADF;
- if (!file_is_kvm(fd_file(f)))
+ source_kvm = file_to_kvm_x86(fd_file(f));
+ if (!source_kvm)
return -EBADF;
- source_kvm = fd_file(f)->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
return ret;
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 4db878c18f41c..373ce574c4319 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1822,17 +1822,27 @@ static const struct attribute_group *vfio_ap_mdev_attr_groups[] = {
/**
* vfio_ap_mdev_set_kvm - sets all data for @matrix_mdev that are needed
- * to manage AP resources for the guest whose state is represented by @kvm
+ * to manage AP resources for the guest whose state is represented by
+ * @kvm_file
*
* @matrix_mdev: a mediated matrix device
- * @kvm: reference to KVM instance
+ * @kvm_file: the KVM VM file this vfio device is associated with
*
- * Return: 0 if no other mediated matrix device has a reference to @kvm;
+ * Return: 0 if no other mediated matrix device has a reference to the VM;
* otherwise, returns an -EPERM.
*/
static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
- struct kvm *kvm)
+ struct file *kvm_file)
{
+ struct kvm *kvm;
+
+ if (!kvm_file)
+ return -ENOENT;
+
+ kvm = file_to_kvm_s390(kvm_file);
+ if (!kvm)
+ return -ENOENT;
+
if (kvm->arch.crypto.crycbd) {
get_update_locks_for_kvm(kvm);
if (kvm->arch.crypto.pqap_hook) {
@@ -1841,7 +1851,6 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
}
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
- kvm_get_kvm(kvm);
matrix_mdev->kvm = kvm;
vfio_ap_mdev_update_guest_apcb(matrix_mdev);
release_update_locks_for_kvm(kvm);
@@ -1894,7 +1903,6 @@ static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
matrix_mdev->kvm = NULL;
release_update_locks_for_kvm(kvm);
- kvm_put_kvm(kvm);
}
}
diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
index b2299e5bc6df3..5bf8cbdff377c 100644
--- a/drivers/vfio/group.c
+++ b/drivers/vfio/group.c
@@ -860,11 +860,20 @@ bool vfio_group_enforced_coherent(struct vfio_group *group)
return ret;
}
-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
+void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)
{
+ struct file *old;
+
+ if (kvm)
+ get_file(kvm);
+
spin_lock(&group->kvm_ref_lock);
+ old = group->kvm;
group->kvm = kvm;
spin_unlock(&group->kvm_ref_lock);
+
+ if (old)
+ fput(old);
}
/**
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index 7728bc99b63d1..9b619951a5d0c 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -23,7 +23,7 @@ struct vfio_device_file {
u8 access_granted;
u32 devid; /* only valid when iommufd is valid */
spinlock_t kvm_ref_lock; /* protect kvm field */
- struct kvm *kvm;
+ struct file *kvm;
struct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */
};
@@ -88,7 +88,7 @@ struct vfio_group {
#endif
enum vfio_group_type type;
struct mutex group_lock;
- struct kvm *kvm;
+ struct file *kvm;
struct file *opened_file;
struct iommufd_ctx *iommufd;
spinlock_t kvm_ref_lock;
@@ -107,7 +107,7 @@ void vfio_device_group_unuse_iommu(struct vfio_device *device);
void vfio_df_group_close(struct vfio_device_file *df);
struct vfio_group *vfio_group_from_file(struct file *file);
bool vfio_group_enforced_coherent(struct vfio_group *group);
-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);
+void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm);
bool vfio_device_has_container(struct vfio_device *device);
int __init vfio_group_init(void);
void vfio_group_cleanup(void);
@@ -165,7 +165,7 @@ static inline bool vfio_group_enforced_coherent(struct vfio_group *group)
return true;
}
-static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
+static inline void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)
{
}
@@ -429,11 +429,11 @@ static inline void vfio_virqfd_exit(void)
#endif
#if IS_ENABLED(CONFIG_KVM)
-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
+void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm);
void vfio_device_put_kvm(struct vfio_device *device);
#else
static inline void vfio_device_get_kvm_safe(struct vfio_device *device,
- struct kvm *kvm)
+ struct file *kvm)
{
}
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 423ead48aafe3..ed96acfa86358 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -472,36 +472,14 @@ void vfio_unregister_group_dev(struct vfio_device *device)
EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
#if IS_ENABLED(CONFIG_KVM)
-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)
+void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)
{
- void (*pfn)(struct kvm *kvm);
- bool (*fn)(struct kvm *kvm);
- bool ret;
-
lockdep_assert_held(&device->dev_set->lock);
if (!kvm)
return;
- pfn = symbol_get(kvm_put_kvm);
- if (WARN_ON(!pfn))
- return;
-
- fn = symbol_get(kvm_get_kvm_safe);
- if (WARN_ON(!fn)) {
- symbol_put(kvm_put_kvm);
- return;
- }
-
- ret = fn(kvm);
- symbol_put(kvm_get_kvm_safe);
- if (!ret) {
- symbol_put(kvm_put_kvm);
- return;
- }
-
- device->put_kvm = pfn;
- device->kvm = kvm;
+ device->kvm = get_file(kvm);
}
void vfio_device_put_kvm(struct vfio_device *device)
@@ -511,14 +489,7 @@ void vfio_device_put_kvm(struct vfio_device *device)
if (!device->kvm)
return;
- if (WARN_ON(!device->put_kvm))
- goto clear;
-
- device->put_kvm(device->kvm);
- device->put_kvm = NULL;
- symbol_put(kvm_put_kvm);
-
-clear:
+ fput(device->kvm);
device->kvm = NULL;
}
#endif
@@ -1544,9 +1515,13 @@ bool vfio_file_enforced_coherent(struct file *file)
}
EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
-static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
+static void vfio_device_file_set_kvm(struct file *file, struct file *kvm)
{
struct vfio_device_file *df = file->private_data;
+ struct file *old;
+
+ if (kvm)
+ get_file(kvm);
/*
* The kvm is first recorded in the vfio_device_file, and will
@@ -1554,28 +1529,32 @@ static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
* iommufd successfully in the vfio device cdev path.
*/
spin_lock(&df->kvm_ref_lock);
+ old = df->kvm;
df->kvm = kvm;
spin_unlock(&df->kvm_ref_lock);
+
+ if (old)
+ fput(old);
}
/**
* vfio_file_set_kvm - Link a kvm with VFIO drivers
- * @file: VFIO group file or VFIO device file
- * @kvm: KVM to link
+ * @vfio_file: VFIO group file or VFIO device file
+ * @kvm: KVM file to link
*
* When a VFIO device is first opened the KVM will be available in
* device->kvm if one was associated with the file.
*/
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm)
+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)
{
struct vfio_group *group;
- group = vfio_group_from_file(file);
+ group = vfio_group_from_file(vfio_file);
if (group)
vfio_group_set_kvm(group, kvm);
- if (vfio_device_from_file(file))
- vfio_device_file_set_kvm(file, kvm);
+ if (vfio_device_from_file(vfio_file))
+ vfio_device_file_set_kvm(vfio_file, kvm);
}
EXPORT_SYMBOL_GPL(vfio_file_set_kvm);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index cf7fe835c4ad2..586f6e8bb81b3 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -784,6 +784,12 @@ struct kvm {
* kvm_swap_active_memslots().
*/
struct mutex slots_arch_lock;
+ /*
+ * Back-reference to the VM file for subsystems (e.g., VFIO). Holds no
+ * reference to avoid pinning the VM. Callers storing the file must
+ * take their own reference.
+ */
+ struct file *file;
struct mm_struct *mm; /* userspace tied to this vm */
unsigned long nr_memslot_pages;
/* The two memslot sets - active and inactive (per address space) */
@@ -1081,7 +1087,18 @@ void kvm_exit(void);
void kvm_get_kvm(struct kvm *kvm);
bool kvm_get_kvm_safe(struct kvm *kvm);
void kvm_put_kvm(struct kvm *kvm);
-bool file_is_kvm(struct file *file);
+
+/*
+ * Architectures define kvm_file_to_kvm_arch to <arch>
+ * to get a typed, arch-namespaced helper:
+ *
+ * struct kvm *file_to_kvm_<arch>(struct file *file)
+ */
+#ifdef kvm_file_to_kvm_arch
+#define kvm_file_to_kvm_fn CONCATENATE(file_to_kvm_, kvm_file_to_kvm_arch)
+struct kvm *kvm_file_to_kvm_fn(struct file *file);
+#endif /* kvm_file_to_kvm_arch */
+
void kvm_put_kvm_no_destroy(struct kvm *kvm);
static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 45f08986359e4..0cc91c6f96d2b 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -54,7 +54,7 @@ struct vfio_device {
struct list_head dev_set_list;
unsigned int migration_flags;
u8 precopy_info_v2;
- struct kvm *kvm;
+ struct file *kvm;
/* Members below here are private, not for driver use */
unsigned int index;
@@ -66,7 +66,6 @@ struct vfio_device {
unsigned int open_count;
struct completion comp;
struct iommufd_access *iommufd_access;
- void (*put_kvm)(struct kvm *kvm);
struct inode *inode;
#if IS_ENABLED(CONFIG_IOMMUFD)
struct iommufd_device *iommufd_device;
@@ -378,7 +377,7 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi
#endif
bool vfio_file_is_valid(struct file *file);
bool vfio_file_enforced_coherent(struct file *file);
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm);
+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm);
#define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long))
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 85f42289748dc..60e614795a36c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1314,7 +1314,7 @@ void kvm_get_kvm(struct kvm *kvm)
{
refcount_inc(&kvm->users_count);
}
-EXPORT_SYMBOL_GPL(kvm_get_kvm);
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_kvm);
/*
* Make sure the vm is not during destruction, which is a safe version of
@@ -1324,14 +1324,14 @@ bool kvm_get_kvm_safe(struct kvm *kvm)
{
return refcount_inc_not_zero(&kvm->users_count);
}
-EXPORT_SYMBOL_GPL(kvm_get_kvm_safe);
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_kvm_safe);
void kvm_put_kvm(struct kvm *kvm)
{
if (refcount_dec_and_test(&kvm->users_count))
kvm_destroy_vm(kvm);
}
-EXPORT_SYMBOL_GPL(kvm_put_kvm);
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_put_kvm);
/*
* Used to put a reference that was taken on behalf of an object associated
@@ -1352,6 +1352,8 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
kvm_irqfd_release(kvm);
+ WRITE_ONCE(kvm->file, NULL);
+
kvm_put_kvm(kvm);
return 0;
}
@@ -5513,11 +5515,16 @@ static struct file_operations kvm_vm_fops = {
KVM_COMPAT(kvm_vm_compat_ioctl),
};
-bool file_is_kvm(struct file *file)
+#ifdef kvm_file_to_kvm_arch
+struct kvm *kvm_file_to_kvm_fn(struct file *file)
{
- return file && file->f_op == &kvm_vm_fops;
+ if (!file || file->f_op != &kvm_vm_fops)
+ return NULL;
+
+ return file->private_data;
}
-EXPORT_SYMBOL_FOR_KVM_INTERNAL(file_is_kvm);
+EXPORT_SYMBOL_GPL(kvm_file_to_kvm_fn);
+#endif
static int kvm_dev_ioctl_create_vm(unsigned long type)
{
@@ -5544,6 +5551,8 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
goto put_kvm;
}
+ kvm->file = file;
+
/*
* Don't call kvm_put_kvm anymore at this point; file->f_op is
* already set, with ->release() being kvm_vm_release(). In error
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
index 6cdc4e9a333a3..19548a4309426 100644
--- a/virt/kvm/vfio.c
+++ b/virt/kvm/vfio.c
@@ -35,15 +35,15 @@ struct kvm_vfio {
bool noncoherent;
};
-static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm)
+static void kvm_vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)
{
- void (*fn)(struct file *file, struct kvm *kvm);
+ void (*fn)(struct file *vfio_file, struct file *kvm);
fn = symbol_get(vfio_file_set_kvm);
if (!fn)
return;
- fn(file, kvm);
+ fn(vfio_file, kvm);
symbol_put(vfio_file_set_kvm);
}
@@ -144,6 +144,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
{
struct kvm_vfio *kv = dev->private;
struct kvm_vfio_file *kvf;
+ struct file *kvm_file __free(fput) = NULL;
struct file *filp __free(fput) = NULL;
filp = fget(fd);
@@ -154,6 +155,10 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
if (!kvm_vfio_file_is_valid(filp))
return -EINVAL;
+ kvm_file = get_file_active(&dev->kvm->file);
+ if (!kvm_file)
+ return -ENOENT;
+
guard(mutex)(&kv->lock);
list_for_each_entry(kvf, &kv->file_list, node) {
@@ -168,7 +173,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
kvf->file = get_file(filp);
list_add_tail(&kvf->node, &kv->file_list);
- kvm_vfio_file_set_kvm(kvf->file, dev->kvm);
+ kvm_vfio_file_set_kvm(kvf->file, kvm_file);
kvm_vfio_update_coherency(dev);
return 0;
|
| 3/2 | 2026/09/29 15:23 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11851 output: 24 thoughts: 1194 Thoughts: **Analyzing the KVM/VFIO Patch: A Deep Dive into Architectural Changes** Okay, so this patch is a significant one, clearly refactoring how `struct kvm` instances are managed and referenced throughout the KVM and VFIO subsystems. My initial assessment is that this is a change with potentially wide-reaching impacts, especially given the various subsystems it touches, like page tracking, the VFIO AP code, and potentially other areas. My primary focus here is understanding the implications of changing the primary KVM handle from a `struct kvm *` to a `struct file *`. That's the core of the change. This architecture is amd64, so I will concentrate on the X86 changes primarily. Let's break down my understanding. * **Architectural Overhaul:** It seems we're moving towards using the file descriptor (`struct file *`) associated with the KVM instance as the primary identifier instead of directly manipulating the `struct kvm` pointer. This has implications for how references are managed and how the lifetime of the KVM instance is tracked. * **X86 Specifics:** On x86, we see this reflected in the replacement of `kvm_get_kvm` and `kvm_put_kvm` with `get_file` and `fput`, respectively. This is a crucial shift in resource management. This also includes the added helper `file_to_kvm_x86(file)` to convert from `struct file` to `struct kvm`. This likely simplifies the interface. I see this across the board from page tracking to SVM contexts. * **VFIO Integration:** VFIO has been substantially altered. The `vfio_group_set_kvm` function, and all related structures, are now using the `struct file *` as the KVM handle, not `struct kvm *`. The modifications to `vfio_device_get_kvm_safe`, `vfio_device_put_kvm`, and `vfio_device_file_set_kvm` are all part of this. It's now using `get_file` and `fput` to manage references to the KVM file. The `get_file` calls, and the `fput` calls, are critical to ensuring the KVM instance doesn't get released prematurely and that its resources are properly cleaned up. * **Page Tracking Implications:** I'll need to carefully examine how these changes affect page tracking. The page tracking code on x86, now uses `file_to_kvm_x86` for its operations, and `get_file` and `fput`, for file handle management. I'll need to thoroughly verify how this impacts how memory is tracked and potentially, how it manages the association of guest physical addresses (GFNs) to host virtual addresses. * **Internalization of `kvm_get_kvm`:** The move to internal-only for the `kvm_get_kvm`, `kvm_get_kvm_safe`, and `kvm_put_kvm` functions suggests a conscious effort to encapsulate KVM's internal data structures and potentially limit external dependencies. * **File Association:** The addition of `struct file *file` within the `struct kvm` is key. This establishes a clear link between the KVM instance and its associated file descriptor. It looks like `kvm->file = file;` is the primary setter. * **Next Steps:** I will use `grepper` and similar tools to determine the call sites and the dependencies on the `kvm_page_track_register_notifier` and other functions to ensure everything is operating as expected. I need to be sure all dependencies are being properly ref-counted. I need to verify that there are no reference leaks or use-after-free conditions. I will be doing extensive testing. Overall, this patch is a significant step towards streamlining and modernizing KVM's internal architecture, particularly in its interaction with VFIO. The shift to using `struct file *` for KVM handles is a well-thought-out move towards a cleaner and more robust design, but one that requires meticulous review and testing to ensure compatibility and stability. |
| 4/2 | 2026/09/29 15:23 | tool | grepper |
0mArgs:{
"Expression": "kvm_page_track_register_notifier"
}Results: {
"Output": "arch/x86/include/asm/kvm_page_track.h=47=struct file;\narch/x86/include/asm/kvm_page_track.h-48-\narch/x86/include/asm/kvm_page_track.h:49:int kvm_page_track_register_notifier(struct file *file,\narch/x86/include/asm/kvm_page_track.h-50-\t\t\t\t struct kvm_page_track_notifier_node *n);\n--\narch/x86/kvm/Makefile=59=exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/arch/x86/kvm | \\\narch/x86/kvm/Makefile:60:\t\t\tgrep -v -e kvm_page_track_register_notifier \\\narch/x86/kvm/Makefile-61-\t\t\t\t-e kvm_page_track_unregister_notifier \\\n--\narch/x86/kvm/mmu/page_track.c=191=static int kvm_enable_external_write_tracking(struct kvm *kvm)\n--\narch/x86/kvm/mmu/page_track.c-241- */\narch/x86/kvm/mmu/page_track.c:242:int kvm_page_track_register_notifier(struct file *file,\narch/x86/kvm/mmu/page_track.c-243-\t\t\t\t struct kvm_page_track_notifier_node *n)\n--\narch/x86/kvm/mmu/page_track.c-266-}\narch/x86/kvm/mmu/page_track.c:267:EXPORT_SYMBOL_GPL(kvm_page_track_register_notifier);\narch/x86/kvm/mmu/page_track.c-268-\n--\narch/x86/kvm/mmu/page_track.c-270- * stop receiving the event interception. It is the opposed operation of\narch/x86/kvm/mmu/page_track.c:271: * kvm_page_track_register_notifier().\narch/x86/kvm/mmu/page_track.c-272- */\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c=663=static int intel_vgpu_open_device(struct vfio_device *vfio_dev)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c-672-\tvgpu-\u003etrack_node.track_remove_region = kvmgt_page_track_remove_region;\ndrivers/gpu/drm/i915/gvt/kvmgt.c:673:\tret = kvm_page_track_register_notifier(vgpu-\u003evfio_device.kvm,\ndrivers/gpu/drm/i915/gvt/kvmgt.c-674-\t\t\t\t\t \u0026vgpu-\u003etrack_node);\n"
} |
| 5/2 | 2026/09/29 15:23 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14751 output: 23 thoughts: 102 Thoughts: **Investigating KVM/VFIO Device Registration** Okay, so `kvm_page_track_register_notifier`... that's only called within `drivers/gpu/drm/i915/gvt/kvmgt.c` as far as I can tell. Hmm, that's interesting. I need to understand the wider context. What else interacts with VFIO and KVM? What other parts of the system are potentially using this or something similar? Alright, let's pivot. I'm going to search for where `kvm_vfio_file_add` is used, or perhaps just search broadly for anything related to "KVM vfio device". The goal is to see how these devices are *created* in the first place. Understanding that should give me insight into the registration process. Right, time to broaden the search. I'll execute a `grep` for `kvm_vfio` across the kernel source. Hopefully, this will uncover the relevant creation and management logic, and provide the broader picture I need to understand this notifier's role in the VFIO ecosystem. |
| 6/2 | 2026/09/29 15:23 | tool | grepper |
0mArgs:{
"Expression": "KVM_DEV_TYPE_VFIO"
}Results: {
"Output": "Documentation/virt/kvm/devices/vfio.rst=7=Device types supported:\nDocumentation/virt/kvm/devices/vfio.rst-8-\nDocumentation/virt/kvm/devices/vfio.rst:9: - KVM_DEV_TYPE_VFIO\nDocumentation/virt/kvm/devices/vfio.rst-10-\n--\ninclude/uapi/linux/kvm.h=1208=enum kvm_device_type {\n--\ninclude/uapi/linux/kvm.h-1214-#define KVM_DEV_TYPE_XICS\t\tKVM_DEV_TYPE_XICS\ninclude/uapi/linux/kvm.h:1215:\tKVM_DEV_TYPE_VFIO,\ninclude/uapi/linux/kvm.h:1216:#define KVM_DEV_TYPE_VFIO\t\tKVM_DEV_TYPE_VFIO\ninclude/uapi/linux/kvm.h-1217-\tKVM_DEV_TYPE_ARM_VGIC_V2,\n--\ntools/include/uapi/linux/kvm.h=1206=enum kvm_device_type {\n--\ntools/include/uapi/linux/kvm.h-1212-#define KVM_DEV_TYPE_XICS\t\tKVM_DEV_TYPE_XICS\ntools/include/uapi/linux/kvm.h:1213:\tKVM_DEV_TYPE_VFIO,\ntools/include/uapi/linux/kvm.h:1214:#define KVM_DEV_TYPE_VFIO\t\tKVM_DEV_TYPE_VFIO\ntools/include/uapi/linux/kvm.h-1215-\tKVM_DEV_TYPE_ARM_VGIC_V2,\n--\nvirt/kvm/vfio.c=356=int kvm_vfio_ops_init(void)\nvirt/kvm/vfio.c-357-{\nvirt/kvm/vfio.c:358:\treturn kvm_register_device_ops(\u0026kvm_vfio_ops, KVM_DEV_TYPE_VFIO);\nvirt/kvm/vfio.c-359-}\n--\nvirt/kvm/vfio.c=361=void kvm_vfio_ops_exit(void)\nvirt/kvm/vfio.c-362-{\nvirt/kvm/vfio.c:363:\tkvm_unregister_device_ops(KVM_DEV_TYPE_VFIO);\nvirt/kvm/vfio.c-364-}\n"
} |
| 7/2 | 2026/09/29 15:23 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15757 output: 37 thoughts: 40 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **VFIO Device Dive** Okay, so the project's digging into KVM and VFIO, and the first thing that jumps out is the specific device type: `KVM_DEV_TYPE_VFIO`. That's a clear signal. I need to understand the architecture, which means... straight to the source. Specifically, I should be looking at `virt/kvm/vfio.c`. That's the core implementation for VFIO device handling within the KVM framework. I need to refresh my understanding of how this particular module integrates with the broader KVM infrastructure, specifically how it manages device passthrough, interrupt routing, memory mapping, and the interaction with the underlying IOMMU. The goal is to see how the VFIO concept is realized in KVM. |
| 8/2 | 2026/09/29 15:23 | tool | read-file |
0mArgs:{
"File": "virt/kvm/vfio.c",
"FirstLine": 140,
"LineCount": 80
}Results: {
"Contents": " 140:\t\t}\n 141:\t}\n 142:\t\n 143:\tstatic int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\n 144:\t{\n 145:\t\tstruct kvm_vfio *kv = dev-\u003eprivate;\n 146:\t\tstruct kvm_vfio_file *kvf;\n 147:\t\tstruct file *kvm_file __free(fput) = NULL;\n 148:\t\tstruct file *filp __free(fput) = NULL;\n 149:\t\n 150:\t\tfilp = fget(fd);\n 151:\t\tif (!filp)\n 152:\t\t\treturn -EBADF;\n 153:\t\n 154:\t\t/* Ensure the FD is a vfio FD. */\n 155:\t\tif (!kvm_vfio_file_is_valid(filp))\n 156:\t\t\treturn -EINVAL;\n 157:\t\n 158:\t\tkvm_file = get_file_active(\u0026dev-\u003ekvm-\u003efile);\n 159:\t\tif (!kvm_file)\n 160:\t\t\treturn -ENOENT;\n 161:\t\n 162:\t\tguard(mutex)(\u0026kv-\u003elock);\n 163:\t\n 164:\t\tlist_for_each_entry(kvf, \u0026kv-\u003efile_list, node) {\n 165:\t\t\tif (kvf-\u003efile == filp)\n 166:\t\t\t\treturn -EEXIST;\n 167:\t\t}\n 168:\t\n 169:\t\tkvf = kzalloc_obj(*kvf, GFP_KERNEL_ACCOUNT);\n 170:\t\tif (!kvf)\n 171:\t\t\treturn -ENOMEM;\n 172:\t\n 173:\t\tkvf-\u003efile = get_file(filp);\n 174:\t\tlist_add_tail(\u0026kvf-\u003enode, \u0026kv-\u003efile_list);\n 175:\t\n 176:\t\tkvm_vfio_file_set_kvm(kvf-\u003efile, kvm_file);\n 177:\t\tkvm_vfio_update_coherency(dev);\n 178:\t\n 179:\t\treturn 0;\n 180:\t}\n 181:\t\n 182:\tstatic void kvm_vfio_file_free(struct kvm_device *dev, struct kvm_vfio_file *kvf)\n 183:\t{\n 184:\t#ifdef CONFIG_SPAPR_TCE_IOMMU\n 185:\t\tkvm_spapr_tce_release_vfio_group(dev-\u003ekvm, kvf);\n 186:\t#endif\n 187:\t\tkvm_vfio_file_set_kvm(kvf-\u003efile, NULL);\n 188:\t\tfput(kvf-\u003efile);\n 189:\t\tlist_del(\u0026kvf-\u003enode);\n 190:\t\tkfree(kvf);\n 191:\t}\n 192:\t\n 193:\tstatic int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd)\n 194:\t{\n 195:\t\tstruct kvm_vfio *kv = dev-\u003eprivate;\n 196:\t\tstruct kvm_vfio_file *kvf;\n 197:\t\tCLASS(fd, f)(fd);\n 198:\t\n 199:\t\tif (fd_empty(f))\n 200:\t\t\treturn -EBADF;\n 201:\t\n 202:\t\tguard(mutex)(\u0026kv-\u003elock);\n 203:\t\n 204:\t\tlist_for_each_entry(kvf, \u0026kv-\u003efile_list, node) {\n 205:\t\t\tif (kvf-\u003efile == fd_file(f)) {\n 206:\t\t\t\tkvm_vfio_file_free(dev, kvf);\n 207:\t\t\t\tkvm_vfio_update_coherency(dev);\n 208:\t\t\t\treturn 0;\n 209:\t\t\t}\n 210:\t\t}\n 211:\t\n 212:\t\treturn -ENOENT;\n 213:\t}\n 214:\t\n 215:\t#ifdef CONFIG_SPAPR_TCE_IOMMU\n 216:\tstatic int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev,\n 217:\t\t\t\t\t void __user *arg)\n 218:\t{\n 219:\t\tstruct kvm_vfio_spapr_tce param;\n"
} |
| 9/2 | 2026/09/29 15:23 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 17230 output: 37 thoughts: 68 Thoughts: Here's my take on those thoughts: **Dissecting the KVM/VFIO Interaction** Alright, let's see what's what. My attention's caught by this `kvm_vfio_file_add` function call within `virt/kvm/vfio.c`. Ah, yes, it appears to be an ioctl on the KVM device. Intriguing! This warrants a deeper dive. First, I need to remind myself of the general flow of how KVM device ioctls work; what's the typical structure? Then, the key question is, specifically, *which* ioctls actually invoke `kvm_vfio_file_add`? Understanding the calling context is crucial to grasping the overall picture of how VFIO and KVM are interacting here. Time to get digging. |
| 10/2 | 2026/09/29 15:23 | tool | read-file |
0mArgs:{
"File": "virt/kvm/vfio.c",
"FirstLine": 290,
"LineCount": 70
}Results: {
"Contents": " 290:\t{\n 291:\t\tswitch (attr-\u003egroup) {\n 292:\t\tcase KVM_DEV_VFIO_FILE:\n 293:\t\t\tswitch (attr-\u003eattr) {\n 294:\t\t\tcase KVM_DEV_VFIO_FILE_ADD:\n 295:\t\t\tcase KVM_DEV_VFIO_FILE_DEL:\n 296:\t#ifdef CONFIG_SPAPR_TCE_IOMMU\n 297:\t\t\tcase KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE:\n 298:\t#endif\n 299:\t\t\t\treturn 0;\n 300:\t\t\t}\n 301:\t\n 302:\t\t\tbreak;\n 303:\t\t}\n 304:\t\n 305:\t\treturn -ENXIO;\n 306:\t}\n 307:\t\n 308:\tstatic void kvm_vfio_release(struct kvm_device *dev)\n 309:\t{\n 310:\t\tstruct kvm_vfio *kv = dev-\u003eprivate;\n 311:\t\tstruct kvm_vfio_file *kvf, *tmp;\n 312:\t\n 313:\t\tlist_for_each_entry_safe(kvf, tmp, \u0026kv-\u003efile_list, node)\n 314:\t\t\tkvm_vfio_file_free(dev, kvf);\n 315:\t\n 316:\t\tkvm_vfio_update_coherency(dev);\n 317:\t\n 318:\t\tkfree(kv);\n 319:\t\tkfree(dev); /* alloc by kvm_ioctl_create_device, free by .release */\n 320:\t}\n 321:\t\n 322:\tstatic int kvm_vfio_create(struct kvm_device *dev, u32 type);\n 323:\t\n 324:\tstatic const struct kvm_device_ops kvm_vfio_ops = {\n 325:\t\t.name = \"kvm-vfio\",\n 326:\t\t.create = kvm_vfio_create,\n 327:\t\t.release = kvm_vfio_release,\n 328:\t\t.set_attr = kvm_vfio_set_attr,\n 329:\t\t.has_attr = kvm_vfio_has_attr,\n 330:\t};\n 331:\t\n 332:\tstatic int kvm_vfio_create(struct kvm_device *dev, u32 type)\n 333:\t{\n 334:\t\tstruct kvm_device *tmp;\n 335:\t\tstruct kvm_vfio *kv;\n 336:\t\n 337:\t\tlockdep_assert_held(\u0026dev-\u003ekvm-\u003elock);\n 338:\t\n 339:\t\t/* Only one VFIO \"device\" per VM */\n 340:\t\tlist_for_each_entry(tmp, \u0026dev-\u003ekvm-\u003edevices, vm_node)\n 341:\t\t\tif (tmp-\u003eops == \u0026kvm_vfio_ops)\n 342:\t\t\t\treturn -EBUSY;\n 343:\t\n 344:\t\tkv = kzalloc_obj(*kv, GFP_KERNEL_ACCOUNT);\n 345:\t\tif (!kv)\n 346:\t\t\treturn -ENOMEM;\n 347:\t\n 348:\t\tINIT_LIST_HEAD(\u0026kv-\u003efile_list);\n 349:\t\tmutex_init(\u0026kv-\u003elock);\n 350:\t\n 351:\t\tdev-\u003eprivate = kv;\n 352:\t\n 353:\t\treturn 0;\n 354:\t}\n 355:\t\n 356:\tint kvm_vfio_ops_init(void)\n 357:\t{\n 358:\t\treturn kvm_register_device_ops(\u0026kvm_vfio_ops, KVM_DEV_TYPE_VFIO);\n 359:\t}\n"
} |
| 11/2 | 2026/09/29 15:23 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 18556 output: 35 thoughts: 185 Thoughts: Here's my thought process, as if I were analyzing this code: **Diving into KVM-VFIO Device Creation** Okay, let's zero in on `virt/kvm/vfio.c`. My immediate goal is to understand how these VFIO devices are created and managed within the KVM framework. I see that `KVM_CREATE_DEVICE` is the starting point, specifically when the `KVM_DEV_TYPE_VFIO` type is specified. That confirms the obvious: this creates the core `kvm-vfio` device. Now, that device has a file descriptor (`fd`). So, subsequent operations on this device *must* be done via that `fd`, right? This suggests that the interface for interacting with the VFIO device is through that file descriptor, using `KVM_SET_DEVICE_ATTR`. Looking at the flags, `KVM_DEV_VFIO_FILE` is definitely key. And within that, there are `KVM_DEV_VFIO_FILE_ADD` and `KVM_DEV_VFIO_FILE_DEL`, which I infer are for adding and removing VFIO files associated with the device. But what *is* a VFIO file? That's the core question now. Clearly, these are critical for interfacing with the VFIO subsystem. I need to understand the nature of this "file" and how it's used. Let's trace this and see what `kvm_vfio_file_is_valid` does. I will need to look into this function to understand the validity checks on these files. Okay, let's take a deep dive into `virt/kvm/vfio.c` and read the first 140 lines of the file. That should give me a solid foundation on how VFIO file descriptors are managed by the KVM framework. |
| 12/2 | 2026/09/29 15:23 | tool | read-file |
0mArgs:{
"File": "virt/kvm/vfio.c",
"FirstLine": 1,
"LineCount": 80
}Results: {
"Contents": " 1:\t// SPDX-License-Identifier: GPL-2.0-only\n 2:\t/*\n 3:\t * VFIO-KVM bridge pseudo device\n 4:\t *\n 5:\t * Copyright (C) 2013 Red Hat, Inc. All rights reserved.\n 6:\t * Author: Alex Williamson \u003calex.williamson@redhat.com\u003e\n 7:\t */\n 8:\t\n 9:\t#include \u003clinux/errno.h\u003e\n 10:\t#include \u003clinux/file.h\u003e\n 11:\t#include \u003clinux/kvm_host.h\u003e\n 12:\t#include \u003clinux/list.h\u003e\n 13:\t#include \u003clinux/module.h\u003e\n 14:\t#include \u003clinux/mutex.h\u003e\n 15:\t#include \u003clinux/slab.h\u003e\n 16:\t#include \u003clinux/uaccess.h\u003e\n 17:\t#include \u003clinux/vfio.h\u003e\n 18:\t#include \"vfio.h\"\n 19:\t\n 20:\t#ifdef CONFIG_SPAPR_TCE_IOMMU\n 21:\t#include \u003casm/kvm_ppc.h\u003e\n 22:\t#endif\n 23:\t\n 24:\tstruct kvm_vfio_file {\n 25:\t\tstruct list_head node;\n 26:\t\tstruct file *file;\n 27:\t#ifdef CONFIG_SPAPR_TCE_IOMMU\n 28:\t\tstruct iommu_group *iommu_group;\n 29:\t#endif\n 30:\t};\n 31:\t\n 32:\tstruct kvm_vfio {\n 33:\t\tstruct list_head file_list;\n 34:\t\tstruct mutex lock;\n 35:\t\tbool noncoherent;\n 36:\t};\n 37:\t\n 38:\tstatic void kvm_vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)\n 39:\t{\n 40:\t\tvoid (*fn)(struct file *vfio_file, struct file *kvm);\n 41:\t\n 42:\t\tfn = symbol_get(vfio_file_set_kvm);\n 43:\t\tif (!fn)\n 44:\t\t\treturn;\n 45:\t\n 46:\t\tfn(vfio_file, kvm);\n 47:\t\n 48:\t\tsymbol_put(vfio_file_set_kvm);\n 49:\t}\n 50:\t\n 51:\tstatic bool kvm_vfio_file_enforced_coherent(struct file *file)\n 52:\t{\n 53:\t\tbool (*fn)(struct file *file);\n 54:\t\tbool ret;\n 55:\t\n 56:\t\tfn = symbol_get(vfio_file_enforced_coherent);\n 57:\t\tif (!fn)\n 58:\t\t\treturn false;\n 59:\t\n 60:\t\tret = fn(file);\n 61:\t\n 62:\t\tsymbol_put(vfio_file_enforced_coherent);\n 63:\t\n 64:\t\treturn ret;\n 65:\t}\n 66:\t\n 67:\tstatic bool kvm_vfio_file_is_valid(struct file *file)\n 68:\t{\n 69:\t\tbool (*fn)(struct file *file);\n 70:\t\tbool ret;\n 71:\t\n 72:\t\tfn = symbol_get(vfio_file_is_valid);\n 73:\t\tif (!fn)\n 74:\t\t\treturn false;\n 75:\t\n 76:\t\tret = fn(file);\n 77:\t\n 78:\t\tsymbol_put(vfio_file_is_valid);\n 79:\t\n 80:\t\treturn ret;\n"
} |
| 13/2 | 2026/09/29 15:23 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 20170 output: 25 thoughts: 633 Thoughts: **VFIO KVM File Handling Analysis** Okay, let's dive into these VFIO functions related to KVM file handling. I'm focusing on `vfio_file_is_valid` and `vfio_file_set_kvm`. Specifically, I need to understand how the KVM file descriptor gets associated with VFIO devices and groups. First, where's `vfio_file_set_kvm` defined? Aha! `drivers/vfio/vfio_main.c`. Let's take a look. It's pretty straightforward. `vfio_file_set_kvm` takes the VFIO file and a KVM file as input. It then calls either `vfio_group_set_kvm` or `vfio_device_file_set_kvm`, depending on whether the VFIO file represents a group or a device. That makes sense; we need to handle KVM association at both levels. Now, examining `vfio_device_file_set_kvm` reveals the key. It grabs the KVM file, increments its reference count, and then stores the KVM file within the `vfio_device_file` structure via the `kvm` field protected by a spinlock. It explicitly mentions that the KVM file is first recorded in the `vfio_device_file` and gets propagated to `struct vfio_device` after the slave binds to iommufd. This is important to note and keep in mind. The old file is also properly released with `fput`. `vfio_group_set_kvm` is very similar. It also stores the KVM file, increments the reference count, and handles the old file with appropriate locking and releasing. Consistent pattern there. Now, let's quickly review the counterparts `vfio_device_get_kvm_safe` and `vfio_device_put_kvm`. It is a good time to search for where `vfio_device_get_kvm_safe` is called. Need to see where that KVM file descriptor is used after all. |
| 14/2 | 2026/09/29 15:23 | tool | grepper |
0mArgs:{
"Expression": "vfio_device_get_kvm_safe"
}Results: {
"Output": "drivers/vfio/device_cdev.c=65=static void vfio_df_get_kvm_safe(struct vfio_device_file *df)\n--\ndrivers/vfio/device_cdev.c-67-\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/device_cdev.c:68:\tvfio_device_get_kvm_safe(df-\u003edevice, df-\u003ekvm);\ndrivers/vfio/device_cdev.c-69-\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\n--\ndrivers/vfio/group.c=163=static void vfio_device_group_get_kvm_safe(struct vfio_device *device)\n--\ndrivers/vfio/group.c-165-\tspin_lock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:166:\tvfio_device_get_kvm_safe(device, device-\u003egroup-\u003ekvm);\ndrivers/vfio/group.c-167-\tspin_unlock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\n--\ndrivers/vfio/vfio.h=426=static inline void vfio_virqfd_exit(void)\n--\ndrivers/vfio/vfio.h-431-#if IS_ENABLED(CONFIG_KVM)\ndrivers/vfio/vfio.h:432:void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm);\ndrivers/vfio/vfio.h-433-void vfio_device_put_kvm(struct vfio_device *device);\ndrivers/vfio/vfio.h-434-#else\ndrivers/vfio/vfio.h:435:static inline void vfio_device_get_kvm_safe(struct vfio_device *device,\ndrivers/vfio/vfio.h-436-\t\t\t\t\t struct file *kvm)\n--\ndrivers/vfio/vfio_main.c=472=EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);\n--\ndrivers/vfio/vfio_main.c-474-#if IS_ENABLED(CONFIG_KVM)\ndrivers/vfio/vfio_main.c:475:void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)\ndrivers/vfio/vfio_main.c-476-{\n"
} |
| 15/2 | 2026/09/29 15:24 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 21908 output: 19 thoughts: 443 Thoughts: **VFIO KVM File Tracking - A Deeper Dive** Okay, let's break this down. I'm seeing a connection between VFIO device binding/opening and KVM file handling. Specifically, my attention is drawn to `drivers/vfio/device_cdev.c` and `drivers/vfio/group.c`, where `vfio_device_get_kvm_safe` gets called. This function, and its counterpart `vfio_device_put_kvm`, appear to manage a reference to a KVM file (`kvm`) within the `vfio_device` structure. It's a simple `get_file()` and `fput()` pattern, ensuring the KVM file stays alive as long as needed. Nothing groundbreaking in and of itself, but it's the *how* that I'm interested in here. Now, shifting gears to `kvm_main.c`, I see `kvm_dev_ioctl_create_vm` associating a file (`file`) with the KVM instance (`kvm->file`). Then, `kvm_vm_release` nullifies the file pointer after calling `kvm_irqfd_release`, and finally the KVM object is released. Seems logical. The interesting part, though, is in `kvm_vfio_file_add`. It uses `get_file_active` to retrieve the KVM file from the VFIO device. And *that* is what's triggered my curiosity. `get_file_active`... hmm, I need to check how that functions. I'll need to go to `include/linux/file.h` and see what it does. |
| 16/2 | 2026/09/29 15:24 | tool | grepper |
0mArgs:{
"Expression": "get_file_active"
}Results: {
"Output": "drivers/gpio/gpiolib-cdev.c=2495=static int lineinfo_changed_notify(struct notifier_block *nb,\n--\ndrivers/gpio/gpiolib-cdev.c-2508-\t/* Keep the file descriptor alive for the duration of the notification. */\ndrivers/gpio/gpiolib-cdev.c:2509:\tfp = get_file_active(\u0026cdev-\u003efp);\ndrivers/gpio/gpiolib-cdev.c-2510-\tif (!fp)\n--\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c=968=static struct file *mmap_singleton(struct drm_i915_private *i915)\n--\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c-971-\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c:972:\tfile = get_file_active(\u0026i915-\u003egem.mmap_singleton);\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c-973-\tif (file)\n--\ndrivers/vfio/pci/vfio_pci_dmabuf.c=336=void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool revoked)\n--\ndrivers/vfio/pci/vfio_pci_dmabuf.c-343-\tlist_for_each_entry_safe(priv, tmp, \u0026vdev-\u003edmabufs, dmabufs_elm) {\ndrivers/vfio/pci/vfio_pci_dmabuf.c:344:\t\tif (!get_file_active(\u0026priv-\u003edmabuf-\u003efile))\ndrivers/vfio/pci/vfio_pci_dmabuf.c-345-\t\t\tcontinue;\n--\ndrivers/vfio/pci/vfio_pci_dmabuf.c=380=void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_dmabuf.c-396-\tlist_for_each_entry_safe(priv, tmp, \u0026vdev-\u003edmabufs, dmabufs_elm) {\ndrivers/vfio/pci/vfio_pci_dmabuf.c:397:\t\tif (!get_file_active(\u0026priv-\u003edmabuf-\u003efile))\ndrivers/vfio/pci/vfio_pci_dmabuf.c-398-\t\t\tcontinue;\n--\nfs/file.c=990=EXPORT_SYMBOL_GPL(get_file_rcu);\n--\nfs/file.c-992-/**\nfs/file.c:993: * get_file_active - try go get a reference to a file\nfs/file.c-994- * @f: the file to get a reference on\n--\nfs/file.c-1003- */\nfs/file.c:1004:struct file *get_file_active(struct file **f)\nfs/file.c-1005-{\n--\nfs/file.c-1014-}\nfs/file.c:1015:EXPORT_SYMBOL_GPL(get_file_active);\nfs/file.c-1016-\n--\ninclude/linux/fs.h=1311=struct file *get_file_rcu(struct file __rcu **f);\ninclude/linux/fs.h:1312:struct file *get_file_active(struct file **f);\ninclude/linux/fs.h-1313-\n--\nvirt/kvm/guest_memfd.c=290=static int kvm_gmem_release(struct inode *inode, struct file *file)\n--\nvirt/kvm/guest_memfd.c-304-\t * Since .release is called only when the reference count is zero,\nvirt/kvm/guest_memfd.c:305:\t * after which file_ref_get() and get_file_active() fail,\nvirt/kvm/guest_memfd.c-306-\t * kvm_gmem_get_pfn() cannot be using the file concurrently.\nvirt/kvm/guest_memfd.c:307:\t * file_ref_put() provides a full barrier, and get_file_active() the\nvirt/kvm/guest_memfd.c-308-\t * matching acquire barrier.\n--\nvirt/kvm/guest_memfd.c=340=static inline struct file *kvm_gmem_get_file(struct kvm_memory_slot *slot)\n--\nvirt/kvm/guest_memfd.c-346-\t */\nvirt/kvm/guest_memfd.c:347:\treturn get_file_active(\u0026slot-\u003egmem.file);\nvirt/kvm/guest_memfd.c-348-}\n--\nvirt/kvm/vfio.c=143=static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\n--\nvirt/kvm/vfio.c-157-\nvirt/kvm/vfio.c:158:\tkvm_file = get_file_active(\u0026dev-\u003ekvm-\u003efile);\nvirt/kvm/vfio.c-159-\tif (!kvm_file)\n"
} |
| 17/2 | 2026/09/29 15:24 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 24117 output: 27 thoughts: 783 Thoughts: **Analyzing the KVM SEV Context Transfer with a Focus on File Descriptors** Okay, let's dive into this SEV context transfer code. My initial thought was to examine the SEV-specific functions, specifically `sev_vm_move_enc_context_from` and `sev_vm_copy_enc_context_from` in `arch/x86/kvm/svm/sev.c`. The core issue, as I see it, centers around how we're now handling the source KVM. The code now uses `file_to_kvm_x86` instead of directly checking `file_is_kvm`. Hmm, that's interesting. I need to understand this `file_to_kvm_x86` function. Let's see... it's defined in `arch/x86/include/asm/kvm_host.h` as a macro that ultimately becomes `file_to_kvm_x86`. Looking deeper, the actual implementation resides in `virt/kvm/kvm_main.c`. This reveals the critical change: `file_to_kvm_fn` checks `file->f_op == &kvm_vm_fops`, and, if it matches, returns `file->private_data`. Now I see it! The previous approach used `file_is_kvm`, which was internal to KVM. This patch now exposes the `struct file *` interface, specifically via `get_file` and `fput`, to external modules, like VFIO, vfio_ap or intel_vgpu (kvmgt). Before this change, these external modules were using `kvm_get_kvm`, `kvm_get_kvm_safe`, and `kvm_put_kvm` to hold references on the `struct kvm *`. Now, they're using the file descriptor and the standard file operations. This changes the fundamental way external drivers manage their KVM references! Instead of holding a direct pointer to the `struct kvm *`, they now hold a `struct file *kvm`! This is quite a departure. Alright, the implication is clear. The whole lifecycle of KVM resources from external modules is now handled through file descriptors. This is a pretty significant shift. So, the key is how this file descriptor, `file *kvm`, is used. Let's figure out what drivers are interacting with `vfio_device` now, by searching for instances of `->kvm` within `vfio_device` structures. That should provide a concrete picture of the impact of this change. |
| 18/2 | 2026/09/29 15:24 | tool | grepper |
0mArgs:{
"Expression": "-\u003ekvm",
"PathPrefix": "drivers/vfio"
}Results: {
"Output": "drivers/vfio/device_cdev.c=65=static void vfio_df_get_kvm_safe(struct vfio_device_file *df)\ndrivers/vfio/device_cdev.c-66-{\ndrivers/vfio/device_cdev.c:67:\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/device_cdev.c:68:\tvfio_device_get_kvm_safe(df-\u003edevice, df-\u003ekvm);\ndrivers/vfio/device_cdev.c:69:\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/device_cdev.c-70-}\n--\ndrivers/vfio/group.c=163=static void vfio_device_group_get_kvm_safe(struct vfio_device *device)\ndrivers/vfio/group.c-164-{\ndrivers/vfio/group.c:165:\tspin_lock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:166:\tvfio_device_get_kvm_safe(device, device-\u003egroup-\u003ekvm);\ndrivers/vfio/group.c:167:\tspin_unlock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\ndrivers/vfio/group.c-168-}\n--\ndrivers/vfio/group.c=516=static struct vfio_group *vfio_group_alloc(struct iommu_group *iommu_group,\n--\ndrivers/vfio/group.c-540-\tmutex_init(\u0026group-\u003egroup_lock);\ndrivers/vfio/group.c:541:\tspin_lock_init(\u0026group-\u003ekvm_ref_lock);\ndrivers/vfio/group.c-542-\tINIT_LIST_HEAD(\u0026group-\u003edevice_list);\n--\ndrivers/vfio/group.c=863=void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\n--\ndrivers/vfio/group.c-869-\ndrivers/vfio/group.c:870:\tspin_lock(\u0026group-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:871:\told = group-\u003ekvm;\ndrivers/vfio/group.c:872:\tgroup-\u003ekvm = kvm;\ndrivers/vfio/group.c:873:\tspin_unlock(\u0026group-\u003ekvm_ref_lock);\ndrivers/vfio/group.c-874-\n--\ndrivers/vfio/vfio_main.c=475=void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)\n--\ndrivers/vfio/vfio_main.c-481-\ndrivers/vfio/vfio_main.c:482:\tdevice-\u003ekvm = get_file(kvm);\ndrivers/vfio/vfio_main.c-483-}\n--\ndrivers/vfio/vfio_main.c=485=void vfio_device_put_kvm(struct vfio_device *device)\n--\ndrivers/vfio/vfio_main.c-488-\ndrivers/vfio/vfio_main.c:489:\tif (!device-\u003ekvm)\ndrivers/vfio/vfio_main.c-490-\t\treturn;\ndrivers/vfio/vfio_main.c-491-\ndrivers/vfio/vfio_main.c:492:\tfput(device-\u003ekvm);\ndrivers/vfio/vfio_main.c:493:\tdevice-\u003ekvm = NULL;\ndrivers/vfio/vfio_main.c-494-}\n--\ndrivers/vfio/vfio_main.c=504=vfio_allocate_device_file(struct vfio_device *device)\n--\ndrivers/vfio/vfio_main.c-512-\tdf-\u003edevice = device;\ndrivers/vfio/vfio_main.c:513:\tspin_lock_init(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/vfio_main.c-514-\n--\ndrivers/vfio/vfio_main.c=1518=static void vfio_device_file_set_kvm(struct file *file, struct file *kvm)\n--\ndrivers/vfio/vfio_main.c-1530-\t */\ndrivers/vfio/vfio_main.c:1531:\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/vfio_main.c:1532:\told = df-\u003ekvm;\ndrivers/vfio/vfio_main.c:1533:\tdf-\u003ekvm = kvm;\ndrivers/vfio/vfio_main.c:1534:\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/vfio_main.c-1535-\n--\ndrivers/vfio/vfio_main.c-1545- * When a VFIO device is first opened the KVM will be available in\ndrivers/vfio/vfio_main.c:1546: * device-\u003ekvm if one was associated with the file.\ndrivers/vfio/vfio_main.c-1547- */\n"
} |
| 19/2 | 2026/09/29 15:24 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 26836 output: 19 thoughts: 23 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Analyzing `->kvm` Usage in Relation to VFIO** Okay, so I need to understand the relationship between `->kvm` and VFIO across the kernel tree. My immediate instinct is to map out where `->kvm` is *actually* used, specifically in proximity to VFIO code. I'm thinking I'll need a way to pinpoint these usages efficiently. The goal is to see how the KVM interface interacts with VFIO, especially from the VFIO side. Am I seeing KVM calls within VFIO driver code? Or perhaps VFIO callbacks into KVM? Maybe it's more subtle; cross-module dependencies, etc. I'm anticipating there could be indirect relationships too, so the naive grep is unlikely to cut it. I will probably need to follow function calls and data flows to get a proper picture. This feels like a good starting point for understanding their interdependence. I need to be methodical here, probably starting with a broad search and then refining it. |
| 20/2 | 2026/09/29 15:24 | tool | grepper |
0mArgs:{
"Expression": "-\u003ekvm\\b"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 10863 lines.\nUse more precise expression if possible.\n\nDocumentation/arch/s390/vfio-ap-locking.rst=50=The KVM pointer is stored in the in the matrix_mdev instance\nDocumentation/arch/s390/vfio-ap-locking.rst:51:(matrix_mdev-\u003ekvm = kvm) containing the state of the mediated device that has\nDocumentation/arch/s390/vfio-ap-locking.rst-52-been attached to the KVM guest.\n--\nDocumentation/arch/s390/vfio-ap-locking.rst=69=KVM guest. This lock must be held:\nDocumentation/arch/s390/vfio-ap-locking.rst-70-\nDocumentation/arch/s390/vfio-ap-locking.rst:71:1. To control access to the KVM pointer (matrix_mdev-\u003ekvm) while the vfio_ap\nDocumentation/arch/s390/vfio-ap-locking.rst-72- device driver is using it to plug/unplug AP devices passed through to the KVM\n--\nDocumentation/arch/s390/vfio-ap-locking.rst-83- the matrix_mdev object to which the queue is assigned will have to be\nDocumentation/arch/s390/vfio-ap-locking.rst:84: found. The KVM pointer (matrix_mdev-\u003ekvm) can then be used to determine if\nDocumentation/arch/s390/vfio-ap-locking.rst:85: the mediated device is passed through (matrix_mdev-\u003ekvm != NULL) and if so,\nDocumentation/arch/s390/vfio-ap-locking.rst-86- to unplug the adapter.\n--\nDocumentation/virt/kvm/locking.rst=99=will happen:\n--\nDocumentation/virt/kvm/locking.rst-130-| if (cmpxchg(spte, old_spte, old_spte+W) |\nDocumentation/virt/kvm/locking.rst:131:|\tmark_page_dirty(vcpu-\u003ekvm, gfn1) |\nDocumentation/virt/kvm/locking.rst-132-| OOPS!!! |\n--\narch/arm64/include/asm/kvm_emulate.h=281=static inline bool is_nested_nv3_ctxt(struct kvm_vcpu *vcpu)\narch/arm64/include/asm/kvm_emulate.h-282-{\narch/arm64/include/asm/kvm_emulate.h:283:\treturn (has_vhe() \u0026\u0026 kvm_has_nv3(vcpu-\u003ekvm) \u0026\u0026 is_nested_ctxt(vcpu) \u0026\u0026\narch/arm64/include/asm/kvm_emulate.h-284-\t\t(__vcpu_sys_reg(vcpu, HCR_EL2) \u0026 HCR_EL2_NV) \u0026\u0026\n--\narch/arm64/include/asm/kvm_emulate.h=684=static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)\narch/arm64/include/asm/kvm_emulate.h-685-{\narch/arm64/include/asm/kvm_emulate.h:686:\tstruct kvm *kvm = vcpu-\u003ekvm;\narch/arm64/include/asm/kvm_emulate.h-687-\n--\narch/arm64/include/asm/kvm_emulate.h-728-\t\t\t */\narch/arm64/include/asm/kvm_emulate.h:729:\t\t\tif (!kvm_has_nv2(vcpu-\u003ekvm)) {\narch/arm64/include/asm/kvm_emulate.h-730-\t\t\t\tvcpu-\u003earch.hcrx_el2 |= (HCRX_EL2_NVnTTLB |\n--\narch/arm64/include/asm/kvm_host.h=847=struct kvm_vcpu_arch {\n--\narch/arm64/include/asm/kvm_host.h-1136-#ifdef __KVM_NVHE_HYPERVISOR__\narch/arm64/include/asm/kvm_host.h:1137:#define vcpu_has_sve(vcpu)\tkvm_has_sve(kern_hyp_va((vcpu)-\u003ekvm))\narch/arm64/include/asm/kvm_host.h-1138-#else\narch/arm64/include/asm/kvm_host.h:1139:#define vcpu_has_sve(vcpu)\tkvm_has_sve((vcpu)-\u003ekvm)\narch/arm64/include/asm/kvm_host.h-1140-#endif\n--\narch/arm64/include/asm/kvm_host.h=1501=struct kvm *kvm_arch_alloc_vm(void);\n--\narch/arm64/include/asm/kvm_host.h-1508-\narch/arm64/include/asm/kvm_host.h:1509:#define vcpu_is_protected(vcpu)\t\tkvm_vm_is_protected((vcpu)-\u003ekvm)\narch/arm64/include/asm/kvm_host.h-1510-\n--\narch/arm64/include/asm/kvm_host.h=1527=static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)\n--\narch/arm64/include/asm/kvm_host.h-1532-#define kvm_vcpu_has_feature(k, f)\t__vcpu_has_feature(\u0026(k)-\u003earch, (f))\narch/arm64/include/asm/kvm_host.h:1533:#define vcpu_has_feature(v, f)\t__vcpu_has_feature(\u0026(v)-\u003ekvm-\u003earch, (f))\narch/arm64/include/asm/kvm_host.h-1534-\n--\narch/arm64/include/asm/kvm_nested.h=174=static inline bool kvm_supported_tlbi_s1e1_op(struct kvm_vcpu *vpcu, u32 instr)\narch/arm64/include/asm/kvm_nested.h-175-{\narch/arm64/include/asm/kvm_nested.h:176:\tstruct kvm *kvm = vpcu-\u003ekvm;\narch/arm64/include/asm/kvm_nested.h-177-\tu8 CRm = sys_reg_CRm(instr);\n--\narch/arm64/include/asm/kvm_nested.h=200=static inline bool kvm_supported_tlbi_s1e2_op(struct kvm_vcpu *vpcu, u32 instr)\narch/arm64/include/asm/kvm_nested.h-201-{\narch/arm64/include/asm/kvm_nested.h:202:\tstruct kvm *kvm = vpcu-\u003ekvm;\narch/arm64/include/asm/kvm_nested.h-203-\tu8 CRm = sys_reg_CRm(instr);\n--\narch/arm64/kvm/arch_timer.c=210=static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)\n--\narch/arm64/kvm/arch_timer.c-234-\narch/arm64/kvm/arch_timer.c:235:\tif (userspace_irqchip(vcpu-\u003ekvm) \u0026\u0026\narch/arm64/kvm/arch_timer.c-236-\t !static_branch_unlikely(\u0026has_gic_active_state))\n--\narch/arm64/kvm/arch_timer.c=457=static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,\n--\narch/arm64/kvm/arch_timer.c-464-\narch/arm64/kvm/arch_timer.c:465:\tif (userspace_irqchip(vcpu-\u003ekvm))\narch/arm64/kvm/arch_timer.c-466-\t\treturn;\n--\narch/arm64/kvm/arch_timer.c-468-\t/* Skip injecting on GICv5 for directly injected (DVI'd) timers */\narch/arm64/kvm/arch_timer.c:469:\tif (vgic_is_v5(vcpu-\u003ekvm)) {\narch/arm64/kvm/arch_timer.c-470-\t\tstruct timer_map map;\n--\narch/arm64/kvm/arch_timer.c-478-\narch/arm64/kvm/arch_timer.c:479:\tkvm_vgic_inject_irq(vcpu-\u003ekvm, vcpu,\narch/arm64/kvm/arch_timer.c-480-\t\t\t timer_irq(timer_ctx),\n--\narch/arm64/kvm/arch_timer.c=686=static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)\n--\narch/arm64/kvm/arch_timer.c-699-\narch/arm64/kvm/arch_timer.c:700:\tif (irqchip_in_kernel(vcpu-\u003ekvm))\narch/arm64/kvm/arch_timer.c-701-\t\tphys_active = kvm_vgic_map_is_active(vcpu, timer_irq(ctx));\n--\narch/arm64/kvm/arch_timer.c-703-\tphys_active |= pending;\narch/arm64/kvm/arch_timer.c:704:\tphys_active |= vgic_is_v5(vcpu-\u003ekvm);\narch/arm64/kvm/arch_timer.c-705-\n--\narch/arm64/kvm/arch_timer.c=747=static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu,\n--\narch/arm64/kvm/arch_timer.c-751-\narch/arm64/kvm/arch_timer.c:752:\tif (!irqchip_in_kernel(vcpu-\u003ekvm))\narch/arm64/kvm/arch_timer.c-753-\t\treturn;\n--\narch/arm64/kvm/arch_timer.c=889=void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-900-\t\t/* We don't do NV on GICv5, yet */\narch/arm64/kvm/arch_timer.c:901:\t\tif (vcpu_has_nv(vcpu) \u0026\u0026 !vgic_is_v5(vcpu-\u003ekvm))\narch/arm64/kvm/arch_timer.c-902-\t\t\tkvm_timer_vcpu_load_nested_switch(vcpu, \u0026map);\n--\narch/arm64/kvm/arch_timer.c=924=void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-954-\narch/arm64/kvm/arch_timer.c:955:\tif (vgic_is_v5(vcpu-\u003ekvm)) {\narch/arm64/kvm/arch_timer.c-956-\t\tset_timer_irq_phys_active(map.direct_vtimer, false);\n--\narch/arm64/kvm/arch_timer.c=1018=void kvm_timer_sync_user(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-1024-\narch/arm64/kvm/arch_timer.c:1025:\tif (unlikely(!irqchip_in_kernel(vcpu-\u003ekvm)))\narch/arm64/kvm/arch_timer.c-1026-\t\tunmask_vtimer_irq_user(vcpu);\n--\narch/arm64/kvm/arch_timer.c=1029=void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-1053-\t\toffs-\u003evcpu_offset = __ctxt_sys_reg(\u0026vcpu-\u003earch.ctxt, CNTVOFF_EL2);\narch/arm64/kvm/arch_timer.c:1054:\t\toffs-\u003evm_offset = \u0026vcpu-\u003ekvm-\u003earch.timer_data.poffset;\narch/arm64/kvm/arch_timer.c-1055-\t}\n--\narch/arm64/kvm/arch_timer.c-1061-\narch/arm64/kvm/arch_timer.c:1062:\t\tif (irqchip_in_kernel(vcpu-\u003ekvm)) {\narch/arm64/kvm/arch_timer.c-1063-\t\t\tkvm_vgic_reset_mapped_irq(vcpu, timer_irq(map.direct_vtimer));\n--\narch/arm64/kvm/arch_timer.c=1075=static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)\n--\narch/arm64/kvm/arch_timer.c-1077-\tstruct arch_timer_context *ctxt = vcpu_get_timer(vcpu, timerid);\narch/arm64/kvm/arch_timer.c:1078:\tstruct kvm *kvm = vcpu-\u003ekvm;\narch/arm64/kvm/arch_timer.c-1079-\n--\narch/arm64/kvm/arch_timer.c-1081-\narch/arm64/kvm/arch_timer.c:1082:\tif (!kvm_vm_is_protected(vcpu-\u003ekvm)) {\narch/arm64/kvm/arch_timer.c-1083-\t\tif (timerid == TIMER_VTIMER)\n--\narch/arm64/kvm/arch_timer.c=1105=void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-1113-\tif (!vcpu_is_protected(vcpu) \u0026\u0026\narch/arm64/kvm/arch_timer.c:1114:\t !test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, \u0026vcpu-\u003ekvm-\u003earch.flags)) {\narch/arm64/kvm/arch_timer.c-1115-\t\ttimer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read());\n--\narch/arm64/kvm/arch_timer.c=1288=static int timer_irq_set_irqchip_state(struct irq_data *d,\n--\narch/arm64/kvm/arch_timer.c-1293-\t\t(kvm_vgic_global_state.type == VGIC_V5 \u0026\u0026\narch/arm64/kvm/arch_timer.c:1294:\t\t vgic_is_v3(kvm_get_running_vcpu()-\u003ekvm));\narch/arm64/kvm/arch_timer.c-1295-\n--\narch/arm64/kvm/arch_timer.c=1525=static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-1529-\narch/arm64/kvm/arch_timer.c:1530:\tmutex_lock(\u0026vcpu-\u003ekvm-\u003earch.config_lock);\narch/arm64/kvm/arch_timer.c-1531-\n--\narch/arm64/kvm/arch_timer.c-1539-\t\t/* With GICv5, the default PPI is what you get -- nothing else */\narch/arm64/kvm/arch_timer.c:1540:\t\tif (vgic_is_v5(vcpu-\u003ekvm) \u0026\u0026 irq != get_vgic_ppi(vcpu-\u003ekvm, default_ppi[i]))\narch/arm64/kvm/arch_timer.c-1541-\t\t\tbreak;\n--\narch/arm64/kvm/arch_timer.c-1558-\tif (valid)\narch/arm64/kvm/arch_timer.c:1559:\t\tset_bit(KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE, \u0026vcpu-\u003ekvm-\u003earch.flags);\narch/arm64/kvm/arch_timer.c-1560-\narch/arm64/kvm/arch_timer.c:1561:\tmutex_unlock(\u0026vcpu-\u003ekvm-\u003earch.config_lock);\narch/arm64/kvm/arch_timer.c-1562-\n--\narch/arm64/kvm/arch_timer.c=1587=int kvm_timer_enable(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arch_timer.c-1597-\t/* Without a VGIC we do not map virtual IRQs to physical IRQs */\narch/arm64/kvm/arch_timer.c:1598:\tif (!irqchip_in_kernel(vcpu-\u003ekvm))\narch/arm64/kvm/arch_timer.c-1599-\t\tgoto no_vgic;\n--\narch/arm64/kvm/arch_timer.c-1611-\narch/arm64/kvm/arch_timer.c:1612:\tops = vgic_is_v5(vcpu-\u003ekvm) ? \u0026arch_timer_irq_ops_vgic_v5 :\narch/arm64/kvm/arch_timer.c-1613-\t\t\t\t \u0026arch_timer_irq_ops;\n--\narch/arm64/kvm/arch_timer.c=1643=int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)\n--\narch/arm64/kvm/arch_timer.c-1647-\narch/arm64/kvm/arch_timer.c:1648:\tif (!irqchip_in_kernel(vcpu-\u003ekvm))\narch/arm64/kvm/arch_timer.c-1649-\t\treturn -EINVAL;\n--\narch/arm64/kvm/arch_timer.c-1653-\narch/arm64/kvm/arch_timer.c:1654:\tif (!(irq_is_ppi(vcpu-\u003ekvm, irq)))\narch/arm64/kvm/arch_timer.c-1655-\t\treturn -EINVAL;\narch/arm64/kvm/arch_timer.c-1656-\narch/arm64/kvm/arch_timer.c:1657:\tguard(mutex)(\u0026vcpu-\u003ekvm-\u003earch.config_lock);\narch/arm64/kvm/arch_timer.c-1658-\narch/arm64/kvm/arch_timer.c-1659-\tif (test_bit(KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE,\narch/arm64/kvm/arch_timer.c:1660:\t\t \u0026vcpu-\u003ekvm-\u003earch.flags)) {\narch/arm64/kvm/arch_timer.c-1661-\t\treturn -EBUSY;\n--\narch/arm64/kvm/arch_timer.c-1685-\t */\narch/arm64/kvm/arch_timer.c:1686:\tvcpu-\u003ekvm-\u003earch.timer_data.ppi[idx] = irq;\narch/arm64/kvm/arch_timer.c-1687-\n--\narch/arm64/kvm/arm.c=541=int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arm.c-549-\tmutex_lock(\u0026vcpu-\u003emutex);\narch/arm64/kvm/arm.c:550:\tmutex_lock(\u0026vcpu-\u003ekvm-\u003earch.config_lock);\narch/arm64/kvm/arm.c:551:\tmutex_unlock(\u0026vcpu-\u003ekvm-\u003earch.config_lock);\narch/arm64/kvm/arm.c-552-\tmutex_unlock(\u0026vcpu-\u003emutex);\n--\narch/arm64/kvm/arm.c-566-\narch/arm64/kvm/arm.c:567:\tvcpu-\u003earch.hw_mmu = \u0026vcpu-\u003ekvm-\u003earch.mmu;\narch/arm64/kvm/arm.c-568-\n--\narch/arm64/kvm/arm.c-573-\t */\narch/arm64/kvm/arm.c:574:\tkvm_destroy_mpidr_data(vcpu-\u003ekvm);\narch/arm64/kvm/arm.c-575-\n--\narch/arm64/kvm/arm.c=647=static bool kvm_vcpu_should_clear_twi(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arm.c-651-\narch/arm64/kvm/arm.c:652:\tif (vgic_is_v5(vcpu-\u003ekvm))\narch/arm64/kvm/arm.c-653-\t\treturn single_task_running();\n--\narch/arm64/kvm/arm.c-655-\treturn single_task_running() \u0026\u0026\narch/arm64/kvm/arm.c:656:\t vcpu-\u003ekvm-\u003earch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 \u0026\u0026\narch/arm64/kvm/arm.c-657-\t (atomic_read(\u0026vcpu-\u003earch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) ||\narch/arm64/kvm/arm.c:658:\t\tvcpu-\u003ekvm-\u003earch.vgic.nassgireq);\narch/arm64/kvm/arm.c-659-}\n--\narch/arm64/kvm/arm.c=669=void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)\n--\narch/arm64/kvm/arm.c-738-\t\tkvm_call_hyp_nvhe(__pkvm_vcpu_load,\narch/arm64/kvm/arm.c:739:\t\t\t\t vcpu-\u003ekvm-\u003earch.pkvm.handle,\narch/arm64/kvm/arm.c-740-\t\t\t\t vcpu-\u003evcpu_idx, vcpu-\u003earch.hcr_el2);\n--\narch/arm64/kvm/arm.c-744-\narch/arm64/kvm/arm.c:745:\tif (!cpumask_test_cpu(cpu, vcpu-\u003ekvm-\u003earch.supported_cpus))\narch/arm64/kvm/arm.c-746-\t\tvcpu_set_on_unsupported_cpu(vcpu);\n--\narch/arm64/kvm/arm.c=751=void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arm.c-757-\t\t/* __pkvm_vcpu_put implies a sync of the state */\narch/arm64/kvm/arm.c:758:\t\tif (!kvm_vm_is_protected(vcpu-\u003ekvm))\narch/arm64/kvm/arm.c-759-\t\t\tvcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);\n--\narch/arm64/kvm/arm.c=849=int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)\n--\narch/arm64/kvm/arm.c-852-\narch/arm64/kvm/arm.c:853:\tirq_lines |= (!irqchip_in_kernel(v-\u003ekvm) \u0026\u0026\narch/arm64/kvm/arm.c-854-\t\t (kvm_timer_should_notify_user(v) ||\n--\narch/arm64/kvm/arm.c=930=int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)\narch/arm64/kvm/arm.c-931-{\narch/arm64/kvm/arm.c:932:\tstruct kvm *kvm = vcpu-\u003ekvm;\narch/arm64/kvm/arm.c-933-\tint ret;\n--\narch/arm64/kvm/arm.c-991-\t\t/* Start with the vcpu in a dirty state */\narch/arm64/kvm/arm.c:992:\t\tif (!kvm_vm_is_protected(vcpu-\u003ekvm))\narch/arm64/kvm/arm.c-993-\t\t\tvcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);\n--\narch/arm64/kvm/arm.c=1218=static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)\n--\narch/arm64/kvm/arm.c-1227-\t */\narch/arm64/kvm/arm.c:1228:\tif (unlikely(!irqchip_in_kernel(vcpu-\u003ekvm))) {\narch/arm64/kvm/arm.c-1229-\t\tif (unlikely(kvm_irq_update_run(vcpu))) {\n--\narch/arm64/kvm/arm.c=1276=int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arm.c-1340-\t\t\t\tkvm_pmu_sync_hwstate(vcpu);\narch/arm64/kvm/arm.c:1341:\t\t\tif (unlikely(!irqchip_in_kernel(vcpu-\u003ekvm)))\narch/arm64/kvm/arm.c-1342-\t\t\t\tkvm_timer_sync_user(vcpu);\n--\narch/arm64/kvm/arm.c-1384-\t\t */\narch/arm64/kvm/arm.c:1385:\t\tif (unlikely(!irqchip_in_kernel(vcpu-\u003ekvm)))\narch/arm64/kvm/arm.c-1386-\t\t\tkvm_timer_sync_user(vcpu);\n--\narch/arm64/kvm/arm.c-1443-\narch/arm64/kvm/arm.c:1444:\tif (unlikely(!irqchip_in_kernel(vcpu-\u003ekvm)))\narch/arm64/kvm/arm.c-1445-\t\tkvm_irq_update_run(vcpu);\n--\narch/arm64/kvm/arm.c=1610=static int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,\n--\narch/arm64/kvm/arm.c-1643-\t/* MTE is incompatible with AArch32 */\narch/arm64/kvm/arm.c:1644:\tif (kvm_has_mte(vcpu-\u003ekvm))\narch/arm64/kvm/arm.c-1645-\t\treturn -EINVAL;\n--\narch/arm64/kvm/arm.c=1654=static bool kvm_vcpu_init_changed(struct kvm_vcpu *vcpu,\n--\narch/arm64/kvm/arm.c-1658-\narch/arm64/kvm/arm.c:1659:\treturn !bitmap_equal(vcpu-\u003ekvm-\u003earch.vcpu_features, \u0026features,\narch/arm64/kvm/arm.c-1660-\t\t\t KVM_VCPU_MAX_FEATURES);\n--\narch/arm64/kvm/arm.c=1663=static int kvm_setup_vcpu(struct kvm_vcpu *vcpu)\narch/arm64/kvm/arm.c-1664-{\narch/arm64/kvm/arm.c:1665:\tstruct kvm *kvm = vcpu-\u003ekvm;\narch/arm64/kvm/arm.c-1666-\tint ret = 0;\n--\narch/arm64/kvm/arm.c=1685=static int __kvm_vcpu_set_target(struct kvm_vcpu *vcpu,\n--\narch/arm64/kvm/arm.c-1688-\tunsigned long features = init-\u003efeatures[0];\narch/arm64/kvm/arm.c:1689:\tstruct kvm *kvm = vcpu-\u003ekvm;\narch/arm64/kvm/arm.c-1690-\tint ret = -EINVAL;\n--\narch/arm64/kvm/arm.c=1738=static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,\n--\narch/arm64/kvm/arm.c-1768-\t\tif (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))\narch/arm64/kvm/arm.c:1769:\t\t\tstage2_unmap_vm(vcpu-\u003ekvm);\narch/arm64/kvm/arm.c-1770-\t\telse\n--\narch/arm64/kvm/arm.c=2967=int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,\n--\narch/arm64/kvm/arm.c-2980-\narch/arm64/kvm/arm.c:2981:\treturn kvm_vgic_v4_set_forwarding(irqfd-\u003ekvm, prod-\u003eirq,\narch/arm64/kvm/arm.c-2982-\t\t\t\t\t \u0026irqfd-\u003eirq_entry);\n--\narch/arm64/kvm/arm.c=2985=void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,\n--\narch/arm64/kvm/arm.c-2994-\narch/arm64/kvm/arm.c:2995:\tkvm_vgic_v4_unset_forwarding(irqfd-\u003ekvm, prod-\u003eirq);\narch/arm64/kvm/arm.c-2996-}\n--\narch/arm64/kvm/arm.c=2998=void kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd,\n--\narch/arm64/kvm/arm.c-3013-\t */\narch/arm64/kvm/arm.c:3014:\treturn kvm_vgic_v4_unset_forwarding(irqfd-\u003ekvm, irqfd-\u003eproducer-\u003eirq);\narch/arm64/kvm/arm.c-3015-}\n--\narch/arm64/kvm/arm.c=3017=void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *cons)\n--\narch/arm64/kvm/arm.c-3021-\narch/arm64/kvm/arm.c:3022:\tkvm_arm_halt_guest(irqfd-\u003ekvm);\narch/arm64/kvm/arm.c-3023-}\n--\narch/arm64/kvm/arm.c=3025=void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)\n--\narch/arm64/kvm/arm.c-3029-\narch/arm64/kvm/arm.c:3030:\tkvm_arm_resume_guest(irqfd-\u003ekvm);\narch/arm64/kvm/arm.c-3031-}\n--\narch/arm64/kvm/at.c=27=static bool has_52bit_pa(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, u64 tcr)\n--\narch/arm64/kvm/at.c-31-\tdefault:\t\t/* IMPDEF: treat any other value as 64k */\narch/arm64/kvm/at.c:32:\t\tif (!kvm_has_feat_enum(vcpu-\u003ekvm, ID_AA64MMFR0_EL1, PARANGE, 52))\narch/arm64/kvm/at.c-33-\t\t\treturn false;\n--\narch/arm64/kvm/at.c-37-\tcase SZ_16K:\narch/arm64/kvm/at.c:38:\t\tif (!kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR0_EL1, TGRAN16, 52_BIT))\narch/arm64/kvm/at.c-39-\t\t\treturn false;\n--\narch/arm64/kvm/at.c-41-\tcase SZ_4K:\narch/arm64/kvm/at.c:42:\t\tif (!kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR0_EL1, TGRAN4, 52_BIT))\narch/arm64/kvm/at.c-43-\t\t\treturn false;\n--\narch/arm64/kvm/at.c=104=static bool s1pie_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)\narch/arm64/kvm/at.c-105-{\narch/arm64/kvm/at.c:106:\tif (!kvm_has_s1pie(vcpu-\u003ekvm))\narch/arm64/kvm/at.c-107-\t\treturn false;\n--\narch/arm64/kvm/at.c=113=static void compute_s1poe(struct kvm_vcpu *vcpu, struct s1_walk_info *wi)\n--\narch/arm64/kvm/at.c-116-\narch/arm64/kvm/at.c:117:\tif (!kvm_has_s1poe(vcpu-\u003ekvm)) {\narch/arm64/kvm/at.c-118-\t\twi-\u003epoe = wi-\u003ee0poe = false;\n--\narch/arm64/kvm/at.c=220=static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,\n--\narch/arm64/kvm/at.c-263-\narch/arm64/kvm/at.c:264:\twi-\u003epgshift = tcr_tg_pgshift(vcpu-\u003ekvm, tcr, upper_range);\narch/arm64/kvm/at.c-265-\twi-\u003epa52bit = has_52bit_pa(vcpu, wi, tcr);\n--\narch/arm64/kvm/at.c-320-\tif (wr-\u003elevel == S1_MMU_DISABLED) {\narch/arm64/kvm/at.c:321:\t\tif (va \u003e= BIT(kvm_get_pa_bits(vcpu-\u003ekvm)))\narch/arm64/kvm/at.c-322-\t\t\tgoto addrsz;\n--\narch/arm64/kvm/at.c-329-\narch/arm64/kvm/at.c:330:\twi-\u003ehpd = kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR1_EL1, HPDS, IMP);\narch/arm64/kvm/at.c-331-\twi-\u003ehpd \u0026= (wi-\u003eregime == TR_EL2 ?\n--\narch/arm64/kvm/at.c-345-\t/* R_PLCGL, R_YXNYW */\narch/arm64/kvm/at.c:346:\tif (!kvm_has_feat_enum(vcpu-\u003ekvm, ID_AA64MMFR2_EL1, ST, 48_47)) {\narch/arm64/kvm/at.c-347-\t\tif (wi-\u003etxsz \u003e 39)\n--\narch/arm64/kvm/at.c-360-\tcase SZ_64K:\narch/arm64/kvm/at.c:361:\t\tlva = kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR2_EL1, VARange, 52);\narch/arm64/kvm/at.c-362-\t\tbreak;\n--\narch/arm64/kvm/at.c-378-\t/* R_BNDVG and following statements */\narch/arm64/kvm/at.c:379:\tif (kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR2_EL1, E0PD, IMP) \u0026\u0026\narch/arm64/kvm/at.c-380-\t wi-\u003eas_el0 \u0026\u0026 (tcr \u0026 (va55 ? TCR_E0PD1 : TCR_E0PD0)))\n--\narch/arm64/kvm/at.c-408-\narch/arm64/kvm/at.c:409:\twi-\u003eha = kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR1_EL1, HAFDBS, AF);\narch/arm64/kvm/at.c-410-\twi-\u003eha \u0026= (wi-\u003eregime == TR_EL2 ?\n--\narch/arm64/kvm/at.c=430=static int kvm_read_s1_desc(struct kvm_vcpu *vcpu, u64 pa, u64 *desc,\n--\narch/arm64/kvm/at.c-435-\narch/arm64/kvm/at.c:436:\tr = kvm_read_guest(vcpu-\u003ekvm, pa, \u0026val, sizeof(val));\narch/arm64/kvm/at.c-437-\tif (r)\n--\narch/arm64/kvm/at.c=448=static int kvm_swap_s1_desc(struct kvm_vcpu *vcpu, u64 pa, u64 old, u64 new,\n--\narch/arm64/kvm/at.c-458-\narch/arm64/kvm/at.c:459:\treturn __kvm_at_swap_desc(vcpu-\u003ekvm, pa, old, new);\narch/arm64/kvm/at.c-460-}\n--\narch/arm64/kvm/at.c=462=static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,\n--\narch/arm64/kvm/at.c-556-\t\tbool valid_block = false;\narch/arm64/kvm/at.c:557:\t\tbool lpa = kvm_has_feat_enum(vcpu-\u003ekvm, ID_AA64MMFR0_EL1, PARANGE, 52);\narch/arm64/kvm/at.c-558-\n--\narch/arm64/kvm/at.c=855=static u64 compute_par_s12(struct kvm_vcpu *vcpu, u64 s1_par,\n--\narch/arm64/kvm/at.c-873-\tif (__vcpu_sys_reg(vcpu, HCR_EL2) \u0026 HCR_FWB) {\narch/arm64/kvm/at.c:874:\t\tif (!kvm_has_feat(vcpu-\u003ekvm, ID_AA64PFR2_EL1, MTEPERM, IMP))\narch/arm64/kvm/at.c-875-\t\t\ts2_memattr \u0026= ~BIT(3);\n--\narch/arm64/kvm/at.c=998=static bool pan3_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)\n--\narch/arm64/kvm/at.c-1001-\narch/arm64/kvm/at.c:1002:\tif (!kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR1_EL1, PAN, PAN3))\narch/arm64/kvm/at.c-1003-\t\treturn false;\n--\narch/arm64/kvm/at.c=1320=static int handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr, u64 *par)\n--\narch/arm64/kvm/at.c-1338-\narch/arm64/kvm/at.c:1339:\tidx = srcu_read_lock(\u0026vcpu-\u003ekvm-\u003esrcu);\narch/arm64/kvm/at.c-1340-\n--\narch/arm64/kvm/at.c-1342-\narch/arm64/kvm/at.c:1343:\tsrcu_read_unlock(\u0026vcpu-\u003ekvm-\u003esrcu, idx);\narch/arm64/kvm/at.c-1344-\n--\narch/arm64/kvm/at.c=1396=static u64 __kvm_at_s1e01_fast(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)\n--\narch/arm64/kvm/at.c-1409-\t */\narch/arm64/kvm/at.c:1410:\tguard(write_lock_irqsave)(\u0026vcpu-\u003ekvm-\u003emmu_lock);\narch/arm64/kvm/at.c-1411-\n--\narch/arm64/kvm/at.c-1439-\twrite_sysreg_el1(vcpu_read_sys_reg(vcpu, MAIR_EL1),\tSYS_MAIR);\narch/arm64/kvm/at.c:1440:\tif (kvm_has_tcr2(vcpu-\u003ekvm)) {\narch/arm64/kvm/at.c-1441-\t\twrite_sysreg_el1(vcpu_read_sys_reg(vcpu, TCR2_EL1), SYS_TCR2);\narch/arm64/kvm/at.c:1442:\t\tif (kvm_has_s1pie(vcpu-\u003ekvm)) {\narch/arm64/kvm/at.c-1443-\t\t\twrite_sysreg_el1(vcpu_read_sys_reg(vcpu, PIR_EL1), SYS_PIR);\n--\narch/arm64/kvm/at.c-1445-\t\t}\narch/arm64/kvm/at.c:1446:\t\tif (kvm_has_s1poe(vcpu-\u003ekvm)) {\narch/arm64/kvm/at.c-1447-\t\t\twrite_sysreg_el1(vcpu_read_sys_reg(vcpu, POR_EL1), SYS_POR);\n--\narch/arm64/kvm/at.c=1537=int __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)\n--\narch/arm64/kvm/at.c-1545-\t */\narch/arm64/kvm/at.c:1546:\tscoped_guard(write_lock_irqsave, \u0026vcpu-\u003ekvm-\u003emmu_lock) {\narch/arm64/kvm/at.c-1547-\t\tu64 val, hcr;\n--\narch/arm64/kvm/at.c=1595=int __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)\n--\narch/arm64/kvm/at.c-1643-\tout.esr = 0;\narch/arm64/kvm/at.c:1644:\tscoped_guard(srcu, \u0026vcpu-\u003ekvm-\u003esrcu)\narch/arm64/kvm/at.c-1645-\t\tret = kvm_walk_nested_s2(vcpu, ipa, \u0026out);\n--\narch/arm64/kvm/at.c=1709=int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa, int *level)\n--\narch/arm64/kvm/at.c-1740-\t/* Walk the guest's PT, looking for a match along the way */\narch/arm64/kvm/at.c:1741:\tscoped_guard(srcu, \u0026vcpu-\u003ekvm-\u003esrcu)\narch/arm64/kvm/at.c-1742-\t\tret = walk_s1(vcpu, \u0026wi, \u0026wr, va);\n--\narch/arm64/kvm/config.c=1683=static __always_inline void __compute_fgt(struct kvm_vcpu *vcpu, enum vcpu_sysreg reg)\narch/arm64/kvm/config.c-1684-{\narch/arm64/kvm/config.c:1685:\tu64 fgu = vcpu-\u003ekvm-\u003earch.fgu[__fgt_reg_to_group_id(reg)];\narch/arm64/kvm/config.c-1686-\tstruct fgt_masks *m = __fgt_reg_to_masks(reg);\n--\narch/arm64/kvm/debug.c=152=void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/debug.c-156-\t/* Must be called before kvm_vcpu_load_vhe() */\narch/arm64/kvm/debug.c:157:\tKVM_BUG_ON(vcpu_get_flag(vcpu, SYSREGS_ON_CPU), vcpu-\u003ekvm);\narch/arm64/kvm/debug.c-158-\n--\narch/arm64/kvm/emulate-nested.c=565=static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/emulate-nested.c-582-\t\t/* Someone used this trap helper for something else... */\narch/arm64/kvm/emulate-nested.c:583:\t\tKVM_BUG_ON(1, vcpu-\u003ekvm);\narch/arm64/kvm/emulate-nested.c-584-\t\treturn BEHAVE_HANDLE_LOCALLY;\n--\narch/arm64/kvm/emulate-nested.c=2518=static bool check_fgt_bit(struct kvm_vcpu *vcpu, enum vcpu_sysreg sr,\n--\narch/arm64/kvm/emulate-nested.c-2520-{\narch/arm64/kvm/emulate-nested.c:2521:\tstruct kvm *kvm = vcpu-\u003ekvm;\narch/arm64/kvm/emulate-nested.c-2522-\tu64 val;\n--\narch/arm64/kvm/emulate-nested.c=2550=bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)\n--\narch/arm64/kvm/emulate-nested.c-2578-\tif (tc.fgt != __NO_FGT_GROUP__ \u0026\u0026\narch/arm64/kvm/emulate-nested.c:2579:\t (vcpu-\u003ekvm-\u003earch.fgu[tc.fgt] \u0026 BIT(tc.bit))) {\narch/arm64/kvm/emulate-nested.c-2580-\t\tkvm_inject_undefined(vcpu);\n--\narch/arm64/kvm/emulate-nested.c-2679-\t\tif (in_feat_id_space(\u0026params)) {\narch/arm64/kvm/emulate-nested.c:2680:\t\t\tif (kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR2_EL1, IDS, IMP))\narch/arm64/kvm/emulate-nested.c-2681-\t\t\t\tkvm_inject_sync(vcpu, kvm_vcpu_get_esr(vcpu));\n--\narch/arm64/kvm/emulate-nested.c=2741=static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)\n--\narch/arm64/kvm/emulate-nested.c-2768-\narch/arm64/kvm/emulate-nested.c:2769:\t\tif (kvm_has_feat(vcpu-\u003ekvm, ID_AA64MMFR1_EL1, PAN, IMP))\narch/arm64/kvm/emulate-nested.c-2770-\t\t\tmask |= PSR_PAN_BIT;\n\n"
} |
| 21/2 | 2026/09/29 15:24 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 39983 output: 30 thoughts: 46 Thoughts: Okay, let's break this down. **Investigating the vfio_device Structure's KVM Pointer** Right, so I'm digging into this `vfio_device` structure and immediately something stands out. I see it's using a `struct file *kvm` where I'd expect to see a `struct kvm *kvm`. That's a bit unusual, and definitely warrants a closer look. My gut tells me something isn't quite right here. It’s important to understand *why* a `file` pointer is being used in this context. I need to understand the relationship it represents. Therefore, the next logical step is to see which parts of the code actually access and manipulate that `vfio_device->kvm` member. This will give me clues about how it's being used and hopefully reveal the rationale behind that `file` pointer. Knowing the access pattern is key to understanding the intent. I will have to find all instances where this member is referenced in the codebase to start formulating a theory on its purpose. |
| 22/2 | 2026/09/29 15:24 | tool | grepper |
0mArgs:{
"Expression": "\\bkvm\\b",
"PathPrefix": "drivers/vfio"
}Results: {
"Output": "drivers/vfio/device_cdev.c=65=static void vfio_df_get_kvm_safe(struct vfio_device_file *df)\n--\ndrivers/vfio/device_cdev.c-67-\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/device_cdev.c:68:\tvfio_device_get_kvm_safe(df-\u003edevice, df-\u003ekvm);\ndrivers/vfio/device_cdev.c-69-\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\n--\ndrivers/vfio/group.c=163=static void vfio_device_group_get_kvm_safe(struct vfio_device *device)\n--\ndrivers/vfio/group.c-165-\tspin_lock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:166:\tvfio_device_get_kvm_safe(device, device-\u003egroup-\u003ekvm);\ndrivers/vfio/group.c-167-\tspin_unlock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\n--\ndrivers/vfio/group.c=792=struct vfio_group *vfio_group_from_file(struct file *file)\n--\ndrivers/vfio/group.c-806- * returns a reference on the group. This function is deprecated, only the SPAPR\ndrivers/vfio/group.c:807: * path in kvm should call it.\ndrivers/vfio/group.c-808- */\n--\ndrivers/vfio/group.c=840=bool vfio_group_enforced_coherent(struct vfio_group *group)\n--\ndrivers/vfio/group.c-862-\ndrivers/vfio/group.c:863:void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\ndrivers/vfio/group.c-864-{\n--\ndrivers/vfio/group.c-866-\ndrivers/vfio/group.c:867:\tif (kvm)\ndrivers/vfio/group.c:868:\t\tget_file(kvm);\ndrivers/vfio/group.c-869-\ndrivers/vfio/group.c-870-\tspin_lock(\u0026group-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:871:\told = group-\u003ekvm;\ndrivers/vfio/group.c:872:\tgroup-\u003ekvm = kvm;\ndrivers/vfio/group.c-873-\tspin_unlock(\u0026group-\u003ekvm_ref_lock);\n--\ndrivers/vfio/pci/vfio_pci_zdev.c=184=int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_zdev.c-193-\ndrivers/vfio/pci/vfio_pci_zdev.c:194:\tif (!vdev-\u003evdev.kvm)\ndrivers/vfio/pci/vfio_pci_zdev.c-195-\t\treturn 0;\n--\ndrivers/vfio/pci/vfio_pci_zdev.c-198-\tif (zpci_kvm_hook.kvm_register)\ndrivers/vfio/pci/vfio_pci_zdev.c:199:\t\tret = zpci_kvm_hook.kvm_register(zdev, vdev-\u003evdev.kvm);\ndrivers/vfio/pci/vfio_pci_zdev.c-200-\n--\ndrivers/vfio/pci/vfio_pci_zdev.c=207=void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_zdev.c-215-\ndrivers/vfio/pci/vfio_pci_zdev.c:216:\tif (!vdev-\u003evdev.kvm)\ndrivers/vfio/pci/vfio_pci_zdev.c-217-\t\treturn;\n--\ndrivers/vfio/vfio.h=19=struct vfio_device_file {\n--\ndrivers/vfio/vfio.h-24-\tu32 devid; /* only valid when iommufd is valid */\ndrivers/vfio/vfio.h:25:\tspinlock_t kvm_ref_lock; /* protect kvm field */\ndrivers/vfio/vfio.h:26:\tstruct file *kvm;\ndrivers/vfio/vfio.h-27-\tstruct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */\n--\ndrivers/vfio/vfio.h=70=struct vfio_group {\n--\ndrivers/vfio/vfio.h-90-\tstruct mutex\t\t\tgroup_lock;\ndrivers/vfio/vfio.h:91:\tstruct file\t\t\t*kvm;\ndrivers/vfio/vfio.h-92-\tstruct file\t\t\t*opened_file;\n--\ndrivers/vfio/vfio.h=109=bool vfio_group_enforced_coherent(struct vfio_group *group);\ndrivers/vfio/vfio.h:110:void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm);\ndrivers/vfio/vfio.h-111-bool vfio_device_has_container(struct vfio_device *device);\n--\ndrivers/vfio/vfio.h=163=static inline bool vfio_group_enforced_coherent(struct vfio_group *group)\n--\ndrivers/vfio/vfio.h-167-\ndrivers/vfio/vfio.h:168:static inline void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\ndrivers/vfio/vfio.h-169-{\n--\ndrivers/vfio/vfio.h=426=static inline void vfio_virqfd_exit(void)\n--\ndrivers/vfio/vfio.h-431-#if IS_ENABLED(CONFIG_KVM)\ndrivers/vfio/vfio.h:432:void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm);\ndrivers/vfio/vfio.h-433-void vfio_device_put_kvm(struct vfio_device *device);\n--\ndrivers/vfio/vfio.h=435=static inline void vfio_device_get_kvm_safe(struct vfio_device *device,\ndrivers/vfio/vfio.h:436:\t\t\t\t\t struct file *kvm)\ndrivers/vfio/vfio.h-437-{\n--\ndrivers/vfio/vfio_main.c=472=EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);\n--\ndrivers/vfio/vfio_main.c-474-#if IS_ENABLED(CONFIG_KVM)\ndrivers/vfio/vfio_main.c:475:void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)\ndrivers/vfio/vfio_main.c-476-{\n--\ndrivers/vfio/vfio_main.c-478-\ndrivers/vfio/vfio_main.c:479:\tif (!kvm)\ndrivers/vfio/vfio_main.c-480-\t\treturn;\ndrivers/vfio/vfio_main.c-481-\ndrivers/vfio/vfio_main.c:482:\tdevice-\u003ekvm = get_file(kvm);\ndrivers/vfio/vfio_main.c-483-}\n--\ndrivers/vfio/vfio_main.c=485=void vfio_device_put_kvm(struct vfio_device *device)\n--\ndrivers/vfio/vfio_main.c-488-\ndrivers/vfio/vfio_main.c:489:\tif (!device-\u003ekvm)\ndrivers/vfio/vfio_main.c-490-\t\treturn;\ndrivers/vfio/vfio_main.c-491-\ndrivers/vfio/vfio_main.c:492:\tfput(device-\u003ekvm);\ndrivers/vfio/vfio_main.c:493:\tdevice-\u003ekvm = NULL;\ndrivers/vfio/vfio_main.c-494-}\n--\ndrivers/vfio/vfio_main.c=1516=EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);\ndrivers/vfio/vfio_main.c-1517-\ndrivers/vfio/vfio_main.c:1518:static void vfio_device_file_set_kvm(struct file *file, struct file *kvm)\ndrivers/vfio/vfio_main.c-1519-{\n--\ndrivers/vfio/vfio_main.c-1522-\ndrivers/vfio/vfio_main.c:1523:\tif (kvm)\ndrivers/vfio/vfio_main.c:1524:\t\tget_file(kvm);\ndrivers/vfio/vfio_main.c-1525-\ndrivers/vfio/vfio_main.c-1526-\t/*\ndrivers/vfio/vfio_main.c:1527:\t * The kvm is first recorded in the vfio_device_file, and will\ndrivers/vfio/vfio_main.c:1528:\t * be propagated to vfio_device::kvm when the file is bound to\ndrivers/vfio/vfio_main.c-1529-\t * iommufd successfully in the vfio device cdev path.\n--\ndrivers/vfio/vfio_main.c-1531-\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/vfio_main.c:1532:\told = df-\u003ekvm;\ndrivers/vfio/vfio_main.c:1533:\tdf-\u003ekvm = kvm;\ndrivers/vfio/vfio_main.c-1534-\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\n--\ndrivers/vfio/vfio_main.c-1540-/**\ndrivers/vfio/vfio_main.c:1541: * vfio_file_set_kvm - Link a kvm with VFIO drivers\ndrivers/vfio/vfio_main.c-1542- * @vfio_file: VFIO group file or VFIO device file\ndrivers/vfio/vfio_main.c:1543: * @kvm: KVM file to link\ndrivers/vfio/vfio_main.c-1544- *\ndrivers/vfio/vfio_main.c-1545- * When a VFIO device is first opened the KVM will be available in\ndrivers/vfio/vfio_main.c:1546: * device-\u003ekvm if one was associated with the file.\ndrivers/vfio/vfio_main.c-1547- */\ndrivers/vfio/vfio_main.c:1548:void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)\ndrivers/vfio/vfio_main.c-1549-{\n--\ndrivers/vfio/vfio_main.c-1553-\tif (group)\ndrivers/vfio/vfio_main.c:1554:\t\tvfio_group_set_kvm(group, kvm);\ndrivers/vfio/vfio_main.c-1555-\ndrivers/vfio/vfio_main.c-1556-\tif (vfio_device_from_file(vfio_file))\ndrivers/vfio/vfio_main.c:1557:\t\tvfio_device_file_set_kvm(vfio_file, kvm);\ndrivers/vfio/vfio_main.c-1558-}\n--\ndrivers/vfio/virqfd.c=40=static int virqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)\n--\ndrivers/vfio/virqfd.c-63-\t\t * virqfd pointer to it is still valid, queue it now. As\ndrivers/vfio/virqfd.c:64:\t\t * with kvm irqfds, we know we won't race against the virqfd\ndrivers/vfio/virqfd.c-65-\t\t * going away because we hold the lock to get here.\n"
} |
| 23/2 | 2026/09/29 15:24 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 43524 output: 28 thoughts: 47 Thoughts: Okay, let's dive into this driver landscape. **Investigating KVM Access in Drivers** My immediate concern is understanding which drivers are interacting with either the `device->kvm` or `vfio_device->kvm` structures. That's the crux of this investigation. To get a handle on this, my first instinct is to run a targeted search. I'm thinking a `grep` across the `drivers/` directory seems like the most efficient approach, focusing on the specific identifiers of interest. I'll need to be precise, so I'll probably leverage word boundaries (`\b`) to avoid false positives. So, something like `grep '\.kvm\b' or '->kvm\b'` is what I have in mind. I need to make sure I am focusing on the kvm access itself and not on kvm related terms. I want to identify any drivers that are *actually* accessing these specific structures. This search should provide a manageable list to scrutinize further, based on my understanding. |
| 24/2 | 2026/09/29 15:24 | tool | grepper |
0mArgs:{
"Expression": "\\bkvm\\b",
"PathPrefix": "drivers/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 515 lines.\nUse more precise expression if possible.\n\ndrivers/crypto/ccp/sev-dev.c=3145=int sev_firmware_supported_vm_types(void)\n--\ndrivers/crypto/ccp/sev-dev.c-3167-}\ndrivers/crypto/ccp/sev-dev.c:3168:EXPORT_SYMBOL_FOR_MODULES(sev_firmware_supported_vm_types, \"kvm-amd\");\n--\ndrivers/gpu/drm/ci/gitlab-ci.yml=1=variables:\n--\ndrivers/gpu/drm/ci/gitlab-ci.yml-42- FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: \"\" # Empty tags are ignored by gitlab\ndrivers/gpu/drm/ci/gitlab-ci.yml:43: FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: kvm\ndrivers/gpu/drm/ci/gitlab-ci.yml-44- FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: aarch64\n--\ndrivers/gpu/drm/i915/display/intel_crt.c=849=intel_crt_detect(struct drm_connector *connector,\n--\ndrivers/gpu/drm/i915/display/intel_crt.c-901-\t/* Load detection is broken on HPD capable machines. Whoever wants a\ndrivers/gpu/drm/i915/display/intel_crt.c:902:\t * broken monitor (without edid) to work behind a broken kvm (that fails\ndrivers/gpu/drm/i915/display/intel_crt.c-903-\t * to have the right resistors for HP detection) needs to fix this up.\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c=642=static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c-652-\ndrivers/gpu/drm/i915/gvt/kvmgt.c:653:\t\tif (vgpu-\u003evfio_device.kvm == itr-\u003evfio_device.kvm) {\ndrivers/gpu/drm/i915/gvt/kvmgt.c-654-\t\t\tret = true;\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c=663=static int intel_vgpu_open_device(struct vfio_device *vfio_dev)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c-672-\tvgpu-\u003etrack_node.track_remove_region = kvmgt_page_track_remove_region;\ndrivers/gpu/drm/i915/gvt/kvmgt.c:673:\tret = kvm_page_track_register_notifier(vgpu-\u003evfio_device.kvm,\ndrivers/gpu/drm/i915/gvt/kvmgt.c-674-\t\t\t\t\t \u0026vgpu-\u003etrack_node);\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c=701=static void intel_vgpu_close_device(struct vfio_device *vfio_dev)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c-710-\ndrivers/gpu/drm/i915/gvt/kvmgt.c:711:\tkvm_page_track_unregister_notifier(vgpu-\u003evfio_device.kvm,\ndrivers/gpu/drm/i915/gvt/kvmgt.c-712-\t\t\t\t\t \u0026vgpu-\u003etrack_node);\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c=1525=int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c-1534-\ndrivers/gpu/drm/i915/gvt/kvmgt.c:1535:\tr = kvm_write_track_add_gfn(info-\u003evfio_device.kvm, gfn);\ndrivers/gpu/drm/i915/gvt/kvmgt.c-1536-\tif (r)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c=1543=int intel_gvt_page_track_remove(struct intel_vgpu *info, u64 gfn)\n--\ndrivers/gpu/drm/i915/gvt/kvmgt.c-1552-\ndrivers/gpu/drm/i915/gvt/kvmgt.c:1553:\tr = kvm_write_track_remove_gfn(info-\u003evfio_device.kvm, gfn);\ndrivers/gpu/drm/i915/gvt/kvmgt.c-1554-\tif (r)\n--\ndrivers/hid/hid-logitech-dj.c-14-#include \u003clinux/delay.h\u003e\ndrivers/hid/hid-logitech-dj.c:15:#include \u003clinux/usb.h\u003e /* For to_usb_interface for kvm extra intf check */\ndrivers/hid/hid-logitech-dj.c-16-#include \u003clinux/unaligned.h\u003e\n--\ndrivers/hv/mshv_eventfd.c-5- * Heavily inspired from KVM implementation of irqfd/ioeventfd. The basic\ndrivers/hv/mshv_eventfd.c:6: * framework code is taken from the kvm implementation.\ndrivers/hv/mshv_eventfd.c-7- *\ndrivers/hv/mshv_eventfd.c:8: * All credits to kvm developers.\ndrivers/hv/mshv_eventfd.c-9- */\n--\ndrivers/hv/mshv_eventfd.h-4- * ioeventfd: Allow an fd to be used to receive a signal from the guest.\ndrivers/hv/mshv_eventfd.h:5: * All credit goes to kvm developers.\ndrivers/hv/mshv_eventfd.h-6- */\n--\ndrivers/iommu/iommufd/vfio_compat.c=197=static int iommufd_vfio_unmap_dma(struct iommufd_ctx *ictx, unsigned int cmd,\n--\ndrivers/iommu/iommufd/vfio_compat.c-203-\t * dirty tracking direction:\ndrivers/iommu/iommufd/vfio_compat.c:204:\t * https://lore.kernel.org/kvm/20220731125503.142683-1-yishaih@nvidia.com/\ndrivers/iommu/iommufd/vfio_compat.c:205:\t * https://lore.kernel.org/kvm/20220428210933.3583-1-joao.m.martins@oracle.com/\ndrivers/iommu/iommufd/vfio_compat.c-206-\t */\n--\ndrivers/iommu/iommufd/vfio_compat.c=279=static int iommufd_vfio_check_extension(struct iommufd_ctx *ictx,\n--\ndrivers/iommu/iommufd/vfio_compat.c-298-\t * VFIO_DMA_MAP_FLAG_VADDR\ndrivers/iommu/iommufd/vfio_compat.c:299:\t * https://lore.kernel.org/kvm/1611939252-7240-1-git-send-email-steven.sistare@oracle.com/\ndrivers/iommu/iommufd/vfio_compat.c-300-\t * https://lore.kernel.org/all/Yz777bJZjTyLrHEQ@nvidia.com/\n--\ndrivers/pci/tsm.c=328=EXPORT_SYMBOL_GPL(pci_tsm_unbind);\n--\ndrivers/pci/tsm.c-330-/**\ndrivers/pci/tsm.c:331: * pci_tsm_bind() - Bind @pdev as a TDI for @kvm\ndrivers/pci/tsm.c-332- * @pdev: PCI device function to bind\ndrivers/pci/tsm.c:333: * @kvm: Private memory attach context\ndrivers/pci/tsm.c-334- * @tdi_id: Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM\n--\ndrivers/pci/tsm.c-341- */\ndrivers/pci/tsm.c:342:int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u32 tdi_id)\ndrivers/pci/tsm.c-343-{\n--\ndrivers/pci/tsm.c-346-\ndrivers/pci/tsm.c:347:\tif (!kvm)\ndrivers/pci/tsm.c-348-\t\treturn -EINVAL;\n--\ndrivers/pci/tsm.c-362-\tif (pdev-\u003etsm-\u003etdi) {\ndrivers/pci/tsm.c:363:\t\tif (pdev-\u003etsm-\u003etdi-\u003ekvm != kvm)\ndrivers/pci/tsm.c-364-\t\t\treturn -EBUSY;\n--\ndrivers/pci/tsm.c-367-\ndrivers/pci/tsm.c:368:\ttdi = to_pci_tsm_ops(pdev-\u003etsm)-\u003ebind(pdev, kvm, tdi_id);\ndrivers/pci/tsm.c-369-\tif (IS_ERR(tdi))\n--\ndrivers/pci/tsm.c=660=static struct pci_dev *find_dsm_dev(struct pci_dev *pdev)\n--\ndrivers/pci/tsm.c-700- * @tdi: context to initialize\ndrivers/pci/tsm.c:701: * @kvm: Private memory attach context\ndrivers/pci/tsm.c-702- * @tdi_id: Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM\n--\ndrivers/pci/tsm.c=704=void pci_tsm_tdi_constructor(struct pci_dev *pdev, struct pci_tdi *tdi,\ndrivers/pci/tsm.c:705:\t\t\t struct kvm *kvm, u32 tdi_id)\ndrivers/pci/tsm.c-706-{\ndrivers/pci/tsm.c-707-\ttdi-\u003epdev = pdev;\ndrivers/pci/tsm.c:708:\ttdi-\u003ekvm = kvm;\ndrivers/pci/tsm.c-709-\ttdi-\u003etdi_id = tdi_id;\n--\ndrivers/ptp/Kconfig=123=config PTP_1588_CLOCK_KVM\n--\ndrivers/ptp/Kconfig-128-\thelp\ndrivers/ptp/Kconfig:129:\t This driver adds support for using kvm infrastructure as a PTP\ndrivers/ptp/Kconfig-130-\t clock. This clock is only useful if you are using KVM guests.\n--\ndrivers/s390/crypto/vfio_ap_ops.c-19-#include \u003clinux/uuid.h\u003e\ndrivers/s390/crypto/vfio_ap_ops.c:20:#include \u003casm/kvm.h\u003e\ndrivers/s390/crypto/vfio_ap_ops.c-21-#include \u003casm/zcrypt.h\u003e\n--\ndrivers/s390/crypto/vfio_ap_ops.c=39=static void vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q);\n--\ndrivers/s390/crypto/vfio_ap_ops.c-44- *\ndrivers/s390/crypto/vfio_ap_ops.c:45: * @kvm: a pointer to a struct kvm object containing the KVM guest's APCB.\ndrivers/s390/crypto/vfio_ap_ops.c-46- *\n--\ndrivers/s390/crypto/vfio_ap_ops.c-49- *\t\t\t guest's APCB.\ndrivers/s390/crypto/vfio_ap_ops.c:50: * 2. kvm-\u003elock:\t required to update a guest's APCB\ndrivers/s390/crypto/vfio_ap_ops.c:51: * 3. kvm-\u003earch.crypto.pqap_hook_rwsem: required to update pqap_hook and\ndrivers/s390/crypto/vfio_ap_ops.c-52- *\t\t\t\t\tserialize against PQAP intercepts\n--\ndrivers/s390/crypto/vfio_ap_ops.c-54- *\ndrivers/s390/crypto/vfio_ap_ops.c:55: * Note: If @kvm is NULL, the KVM lock and pqap_hook_rwsem will not be taken.\ndrivers/s390/crypto/vfio_ap_ops.c-56- */\ndrivers/s390/crypto/vfio_ap_ops.c:57:static inline void get_update_locks_for_kvm(struct kvm *kvm)\ndrivers/s390/crypto/vfio_ap_ops.c-58-{\ndrivers/s390/crypto/vfio_ap_ops.c-59-\tmutex_lock(\u0026matrix_dev-\u003eguests_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:60:\tif (kvm) {\ndrivers/s390/crypto/vfio_ap_ops.c:61:\t\tmutex_lock(\u0026kvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c:62:\t\tdown_write(\u0026kvm-\u003earch.crypto.pqap_hook_rwsem);\ndrivers/s390/crypto/vfio_ap_ops.c-63-\t}\n--\ndrivers/s390/crypto/vfio_ap_ops.c-70- *\ndrivers/s390/crypto/vfio_ap_ops.c:71: * @kvm: a pointer to a struct kvm object containing the KVM guest's APCB.\ndrivers/s390/crypto/vfio_ap_ops.c-72- *\n--\ndrivers/s390/crypto/vfio_ap_ops.c-74- * 1. matrix_dev-\u003emdevs_lock\ndrivers/s390/crypto/vfio_ap_ops.c:75: * 2. kvm-\u003earch.crypto.pqap_hook_rwsem\ndrivers/s390/crypto/vfio_ap_ops.c:76: * 3. kvm-\u003elock\ndrivers/s390/crypto/vfio_ap_ops.c-77- * 4. matrix_dev-\u003eguests_lock\ndrivers/s390/crypto/vfio_ap_ops.c-78- *\ndrivers/s390/crypto/vfio_ap_ops.c:79: * Note: If @kvm is NULL, the KVM lock and pqap_hook_rwsem will not be released.\ndrivers/s390/crypto/vfio_ap_ops.c-80- */\ndrivers/s390/crypto/vfio_ap_ops.c:81:static inline void release_update_locks_for_kvm(struct kvm *kvm)\ndrivers/s390/crypto/vfio_ap_ops.c-82-{\ndrivers/s390/crypto/vfio_ap_ops.c-83-\tmutex_unlock(\u0026matrix_dev-\u003emdevs_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:84:\tif (kvm) {\ndrivers/s390/crypto/vfio_ap_ops.c:85:\t\tup_write(\u0026kvm-\u003earch.crypto.pqap_hook_rwsem);\ndrivers/s390/crypto/vfio_ap_ops.c:86:\t\tmutex_unlock(\u0026kvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-87-\t}\n--\ndrivers/s390/crypto/vfio_ap_ops.c-100- *\t\t\t guest's APCB.\ndrivers/s390/crypto/vfio_ap_ops.c:101: * 2. matrix_mdev-\u003ekvm-\u003elock: required to update a guest's APCB\ndrivers/s390/crypto/vfio_ap_ops.c-102- * 3. matrix_dev-\u003emdevs_lock: required to access data stored in a matrix_mdev\n--\ndrivers/s390/crypto/vfio_ap_ops.c=107=static inline void get_update_locks_for_mdev(struct ap_matrix_mdev *matrix_mdev)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-109-\tmutex_lock(\u0026matrix_dev-\u003eguests_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:110:\tif (matrix_mdev \u0026\u0026 matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:111:\t\tmutex_lock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-112-\tmutex_lock(\u0026matrix_dev-\u003emdevs_lock);\n--\ndrivers/s390/crypto/vfio_ap_ops.c-123- * 1. matrix_dev-\u003emdevs_lock\ndrivers/s390/crypto/vfio_ap_ops.c:124: * 2. matrix_mdev-\u003ekvm-\u003elock\ndrivers/s390/crypto/vfio_ap_ops.c-125- * 3. matrix_dev-\u003eguests_lock\n--\ndrivers/s390/crypto/vfio_ap_ops.c=130=static inline void release_update_locks_for_mdev(struct ap_matrix_mdev *matrix_mdev)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-132-\tmutex_unlock(\u0026matrix_dev-\u003emdevs_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:133:\tif (matrix_mdev \u0026\u0026 matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:134:\t\tmutex_unlock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-135-\tmutex_unlock(\u0026matrix_dev-\u003eguests_lock);\n--\ndrivers/s390/crypto/vfio_ap_ops.c-147- *\t\t\t guest's APCB.\ndrivers/s390/crypto/vfio_ap_ops.c:148: * 2. matrix_mdev-\u003ekvm-\u003elock: required to update a guest's APCB\ndrivers/s390/crypto/vfio_ap_ops.c-149- * 3. matrix_dev-\u003emdevs_lock: required to access data stored in a matrix_mdev\ndrivers/s390/crypto/vfio_ap_ops.c-150- *\ndrivers/s390/crypto/vfio_ap_ops.c:151: * Note: If @apqn is not assigned to a matrix_mdev, the matrix_mdev-\u003ekvm-\u003elock\ndrivers/s390/crypto/vfio_ap_ops.c-152- *\t will not be taken.\n--\ndrivers/s390/crypto/vfio_ap_ops.c=157=static struct ap_matrix_mdev *get_update_locks_by_apqn(int apqn)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-165-\t\t test_bit_inv(AP_QID_QUEUE(apqn), matrix_mdev-\u003ematrix.aqm)) {\ndrivers/s390/crypto/vfio_ap_ops.c:166:\t\t\tif (matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:167:\t\t\t\tmutex_lock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-168-\n--\ndrivers/s390/crypto/vfio_ap_ops.c-189- *\t\t\t\t KVM guest's APCB.\ndrivers/s390/crypto/vfio_ap_ops.c:190: * 2. q-\u003ematrix_mdev-\u003ekvm-\u003elock: required to update a guest's APCB\ndrivers/s390/crypto/vfio_ap_ops.c-191- * 3. matrix_dev-\u003emdevs_lock:\t required to access data stored in matrix_mdev\n--\ndrivers/s390/crypto/vfio_ap_ops.c=196=static inline void get_update_locks_for_queue(struct vfio_ap_queue *q)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-198-\tmutex_lock(\u0026matrix_dev-\u003eguests_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:199:\tif (q-\u003ematrix_mdev \u0026\u0026 q-\u003ematrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:200:\t\tmutex_lock(\u0026q-\u003ematrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-201-\tmutex_lock(\u0026matrix_dev-\u003emdevs_lock);\n--\ndrivers/s390/crypto/vfio_ap_ops.c=276=static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-280-\tif (q-\u003esaved_isc != VFIO_AP_ISC_INVALID) {\ndrivers/s390/crypto/vfio_ap_ops.c:281:\t\tif (!WARN_ON(!q-\u003ematrix_mdev) \u0026\u0026 q-\u003ematrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:282:\t\t\tkvm_s390_gisc_unregister(q-\u003ematrix_mdev-\u003ekvm, q-\u003esaved_isc);\ndrivers/s390/crypto/vfio_ap_ops.c-283-\t\tq-\u003esaved_isc = VFIO_AP_ISC_INVALID;\n--\ndrivers/s390/crypto/vfio_ap_ops.c=358=static int vfio_ap_validate_nib(struct kvm_vcpu *vcpu, dma_addr_t *nib)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-363-\t\treturn -EINVAL;\ndrivers/s390/crypto/vfio_ap_ops.c:364:\tif (!kvm_s390_is_gpa_in_memslot(vcpu-\u003ekvm, *nib))\ndrivers/s390/crypto/vfio_ap_ops.c-365-\t\treturn -EINVAL;\n--\ndrivers/s390/crypto/vfio_ap_ops.c=423=static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q,\n--\ndrivers/s390/crypto/vfio_ap_ops.c-431-\tint nisc;\ndrivers/s390/crypto/vfio_ap_ops.c:432:\tstruct kvm *kvm;\ndrivers/s390/crypto/vfio_ap_ops.c-433-\tphys_addr_t h_nib;\n--\ndrivers/s390/crypto/vfio_ap_ops.c-460-\ndrivers/s390/crypto/vfio_ap_ops.c:461:\tkvm = q-\u003ematrix_mdev-\u003ekvm;\ndrivers/s390/crypto/vfio_ap_ops.c:462:\tgisa = kvm-\u003earch.gisa_int.origin;\ndrivers/s390/crypto/vfio_ap_ops.c-463-\n--\ndrivers/s390/crypto/vfio_ap_ops.c-474-\ndrivers/s390/crypto/vfio_ap_ops.c:475:\tnisc = kvm_s390_gisc_register(kvm, isc);\ndrivers/s390/crypto/vfio_ap_ops.c-476-\tif (nisc \u003c 0) {\n--\ndrivers/s390/crypto/vfio_ap_ops.c-498-\t\t/* We could not modify IRQ settings: clear new configuration */\ndrivers/s390/crypto/vfio_ap_ops.c:499:\t\tret = kvm_s390_gisc_unregister(kvm, isc);\ndrivers/s390/crypto/vfio_ap_ops.c-500-\t\tif (ret)\n--\ndrivers/s390/crypto/vfio_ap_ops.c=588=static int handle_pqap(struct kvm_vcpu *vcpu)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-609-\ndrivers/s390/crypto/vfio_ap_ops.c:610:\tif (!vcpu-\u003ekvm-\u003earch.crypto.pqap_hook) {\ndrivers/s390/crypto/vfio_ap_ops.c-611-\t\tVFIO_AP_DBF_WARN(\"%s: PQAP(AQIC) hook not registered with the vfio_ap driver: apqn=0x%04x\\n\",\n--\ndrivers/s390/crypto/vfio_ap_ops.c-616-\ndrivers/s390/crypto/vfio_ap_ops.c:617:\tmatrix_mdev = container_of(vcpu-\u003ekvm-\u003earch.crypto.pqap_hook,\ndrivers/s390/crypto/vfio_ap_ops.c-618-\t\t\t\t struct ap_matrix_mdev, pqap_hook);\n--\ndrivers/s390/crypto/vfio_ap_ops.c-620-\t/* If the there is no guest using the mdev, there is nothing to do */\ndrivers/s390/crypto/vfio_ap_ops.c:621:\tif (!matrix_mdev-\u003ekvm) {\ndrivers/s390/crypto/vfio_ap_ops.c-622-\t\tvfio_ap_le_guid_to_be_uuid(\u0026matrix_mdev-\u003emdev-\u003euuid, uuid);\n--\ndrivers/s390/crypto/vfio_ap_ops.c=666=static void vfio_ap_mdev_update_guest_apcb(struct ap_matrix_mdev *matrix_mdev)\ndrivers/s390/crypto/vfio_ap_ops.c-667-{\ndrivers/s390/crypto/vfio_ap_ops.c:668:\tif (matrix_mdev-\u003ekvm) {\ndrivers/s390/crypto/vfio_ap_ops.c:669:\t\tkvm_arch_crypto_set_masks(matrix_mdev-\u003ekvm,\ndrivers/s390/crypto/vfio_ap_ops.c-670-\t\t\t\t\t matrix_mdev-\u003eshadow_apcb.apm,\n--\ndrivers/s390/crypto/vfio_ap_ops.c=1834=static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,\n--\ndrivers/s390/crypto/vfio_ap_ops.c-1836-{\ndrivers/s390/crypto/vfio_ap_ops.c:1837:\tstruct kvm *kvm;\ndrivers/s390/crypto/vfio_ap_ops.c-1838-\n--\ndrivers/s390/crypto/vfio_ap_ops.c-1841-\ndrivers/s390/crypto/vfio_ap_ops.c:1842:\tkvm = file_to_kvm_s390(kvm_file);\ndrivers/s390/crypto/vfio_ap_ops.c:1843:\tif (!kvm)\ndrivers/s390/crypto/vfio_ap_ops.c-1844-\t\treturn -ENOENT;\ndrivers/s390/crypto/vfio_ap_ops.c-1845-\ndrivers/s390/crypto/vfio_ap_ops.c:1846:\tif (kvm-\u003earch.crypto.crycbd) {\ndrivers/s390/crypto/vfio_ap_ops.c:1847:\t\tget_update_locks_for_kvm(kvm);\ndrivers/s390/crypto/vfio_ap_ops.c:1848:\t\tif (kvm-\u003earch.crypto.pqap_hook) {\ndrivers/s390/crypto/vfio_ap_ops.c:1849:\t\t\trelease_update_locks_for_kvm(kvm);\ndrivers/s390/crypto/vfio_ap_ops.c-1850-\t\t\treturn -EPERM;\ndrivers/s390/crypto/vfio_ap_ops.c-1851-\t\t}\ndrivers/s390/crypto/vfio_ap_ops.c:1852:\t\tkvm-\u003earch.crypto.pqap_hook = \u0026matrix_mdev-\u003epqap_hook;\ndrivers/s390/crypto/vfio_ap_ops.c-1853-\ndrivers/s390/crypto/vfio_ap_ops.c:1854:\t\tmatrix_mdev-\u003ekvm = kvm;\ndrivers/s390/crypto/vfio_ap_ops.c-1855-\t\tvfio_ap_mdev_update_guest_apcb(matrix_mdev);\ndrivers/s390/crypto/vfio_ap_ops.c:1856:\t\trelease_update_locks_for_kvm(kvm);\ndrivers/s390/crypto/vfio_ap_ops.c-1857-\t}\n--\ndrivers/s390/crypto/vfio_ap_ops.c=1893=static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)\ndrivers/s390/crypto/vfio_ap_ops.c-1894-{\ndrivers/s390/crypto/vfio_ap_ops.c:1895:\tstruct kvm *kvm = matrix_mdev-\u003ekvm;\ndrivers/s390/crypto/vfio_ap_ops.c-1896-\ndrivers/s390/crypto/vfio_ap_ops.c:1897:\tif (kvm \u0026\u0026 kvm-\u003earch.crypto.crycbd) {\ndrivers/s390/crypto/vfio_ap_ops.c:1898:\t\tget_update_locks_for_kvm(kvm);\ndrivers/s390/crypto/vfio_ap_ops.c:1899:\t\tkvm-\u003earch.crypto.pqap_hook = NULL;\ndrivers/s390/crypto/vfio_ap_ops.c-1900-\ndrivers/s390/crypto/vfio_ap_ops.c:1901:\t\tkvm_arch_crypto_clear_masks(kvm);\ndrivers/s390/crypto/vfio_ap_ops.c-1902-\t\tvfio_ap_mdev_reset_queues(matrix_mdev);\ndrivers/s390/crypto/vfio_ap_ops.c:1903:\t\tmatrix_mdev-\u003ekvm = NULL;\ndrivers/s390/crypto/vfio_ap_ops.c-1904-\ndrivers/s390/crypto/vfio_ap_ops.c:1905:\t\trelease_update_locks_for_kvm(kvm);\ndrivers/s390/crypto/vfio_ap_ops.c-1906-\t}\n--\ndrivers/s390/crypto/vfio_ap_ops.c=2068=static int vfio_ap_mdev_open_device(struct vfio_device *vdev)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2072-\ndrivers/s390/crypto/vfio_ap_ops.c:2073:\tif (!vdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c-2074-\t\treturn -EINVAL;\ndrivers/s390/crypto/vfio_ap_ops.c-2075-\ndrivers/s390/crypto/vfio_ap_ops.c:2076:\treturn vfio_ap_mdev_set_kvm(matrix_mdev, vdev-\u003ekvm);\ndrivers/s390/crypto/vfio_ap_ops.c-2077-}\n--\ndrivers/s390/crypto/vfio_ap_ops.c=2087=static void vfio_ap_mdev_request(struct vfio_device *vdev, unsigned int count)\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2095-\ndrivers/s390/crypto/vfio_ap_ops.c:2096:\tif (matrix_mdev-\u003ekvm) {\ndrivers/s390/crypto/vfio_ap_ops.c:2097:\t\tkvm_arch_crypto_clear_masks(matrix_mdev-\u003ekvm);\ndrivers/s390/crypto/vfio_ap_ops.c-2098-\t\tsignal_guest_ap_cfg_changed(matrix_mdev);\n--\ndrivers/s390/crypto/vfio_ap_ops.c=2326=static ssize_t status_show(struct device *dev,\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2369-\t\t */\ndrivers/s390/crypto/vfio_ap_ops.c:2370:\t\tif (matrix_mdev-\u003ekvm \u0026\u0026\ndrivers/s390/crypto/vfio_ap_ops.c-2371-\t\t test_bit_inv(apid, matrix_mdev-\u003eshadow_apcb.apm) \u0026\u0026\n--\ndrivers/s390/crypto/vfio_ap_ops.c=2649=static void vfio_ap_mdev_cfg_remove(unsigned long *ap_remove,\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2667-\t\t * The mdevs_lock must be held to access fields within matrix_mdev,\ndrivers/s390/crypto/vfio_ap_ops.c:2668:\t\t * and kvm-\u003elock must be taken before mdevs_lock to satisfy the lock\ndrivers/s390/crypto/vfio_ap_ops.c-2669-\t\t * ordering requirement and prevent a lockdep splat.\ndrivers/s390/crypto/vfio_ap_ops.c-2670-\t\t */\ndrivers/s390/crypto/vfio_ap_ops.c:2671:\t\tif (matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:2672:\t\t\tmutex_lock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-2673-\t\tmutex_lock(\u0026matrix_dev-\u003emdevs_lock);\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2689-\t\tmutex_unlock(\u0026matrix_dev-\u003emdevs_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:2690:\t\tif (matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:2691:\t\t\tmutex_unlock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-2692-\t}\n--\ndrivers/s390/crypto/vfio_ap_ops.c=2934=void vfio_ap_on_scan_complete(struct ap_config_info *new_config_info,\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2943-\t\t * The mdevs_lock must be held to access fields within matrix_mdev,\ndrivers/s390/crypto/vfio_ap_ops.c:2944:\t\t * and kvm-\u003elock must be taken before mdevs_lock to satisfy the lock\ndrivers/s390/crypto/vfio_ap_ops.c-2945-\t\t * ordering requirement and prevent a lockdep splat.\ndrivers/s390/crypto/vfio_ap_ops.c-2946-\t\t */\ndrivers/s390/crypto/vfio_ap_ops.c:2947:\t\tif (matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:2948:\t\t\tmutex_lock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-2949-\t\tmutex_lock(\u0026matrix_dev-\u003emdevs_lock);\n--\ndrivers/s390/crypto/vfio_ap_ops.c-2962-\t\tmutex_unlock(\u0026matrix_dev-\u003emdevs_lock);\ndrivers/s390/crypto/vfio_ap_ops.c:2963:\t\tif (matrix_mdev-\u003ekvm)\ndrivers/s390/crypto/vfio_ap_ops.c:2964:\t\t\tmutex_unlock(\u0026matrix_mdev-\u003ekvm-\u003elock);\ndrivers/s390/crypto/vfio_ap_ops.c-2965-\t}\n--\ndrivers/s390/crypto/vfio_ap_private.h=90=struct ap_queue_table {\n--\ndrivers/s390/crypto/vfio_ap_private.h-101- * @shadow_apcb: the shadow copy of the APCB field of the KVM guest's CRYCB\ndrivers/s390/crypto/vfio_ap_private.h:102: * @kvm:\tthe struct holding guest's state\ndrivers/s390/crypto/vfio_ap_private.h-103- * @pqap_hook:\tthe function pointer to the interception handler for the\n--\ndrivers/s390/crypto/vfio_ap_private.h=114=struct ap_matrix_mdev {\n--\ndrivers/s390/crypto/vfio_ap_private.h-118-\tstruct ap_matrix shadow_apcb;\ndrivers/s390/crypto/vfio_ap_private.h:119:\tstruct kvm *kvm;\ndrivers/s390/crypto/vfio_ap_private.h-120-\tcrypto_hook pqap_hook;\n--\ndrivers/s390/virtio/Makefile-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/s390/virtio/Makefile:2:# Makefile for kvm guest drivers on s390\ndrivers/s390/virtio/Makefile-3-#\n--\ndrivers/vfio/device_cdev.c=65=static void vfio_df_get_kvm_safe(struct vfio_device_file *df)\n--\ndrivers/vfio/device_cdev.c-67-\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/device_cdev.c:68:\tvfio_device_get_kvm_safe(df-\u003edevice, df-\u003ekvm);\ndrivers/vfio/device_cdev.c-69-\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\n--\ndrivers/vfio/group.c=163=static void vfio_device_group_get_kvm_safe(struct vfio_device *device)\n--\ndrivers/vfio/group.c-165-\tspin_lock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:166:\tvfio_device_get_kvm_safe(device, device-\u003egroup-\u003ekvm);\ndrivers/vfio/group.c-167-\tspin_unlock(\u0026device-\u003egroup-\u003ekvm_ref_lock);\n--\ndrivers/vfio/group.c=792=struct vfio_group *vfio_group_from_file(struct file *file)\n--\ndrivers/vfio/group.c-806- * returns a reference on the group. This function is deprecated, only the SPAPR\ndrivers/vfio/group.c:807: * path in kvm should call it.\ndrivers/vfio/group.c-808- */\n--\ndrivers/vfio/group.c=840=bool vfio_group_enforced_coherent(struct vfio_group *group)\n--\ndrivers/vfio/group.c-862-\ndrivers/vfio/group.c:863:void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\ndrivers/vfio/group.c-864-{\n--\ndrivers/vfio/group.c-866-\ndrivers/vfio/group.c:867:\tif (kvm)\ndrivers/vfio/group.c:868:\t\tget_file(kvm);\ndrivers/vfio/group.c-869-\ndrivers/vfio/group.c-870-\tspin_lock(\u0026group-\u003ekvm_ref_lock);\ndrivers/vfio/group.c:871:\told = group-\u003ekvm;\ndrivers/vfio/group.c:872:\tgroup-\u003ekvm = kvm;\ndrivers/vfio/group.c-873-\tspin_unlock(\u0026group-\u003ekvm_ref_lock);\n--\ndrivers/vfio/pci/vfio_pci_zdev.c=184=int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_zdev.c-193-\ndrivers/vfio/pci/vfio_pci_zdev.c:194:\tif (!vdev-\u003evdev.kvm)\ndrivers/vfio/pci/vfio_pci_zdev.c-195-\t\treturn 0;\n--\ndrivers/vfio/pci/vfio_pci_zdev.c-198-\tif (zpci_kvm_hook.kvm_register)\ndrivers/vfio/pci/vfio_pci_zdev.c:199:\t\tret = zpci_kvm_hook.kvm_register(zdev, vdev-\u003evdev.kvm);\ndrivers/vfio/pci/vfio_pci_zdev.c-200-\n--\ndrivers/vfio/pci/vfio_pci_zdev.c=207=void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_zdev.c-215-\ndrivers/vfio/pci/vfio_pci_zdev.c:216:\tif (!vdev-\u003evdev.kvm)\ndrivers/vfio/pci/vfio_pci_zdev.c-217-\t\treturn;\n--\ndrivers/vfio/vfio.h=19=struct vfio_device_file {\n--\ndrivers/vfio/vfio.h-24-\tu32 devid; /* only valid when iommufd is valid */\ndrivers/vfio/vfio.h:25:\tspinlock_t kvm_ref_lock; /* protect kvm field */\ndrivers/vfio/vfio.h:26:\tstruct file *kvm;\ndrivers/vfio/vfio.h-27-\tstruct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */\n--\ndrivers/vfio/vfio.h=70=struct vfio_group {\n--\ndrivers/vfio/vfio.h-90-\tstruct mutex\t\t\tgroup_lock;\ndrivers/vfio/vfio.h:91:\tstruct file\t\t\t*kvm;\ndrivers/vfio/vfio.h-92-\tstruct file\t\t\t*opened_file;\n--\ndrivers/vfio/vfio.h=109=bool vfio_group_enforced_coherent(struct vfio_group *group);\ndrivers/vfio/vfio.h:110:void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm);\ndrivers/vfio/vfio.h-111-bool vfio_device_has_container(struct vfio_device *device);\n--\ndrivers/vfio/vfio.h=163=static inline bool vfio_group_enforced_coherent(struct vfio_group *group)\n--\ndrivers/vfio/vfio.h-167-\ndrivers/vfio/vfio.h:168:static inline void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)\ndrivers/vfio/vfio.h-169-{\n--\ndrivers/vfio/vfio.h=426=static inline void vfio_virqfd_exit(void)\n--\ndrivers/vfio/vfio.h-431-#if IS_ENABLED(CONFIG_KVM)\ndrivers/vfio/vfio.h:432:void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm);\ndrivers/vfio/vfio.h-433-void vfio_device_put_kvm(struct vfio_device *device);\n--\ndrivers/vfio/vfio.h=435=static inline void vfio_device_get_kvm_safe(struct vfio_device *device,\ndrivers/vfio/vfio.h:436:\t\t\t\t\t struct file *kvm)\ndrivers/vfio/vfio.h-437-{\n--\ndrivers/vfio/vfio_main.c=472=EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);\n--\ndrivers/vfio/vfio_main.c-474-#if IS_ENABLED(CONFIG_KVM)\ndrivers/vfio/vfio_main.c:475:void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)\ndrivers/vfio/vfio_main.c-476-{\n--\ndrivers/vfio/vfio_main.c-478-\ndrivers/vfio/vfio_main.c:479:\tif (!kvm)\ndrivers/vfio/vfio_main.c-480-\t\treturn;\ndrivers/vfio/vfio_main.c-481-\ndrivers/vfio/vfio_main.c:482:\tdevice-\u003ekvm = get_file(kvm);\ndrivers/vfio/vfio_main.c-483-}\n--\ndrivers/vfio/vfio_main.c=485=void vfio_device_put_kvm(struct vfio_device *device)\n--\ndrivers/vfio/vfio_main.c-488-\ndrivers/vfio/vfio_main.c:489:\tif (!device-\u003ekvm)\ndrivers/vfio/vfio_main.c-490-\t\treturn;\ndrivers/vfio/vfio_main.c-491-\ndrivers/vfio/vfio_main.c:492:\tfput(device-\u003ekvm);\ndrivers/vfio/vfio_main.c:493:\tdevice-\u003ekvm = NULL;\ndrivers/vfio/vfio_main.c-494-}\n--\ndrivers/vfio/vfio_main.c=1516=EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);\ndrivers/vfio/vfio_main.c-1517-\ndrivers/vfio/vfio_main.c:1518:static void vfio_device_file_set_kvm(struct file *file, struct file *kvm)\ndrivers/vfio/vfio_main.c-1519-{\n--\ndrivers/vfio/vfio_main.c-1522-\ndrivers/vfio/vfio_main.c:1523:\tif (kvm)\ndrivers/vfio/vfio_main.c:1524:\t\tget_file(kvm);\ndrivers/vfio/vfio_main.c-1525-\ndrivers/vfio/vfio_main.c-1526-\t/*\ndrivers/vfio/vfio_main.c:1527:\t * The kvm is first recorded in the vfio_device_file, and will\ndrivers/vfio/vfio_main.c:1528:\t * be propagated to vfio_device::kvm when the file is bound to\ndrivers/vfio/vfio_main.c-1529-\t * iommufd successfully in the vfio device cdev path.\n--\ndrivers/vfio/vfio_main.c-1531-\tspin_lock(\u0026df-\u003ekvm_ref_lock);\ndrivers/vfio/vfio_main.c:1532:\told = df-\u003ekvm;\ndrivers/vfio/vfio_main.c:1533:\tdf-\u003ekvm = kvm;\ndrivers/vfio/vfio_main.c-1534-\tspin_unlock(\u0026df-\u003ekvm_ref_lock);\n--\ndrivers/vfio/vfio_main.c-1540-/**\ndrivers/vfio/vfio_main.c:1541: * vfio_file_set_kvm - Link a kvm with VFIO drivers\ndrivers/vfio/vfio_main.c-1542- * @vfio_file: VFIO group file or VFIO device file\ndrivers/vfio/vfio_main.c:1543: * @kvm: KVM file to link\ndrivers/vfio/vfio_main.c-1544- *\ndrivers/vfio/vfio_main.c-1545- * When a VFIO device is first opened the KVM will be available in\ndrivers/vfio/vfio_main.c:1546: * device-\u003ekvm if one was associated with the file.\ndrivers/vfio/vfio_main.c-1547- */\n\n"
} |
| 25/2 | 2026/09/29 15:24 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 56865 output: 51 thoughts: 223 Thoughts: **Analyzing the KVMGT Changes** Okay, let's dive into this. I'm looking at `kvmgt.c`, specifically `drivers/gpu/drm/i915/gvt/kvmgt.c`. I need to make sure this still compiles and runs correctly on x86, which is critical. I see a specific call to `intel_vgpu_open_device` and it's bringing my attention to this line: `ret = kvm_page_track_register_notifier(vgpu->vfio_device.kvm, &vgpu->track_node);`. Interesting... and I'm catching that `vgpu->vfio_device.kvm` has been changed in this patch. I see that it's now a `struct file *kvm`! And, just like I expected, `kvm_page_track_register_notifier` is now taking `struct file *file` as its argument. Looks like a logical shift. Inside `kvm_page_track_register_notifier`, I see the expected conversion: `struct kvm *kvm = file_to_kvm_x86(file);`. This makes sense, as a `struct file` is converted to a `struct kvm`. Now I need to see what else might have been affected by this change. It's time to dig into the commit log to fully understand the rationale behind this patch. Let's use `git log` to get the commit message and reasoning; I'm certain the history will explain the design decision. |
| 26/2 | 2026/09/29 15:25 | tool | grepper |
0mError:no matches Args: {
"Expression": "commit 11fd22d39468642a418c5aacd0251911ee9247dc"
}Results: {
"error": "no matches"
} |
| 27/2 | 2026/09/29 15:25 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 57493 output: 43 thoughts: 400 Thoughts: **Analyzing the Scope of the KVM/VFIO Patch** Okay, so I don't have direct access to `git log` here, but I can work with what I *do* have. I need to understand the full extent of this change, so I'll grep the commit messages if necessary or examine the modified files directly. My immediate focus is on the diff. Let's see what's actually changed. Here's the rundown of files that have been touched, I'll need to go through each: 1. `arch/s390/include/asm/kvm_host_s390.h` 2. `arch/s390/kvm/s390/pci.c` 3. `arch/x86/include/asm/kvm_host.h` 4. `arch/x86/include/asm/kvm_page_track.h` 5. `arch/x86/kvm/Makefile` 6. `arch/x86/kvm/mmu/page_track.c` 7. `arch/x86/kvm/svm/sev.c` 8. `drivers/s390/crypto/vfio_ap_ops.c` 9. `drivers/vfio/group.c` 10. `drivers/vfio/vfio.h` 11. `drivers/vfio/vfio_main.c` 12. `include/linux/kvm_host.h` 13. `include/linux/vfio.h` 14. `virt/kvm/kvm_main.c` 15. `virt/kvm/vfio.c` Looking at the list, I see `arch/x86/kvm/svm/sev.c`. That's an interesting one, and given the nature of the other files, I suspect some sort of security implication might be addressed here with Secure Encrypted Virtualization (SEV). I'll start there. Specifically, I need to check out the context of `sev_vm_move_enc_context_from` and `sev_vm_copy_enc_context_from`. To get started, I'll review `arch/x86/kvm/svm/sev.c` around lines 2151 and 2876. I have a hunch that these functions might be key to understanding the changes, and if they are related to SEV it has high security implications, I'll need to fully assess the code around these locations to understand the context and potential vulnerabilities. |
| 28/2 | 2026/09/29 15:25 | tool | read-file |
0mArgs:{
"File": "arch/x86/kvm/svm/sev.c",
"FirstLine": 2145,
"LineCount": 35
}Results: {
"Contents": "2145:\t\tstruct kvm_sev_info *src_sev, *cg_cleanup_sev;\n2146:\t\tCLASS(fd, f)(source_fd);\n2147:\t\tstruct kvm *source_kvm;\n2148:\t\tbool charged = false;\n2149:\t\tint ret;\n2150:\t\n2151:\t\tif (fd_empty(f))\n2152:\t\t\treturn -EBADF;\n2153:\t\n2154:\t\tsource_kvm = file_to_kvm_x86(fd_file(f));\n2155:\t\tif (!source_kvm)\n2156:\t\t\treturn -EBADF;\n2157:\t\n2158:\t\tret = sev_lock_two_vms(kvm, source_kvm);\n2159:\t\tif (ret)\n2160:\t\t\treturn ret;\n2161:\t\n2162:\t\t/* Do not allow SNP VM migration until additional state transfer is implemented */\n2163:\t\tif (kvm-\u003earch.vm_type != source_kvm-\u003earch.vm_type ||\n2164:\t\t sev_guest(kvm) || !sev_guest(source_kvm) || sev_snp_guest(source_kvm)) {\n2165:\t\t\tret = -EINVAL;\n2166:\t\t\tgoto out_unlock;\n2167:\t\t}\n2168:\t\n2169:\t\tsrc_sev = to_kvm_sev_info(source_kvm);\n2170:\t\n2171:\t\tdst_sev-\u003emisc_cg = get_current_misc_cg();\n2172:\t\tcg_cleanup_sev = dst_sev;\n2173:\t\tif (dst_sev-\u003emisc_cg != src_sev-\u003emisc_cg) {\n2174:\t\t\tret = sev_misc_cg_try_charge(dst_sev);\n2175:\t\t\tif (ret)\n2176:\t\t\t\tgoto out_dst_cgroup;\n2177:\t\t\tcharged = true;\n2178:\t\t}\n2179:\t\n"
} |
| 29/2 | 2026/09/29 15:25 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 59088 output: 43 thoughts: 28 Thoughts: Okay, let's dive into this. I'm going to take a look at the code. **Diving into `arch/x86/kvm/svm/sev.c` - Line 2876** Alright, my expert eye tells me we're focusing on `arch/x86/kvm/svm/sev.c` specifically around line 2876. This likely indicates we're dealing with some core Secure Encrypted Virtualization (SEV) functionality within the KVM/SVM framework on x86 architectures. Given my experience, I'm expecting this area to be handling a critical operation. It could be memory encryption setup, key management, guest attestation, or perhaps something lower-level related to the hardware interface. The line number is a good starting point, as it should give me some context, especially if there's an associated comment block nearby describing the adjacent code block. I'll be looking for clues in the surrounding code. |
| 30/2 | 2026/09/29 15:25 | tool | read-file |
0mArgs:{
"File": "arch/x86/kvm/svm/sev.c",
"FirstLine": 2870,
"LineCount": 35
}Results: {
"Contents": "2870:\t{\n2871:\t\tCLASS(fd, f)(source_fd);\n2872:\t\tstruct kvm *source_kvm;\n2873:\t\tstruct kvm_sev_info *source_sev, *mirror_sev;\n2874:\t\tint ret;\n2875:\t\n2876:\t\tif (fd_empty(f))\n2877:\t\t\treturn -EBADF;\n2878:\t\n2879:\t\tsource_kvm = file_to_kvm_x86(fd_file(f));\n2880:\t\tif (!source_kvm)\n2881:\t\t\treturn -EBADF;\n2882:\t\n2883:\t\tret = sev_lock_two_vms(kvm, source_kvm);\n2884:\t\tif (ret)\n2885:\t\t\treturn ret;\n2886:\t\n2887:\t\t/*\n2888:\t\t * Mirrors of mirrors should work, but let's not get silly. Also\n2889:\t\t * disallow out-of-band SEV/SEV-ES init if the target is already an\n2890:\t\t * SEV guest, or if vCPUs have been created. KVM relies on vCPUs being\n2891:\t\t * created after SEV/SEV-ES initialization, e.g. to init intercepts.\n2892:\t\t * Also do not allow SNP VM mirroring until additional state transfer is implemented.\n2893:\t\t */\n2894:\t\tif (sev_guest(kvm) || !sev_guest(source_kvm) || sev_snp_guest(source_kvm) ||\n2895:\t\t is_mirroring_enc_context(source_kvm) || kvm-\u003ecreated_vcpus) {\n2896:\t\t\tret = -EINVAL;\n2897:\t\t\tgoto e_unlock;\n2898:\t\t}\n2899:\t\n2900:\t\tmirror_sev = to_kvm_sev_info(kvm);\n2901:\t\tif (!zalloc_cpumask_var(\u0026mirror_sev-\u003ehave_run_cpus, GFP_KERNEL_ACCOUNT)) {\n2902:\t\t\tret = -ENOMEM;\n2903:\t\t\tgoto e_unlock;\n2904:\t\t}\n"
} |
| 31/2 | 2026/09/29 15:25 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 59970 output: 31 thoughts: 471 Thoughts: **Analyzing KVM VM Release and File Descriptor Management** Okay, let's dive into this KVM code, specifically focusing on how virtual machines are released and how file descriptors are managed. I'm going to start by examining `virt/kvm/kvm_main.c` and `virt/kvm/vfio.c`. In `kvm_main.c`, I see `kvm_vm_release` and `kvm_dev_ioctl_create_vm`. `kvm_vm_release` looks straightforward: it calls `kvm_irqfd_release`, nullifies the `kvm->file` pointer using `WRITE_ONCE`, and then calls `kvm_put_kvm`. Pretty standard cleanup procedure. The more interesting part is `kvm_dev_ioctl_create_vm`. Here, the code calls `anon_inode_getfd` to get a file descriptor for the VM. This function seems crucial. It's installing a file into the file descriptor table, or perhaps allocating a descriptor and creating an anonymous inode file. Hold on a second, is it `anon_inode_getfd` or `anon_inode_getfile` that's the key function here? I need to check how `anon_inode_getfd` actually works. Let's head over to `fs/anon_inodes.c` to understand that process, or determine if I've been led down a rabbit hole. The core of this must be getting the anon file setup, and then making sure it's closed correctly. |
| 32/2 | 2026/09/29 15:25 | tool | grepper |
0mArgs:{
"Expression": "anon_inode_getfd",
"PathPrefix": "virt/kvm/"
}Results: {
"Output": "virt/kvm/kvm_main.c=4139=static int create_vcpu_fd(struct kvm_vcpu *vcpu)\n--\nvirt/kvm/kvm_main.c-4143-\tsnprintf(name, sizeof(name), \"kvm-vcpu:%d\", vcpu-\u003evcpu_id);\nvirt/kvm/kvm_main.c:4144:\treturn anon_inode_getfd(name, \u0026kvm_vcpu_fops, vcpu, O_RDWR | O_CLOEXEC);\nvirt/kvm/kvm_main.c-4145-}\n--\nvirt/kvm/kvm_main.c=4849=static int kvm_ioctl_create_device(struct kvm *kvm,\n--\nvirt/kvm/kvm_main.c-4889-\tkvm_get_kvm(kvm);\nvirt/kvm/kvm_main.c:4890:\tret = anon_inode_getfd(ops-\u003ename, \u0026kvm_device_fops, dev, O_RDWR | O_CLOEXEC);\nvirt/kvm/kvm_main.c-4891-\tif (ret \u003c 0) {\n"
} |
| 33/2 | 2026/09/29 15:25 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 61126 output: 40 thoughts: 42 Thoughts: Okay, let's dive into this. I need to understand what's happening with VM creation within KVM. Specifically, I'm going to focus on `kvm_dev_ioctl_create_vm`. I'm going to start by examining the code snippet around lines 5530-5570 in `virt/kvm/kvm_main.c`. My immediate goal is to get a handle on the function's core purpose and the key data structures it interacts with during the VM initialization sequence. I'll pay close attention to the arguments it takes and how it handles potential errors. I'm expecting to see calls to lower-level functions that allocate memory for the VM and potentially set up initial control structures. I'll need to look for any interaction with the hardware virtualization extensions, and I will be looking to see if the implementation performs any initial configuration steps. From here, I will begin to understand the critical path of VM initialization. |
| 34/2 | 2026/09/29 15:26 | tool | read-file |
0mArgs:{
"File": "virt/kvm/kvm_main.c",
"FirstLine": 5530,
"LineCount": 45
}Results: {
"Contents": "5530:\t{\n5531:\t\tchar fdname[ITOA_MAX_LEN + 1];\n5532:\t\tint r, fd;\n5533:\t\tstruct kvm *kvm;\n5534:\t\tstruct file *file;\n5535:\t\n5536:\t\tfd = get_unused_fd_flags(O_CLOEXEC);\n5537:\t\tif (fd \u003c 0)\n5538:\t\t\treturn fd;\n5539:\t\n5540:\t\tsnprintf(fdname, sizeof(fdname), \"%d\", fd);\n5541:\t\n5542:\t\tkvm = kvm_create_vm(type, fdname);\n5543:\t\tif (IS_ERR(kvm)) {\n5544:\t\t\tr = PTR_ERR(kvm);\n5545:\t\t\tgoto put_fd;\n5546:\t\t}\n5547:\t\n5548:\t\tfile = anon_inode_getfile(\"kvm-vm\", \u0026kvm_vm_fops, kvm, O_RDWR);\n5549:\t\tif (IS_ERR(file)) {\n5550:\t\t\tr = PTR_ERR(file);\n5551:\t\t\tgoto put_kvm;\n5552:\t\t}\n5553:\t\n5554:\t\tkvm-\u003efile = file;\n5555:\t\n5556:\t\t/*\n5557:\t\t * Don't call kvm_put_kvm anymore at this point; file-\u003ef_op is\n5558:\t\t * already set, with -\u003erelease() being kvm_vm_release(). In error\n5559:\t\t * cases it will be called by the final fput(file) and will take\n5560:\t\t * care of doing kvm_put_kvm(kvm).\n5561:\t\t */\n5562:\t\tkvm_uevent_notify_change(KVM_EVENT_CREATE_VM, kvm);\n5563:\t\n5564:\t\tfd_install(fd, file);\n5565:\t\treturn fd;\n5566:\t\n5567:\tput_kvm:\n5568:\t\tkvm_put_kvm(kvm);\n5569:\tput_fd:\n5570:\t\tput_unused_fd(fd);\n5571:\t\treturn r;\n5572:\t}\n5573:\t\n5574:\tstatic long kvm_dev_ioctl(struct file *filp,\n"
} |
| 35/2 | 2026/09/29 15:26 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 62070 output: 33 thoughts: 439 Thoughts: **Analyzing KVM VM File Handling and Potential Race Conditions** Okay, so I'm digging into how the KVM virtual machine file descriptor is managed, specifically focusing on a potential race condition. First, I see the VM's file descriptor (`file`) being created using `anon_inode_getfile` and assigned to the `kvm->file` field. Then, in `kvm_vm_release`, the code explicitly sets `kvm->file` to `NULL` using `WRITE_ONCE` when the file descriptor is being released. This happens when the file descriptor's reference count goes to zero. Now, what caught my eye is this `get_file_active(&dev->kvm->file)` call in `kvm_vfio_file_add`. This is grabbing a pointer to that file, *and* `dev->kvm` is the `struct kvm *` for this VM; so `dev->kvm->file` is that file pointer that was stored when the VM was created. The crucial point is that `get_file_active` returns NULL if `f_count` is 0 or if the file pointer is NULL! So, *after* `kvm_vm_release` sets the `kvm->file` to NULL, there is a time in which `kvm_vfio_file_add` can return an invalid pointer if `kvm_vm_release` is executing at the same time and the file is in the process of closing. This means there's a window where `get_file_active` could return NULL if `kvm_vm_release` is running concurrently, potentially leading to a race condition. Let me take a look at the implementation of `get_file_active` and how it interacts with the file's reference count in `fs/file.c` to understand the exact synchronization and possible failure scenarios. |
| 36/2 | 2026/09/29 15:26 | tool | read-file |
0mArgs:{
"File": "fs/file.c",
"FirstLine": 990,
"LineCount": 35
}Results: {
"Contents": " 990:\tEXPORT_SYMBOL_GPL(get_file_rcu);\n 991:\t\n 992:\t/**\n 993:\t * get_file_active - try go get a reference to a file\n 994:\t * @f: the file to get a reference on\n 995:\t *\n 996:\t * In contast to get_file_rcu() the pointer itself isn't part of the\n 997:\t * reference counting.\n 998:\t *\n 999:\t * This function should rarely have to be used and only by users who\n1000:\t * understand the implications of SLAB_TYPESAFE_BY_RCU. Try to avoid it.\n1001:\t *\n1002:\t * Return: Returns @f with the reference count increased or NULL.\n1003:\t */\n1004:\tstruct file *get_file_active(struct file **f)\n1005:\t{\n1006:\t\tstruct file __rcu *file;\n1007:\t\n1008:\t\trcu_read_lock();\n1009:\t\tfile = __get_file_rcu(f);\n1010:\t\trcu_read_unlock();\n1011:\t\tif (IS_ERR(file))\n1012:\t\t\tfile = NULL;\n1013:\t\treturn file;\n1014:\t}\n1015:\tEXPORT_SYMBOL_GPL(get_file_active);\n1016:\t\n1017:\tstatic inline struct file *__fget_files_rcu(struct files_struct *files,\n1018:\t unsigned int fd, fmode_t mask)\n1019:\t{\n1020:\t\tfor (;;) {\n1021:\t\t\tstruct file *file;\n1022:\t\t\tstruct fdtable *fdt = rcu_dereference_raw(files-\u003efdt);\n1023:\t\t\tstruct file __rcu **fdentry;\n1024:\t\t\tunsigned long nospec_mask;\n"
} |
| 37/2 | 2026/09/29 15:26 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 63482 output: 23 thoughts: 211 Thoughts: **Analyzing Potential Fuzzing Targets** Okay, so `get_file_active` utilizes an RCU read lock and calls `__get_file_rcu(f)`. My focus is on whether this code path is reachable via syzkaller fuzzing, specifically on amd64. Let's break this down systematically. First, I need to consider potential triggering mechanisms. The `KVM_CREATE_DEVICE` ioctl on a KVM VM file descriptor seems like a viable starting point. Can syzkaller reach this? Yes, it actively targets `/dev/kvm`. Excellent. I should double-check the syzlang descriptions within syzkaller, or just grep the kernel sources for `KVM_CREATE_DEVICE` or other relevant "kvm" ioctls to confirm and identify potential variations or dependencies. Now, within the KVM context, can `KVM_CREATE_DEVICE` instantiate a `KVM_DEV_TYPE_VFIO`? This is critical. To answer this definitively, I'll need to scrutinize the Kconfig options for `KVM_VFIO`. Where exactly is `kvm_vfio_ops_init()` called? That will be the next piece of information I need to confirm this line of thinking. |
| 38/2 | 2026/09/29 15:27 | tool | grepper |
0mArgs:{
"Expression": "kvm_vfio_ops_init"
}Results: {
"Output": "virt/kvm/kvm_main.c=6532=int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)\n--\nvirt/kvm/kvm_main.c-6575-\nvirt/kvm/kvm_main.c:6576:\tr = kvm_vfio_ops_init();\nvirt/kvm/kvm_main.c-6577-\tif (WARN_ON_ONCE(r))\n--\nvirt/kvm/vfio.c=332=static int kvm_vfio_create(struct kvm_device *dev, u32 type)\n--\nvirt/kvm/vfio.c-355-\nvirt/kvm/vfio.c:356:int kvm_vfio_ops_init(void)\nvirt/kvm/vfio.c-357-{\n--\nvirt/kvm/vfio.h-5-#ifdef CONFIG_KVM_VFIO\nvirt/kvm/vfio.h:6:int kvm_vfio_ops_init(void);\nvirt/kvm/vfio.h-7-void kvm_vfio_ops_exit(void);\nvirt/kvm/vfio.h-8-#else\nvirt/kvm/vfio.h:9:static inline int kvm_vfio_ops_init(void)\nvirt/kvm/vfio.h-10-{\n"
} |
| 39/2 | 2026/09/29 15:27 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64350 output: 20 thoughts: 16 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Kconfig Shenanigans: Hunting for `CONFIG_KVM_VFIO`** Alright, time to get down to brass tacks. My initial thought process is pretty straightforward: I need to verify something related to the KVM Virtual Function I/O setup, and the Kconfig files are the obvious place to start. I'm going to quickly check for the `CONFIG_KVM_VFIO` option. This isn't a complex analysis; it's a direct, targeted lookup. I'm assuming the problem I'm trying to solve, or the configuration I'm trying to confirm, hinges on the presence, absence, or particular settings of that configuration option. This is the first diagnostic step, a sanity check, if you will. I'm implicitly assuming that this option is either directly relevant, or indirectly part of something larger. I need to know where we stand with that key. |
| 40/2 | 2026/09/29 15:27 | tool | grepper |
0mArgs:{
"Expression": "config KVM_VFIO"
}Results: {
"Output": "virt/kvm/Kconfig=59=config HAVE_KVM_CPU_RELAX_INTERCEPT\n--\nvirt/kvm/Kconfig-61-\nvirt/kvm/Kconfig:62:config KVM_VFIO\nvirt/kvm/Kconfig-63- bool\n"
} |
| 41/2 | 2026/09/29 15:27 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64685 output: 20 thoughts: 20 Thoughts: Here's my thought process, as if I were considering this myself: **Tracing KVM_VFIO in Kconfig** Alright, let's get down to brass tacks. I need to figure out the dependencies and location of `KVM_VFIO` within the Kconfig system. Time to crack open the Kconfig files. My initial approach will be to leverage my knowledge of the kernel source structure and search methodologies. I'll need to use my usual methods, likely a `grep` or similar command, across the kernel source. The goal is pinpointing *where* and *how* `KVM_VFIO` is defined or selected. I'll need to note any dependencies, any other config options that impact it, and the general location of the relevant Kconfig fragment. This initial tracing will be critical for understanding how the feature is enabled. From here, I'll be able to quickly understand its context. |
| 42/2 | 2026/09/29 15:27 | tool | grepper |
0mArgs:{
"Expression": "select KVM_VFIO"
}Results: {
"Output": "arch/arm64/kvm/Kconfig=20=menuconfig KVM\n--\narch/arm64/kvm/Kconfig-27-\tselect VIRT_XFER_TO_GUEST_WORK\narch/arm64/kvm/Kconfig:28:\tselect KVM_VFIO\narch/arm64/kvm/Kconfig-29-\tselect HAVE_KVM_DIRTY_RING_ACQ_REL\n--\narch/powerpc/kvm/Kconfig=20=config KVM\n--\narch/powerpc/kvm/Kconfig-22-\tselect KVM_COMMON\narch/powerpc/kvm/Kconfig:23:\tselect KVM_VFIO\narch/powerpc/kvm/Kconfig-24-\tselect HAVE_KVM_IRQ_BYPASS\n--\narch/s390/kvm/Kconfig=19=config KVM\n--\narch/s390/kvm/Kconfig-29-\tselect HAVE_KVM_NO_POLL\narch/s390/kvm/Kconfig:30:\tselect KVM_VFIO\narch/s390/kvm/Kconfig-31-\tselect VIRT_XFER_TO_GUEST_WORK\n--\narch/x86/kvm/Kconfig=20=config KVM_X86\n--\narch/x86/kvm/Kconfig-44-\tselect KVM_GENERIC_DIRTYLOG_READ_PROTECT\narch/x86/kvm/Kconfig:45:\tselect KVM_VFIO\narch/x86/kvm/Kconfig-46-\tselect HAVE_KVM_PM_NOTIFIER if PM\n"
} |
| 43/2 | 2026/09/29 15:27 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 65348 output: 23 thoughts: 175 Thoughts: **VFIO and KVM - A Quick Mental Audit** Okay, so `CONFIG_KVM_X86` implicitly selects `CONFIG_KVM_VFIO`. That's a key dependency. This means, as long as we're building KVM for an x86 platform (Intel or AMD - `CONFIG_KVM_INTEL` or `CONFIG_KVM_AMD`), VFIO gets enabled. This is crucial because `CONFIG_KVM` is pretty much the cornerstone for KVM fuzzing. Now, I need to think about user-space interactions. Can a user-space program simply open `/dev/kvm`, spin up a VM, and then create a VFIO device and start operating on it? What kind of file descriptor does that operation even yield? And can the user-space program even directly open `/dev/vfio/vfio` or even `/dev/vfio/devices/...`? That's the real question. Alright, time to sanity check myself. Let's go look at `drivers/vfio/vfio_main.c` and specifically, let's look at `vfio_file_is_valid`. This will be the key to understanding how user-space interacts with VFIO devices, and how to validate whether a handle is valid. Let's see what the check looks for. |
| 44/2 | 2026/09/29 15:27 | tool | grepper |
0mArgs:{
"Expression": "bool vfio_file_is_valid"
}Results: {
"Output": "drivers/vfio/vfio_main.c=1471=static struct vfio_device *vfio_device_from_file(struct file *file)\n--\ndrivers/vfio/vfio_main.c-1483- */\ndrivers/vfio/vfio_main.c:1484:bool vfio_file_is_valid(struct file *file)\ndrivers/vfio/vfio_main.c-1485-{\n--\ninclude/linux/vfio.h=373=static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *device)\n--\ninclude/linux/vfio.h-377-#endif\ninclude/linux/vfio.h:378:bool vfio_file_is_valid(struct file *file);\ninclude/linux/vfio.h-379-bool vfio_file_enforced_coherent(struct file *file);\n"
} |
| 45/2 | 2026/09/29 15:27 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 66075 output: 40 thoughts: 28 Thoughts: Okay, let's dive into this. I'm going to take a look at the `vfio_file_is_valid` function. I know this is located within `drivers/vfio/vfio_main.c`, and that's going to tell me a lot. The VFIO subsystem is crucial for direct device assignment in virtualization, so understanding how it validates files is key to understanding its security and functionality. I'm expecting to see checks for permissions, possibly file type, and likely some interaction with the device itself to make sure it's in a safe state to be assigned. I'm going to look for any potential race conditions or flaws. Let's see what they've done... |
| 46/2 | 2026/09/29 15:27 | tool | read-file |
0mArgs:{
"File": "drivers/vfio/vfio_main.c",
"FirstLine": 1480,
"LineCount": 40
}Results: {
"Contents": "1480:\t/**\n1481:\t * vfio_file_is_valid - True if the file is valid vfio file\n1482:\t * @file: VFIO group file or VFIO device file\n1483:\t */\n1484:\tbool vfio_file_is_valid(struct file *file)\n1485:\t{\n1486:\t\treturn vfio_group_from_file(file) ||\n1487:\t\t vfio_device_from_file(file);\n1488:\t}\n1489:\tEXPORT_SYMBOL_GPL(vfio_file_is_valid);\n1490:\t\n1491:\t/**\n1492:\t * vfio_file_enforced_coherent - True if the DMA associated with the VFIO file\n1493:\t * is always CPU cache coherent\n1494:\t * @file: VFIO group file or VFIO device file\n1495:\t *\n1496:\t * Enforced coherency means that the IOMMU ignores things like the PCIe no-snoop\n1497:\t * bit in DMA transactions. A return of false indicates that the user has\n1498:\t * rights to access additional instructions such as wbinvd on x86.\n1499:\t */\n1500:\tbool vfio_file_enforced_coherent(struct file *file)\n1501:\t{\n1502:\t\tstruct vfio_device *device;\n1503:\t\tstruct vfio_group *group;\n1504:\t\n1505:\t\tgroup = vfio_group_from_file(file);\n1506:\t\tif (group)\n1507:\t\t\treturn vfio_group_enforced_coherent(group);\n1508:\t\n1509:\t\tdevice = vfio_device_from_file(file);\n1510:\t\tif (device)\n1511:\t\t\treturn device_iommu_capable(device-\u003edev,\n1512:\t\t\t\t\t\t IOMMU_CAP_ENFORCE_CACHE_COHERENCY);\n1513:\t\n1514:\t\treturn true;\n1515:\t}\n1516:\tEXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);\n1517:\t\n1518:\tstatic void vfio_device_file_set_kvm(struct file *file, struct file *kvm)\n1519:\t{\n"
} |
| 47/2 | 2026/09/29 15:27 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 66929 output: 28 thoughts: 15 Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind the audience is an expert, and writing in the first person: **Diving into `vfio_group_from_file`** Alright, time to dig into this `vfio_group_from_file` function. I need to refresh my memory on exactly how this part of the VFIO system works. Specifically, I'm going to look at how it handles the discovery and grouping of devices based on the information it reads from a file, presumably a sysfs entry or similar. I'm going to be thinking about potential edge cases, error handling, and how it interacts with the underlying kernel structures. I want to see if any of the usual suspects of VFIO issues might be exposed here. Let's see what we've got. |
| 48/2 | 2026/09/29 15:27 | tool | grepper |
0mArgs:{
"Expression": "struct vfio_group \\*vfio_group_from_file"
}Results: {
"Output": "drivers/vfio/group.c=787=bool vfio_device_has_container(struct vfio_device *device)\n--\ndrivers/vfio/group.c-791-\ndrivers/vfio/group.c:792:struct vfio_group *vfio_group_from_file(struct file *file)\ndrivers/vfio/group.c-793-{\n--\ndrivers/vfio/vfio.h=107=void vfio_df_group_close(struct vfio_device_file *df);\ndrivers/vfio/vfio.h:108:struct vfio_group *vfio_group_from_file(struct file *file);\ndrivers/vfio/vfio.h-109-bool vfio_group_enforced_coherent(struct vfio_group *group);\n--\ndrivers/vfio/vfio.h=154=static inline void vfio_df_group_close(struct vfio_device_file *df)\n--\ndrivers/vfio/vfio.h-157-\ndrivers/vfio/vfio.h:158:static inline struct vfio_group *vfio_group_from_file(struct file *file)\ndrivers/vfio/vfio.h-159-{\n"
} |
| 49/2 | 2026/09/29 15:27 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 67468 output: 36 thoughts: 21 Thoughts: Okay, let's dive into this. I'm going to pull up `drivers/vfio/group.c` and zero in on line 790. I'm expecting this to be a crucial point in the device group management within VFIO. Likely dealing with resource allocation, permission checks, or perhaps even the core mechanism for attaching or detaching devices. Based on my experience with VFIO's internals, this is the area where things get really interesting, and potentially quite complex. I'll be looking for the specific context – which function we're in, what data structures are being manipulated, and what the logic flow is. I want to understand exactly what that line, and the surrounding code, is *doing* in the grand scheme of the VFIO group management process. Let's see what we've got. |
| 50/2 | 2026/09/29 15:28 | tool | read-file |
0mArgs:{
"File": "drivers/vfio/group.c",
"FirstLine": 790,
"LineCount": 30
}Results: {
"Contents": " 790:\t}\n 791:\t\n 792:\tstruct vfio_group *vfio_group_from_file(struct file *file)\n 793:\t{\n 794:\t\tstruct vfio_group *group = file-\u003eprivate_data;\n 795:\t\n 796:\t\tif (file-\u003ef_op != \u0026vfio_group_fops)\n 797:\t\t\treturn NULL;\n 798:\t\treturn group;\n 799:\t}\n 800:\t\n 801:\t/**\n 802:\t * vfio_file_iommu_group - Return the struct iommu_group for the vfio group file\n 803:\t * @file: VFIO group file\n 804:\t *\n 805:\t * The returned iommu_group is valid as long as a ref is held on the file. This\n 806:\t * returns a reference on the group. This function is deprecated, only the SPAPR\n 807:\t * path in kvm should call it.\n 808:\t */\n 809:\tstruct iommu_group *vfio_file_iommu_group(struct file *file)\n 810:\t{\n 811:\t\tstruct vfio_group *group = vfio_group_from_file(file);\n 812:\t\tstruct iommu_group *iommu_group = NULL;\n 813:\t\n 814:\t\tif (!IS_ENABLED(CONFIG_SPAPR_TCE_IOMMU))\n 815:\t\t\treturn NULL;\n 816:\t\n 817:\t\tif (!group)\n 818:\t\t\treturn NULL;\n 819:\t\n"
} |
| 51/2 | 2026/09/29 15:28 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 68154 output: 28 thoughts: 27 Thoughts: Okay, here's my attempt at summarizing the thought process, as if it were my own, assuming the user is an expert. **Diving into `vfio_device_from_file`** Alright, let's see, the next logical step is to understand this `vfio_device_from_file` function. I need to get a clear picture of what it's doing, right? Specifically, I'm thinking about how it constructs the VFIO device from a file, so I need to track down its definition. Where is this thing defined? Let's check the source code... I need to understand its control flow. Is it doing any resource management that I need to be aware of? Are there any potential gotchas or edge cases I should consider? Are we talking about a simple file read or some more complex device initialization sequence? I need to analyze its internal workings thoroughly to have a solid grasp on how it fits into the overall VFIO device management scheme. Knowing this should really help me solve the issue. |
| 52/2 | 2026/09/29 15:28 | tool | grepper |
0mArgs:{
"Expression": "struct vfio_device \\*vfio_device_from_file"
}Results: {
"Output": "drivers/vfio/vfio_main.c=1457=const struct file_operations vfio_device_fops = {\n--\ndrivers/vfio/vfio_main.c-1470-\ndrivers/vfio/vfio_main.c:1471:static struct vfio_device *vfio_device_from_file(struct file *file)\ndrivers/vfio/vfio_main.c-1472-{\n"
} |
| 53/2 | 2026/09/29 15:28 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 68546 output: 40 thoughts: 29 Thoughts: Okay, let's dive into this. Here's my take on those lines of code: **Analyzing `drivers/vfio/vfio_main.c` - Lines 1465-1485** Right, let's focus in on lines 1465 to 1485 within `vfio_main.c`. My initial assumption is that we're likely dealing with something relatively fundamental within the VFIO core, given the file and the line range. This tells me it's probably not a device-specific quirk, but something more integral to the framework's operation, most likely related to initialization, resource management, or possibly the core I/O path. My experience with VFIO suggests we're probably somewhere in the region of the initialization or event handling flow for a VFIO group, or even the control of the IOMMU. The first thing I'll be looking for is the context. What function are we inside? What data structures are in scope? Are there any obvious locks being held, or released? If it's resource management, I'll be watching for calls to `kmem_cache_alloc` or similar memory management functions, as well as functions relating to IOMMU mappings. If it's event handling, I'll be looking for the typical signal handling or interrupt related code. I'm also ready to see some critical sections in action given this is VFIO. I know from past debugging sessions that proper locking is essential here, or else we're going to see a deadlock. Any potential race conditions are immediately of interest. Given this specific line range, I expect to see some pretty tight logic - potentially dealing with low-level details. |
| 54/2 | 2026/09/29 15:28 | tool | read-file |
0mArgs:{
"File": "drivers/vfio/vfio_main.c",
"FirstLine": 1465,
"LineCount": 20
}Results: {
"Contents": "1465:\t\t.mmap\t\t= vfio_device_fops_mmap,\n1466:\t#ifdef CONFIG_PROC_FS\n1467:\t\t.show_fdinfo\t= vfio_device_show_fdinfo,\n1468:\t#endif\n1469:\t};\n1470:\t\n1471:\tstatic struct vfio_device *vfio_device_from_file(struct file *file)\n1472:\t{\n1473:\t\tstruct vfio_device_file *df = file-\u003eprivate_data;\n1474:\t\n1475:\t\tif (file-\u003ef_op != \u0026vfio_device_fops)\n1476:\t\t\treturn NULL;\n1477:\t\treturn df-\u003edevice;\n1478:\t}\n1479:\t\n1480:\t/**\n1481:\t * vfio_file_is_valid - True if the file is valid vfio file\n1482:\t * @file: VFIO group file or VFIO device file\n1483:\t */\n1484:\tbool vfio_file_is_valid(struct file *file)\n"
} |
| 55/2 | 2026/09/29 15:28 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 69286 output: 25 thoughts: 66 Thoughts: Here's my summary, as though I'm thinking through this process: **Diving into the SEV Encrypted State Management in KVM/x86** Okay, I'm digging into the KVM/x86 code related to Secure Encrypted Virtualization (SEV). Specifically, I'm looking at `arch/x86/kvm/svm/sev.c`. My immediate focus is on the functions `sev_vm_move_enc_context_from` and `sev_vm_copy_enc_context_from`. I need to understand what's *triggering* these functions. What ioctls are calling these, which means I should go find out! Time to start tracing back the calls. Let's see what the interface is to this. |
| 56/2 | 2026/09/29 15:28 | tool | grepper |
0mArgs:{
"Expression": "sev_vm_move_enc_context_from"
}Results: {
"Output": "arch/x86/kvm/svm/sev.c=2119=static int sev_check_source_vcpus(struct kvm *dst, struct kvm *src)\n--\narch/x86/kvm/svm/sev.c-2141-\narch/x86/kvm/svm/sev.c:2142:int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)\narch/x86/kvm/svm/sev.c-2143-{\n--\narch/x86/kvm/svm/svm.c=5328=struct kvm_x86_ops svm_x86_ops __initdata = {\n--\narch/x86/kvm/svm/svm.c-5452-\t.vm_copy_enc_context_from = sev_vm_copy_enc_context_from,\narch/x86/kvm/svm/svm.c:5453:\t.vm_move_enc_context_from = sev_vm_move_enc_context_from,\narch/x86/kvm/svm/svm.c-5454-\n--\narch/x86/kvm/svm/svm.h=989=int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd);\narch/x86/kvm/svm/svm.h:990:int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd);\narch/x86/kvm/svm/svm.h-991-void sev_guest_memory_reclaimed(struct kvm *kvm);\n"
} |
| 57/2 | 2026/09/29 15:28 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 69983 output: 23 thoughts: 52 Thoughts: Here's my summary, as I see it: **Digging into KVM Encryption Context Management** Okay, so I'm trying to trace the usage of these encryption context functions, specifically `vm_copy_enc_context_from` and `vm_move_enc_context_from`. These are both defined in `svm.c`, which, of course, suggests they're specific to AMD's Secure Virtual Machine (SVM) implementation within KVM. My hunch is that they handle copying or moving the cryptographic context associated with encrypted VMs. I need to understand *where* and *why* this happens. Since I'm working at the architecture-specific level, I figured `arch/x86/kvm/x86.c` would be the logical place to start looking for the calls. I'm expecting to find them used within the x86-specific parts of KVM, probably around VM entry or exit, or maybe during guest memory operations if encryption is enabled. I'll need to use grep or the equivalent to search for those function names, so I can see what code path is using them. This should help me better understand how KVM handles the cryptographic state in those scenarios. |
| 58/2 | 2026/09/29 15:28 | tool | grepper |
0mArgs:{
"Expression": "vm_copy_enc_context_from"
}Results: {
"Output": "arch/x86/include/asm/kvm-x86-ops.h=134=KVM_X86_OP_OPTIONAL(mem_enc_unregister_region)\narch/x86/include/asm/kvm-x86-ops.h:135:KVM_X86_OP_OPTIONAL(vm_copy_enc_context_from)\narch/x86/include/asm/kvm-x86-ops.h-136-KVM_X86_OP_OPTIONAL(vm_move_enc_context_from)\n--\narch/x86/include/asm/kvm_host.h=1507=struct kvm_x86_ops {\n--\narch/x86/include/asm/kvm_host.h-1706-\tint (*mem_enc_unregister_region)(struct kvm *kvm, struct kvm_enc_region *argp);\narch/x86/include/asm/kvm_host.h:1707:\tint (*vm_copy_enc_context_from)(struct kvm *kvm, unsigned int source_fd);\narch/x86/include/asm/kvm_host.h-1708-\tint (*vm_move_enc_context_from)(struct kvm *kvm, unsigned int source_fd);\n--\narch/x86/kvm/svm/sev.c=2844=int sev_mem_enc_unregister_region(struct kvm *kvm,\n--\narch/x86/kvm/svm/sev.c-2868-\narch/x86/kvm/svm/sev.c:2869:int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)\narch/x86/kvm/svm/sev.c-2870-{\n--\narch/x86/kvm/svm/svm.c=5328=struct kvm_x86_ops svm_x86_ops __initdata = {\n--\narch/x86/kvm/svm/svm.c-5451-\narch/x86/kvm/svm/svm.c:5452:\t.vm_copy_enc_context_from = sev_vm_copy_enc_context_from,\narch/x86/kvm/svm/svm.c-5453-\t.vm_move_enc_context_from = sev_vm_move_enc_context_from,\n--\narch/x86/kvm/svm/svm.h=987=int sev_mem_enc_unregister_region(struct kvm *kvm,\narch/x86/kvm/svm/svm.h-988-\t\t\t\t struct kvm_enc_region *range);\narch/x86/kvm/svm/svm.h:989:int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd);\narch/x86/kvm/svm/svm.h-990-int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd);\n--\narch/x86/kvm/x86.c=3944=int kvm_vm_ioctl_enable_cap(struct kvm *kvm,\n--\narch/x86/kvm/x86.c-4084-\t\tr = -EINVAL;\narch/x86/kvm/x86.c:4085:\t\tif (!kvm_x86_ops.vm_copy_enc_context_from)\narch/x86/kvm/x86.c-4086-\t\t\tbreak;\narch/x86/kvm/x86.c-4087-\narch/x86/kvm/x86.c:4088:\t\tr = kvm_x86_call(vm_copy_enc_context_from)(kvm, cap-\u003eargs[0]);\narch/x86/kvm/x86.c-4089-\t\tbreak;\n"
} |
| 59/2 | 2026/09/29 15:28 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 71344 output: 21 thoughts: 2355 Thoughts: **Analyzing KVM VM Context Copying and Potential VFIO Interactions** Okay, so I'm diving into this `KVM_ENABLE_CAP` with `KVM_CAP_VM_COPY_ENC_CONTEXT_FROM` and `KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM` thing. Specifically, `KVM_CAP_VM_COPY_ENC_CONTEXT_FROM` takes a `source_fd` in `cap->args[0]`. The code retrieves the source KVM instance using `file_to_kvm_x86`, which is defined with the help of a `kvm_file_to_kvm_fn` that validates the file is a KVM VM file. Now, `file_to_kvm_x86` is generated and exported, which is good. `kvm_main.c` shows that the `kvm->file` pointer, which represents the file associated with a VM instance, is set during VM creation (`kvm_dev_ioctl_create_vm`) and cleared during VM release (`kvm_vm_release`). The plot thickens with VFIO. `kvm_vfio_file_add` seems to be the entry point for VFIO to interact with the KVM file. It grabs a file descriptor, checks it's a VFIO FD and then calls `kvm_vfio_file_set_kvm` which in turn calls `vfio_group_set_kvm` and `vfio_device_file_set_kvm`. These functions, in turn, are key, as they end up holding a reference to the KVM VM file (`struct file *`). In these two, they call `get_file` on `kvm`, which increments the file's reference count. This leads me to the lifecycle and reference counting. Previously, VFIO held a `struct kvm *` pointer, but now it's holding `struct file *`. `kvm_vfio_file_add` appears to be carefully managing references, using `get_file_active`, `get_file`, and `fput`. But, something seems off. Consider this: the VM's file (`kvm-vm`) is potentially held by `df->kvm` within `vfio_device_file_set_kvm`. It appears there is a circular dependency. When the VM's file is closed, will that `fput` be sufficient? Can that cause a circular reference? If `df->kvm` holds a reference to `kvm_file`, does the VM file also hold a reference to the VFIO device? This could be a circular reference, with one object holding the other, potentially creating a reference cycle. Looking at `kvm_device` (the `kvm-vfio` device), there's a `struct kvm_device *dev`. The `dev->kvm` points to the `struct kvm`, and `dev` is owned by `kvm`. When the `kvm-device` file descriptor is closed, `kvm_vfio_release` is called, and calls `kvm_vfio_file_free`, which in turn, sets `group->kvm` and `df->kvm` to `NULL`, then does `fput` on the `old` value, presumably releasing the reference on the VM's file. The critical question now: What happens if the VM's file descriptor (`kvm-vm`) is closed before the `kvm-device` or before the VFIO file is deleted? If `df->kvm` holds a reference to the `kvm-vm` file, then the file's reference count cannot drop to zero until `df->kvm` is also dropped. Is this intentional, or could this be a potential lifecycle issue or a bug? I need to know the rationale for this change. Looking into the kernel's source code, I see this in `include/linux/kvm_host.h`: "Callers storing the file must take their own reference." That suggests this approach is intentional. It's designed to *not* pin the VM, but VFIO *must* manage its own references to the VM file. I wonder why the switch to using `struct file *`? Maybe to avoid pinning? Now, let's try to search the commit history with `grepper`. |
| 60/2 | 2026/09/29 15:29 | tool | grepper |
0mArgs:{
"Expression": "file_to_kvm_"
}Results: {
"Output": "arch/s390/include/asm/kvm_host_s390.h-29-\narch/s390/include/asm/kvm_host_s390.h:30:#define kvm_file_to_kvm_arch s390\narch/s390/include/asm/kvm_host_s390.h-31-\n--\narch/s390/kvm/s390/pci.c=501=static int kvm_s390_pci_register_kvm(void *opaque, struct file *kvm_file)\n--\narch/s390/kvm/s390/pci.c-509-\narch/s390/kvm/s390/pci.c:510:\tkvm = file_to_kvm_s390(kvm_file);\narch/s390/kvm/s390/pci.c-511-\tif (!kvm)\n--\narch/x86/include/asm/kvm_host.h-46-\narch/x86/include/asm/kvm_host.h:47:#define kvm_file_to_kvm_arch x86\narch/x86/include/asm/kvm_host.h-48-\n--\narch/x86/kvm/Makefile=59=exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/arch/x86/kvm | \\\n--\narch/x86/kvm/Makefile-63-\t\t\t\t-e kvm_write_track_remove_gfn \\\narch/x86/kvm/Makefile:64:\t\t\t\t-e kvm_file_to_kvm_fn\narch/x86/kvm/Makefile-65-\n--\narch/x86/kvm/mmu/page_track.c=242=int kvm_page_track_register_notifier(struct file *file,\n--\narch/x86/kvm/mmu/page_track.c-245-\tstruct kvm_page_track_notifier_head *head;\narch/x86/kvm/mmu/page_track.c:246:\tstruct kvm *kvm = file_to_kvm_x86(file);\narch/x86/kvm/mmu/page_track.c-247-\tint r;\n--\narch/x86/kvm/mmu/page_track.c=273=void kvm_page_track_unregister_notifier(struct file *file,\n--\narch/x86/kvm/mmu/page_track.c-276-\tstruct kvm_page_track_notifier_head *head;\narch/x86/kvm/mmu/page_track.c:277:\tstruct kvm *kvm = file_to_kvm_x86(file);\narch/x86/kvm/mmu/page_track.c-278-\n--\narch/x86/kvm/mmu/page_track.c=346=int kvm_write_track_add_gfn(struct file *file, gfn_t gfn)\narch/x86/kvm/mmu/page_track.c-347-{\narch/x86/kvm/mmu/page_track.c:348:\tstruct kvm *kvm = file_to_kvm_x86(file);\narch/x86/kvm/mmu/page_track.c-349-\tstruct kvm_memory_slot *slot;\n--\narch/x86/kvm/mmu/page_track.c=377=int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn)\narch/x86/kvm/mmu/page_track.c-378-{\narch/x86/kvm/mmu/page_track.c:379:\tstruct kvm *kvm = file_to_kvm_x86(file);\narch/x86/kvm/mmu/page_track.c-380-\tstruct kvm_memory_slot *slot;\n--\narch/x86/kvm/svm/sev.c=2142=int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)\n--\narch/x86/kvm/svm/sev.c-2153-\narch/x86/kvm/svm/sev.c:2154:\tsource_kvm = file_to_kvm_x86(fd_file(f));\narch/x86/kvm/svm/sev.c-2155-\tif (!source_kvm)\n--\narch/x86/kvm/svm/sev.c=2869=int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)\n--\narch/x86/kvm/svm/sev.c-2878-\narch/x86/kvm/svm/sev.c:2879:\tsource_kvm = file_to_kvm_x86(fd_file(f));\narch/x86/kvm/svm/sev.c-2880-\tif (!source_kvm)\n--\ndrivers/s390/crypto/vfio_ap_ops.c=1834=static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,\n--\ndrivers/s390/crypto/vfio_ap_ops.c-1841-\ndrivers/s390/crypto/vfio_ap_ops.c:1842:\tkvm = file_to_kvm_s390(kvm_file);\ndrivers/s390/crypto/vfio_ap_ops.c-1843-\tif (!kvm)\n--\ninclude/linux/kvm_host.h=1089=void kvm_put_kvm(struct kvm *kvm);\n--\ninclude/linux/kvm_host.h-1091-/*\ninclude/linux/kvm_host.h:1092: * Architectures define kvm_file_to_kvm_arch to \u003carch\u003e\ninclude/linux/kvm_host.h-1093- * to get a typed, arch-namespaced helper:\ninclude/linux/kvm_host.h-1094- *\ninclude/linux/kvm_host.h:1095: * struct kvm *file_to_kvm_\u003carch\u003e(struct file *file)\ninclude/linux/kvm_host.h-1096- */\ninclude/linux/kvm_host.h:1097:#ifdef kvm_file_to_kvm_arch\ninclude/linux/kvm_host.h:1098:#define kvm_file_to_kvm_fn CONCATENATE(file_to_kvm_, kvm_file_to_kvm_arch)\ninclude/linux/kvm_host.h:1099:struct kvm *kvm_file_to_kvm_fn(struct file *file);\ninclude/linux/kvm_host.h:1100:#endif /* kvm_file_to_kvm_arch */\ninclude/linux/kvm_host.h-1101-\n--\nvirt/kvm/kvm_main.c=5511=static struct file_operations kvm_vm_fops = {\n--\nvirt/kvm/kvm_main.c-5517-\nvirt/kvm/kvm_main.c:5518:#ifdef kvm_file_to_kvm_arch\nvirt/kvm/kvm_main.c:5519:struct kvm *kvm_file_to_kvm_fn(struct file *file)\nvirt/kvm/kvm_main.c-5520-{\n--\nvirt/kvm/kvm_main.c-5525-}\nvirt/kvm/kvm_main.c:5526:EXPORT_SYMBOL_GPL(kvm_file_to_kvm_fn);\nvirt/kvm/kvm_main.c-5527-#endif\n"
} |
| 61/2 | 2026/09/29 15:29 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 76781 output: 20 thoughts: 1402 Thoughts: **KVM Patch Triage: AMD64 Focus**
Okay, let's break this down from a fuzzing perspective, keeping in mind the target is amd64. My initial assessment is that this patch is primarily a refactoring focused on `struct file` management within KVM, shifting away from direct `kvm_get_kvm`/`kvm_put_kvm` calls for external modules. The aim is better reference counting for the `struct kvm` instances, so that multiple drivers and subsystems can manage the lifetime of a KVM instance more correctly.
First, I see the core changes revolve around these points:
1. **File Association:** The patch adds `kvm->file = file;` in `kvm_dev_ioctl_create_vm` and `WRITE_ONCE(kvm->file, NULL);` in `kvm_vm_release`. This looks like the main entry point to all of this. This establishes an explicit link between the `struct kvm` instance and its associated `struct file`. This must be reachable!
2. **Abstraction:** The patch introduces `file_to_kvm_x86(file)` to replace the previous macro `file_is_kvm(file)`. This is a *crucial* change as this new function is how the patch retrieves the KVM struct from the file struct. This is a very reachable function, as this is how all the external consumers of KVM get a pointer to the KVM struct.
3. **Export Changes:** The `kvm_get_kvm` and `kvm_put_kvm` functions are no longer exported. This is a significant change, restricting direct KVM instance manipulation. External modules now work on the `struct file` instead. This is likely due to the previous two changes and their aims.
4. **VFIO Integration:** `kvm_vfio_file_add` in `virt/kvm/vfio.c` has been changed to `get_file_active(&dev->kvm->file)` and pass `kvf->file` to VFIO. The VFIO module is now holding a reference to the `struct file` that represents the KVM instance.
Now, applying the triage principles:
* **Reachability is Key:** I need to determine if the modified code *can* be executed in a standard fuzzed environment. Can it be hit in QEMU? GCE? Can the changes be triggered through standard ioctls?
* **No Free Passes:** I can't blindly trust claims of "no functional change" or refactoring. Any reachable code modification demands fuzzing attention, especially if it relates to a core KVM structure like the `file`.
* **Assertions Matter:** New or modified assertions are *definitely* fuzzing targets if reachable.
Let's zoom in on the amd64-relevant changes:
1. **`virt/kvm/kvm_main.c` Changes:**
* `kvm_dev_ioctl_create_vm` and `kvm_vm_release` are *definitely* reachable via standard KVM setup. I can use those to set up our test case.
* `file_to_kvm_x86()` is now the *primary* path to get the `struct kvm` from a `struct file`. This is critical. **This function *must* be fuzzed.**
2. **`virt/kvm/vfio.c`:**
* `kvm_vfio_file_add` is *very* interesting. This is triggered by `KVM_SET_DEVICE_ATTR` on a `kvm-vfio` device. Syzkaller can open a VFIO device, right? Can it open `/dev/vfio/vfio`? Let me check `drivers/vfio/vfio_main.c`....Okay, syzkaller *can* open `/dev/vfio/vfio`! That means I can reach the `get_file_active(&dev->kvm->file)` call, and thus `file_to_kvm_x86()` is reachable.
* `kvm_vfio_file_set_kvm(kvf->file, kvm_file)` is also important. What file is this passing? *Any* VFIO file descriptor. This likely creates a new attack surface, since it is now possible for a VFIO file to have incorrect references.
3. **AMD64-Specific Considerations**: The presence of `file_to_kvm_x86()` shows AMD64-specific code and means that all consumers of K
|
| 62/2 | 2026/09/29 15:30 | tool | grepper |
0mError:no matches Args: {
"Expression": "\"/dev/vfio\""
}Results: {
"error": "no matches"
} |
| 63/2 | 2026/09/29 15:30 | llm | patch-evaluator-compressor |
1mModel:gemini-3.8-flash Args: null Results: null Reply: ### 1. Approaches Tried and Results
- **Patch Diff Inspection**:
- Target architecture: `amd64` (`x86_64`).
- Commit modifies how references between KVM and external subsystems (especially VFIO and arch-specific modules like x86 page track, s390 zPCI/vfio-ap, and SVM SEV) are managed.
- Replaces direct `struct kvm *` pointer sharing and `kvm_get_kvm()` / `kvm_put_kvm()` / `kvm_get_kvm_safe()` in external modules with `struct file *` reference counting via `get_file()`, `fput()`, and `get_file_active()`.
- Added 1-way backpointer `kvm->file` (uncounted, zeroed at `kvm_vm_release()` via `WRITE_ONCE(kvm->file, NULL)`).
- Introduced macro `kvm_file_to_kvm_arch` generating `file_to_kvm_<arch>()` (e.g. `file_to_kvm_x86()`, `file_to_kvm_s390()`), calling `kvm_file_to_kvm_fn()`, which validates `file->f_op == &kvm_vm_fops` and returns `file->private_data`.
- Converted `kvm_get_kvm`, `kvm_get_kvm_safe`, `kvm_put_kvm` from `EXPORT_SYMBOL_GPL` to `EXPORT_SYMBOL_FOR_KVM_INTERNAL`.
- Replaced `file_is_kvm()` in `arch/x86/kvm/svm/sev.c` with `file_to_kvm_x86()`.
- Updated VFIO subsystem (`drivers/vfio/`): `vfio_group.kvm`, `vfio_device_file.kvm`, and `vfio_device.kvm` now hold `struct file *` instead of `struct kvm *`.
- Updated `virt/kvm/vfio.c`: `kvm_vfio_file_add()` obtains `kvm_file = get_file_active(&dev->kvm->file)` and passes it to `kvm_vfio_file_set_kvm(kvf->file, kvm_file)`.
- **Caller and Reachability Analysis**:
- `kvm_page_track_register_notifier` / `kvm_page_track_unregister_notifier` / `kvm_write_track_add_gfn` / `kvm_write_track_remove_gfn`:
- Callers found in `drivers/gpu/drm/i915/gvt/kvmgt.c` (`intel_vgpu_open_device`, `intel_vgpu_close_device`, `intel_gvt_page_track_add`, `intel_gvt_page_track_remove`).
- Takes `vgpu->vfio_device.kvm`, which is now `struct file *`.
- `virt/kvm/vfio.c`:
- Implements KVM device type `KVM_DEV_TYPE_VFIO` created via `KVM_CREATE_DEVICE` on VM fd.
- Interacts directly with VFIO groups and device cdev files via `KVM_SET_DEVICE_ATTR` (`KVM_DEV_VFIO_FILE_ADD` / `KVM_DEV_VFIO_FILE_DEL`).
- Calls `get_file_active(&dev->kvm->file)` and `vfio_file_set_kvm()`.
- `drivers/vfio/vfio_main.c`:
- `vfio_file_set_kvm()` is exported GPL; sets KVM file on `vfio_group` or `vfio_device_file`.
- `vfio_device_get_kvm_safe()` and `vfio_device_put_kvm()` take/release references via `get_file()` and `fput()`.
- `arch/x86/kvm/svm/sev.c`:
- `sev_vm_move_enc_context_from` and `sev_vm_copy_enc_context_from` invoke `file_to_kvm_x86(fd_file(f))`.
### 2. Current Theories and Hypotheses
- **Reachability and Fuzzability Evaluation**:
- The patch touches core x86 KVM (`arch/x86/kvm/mmu/page_track.c`, `arch/x86/kvm/svm/sev.c`), generic KVM core (`virt/kvm/kvm_main.c`, `virt/kvm/vfio.c`), and core VFIO driver framework (`drivers/vfio/group.c`, `drivers/vfio/vfio_main.c`).
- These code paths are executable on `amd64` in standard QEMU/KVM virtual environments.
- Specifically reachable via standard user syscalls:
- `ioctl(kvm_fd, KVM_CREATE_VM)` -> initializes `kvm->file`.
- `ioctl(vm_fd, KVM_CREATE_DEVICE, {type: KVM_DEV_TYPE_VFIO})`.
- `ioctl(dev_fd, KVM_SET_DEVICE_ATTR, {group: KVM_DEV_VFIO_FILE, attr: KVM_DEV_VFIO_FILE_ADD/DEL, addr: &vfio_fd})`.
- `ioctl(vm_fd, KVM_MEMORY_ENCRYPT_OP, ...)` (SEV copy/move enc context).
- The changes directly affect object lifetime management, reference counting (`get_file_active`, `get_file`, `fput` vs `kvm_get_kvm`, `kvm_put_kvm`), concurrent release handling, and cross-subsystem file conversions.
- Under Section 1 & Section 3 of instructions: Refactoring reachable lifetime tracking, synchronization, and driver-KVM interfaces warrants fuzzing (`WorthFuzzing=true`).
- **Potential Issues / Nuances to Keep in Mind**:
- `kvm_vfio_file_add` uses `get_file_active(&dev->kvm->file)`. If VM is shutting down or file refcount drops to 0, `get_file_active` returns NULL (-ENOENT).
- Race window around `WRITE_ONCE(kvm->file, NULL)` in `kvm_vm_release()` vs concurrent access.
- Proper target symbols must focus on the x86 and core entrypoints rather than generic file helpers.
### 3. Critical Code Snippets, Symbols, and Configs
- **Key Functions Modified (x86 & Core)**:
- `kvm_vfio_file_add` (`virt/kvm/vfio.c`)
- `kvm_vfio_file_set_kvm` (`virt/kvm/vfio.c`)
- `vfio_file_set_kvm` (`drivers/vfio/vfio_main.c`)
- `vfio_device_get_kvm_safe` (`drivers/vfio/vfio_main.c`)
- `vfio_device_put_kvm` (`drivers/vfio/vfio_main.c`)
- `vfio_group_set_kvm` (`drivers/vfio/group.c`)
- `kvm_file_to_kvm_fn` (`virt/kvm/kvm_main.c`)
- `kvm_page_track_register_notifier` (`arch/x86/kvm/mmu/page_track.c`)
- `kvm_page_track_unregister_notifier` (`arch/x86/kvm/mmu/page_track.c`)
- `kvm_write_track_add_gfn` (`arch/x86/kvm/mmu/page_track.c`)
- `kvm_write_track_remove_gfn` (`arch/x86/kvm/mmu/page_track.c`)
- `sev_vm_move_enc_context_from` (`arch/x86/kvm/svm/sev.c`)
- `sev_vm_copy_enc_context_from` (`arch/x86/kvm/svm/sev.c`)
- **Relevant Data Structures**:
```c
struct kvm {
...
struct file *file;
...
};
struct vfio_device {
...
struct file *kvm;
...
};
struct vfio_group {
...
struct file *kvm;
...
};
```
- **Kconfig Options**:
- `KVM`
- `VFIO`
- `KVM_VFIO`
- `KVM_AMD` (for SEV functions)
### 4. Watch Out / Anti-loop Notes
- Avoid repeated generic grepping for `\bkvm\b` or ubiquitous symbols; all modified files and their callers have already been identified.
- Avoid listing generic VFS helpers like `get_file` or `fput` in `FocusSymbols`.
- S390 changes (`arch/s390/*`, `drivers/s390/*`) are not targetable on `amd64` and should be excluded from `FocusSymbols`.Tokens: input: 56918 output: 2191 thoughts: 0 |
| 64/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 30412 output: 22 thoughts: 0 |
| 65/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "VFIO_GET_API_VERSION"
}Results: {
"Output": "Documentation/driver-api/vfio.rst=167=group and can access them as follows::\n--\nDocumentation/driver-api/vfio.rst-178-\nDocumentation/driver-api/vfio.rst:179:\tif (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)\nDocumentation/driver-api/vfio.rst-180-\t\t/* Unknown API version */\n--\narch/um/drivers/vfio_user.c=23=int uml_vfio_user_open_container(void)\n--\narch/um/drivers/vfio_user.c-30-\narch/um/drivers/vfio_user.c:31:\tr = ioctl(fd, VFIO_GET_API_VERSION);\narch/um/drivers/vfio_user.c-32-\tif (r != VFIO_API_VERSION) {\n--\ndrivers/iommu/iommufd/vfio_compat.c=513=int iommufd_vfio_ioctl(struct iommufd_ctx *ictx, unsigned int cmd,\n--\ndrivers/iommu/iommufd/vfio_compat.c-518-\tswitch (cmd) {\ndrivers/iommu/iommufd/vfio_compat.c:519:\tcase VFIO_GET_API_VERSION:\ndrivers/iommu/iommufd/vfio_compat.c-520-\t\treturn VFIO_API_VERSION;\n--\ndrivers/vfio/container.c=327=static long vfio_fops_unl_ioctl(struct file *filep,\n--\ndrivers/vfio/container.c-338-\tswitch (cmd) {\ndrivers/vfio/container.c:339:\tcase VFIO_GET_API_VERSION:\ndrivers/vfio/container.c-340-\t\tret = VFIO_API_VERSION;\n--\ninclude/uapi/linux/vfio.h=86=struct vfio_info_cap_header {\n--\ninclude/uapi/linux/vfio.h-103-/**\ninclude/uapi/linux/vfio.h:104: * VFIO_GET_API_VERSION - _IO(VFIO_TYPE, VFIO_BASE + 0)\ninclude/uapi/linux/vfio.h-105- *\n--\ninclude/uapi/linux/vfio.h-111- */\ninclude/uapi/linux/vfio.h:112:#define VFIO_GET_API_VERSION\t\t_IO(VFIO_TYPE, VFIO_BASE + 0)\ninclude/uapi/linux/vfio.h-113-\n--\ntools/testing/selftests/iommu/iommufd.c=2428=TEST_F(iommufd, simple_ioctls)\ntools/testing/selftests/iommu/iommufd.c-2429-{\ntools/testing/selftests/iommu/iommufd.c:2430:\tASSERT_EQ(VFIO_API_VERSION, ioctl(self-\u003efd, VFIO_GET_API_VERSION));\ntools/testing/selftests/iommu/iommufd.c-2431-\tASSERT_EQ(1, ioctl(self-\u003efd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU));\n--\ntools/testing/selftests/vfio/lib/iommu.c=418=struct iommu *iommu_init(const char *iommu_mode)\n--\ntools/testing/selftests/vfio/lib/iommu.c-434-\ntools/testing/selftests/vfio/lib/iommu.c:435:\t\tversion = ioctl(iommu-\u003econtainer_fd, VFIO_GET_API_VERSION);\ntools/testing/selftests/vfio/lib/iommu.c-436-\t\tVFIO_ASSERT_EQ(version, VFIO_API_VERSION, \"Unsupported version: %d\\n\", version);\n"
} |
| 66/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 31458 output: 21 thoughts: 0 |
| 67/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_KVM_VFIO"
}Results: {
"Output": "virt/kvm/Makefile.kvm=8=kvm-y := $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/binary_stats.o\nvirt/kvm/Makefile.kvm:9:kvm-$(CONFIG_KVM_VFIO) += $(KVM)/vfio.o\nvirt/kvm/Makefile.kvm-10-kvm-$(CONFIG_KVM_MMIO) += $(KVM)/coalesced_mmio.o\n--\nvirt/kvm/vfio.h-4-\nvirt/kvm/vfio.h:5:#ifdef CONFIG_KVM_VFIO\nvirt/kvm/vfio.h-6-int kvm_vfio_ops_init(void);\n"
} |
| 68/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 31671 output: 18 thoughts: 0 |
| 69/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_VFIO"
}Results: {
"Output": "Documentation/driver-api/vfio.rst=273=in a VFIO group.\nDocumentation/driver-api/vfio.rst-274-\nDocumentation/driver-api/vfio.rst:275:With CONFIG_VFIO_DEVICE_CDEV=y the user can now acquire a device fd\nDocumentation/driver-api/vfio.rst-276-by directly opening a character device /dev/vfio/devices/vfioX where\n--\nDocumentation/driver-api/vfio.rst=403=Note that the VFIO container case includes IOMMUFD provided VFIO compatibility\nDocumentation/driver-api/vfio.rst:404:interfaces when either CONFIG_VFIO_CONTAINER or CONFIG_IOMMUFD_VFIO_CONTAINER is\nDocumentation/driver-api/vfio.rst-405-enabled.\n--\nDocumentation/driver-api/vfio.rst=410=Kconfig Support Matrix\n--\nDocumentation/driver-api/vfio.rst-412-\nDocumentation/driver-api/vfio.rst:413:The visibility of CONFIG_VFIO_NOIOMMU depends on the combination of\nDocumentation/driver-api/vfio.rst:414:CONFIG_VFIO_GROUP, CONFIG_VFIO_DEVICE_CDEV, and whether a container backend\nDocumentation/driver-api/vfio.rst:415:(CONFIG_VFIO_CONTAINER or CONFIG_IOMMUFD_VFIO_CONTAINER) is configured. The\nDocumentation/driver-api/vfio.rst-416-Kconfig dependencies enforce the following constraints:\n--\nDocumentation/driver-api/vfio.rst=424=The resulting support matrix:\n--\nDocumentation/driver-api/vfio.rst-441-\nDocumentation/driver-api/vfio.rst:442:Container = CONFIG_VFIO_CONTAINER or CONFIG_IOMMUFD_VFIO_CONTAINER (either\nDocumentation/driver-api/vfio.rst-443-suffices). Case 4 is intentionally blocked: allowing NOIOMMU with GROUP\nDocumentation/driver-api/vfio.rst=444=enabled but no container would create unusable group nodes. Users who want\nDocumentation/driver-api/vfio.rst:445:cdev-only noiommu should set CONFIG_VFIO_GROUP=n (case 5).\nDocumentation/driver-api/vfio.rst-446-\nDocumentation/driver-api/vfio.rst-447-.. [#cdev] The cdev noiommu path requires CONFIG_GENERIC_ATOMIC64=n. When\nDocumentation/driver-api/vfio.rst:448: CONFIG_VFIO_GROUP=y, CONFIG_VFIO_DEVICE_CDEV=y, and\nDocumentation/driver-api/vfio.rst:449: CONFIG_GENERIC_ATOMIC64=y, CONFIG_VFIO_NOIOMMU remains selectable for the\nDocumentation/driver-api/vfio.rst-450- group path, but no noiommu device cdev is registered. Cdev-only noiommu is\n--\narch/arm64/configs/defconfig=1411=CONFIG_DMABUF_HEAPS_CMA=m\narch/arm64/configs/defconfig:1412:CONFIG_VFIO=y\narch/arm64/configs/defconfig:1413:CONFIG_VFIO_PCI=y\narch/arm64/configs/defconfig-1414-CONFIG_VIRTIO_PCI=y\n--\narch/loongarch/configs/loongson32_defconfig=901=CONFIG_UIO_PCI_GENERIC=m\narch/loongarch/configs/loongson32_defconfig:902:CONFIG_VFIO=m\narch/loongarch/configs/loongson32_defconfig:903:CONFIG_VFIO_PCI=m\narch/loongarch/configs/loongson32_defconfig-904-CONFIG_VIRTIO_PCI=y\n--\narch/loongarch/configs/loongson64_defconfig=930=CONFIG_UIO_PCI_GENERIC=m\narch/loongarch/configs/loongson64_defconfig:931:CONFIG_VFIO=m\narch/loongarch/configs/loongson64_defconfig:932:CONFIG_VFIO_PCI=m\narch/loongarch/configs/loongson64_defconfig-933-CONFIG_VIRTIO_PCI=y\n--\narch/s390/configs/debug_defconfig=58=CONFIG_CHSC_SCH=y\narch/s390/configs/debug_defconfig:59:CONFIG_VFIO_CCW=m\narch/s390/configs/debug_defconfig:60:CONFIG_VFIO_AP=m\narch/s390/configs/debug_defconfig:61:CONFIG_VFIO_DEVICE_CDEV=y\narch/s390/configs/debug_defconfig-62-CONFIG_IOMMUFD_DRIVER=y\n--\narch/s390/configs/debug_defconfig=635=CONFIG_MLX5_INFINIBAND=m\narch/s390/configs/debug_defconfig:636:CONFIG_VFIO=m\narch/s390/configs/debug_defconfig:637:CONFIG_VFIO_PCI=m\narch/s390/configs/debug_defconfig-638-CONFIG_MLX5_VFIO_PCI=m\n--\narch/s390/configs/defconfig=56=CONFIG_CHSC_SCH=y\narch/s390/configs/defconfig:57:CONFIG_VFIO_CCW=m\narch/s390/configs/defconfig:58:CONFIG_VFIO_AP=m\narch/s390/configs/defconfig:59:CONFIG_VFIO_DEVICE_CDEV=y\narch/s390/configs/defconfig-60-CONFIG_IOMMUFD_DRIVER=y\n--\narch/s390/configs/defconfig=625=CONFIG_MLX5_INFINIBAND=m\narch/s390/configs/defconfig:626:CONFIG_VFIO=m\narch/s390/configs/defconfig:627:CONFIG_VFIO_PCI=m\narch/s390/configs/defconfig-628-CONFIG_MLX5_VFIO_PCI=m\n--\narch/s390/kvm/s390/Makefile=11=kvm-y += $(gmap-y)\narch/s390/kvm/s390/Makefile-12-\narch/s390/kvm/s390/Makefile:13:kvm-$(CONFIG_VFIO_PCI_ZDEV_KVM) += pci.o\narch/s390/kvm/s390/Makefile-14-obj-$(CONFIG_KVM) += kvm.o\n--\narch/s390/kvm/s390/interrupt.c=3661=static void gib_alert_irq_handler(struct airq_struct *airq,\n--\narch/s390/kvm/s390/interrupt.c-3668-\tif ((info-\u003eforward || info-\u003eerror) \u0026\u0026\narch/s390/kvm/s390/interrupt.c:3669:\t IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM)) {\narch/s390/kvm/s390/interrupt.c-3670-\t\taen_process_gait(info-\u003eisc);\n--\narch/s390/kvm/s390/pci.h=48=static inline struct kvm *kvm_s390_pci_si_to_kvm(struct zpci_aift *aift,\n--\narch/s390/kvm/s390/pci.h-50-{\narch/s390/kvm/s390/pci.h:51:\tif (!IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM) || !aift-\u003ekzdev ||\narch/s390/kvm/s390/pci.h-52-\t !aift-\u003ekzdev[si])\n--\narch/s390/kvm/s390/pci.h=68=static inline bool kvm_s390_pci_interp_allowed(void)\n--\narch/s390/kvm/s390/pci.h-82-\tdefault:\narch/s390/kvm/s390/pci.h:83:\t\treturn (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM) \u0026\u0026\narch/s390/kvm/s390/pci.h-84-\t\t\tsclp.has_zpci_lsi \u0026\u0026 sclp.has_aeni \u0026\u0026 sclp.has_aisi \u0026\u0026\n--\narch/s390/kvm/s390/priv.c=541=static int handle_io_inst(struct kvm_vcpu *vcpu)\n--\narch/s390/kvm/s390/priv.c-569-\narch/s390/kvm/s390/priv.c:570:#if IS_ENABLED(CONFIG_VFIO_AP)\narch/s390/kvm/s390/priv.c-571-bool kvm_s390_is_gpa_in_memslot(struct kvm *kvm, gpa_t gpa)\n--\narch/s390/kvm/s390/s390.c=496=static int __init __kvm_s390_init(void)\n--\narch/s390/kvm/s390/s390.c-520-\narch/s390/kvm/s390/s390.c:521:\tif (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM)) {\narch/s390/kvm/s390/s390.c-522-\t\trc = kvm_s390_pci_init();\n--\narch/s390/kvm/s390/s390.c-538-err_gib:\narch/s390/kvm/s390/s390.c:539:\tif (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM))\narch/s390/kvm/s390/s390.c-540-\t\tkvm_s390_pci_exit();\n--\narch/s390/kvm/s390/s390.c=550=static void __kvm_s390_exit(void)\n--\narch/s390/kvm/s390/s390.c-555-\tkvm_s390_gib_destroy();\narch/s390/kvm/s390/s390.c:556:\tif (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM))\narch/s390/kvm/s390/s390.c-557-\t\tkvm_s390_pci_exit();\n--\narch/s390/kvm/s390/s390.c=2900=int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)\n--\narch/s390/kvm/s390/s390.c-3063-\t\tr = -EINVAL;\narch/s390/kvm/s390/s390.c:3064:\t\tif (!IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM))\narch/s390/kvm/s390/s390.c-3065-\t\t\tbreak;\n--\narch/s390/kvm/s390/s390.c=3232=void kvm_arch_free_vm(struct kvm *kvm)\narch/s390/kvm/s390/s390.c-3233-{\narch/s390/kvm/s390/s390.c:3234:\tif (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM))\narch/s390/kvm/s390/s390.c-3235-\t\tkvm_s390_pci_clear_list(kvm);\n--\narch/s390/kvm/s390/s390.c=3240=int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)\n--\narch/s390/kvm/s390/s390.c-3316-\narch/s390/kvm/s390/s390.c:3317:\tif (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM)) {\narch/s390/kvm/s390/s390.c-3318-\t\tmutex_lock(\u0026kvm-\u003elock);\n--\ndrivers/Makefile=96=obj-$(CONFIG_UIO)\t\t+= uio/\ndrivers/Makefile:97:obj-$(CONFIG_VFIO)\t\t+= vfio/\ndrivers/Makefile-98-obj-y\t\t\t\t+= cdrom/\n--\ndrivers/iommu/iommufd/pages.c=1463=sym_vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,\n--\ndrivers/iommu/iommufd/pages.c-1472-\ndrivers/iommu/iommufd/pages.c:1473:\tif (!IS_ENABLED(CONFIG_VFIO_PCI_DMABUF))\ndrivers/iommu/iommufd/pages.c-1474-\t\treturn -EOPNOTSUPP;\n--\ndrivers/iommu/iommufd/vfio_compat.c=279=static int iommufd_vfio_check_extension(struct iommufd_ctx *ictx,\n--\ndrivers/iommu/iommufd/vfio_compat.c-288-\tcase VFIO_NOIOMMU_IOMMU:\ndrivers/iommu/iommufd/vfio_compat.c:289:\t\treturn IS_ENABLED(CONFIG_VFIO_NOIOMMU);\ndrivers/iommu/iommufd/vfio_compat.c-290-\n--\ndrivers/iommu/iommufd/vfio_compat.c=310=static int iommufd_vfio_set_iommu(struct iommufd_ctx *ictx, unsigned long type)\n--\ndrivers/iommu/iommufd/vfio_compat.c-320-\t */\ndrivers/iommu/iommufd/vfio_compat.c:321:\tif (IS_ENABLED(CONFIG_VFIO_NOIOMMU) \u0026\u0026 type == VFIO_NOIOMMU_IOMMU \u0026\u0026\ndrivers/iommu/iommufd/vfio_compat.c-322-\t no_iommu_mode) {\n--\ndrivers/s390/cio/Makefile=25=vfio_ccw-objs += vfio_ccw_drv.o vfio_ccw_cp.o vfio_ccw_ops.o vfio_ccw_fsm.o \\\ndrivers/s390/cio/Makefile-26-\tvfio_ccw_async.o vfio_ccw_trace.o vfio_ccw_chp.o\ndrivers/s390/cio/Makefile:27:obj-$(CONFIG_VFIO_CCW) += vfio_ccw.o\ndrivers/s390/cio/Makefile-28-\n--\ndrivers/s390/crypto/Makefile=37=vfio_ap-objs := vfio_ap_drv.o vfio_ap_ops.o\ndrivers/s390/crypto/Makefile:38:obj-$(CONFIG_VFIO_AP) += vfio_ap.o\n--\ndrivers/vfio/Makefile-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/vfio/Makefile:2:obj-$(CONFIG_VFIO) += vfio.o\ndrivers/vfio/Makefile-3-\ndrivers/vfio/Makefile=4=vfio-y += vfio_main.o\ndrivers/vfio/Makefile:5:vfio-$(CONFIG_VFIO_DEVICE_CDEV) += device_cdev.o\ndrivers/vfio/Makefile:6:vfio-$(CONFIG_VFIO_GROUP) += group.o\ndrivers/vfio/Makefile-7-vfio-$(CONFIG_IOMMUFD) += iommufd.o\ndrivers/vfio/Makefile:8:vfio-$(CONFIG_VFIO_CONTAINER) += container.o\ndrivers/vfio/Makefile:9:vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o\ndrivers/vfio/Makefile:10:vfio-$(CONFIG_VFIO_DEBUGFS) += debugfs.o\ndrivers/vfio/Makefile-11-\ndrivers/vfio/Makefile:12:obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o\ndrivers/vfio/Makefile:13:obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o\ndrivers/vfio/Makefile:14:obj-$(CONFIG_VFIO_PCI_CORE) += pci/\ndrivers/vfio/Makefile:15:obj-$(CONFIG_VFIO_PLATFORM_BASE) += platform/\ndrivers/vfio/Makefile:16:obj-$(CONFIG_VFIO_MDEV) += mdev/\ndrivers/vfio/Makefile:17:obj-$(CONFIG_VFIO_FSL_MC) += fsl-mc/\ndrivers/vfio/Makefile:18:obj-$(CONFIG_VFIO_CDX) += cdx/\n--\ndrivers/vfio/cdx/Makefile-5-\ndrivers/vfio/cdx/Makefile:6:obj-$(CONFIG_VFIO_CDX) += vfio-cdx.o\ndrivers/vfio/cdx/Makefile-7-\n--\ndrivers/vfio/container.c=80=static bool vfio_iommu_driver_allowed(struct vfio_container *container,\n--\ndrivers/vfio/container.c-82-{\ndrivers/vfio/container.c:83:\tif (!IS_ENABLED(CONFIG_VFIO_NOIOMMU))\ndrivers/vfio/container.c-84-\t\treturn true;\n--\ndrivers/vfio/container.c=573=int __init vfio_container_init(void)\n--\ndrivers/vfio/container.c-585-\ndrivers/vfio/container.c:586:\tif (IS_ENABLED(CONFIG_VFIO_NOIOMMU)) {\ndrivers/vfio/container.c-587-\t\tret = vfio_register_iommu_driver(\u0026vfio_noiommu_ops);\n--\ndrivers/vfio/container.c=598=void vfio_container_cleanup(void)\ndrivers/vfio/container.c-599-{\ndrivers/vfio/container.c:600:\tif (IS_ENABLED(CONFIG_VFIO_NOIOMMU))\ndrivers/vfio/container.c-601-\t\tvfio_unregister_iommu_driver(\u0026vfio_noiommu_ops);\n--\ndrivers/vfio/fsl-mc/Makefile=3=vfio-fsl-mc-y := vfio_fsl_mc.o vfio_fsl_mc_intr.o\ndrivers/vfio/fsl-mc/Makefile:4:obj-$(CONFIG_VFIO_FSL_MC) += vfio-fsl-mc.o\n--\ndrivers/vfio/group.c=107=static int vfio_group_ioctl_set_container(struct vfio_group *group,\n--\ndrivers/vfio/group.c-139-\tif (!IS_ERR(iommufd)) {\ndrivers/vfio/group.c:140:\t\tif (IS_ENABLED(CONFIG_VFIO_NOIOMMU) \u0026\u0026\ndrivers/vfio/group.c-141-\t\t group-\u003etype == VFIO_NO_IOMMU)\n--\ndrivers/vfio/mdev/Makefile=3=mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o\ndrivers/vfio/mdev/Makefile-4-\ndrivers/vfio/mdev/Makefile:5:obj-$(CONFIG_VFIO_MDEV) += mdev.o\n--\ndrivers/vfio/pci/Makefile=3=vfio-pci-core-y := vfio_pci_core.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o\ndrivers/vfio/pci/Makefile:4:vfio-pci-core-$(CONFIG_VFIO_PCI_ZDEV_KVM) += vfio_pci_zdev.o\ndrivers/vfio/pci/Makefile:5:vfio-pci-core-$(CONFIG_VFIO_PCI_DMABUF) += vfio_pci_dmabuf.o\ndrivers/vfio/pci/Makefile:6:obj-$(CONFIG_VFIO_PCI_CORE) += vfio-pci-core.o\ndrivers/vfio/pci/Makefile-7-\ndrivers/vfio/pci/Makefile=8=vfio-pci-y := vfio_pci.o\ndrivers/vfio/pci/Makefile:9:vfio-pci-$(CONFIG_VFIO_PCI_IGD) += vfio_pci_igd.o\ndrivers/vfio/pci/Makefile:10:obj-$(CONFIG_VFIO_PCI) += vfio-pci.o\ndrivers/vfio/pci/Makefile-11-\n--\ndrivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c=1623=static void hisi_acc_vfio_debug_init(struct hisi_acc_vf_core_device *hisi_acc_vdev)\n--\ndrivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c-1631-\tif (!debugfs_initialized() ||\ndrivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c:1632:\t !IS_ENABLED(CONFIG_VFIO_DEBUGFS))\ndrivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c-1633-\t\treturn;\n--\ndrivers/vfio/pci/vfio_pci.c=39=MODULE_PARM_DESC(nointxmask,\n--\ndrivers/vfio/pci/vfio_pci.c-41-\ndrivers/vfio/pci/vfio_pci.c:42:#ifdef CONFIG_VFIO_PCI_VGA\ndrivers/vfio/pci/vfio_pci.c-43-static bool disable_vga;\n--\ndrivers/vfio/pci/vfio_pci.c=128=static int vfio_pci_init_dev(struct vfio_device *core_vdev)\n--\ndrivers/vfio/pci/vfio_pci.c-141-\tvdev-\u003edisable_idle_d3 = disable_idle_d3;\ndrivers/vfio/pci/vfio_pci.c:142:#ifdef CONFIG_VFIO_PCI_VGA\ndrivers/vfio/pci/vfio_pci.c-143-\tvdev-\u003edisable_vga = disable_vga;\n--\ndrivers/vfio/pci/vfio_pci_config.c=1750=int vfio_config_init(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_config.c-1832-\ndrivers/vfio/pci/vfio_pci_config.c:1833:\tif (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev-\u003enointx ||\ndrivers/vfio/pci/vfio_pci_config.c-1834-\t !vdev-\u003epdev-\u003eirq || vdev-\u003epdev-\u003eirq == IRQ_NOTCONNECTED)\n--\ndrivers/vfio/pci/vfio_pci_core.c=94=static inline bool vfio_vga_disabled(struct vfio_pci_core_device *vdev)\ndrivers/vfio/pci/vfio_pci_core.c-95-{\ndrivers/vfio/pci/vfio_pci_core.c:96:#ifdef CONFIG_VFIO_PCI_VGA\ndrivers/vfio/pci/vfio_pci_core.c-97-\treturn vdev-\u003edisable_vga;\n--\ndrivers/vfio/pci/vfio_pci_core.c-102-\ndrivers/vfio/pci/vfio_pci_core.c:103:#ifdef CONFIG_VFIO_DEBUGFS\ndrivers/vfio/pci/vfio_pci_core.c-104-static struct vfio_pci_core_device *\n--\ndrivers/vfio/pci/vfio_pci_core.c=152=static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_core.c-154-}\ndrivers/vfio/pci/vfio_pci_core.c:155:#endif /* CONFIG_VFIO_DEBUGFS */\ndrivers/vfio/pci/vfio_pci_core.c-156-\n--\ndrivers/vfio/pci/vfio_pci_priv.h=44=ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,\n--\ndrivers/vfio/pci/vfio_pci_priv.h-46-\ndrivers/vfio/pci/vfio_pci_priv.h:47:#ifdef CONFIG_VFIO_PCI_VGA\ndrivers/vfio/pci/vfio_pci_priv.h-48-ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,\n--\ndrivers/vfio/pci/vfio_pci_priv.h=73=void vfio_pci_memory_unlock_and_restore(struct vfio_pci_core_device *vdev,\n--\ndrivers/vfio/pci/vfio_pci_priv.h-75-\ndrivers/vfio/pci/vfio_pci_priv.h:76:#ifdef CONFIG_VFIO_PCI_IGD\ndrivers/vfio/pci/vfio_pci_priv.h-77-bool vfio_pci_is_intel_display(struct pci_dev *pdev);\n--\ndrivers/vfio/pci/vfio_pci_priv.h=85=static inline int vfio_pci_igd_init(struct vfio_pci_core_device *vdev)\n--\ndrivers/vfio/pci/vfio_pci_priv.h-90-\ndrivers/vfio/pci/vfio_pci_priv.h:91:#ifdef CONFIG_VFIO_PCI_ZDEV_KVM\ndrivers/vfio/pci/vfio_pci_priv.h-92-int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,\n--\ndrivers/vfio/pci/vfio_pci_priv.h=121=static inline bool vfio_pci_is_vga(struct pci_dev *pdev)\n--\ndrivers/vfio/pci/vfio_pci_priv.h-125-\ndrivers/vfio/pci/vfio_pci_priv.h:126:#ifdef CONFIG_VFIO_PCI_DMABUF\ndrivers/vfio/pci/vfio_pci_priv.h-127-int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n--\ndrivers/vfio/pci/vfio_pci_rdwr.c=201=ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,\n--\ndrivers/vfio/pci/vfio_pci_rdwr.c-280-\ndrivers/vfio/pci/vfio_pci_rdwr.c:281:#ifdef CONFIG_VFIO_PCI_VGA\ndrivers/vfio/pci/vfio_pci_rdwr.c-282-ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,\n--\ndrivers/vfio/platform/Makefile=2=vfio-platform-base-y := vfio_platform_common.o vfio_platform_irq.o\ndrivers/vfio/platform/Makefile:3:obj-$(CONFIG_VFIO_PLATFORM_BASE) += vfio-platform-base.o\ndrivers/vfio/platform/Makefile:4:obj-$(CONFIG_VFIO_PLATFORM_BASE) += reset/\ndrivers/vfio/platform/Makefile-5-\ndrivers/vfio/platform/Makefile=6=vfio-platform-y := vfio_platform.o\ndrivers/vfio/platform/Makefile:7:obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o\ndrivers/vfio/platform/Makefile-8-\ndrivers/vfio/platform/Makefile=9=vfio-amba-y := vfio_amba.o\ndrivers/vfio/platform/Makefile:10:obj-$(CONFIG_VFIO_AMBA) += vfio-amba.o\n--\ndrivers/vfio/platform/reset/Makefile=3=vfio-platform-amdxgbe-y := vfio_platform_amdxgbe.o\ndrivers/vfio/platform/reset/Makefile-4-\ndrivers/vfio/platform/reset/Makefile:5:obj-$(CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET) += vfio-platform-calxedaxgmac.o\ndrivers/vfio/platform/reset/Makefile:6:obj-$(CONFIG_VFIO_PLATFORM_AMDXGBE_RESET) += vfio-platform-amdxgbe.o\ndrivers/vfio/platform/reset/Makefile:7:obj-$(CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET) += vfio_platform_bcmflexrm.o\n--\ndrivers/vfio/vfio.h=37=extern const struct file_operations vfio_device_fops;\ndrivers/vfio/vfio.h-38-\ndrivers/vfio/vfio.h:39:#ifdef CONFIG_VFIO_NOIOMMU\ndrivers/vfio/vfio.h-40-extern bool vfio_noiommu __read_mostly;\n--\ndrivers/vfio/vfio.h=45=enum vfio_group_type {\n--\ndrivers/vfio/vfio.h-68-\ndrivers/vfio/vfio.h:69:#if IS_ENABLED(CONFIG_VFIO_GROUP)\ndrivers/vfio/vfio.h-70-struct vfio_group {\n--\ndrivers/vfio/vfio.h-85-\tstruct list_head\t\tvfio_next;\ndrivers/vfio/vfio.h:86:#if IS_ENABLED(CONFIG_VFIO_CONTAINER)\ndrivers/vfio/vfio.h-87-\tstruct list_head\t\tcontainer_next;\n--\ndrivers/vfio/vfio.h=182=static inline void vfio_group_cleanup(void)\n--\ndrivers/vfio/vfio.h-185-\ndrivers/vfio/vfio.h:186:#endif /* CONFIG_VFIO_GROUP */\ndrivers/vfio/vfio.h-187-\ndrivers/vfio/vfio.h=188=static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)\ndrivers/vfio/vfio.h-189-{\ndrivers/vfio/vfio.h:190:#if IS_ENABLED(CONFIG_VFIO_GROUP)\ndrivers/vfio/vfio.h-191-\tif (vdev-\u003egroup \u0026\u0026 vdev-\u003egroup-\u003etype == VFIO_NO_IOMMU)\n--\ndrivers/vfio/vfio.h-197-\ndrivers/vfio/vfio.h:198:#if IS_ENABLED(CONFIG_VFIO_CONTAINER)\ndrivers/vfio/vfio.h-199-/**\n--\ndrivers/vfio/vfio.h=354=int vfio_df_ioctl_detach_pt(struct vfio_device_file *df,\n--\ndrivers/vfio/vfio.h-356-\ndrivers/vfio/vfio.h:357:#if IS_ENABLED(CONFIG_VFIO_DEVICE_CDEV)\ndrivers/vfio/vfio.h-358-void vfio_init_device_cdev(struct vfio_device *device);\n--\ndrivers/vfio/vfio.h=413=static inline void vfio_cdev_cleanup(void)\n--\ndrivers/vfio/vfio.h-415-}\ndrivers/vfio/vfio.h:416:#endif /* CONFIG_VFIO_DEVICE_CDEV */\ndrivers/vfio/vfio.h-417-\ndrivers/vfio/vfio.h:418:#if IS_ENABLED(CONFIG_VFIO_VIRQFD)\ndrivers/vfio/vfio.h-419-int __init vfio_virqfd_init(void);\n--\ndrivers/vfio/vfio.h=440=static inline void vfio_device_put_kvm(struct vfio_device *device)\n--\ndrivers/vfio/vfio.h-444-\ndrivers/vfio/vfio.h:445:#ifdef CONFIG_VFIO_DEBUGFS\ndrivers/vfio/vfio.h-446-void vfio_debugfs_create_root(void);\n--\ndrivers/vfio/vfio.h=456=static inline void vfio_device_debugfs_exit(struct vfio_device *vdev) { }\ndrivers/vfio/vfio.h:457:#endif /* CONFIG_VFIO_DEBUGFS */\ndrivers/vfio/vfio.h-458-\n--\ndrivers/vfio/vfio_main.c=51=static struct vfio {\n--\ndrivers/vfio/vfio_main.c-56-\ndrivers/vfio/vfio_main.c:57:#ifdef CONFIG_VFIO_NOIOMMU\ndrivers/vfio/vfio_main.c-58-bool vfio_noiommu __read_mostly;\n--\ndrivers/vfio/vfio_main.c=1340=static long vfio_device_fops_unl_ioctl(struct file *filep,\n--\ndrivers/vfio/vfio_main.c-1359-\t/* cdev only ioctls */\ndrivers/vfio/vfio_main.c:1360:\tif (IS_ENABLED(CONFIG_VFIO_DEVICE_CDEV) \u0026\u0026 !df-\u003egroup) {\ndrivers/vfio/vfio_main.c-1361-\t\tswitch (cmd) {\n--\ninclude/linux/sched/user.h=14=struct user_struct {\n--\ninclude/linux/sched/user.h-27-\tdefined(CONFIG_NET) || defined(CONFIG_IO_URING) || \\\ninclude/linux/sched/user.h:28:\tdefined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD) || \\\ninclude/linux/sched/user.h-29-\tdefined(CONFIG_SECRETMEM)\n--\ninclude/linux/vfio.h=39=struct vfio_device {\n--\ninclude/linux/vfio.h-47-\tconst struct vfio_log_ops *log_ops;\ninclude/linux/vfio.h:48:#if IS_ENABLED(CONFIG_VFIO_GROUP)\ninclude/linux/vfio.h-49-\tstruct vfio_group *group;\n--\ninclude/linux/vfio.h-61-\tstruct device device;\t/* device.kref covers object life circle */\ninclude/linux/vfio.h:62:#if IS_ENABLED(CONFIG_VFIO_DEVICE_CDEV)\ninclude/linux/vfio.h-63-\tstruct cdev cdev;\n--\ninclude/linux/vfio.h=362=struct iommu_group *vfio_file_iommu_group(struct file *file);\ninclude/linux/vfio.h-363-\ninclude/linux/vfio.h:364:#if IS_ENABLED(CONFIG_VFIO_GROUP)\ninclude/linux/vfio.h-365-bool vfio_file_is_group(struct file *file);\n--\ninclude/linux/vfio_pci_core.h=60=struct vfio_pci_device_ops {\n--\ninclude/linux/vfio_pci_core.h-68-\ninclude/linux/vfio_pci_core.h:69:#if IS_ENABLED(CONFIG_VFIO_PCI_DMABUF)\ninclude/linux/vfio_pci_core.h-70-int vfio_pci_core_fill_phys_vec(struct phys_vec *phys_vec,\n"
} |
| 70/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41262 output: 19 thoughts: 0 |
| 71/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "config VFIO\\b"
}Results: {
"Output": "drivers/vfio/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/vfio/Kconfig:2:menuconfig VFIO\ndrivers/vfio/Kconfig-3-\ttristate \"VFIO Non-Privileged userspace driver framework\"\n"
} |
| 72/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41359 output: 33 thoughts: 0 |
| 73/2 | 2026/09/29 15:31 | tool | read-file |
0mArgs:{
"File": "drivers/vfio/Kconfig",
"FirstLine": 1,
"LineCount": 40
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\tmenuconfig VFIO\n 3:\t\ttristate \"VFIO Non-Privileged userspace driver framework\"\n 4:\t\tselect IOMMU_API\n 5:\t\tdepends on IOMMUFD || !IOMMUFD\n 6:\t\tselect INTERVAL_TREE\n 7:\t\tselect VFIO_GROUP if SPAPR_TCE_IOMMU || IOMMUFD=n\n 8:\t\tselect VFIO_DEVICE_CDEV if !VFIO_GROUP\n 9:\t\tselect VFIO_CONTAINER if IOMMUFD=n\n 10:\t\thelp\n 11:\t\t VFIO provides a framework for secure userspace device drivers.\n 12:\t\t See Documentation/driver-api/vfio.rst for more details.\n 13:\t\n 14:\t\t If you don't know what to do here, say N.\n 15:\t\n 16:\tif VFIO\n 17:\tconfig VFIO_DEVICE_CDEV\n 18:\t\tbool \"Support for the VFIO cdev /dev/vfio/devices/vfioX\"\n 19:\t\tdepends on IOMMUFD \u0026\u0026 !SPAPR_TCE_IOMMU\n 20:\t\tdefault !VFIO_GROUP\n 21:\t\thelp\n 22:\t\t The VFIO device cdev is another way for userspace to get device\n 23:\t\t access. Userspace gets device fd by opening device cdev under\n 24:\t\t /dev/vfio/devices/vfioX, and then bind the device fd with an iommufd\n 25:\t\t to set up secure DMA context for device access.\n 26:\t\n 27:\t\t If you don't know what to do here, say N.\n 28:\t\n 29:\tconfig VFIO_GROUP\n 30:\t\tbool \"Support for the VFIO group /dev/vfio/$group_id\"\n 31:\t\tdefault y\n 32:\t\thelp\n 33:\t\t VFIO group support provides the traditional model for accessing\n 34:\t\t devices through VFIO and is used by the majority of userspace\n 35:\t\t applications and drivers making use of VFIO.\n 36:\t\n 37:\t\t If you don't know what to do here, say Y.\n 38:\t\n 39:\tconfig VFIO_CONTAINER\n 40:\t\tbool \"Support for the VFIO container /dev/vfio/vfio\"\n"
} |
| 74/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 42021 output: 30 thoughts: 0 |
| 75/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_KVM",
"PathPrefix": "arch/x86/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1124 lines.\nUse more precise expression if possible.\n\narch/x86/Kbuild=12=obj-$(CONFIG_PERF_EVENTS) += events/\narch/x86/Kbuild-13-\narch/x86/Kbuild:14:obj-$(CONFIG_KVM) += kvm/\narch/x86/Kbuild-15-\n--\narch/x86/coco/tdx/tdx.c=47=noinstr void __noreturn __tdx_hypercall_failed(void)\n--\narch/x86/coco/tdx/tdx.c-52-\narch/x86/coco/tdx/tdx.c:53:#ifdef CONFIG_KVM_GUEST\narch/x86/coco/tdx/tdx.c-54-long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,\n--\narch/x86/entry/common.c-8-\narch/x86/entry/common.c:9:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/entry/common.c-10-/*\n--\narch/x86/entry/entry.S=76=EXPORT_SYMBOL(__ref_stack_chk_guard);\n--\narch/x86/entry/entry.S-78-\narch/x86/entry/entry.S:79:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/entry/entry.S-80-.macro IDT_DO_EVENT_IRQOFF call_insn call_target\n--\narch/x86/entry/entry_64_fred.S=60=SYM_CODE_END(asm_fred_entrypoint_kernel)\narch/x86/entry/entry_64_fred.S-61-\narch/x86/entry/entry_64_fred.S:62:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/entry/entry_64_fred.S-63-SYM_FUNC_START(asm_fred_entry_from_kvm)\n--\narch/x86/entry/entry_fred.c=269=__visible noinstr void fred_entry_from_kernel(struct pt_regs *regs)\n--\narch/x86/entry/entry_fred.c-296-\narch/x86/entry/entry_fred.c:297:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/entry/entry_fred.c-298-__visible noinstr void __fred_entry_from_kvm(struct pt_regs *regs)\n--\narch/x86/include/asm/hardirq.h=7=enum irq_stat_counts {\n--\narch/x86/include/asm/hardirq.h-41-#endif\narch/x86/include/asm/hardirq.h:42:#if IS_ENABLED(CONFIG_KVM)\narch/x86/include/asm/hardirq.h-43-\tIRQ_COUNT_POSTED_INTR,\n--\narch/x86/include/asm/hardirq.h=60=typedef struct {\narch/x86/include/asm/hardirq.h:61:#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) \u0026\u0026 IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/include/asm/hardirq.h-62-\tu8\t kvm_cpu_l1tf_flush_l1d;\n--\narch/x86/include/asm/hardirq.h=90=DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending);\n--\narch/x86/include/asm/hardirq.h-92-\narch/x86/include/asm/hardirq.h:93:#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) \u0026\u0026 IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/include/asm/hardirq.h-94-/*\n--\narch/x86/include/asm/hardirq.h=108=static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)\n--\narch/x86/include/asm/hardirq.h-111-}\narch/x86/include/asm/hardirq.h:112:#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */\narch/x86/include/asm/hardirq.h-113-static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }\narch/x86/include/asm/hardirq.h:114:#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */\narch/x86/include/asm/hardirq.h-115-\n--\narch/x86/include/asm/idtentry.h=608=DECLARE_IDTENTRY_RAW(X86_TRAP_MC,\txenpv_exc_machine_check);\n--\narch/x86/include/asm/idtentry.h-613-\narch/x86/include/asm/idtentry.h:614:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/include/asm/idtentry.h-615-/*\n--\narch/x86/include/asm/idtentry.h=710=DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR,\t\tsysvec_irq_work);\n--\narch/x86/include/asm/idtentry.h-715-\narch/x86/include/asm/idtentry.h:716:#if IS_ENABLED(CONFIG_KVM)\narch/x86/include/asm/idtentry.h-717-DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR,\t\tsysvec_kvm_posted_intr_ipi);\n--\narch/x86/include/asm/idtentry.h=749=DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,\tsysvec_xen_hvm_callback);\n--\narch/x86/include/asm/idtentry.h-751-\narch/x86/include/asm/idtentry.h:752:#ifdef CONFIG_KVM_GUEST\narch/x86/include/asm/idtentry.h-753-DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,\tsysvec_kvm_asyncpf_interrupt);\n--\narch/x86/include/asm/irq.h=30=extern void fixup_irqs(void);\narch/x86/include/asm/irq.h-31-\narch/x86/include/asm/irq.h:32:#if IS_ENABLED(CONFIG_KVM)\narch/x86/include/asm/irq.h-33-extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void));\n--\narch/x86/include/asm/kvm-x86-nested-ops.h=26=KVM_X86_NESTED_OP(translate_nested_gpa)\narch/x86/include/asm/kvm-x86-nested-ops.h:27:#ifdef CONFIG_KVM_HYPERV\narch/x86/include/asm/kvm-x86-nested-ops.h-28-KVM_X86_NESTED_OP_OPTIONAL(enable_evmcs)\n--\narch/x86/include/asm/kvm-x86-ops.h=122=KVM_X86_OP(setup_mce)\narch/x86/include/asm/kvm-x86-ops.h:123:#ifdef CONFIG_KVM_SMM\narch/x86/include/asm/kvm-x86-ops.h-124-KVM_X86_OP(smi_allowed)\n--\narch/x86/include/asm/kvm_host.h-51-/*\narch/x86/include/asm/kvm_host.h:52: * CONFIG_KVM_MAX_NR_VCPUS is defined iff CONFIG_KVM!=n, provide a dummy max if\narch/x86/include/asm/kvm_host.h:53: * KVM is disabled (arbitrarily use the default from CONFIG_KVM_MAX_NR_VCPUS).\narch/x86/include/asm/kvm_host.h-54- */\narch/x86/include/asm/kvm_host.h:55:#ifdef CONFIG_KVM_MAX_NR_VCPUS\narch/x86/include/asm/kvm_host.h:56:#define KVM_MAX_VCPUS CONFIG_KVM_MAX_NR_VCPUS\narch/x86/include/asm/kvm_host.h-57-#else\n--\narch/x86/include/asm/kvm_host.h-95-#define KVM_REQ_PMI\t\t\tKVM_ARCH_REQ(11)\narch/x86/include/asm/kvm_host.h:96:#ifdef CONFIG_KVM_SMM\narch/x86/include/asm/kvm_host.h-97-#define KVM_REQ_SMI\t\t\tKVM_ARCH_REQ(12)\n--\narch/x86/include/asm/kvm_host.h=657=struct kvm_hypervisor_cpuid {\n--\narch/x86/include/asm/kvm_host.h-661-\narch/x86/include/asm/kvm_host.h:662:#ifdef CONFIG_KVM_XEN\narch/x86/include/asm/kvm_host.h-663-/* Xen HVM per vcpu emulation context */\n--\narch/x86/include/asm/kvm_host.h=720=struct kvm_vcpu_arch {\n--\narch/x86/include/asm/kvm_host.h-935-\narch/x86/include/asm/kvm_host.h:936:#ifdef CONFIG_KVM_HYPERV\narch/x86/include/asm/kvm_host.h-937-\tbool hyperv_enabled;\n--\narch/x86/include/asm/kvm_host.h-939-#endif\narch/x86/include/asm/kvm_host.h:940:#ifdef CONFIG_KVM_XEN\narch/x86/include/asm/kvm_host.h-941-\tstruct kvm_vcpu_xen xen;\n--\narch/x86/include/asm/kvm_host.h=1059=enum hv_tsc_page_status {\n--\narch/x86/include/asm/kvm_host.h-1071-\narch/x86/include/asm/kvm_host.h:1072:#ifdef CONFIG_KVM_HYPERV\narch/x86/include/asm/kvm_host.h-1073-/* Hyper-V emulation context */\narch/x86/include/asm/kvm_host.h=1074=struct kvm_hv {\n--\narch/x86/include/asm/kvm_host.h-1108-\narch/x86/include/asm/kvm_host.h:1109:#ifdef CONFIG_KVM_XEN\narch/x86/include/asm/kvm_host.h-1110-/* Xen emulation context */\n--\narch/x86/include/asm/kvm_host.h=1125=enum kvm_irqchip_mode {\narch/x86/include/asm/kvm_host.h-1126-\tKVM_IRQCHIP_NONE,\narch/x86/include/asm/kvm_host.h:1127:#ifdef CONFIG_KVM_IOAPIC\narch/x86/include/asm/kvm_host.h-1128-\tKVM_IRQCHIP_KERNEL, /* created with KVM_CREATE_IRQCHIP */\n--\narch/x86/include/asm/kvm_host.h=1163=struct kvm_arch {\n--\narch/x86/include/asm/kvm_host.h-1176-\tstruct kvm_possible_nx_huge_pages possible_nx_huge_pages[KVM_NR_MMU_TYPES];\narch/x86/include/asm/kvm_host.h:1177:#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING\narch/x86/include/asm/kvm_host.h-1178-\tstruct kvm_page_track_notifier_head track_notifier_head;\n--\narch/x86/include/asm/kvm_host.h-1193-\narch/x86/include/asm/kvm_host.h:1194:#ifdef CONFIG_KVM_IOAPIC\narch/x86/include/asm/kvm_host.h-1195-\tstruct kvm_pic *vpic;\n--\narch/x86/include/asm/kvm_host.h-1256-\narch/x86/include/asm/kvm_host.h:1257:#ifdef CONFIG_KVM_HYPERV\narch/x86/include/asm/kvm_host.h-1258-\tstruct kvm_hv hyperv;\n--\narch/x86/include/asm/kvm_host.h-1260-\narch/x86/include/asm/kvm_host.h:1261:#ifdef CONFIG_KVM_XEN\narch/x86/include/asm/kvm_host.h-1262-\tstruct kvm_xen xen;\n--\narch/x86/include/asm/kvm_host.h-1313-#ifdef CONFIG_X86_64\narch/x86/include/asm/kvm_host.h:1314:#ifdef CONFIG_KVM_PROVE_MMU\narch/x86/include/asm/kvm_host.h-1315-\t/*\n--\narch/x86/include/asm/kvm_host.h-1364-\narch/x86/include/asm/kvm_host.h:1365:#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING\narch/x86/include/asm/kvm_host.h-1366-\t/*\n--\narch/x86/include/asm/kvm_host.h=1507=struct kvm_x86_ops {\n--\narch/x86/include/asm/kvm_host.h-1693-\narch/x86/include/asm/kvm_host.h:1694:#ifdef CONFIG_KVM_SMM\narch/x86/include/asm/kvm_host.h-1695-\tint (*smi_allowed)(struct kvm_vcpu *vcpu, bool for_injection);\n--\narch/x86/include/asm/kvm_host.h=1845=enum kvm_intr_type {\n--\narch/x86/include/asm/kvm_host.h-1855-\narch/x86/include/asm/kvm_host.h:1856:#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES\narch/x86/include/asm/kvm_host.h-1857-#define kvm_arch_has_private_mem(kvm) ((kvm)-\u003earch.has_private_mem)\n--\narch/x86/include/asm/kvm_host.h=1863=static inline unsigned long read_msr(unsigned long msr)\n--\narch/x86/include/asm/kvm_host.h-1873-\narch/x86/include/asm/kvm_host.h:1874:#ifdef CONFIG_KVM_SMM\narch/x86/include/asm/kvm_host.h-1875-#define HF_SMM_MASK\t\t(1 \u003c\u003c 1)\n--\narch/x86/include/asm/kvm_page_track.h-6-\narch/x86/include/asm/kvm_page_track.h:7:#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING\narch/x86/include/asm/kvm_page_track.h-8-/*\n--\narch/x86/include/asm/kvm_page_track.h=61=struct kvm_page_track_notifier_node {};\narch/x86/include/asm/kvm_page_track.h:62:#endif /* CONFIG_KVM_EXTERNAL_WRITE_TRACKING */\narch/x86/include/asm/kvm_page_track.h-63-\n--\narch/x86/include/asm/kvm_para.h-11-\narch/x86/include/asm/kvm_para.h:12:#ifdef CONFIG_KVM_GUEST\narch/x86/include/asm/kvm_para.h-13-bool kvm_check_and_clear_guest_paused(void);\n--\narch/x86/include/asm/kvm_para.h=15=static inline bool kvm_check_and_clear_guest_paused(void)\n--\narch/x86/include/asm/kvm_para.h-18-}\narch/x86/include/asm/kvm_para.h:19:#endif /* CONFIG_KVM_GUEST */\narch/x86/include/asm/kvm_para.h-20-\n--\narch/x86/include/asm/kvm_para.h=108=static inline long kvm_sev_hypercall3(unsigned int nr, unsigned long p1,\n--\narch/x86/include/asm/kvm_para.h-119-\narch/x86/include/asm/kvm_para.h:120:#ifdef CONFIG_KVM_GUEST\narch/x86/include/asm/kvm_para.h-121-void kvmclock_init(void);\n--\narch/x86/include/asm/kvm_para.h=143=static inline void kvm_spinlock_init(void)\n--\narch/x86/include/asm/kvm_para.h-147-\narch/x86/include/asm/kvm_para.h:148:#else /* CONFIG_KVM_GUEST */\narch/x86/include/asm/kvm_para.h-149-#define kvm_async_pf_task_wait_schedule(T) do {} while(0)\n--\narch/x86/include/asm/kvm_types.h-4-\narch/x86/include/asm/kvm_types.h:5:#if IS_MODULE(CONFIG_KVM_AMD) \u0026\u0026 IS_MODULE(CONFIG_KVM_INTEL)\narch/x86/include/asm/kvm_types.h-6-#define KVM_SUB_MODULES kvm-amd,kvm-intel\narch/x86/include/asm/kvm_types.h:7:#elif IS_MODULE(CONFIG_KVM_AMD)\narch/x86/include/asm/kvm_types.h-8-#define KVM_SUB_MODULES kvm-amd\narch/x86/include/asm/kvm_types.h:9:#elif IS_MODULE(CONFIG_KVM_INTEL)\narch/x86/include/asm/kvm_types.h-10-#define KVM_SUB_MODULES kvm-intel\n--\narch/x86/include/asm/sev.h=645=static inline u64 savic_ghcb_msr_read(u32 reg) { return 0; }\n--\narch/x86/include/asm/sev.h-648-\narch/x86/include/asm/sev.h:649:#ifdef CONFIG_KVM_AMD_SEV\narch/x86/include/asm/sev.h-650-bool snp_probe_rmptable_info(void);\n--\narch/x86/include/asm/tdx.h=94=static inline bool tdx_early_handle_ve(struct pt_regs *regs) { return false; }\n--\narch/x86/include/asm/tdx.h-97-\narch/x86/include/asm/tdx.h:98:#if defined(CONFIG_KVM_GUEST) \u0026\u0026 defined(CONFIG_INTEL_TDX_GUEST)\narch/x86/include/asm/tdx.h-99-long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,\n--\narch/x86/include/asm/tdx.h=102=static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1,\n--\narch/x86/include/asm/tdx.h-107-}\narch/x86/include/asm/tdx.h:108:#endif /* CONFIG_INTEL_TDX_GUEST \u0026\u0026 CONFIG_KVM_GUEST */\narch/x86/include/asm/tdx.h-109-\n--\narch/x86/include/asm/virt.h=7=typedef void (cpu_emergency_virt_cb)(void);\narch/x86/include/asm/virt.h-8-\narch/x86/include/asm/virt.h:9:#if IS_ENABLED(CONFIG_KVM_X86)\narch/x86/include/asm/virt.h-10-extern bool virt_rebooting;\n--\narch/x86/kernel/Makefile=139=obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o\narch/x86/kernel/Makefile-140-\narch/x86/kernel/Makefile:141:obj-$(CONFIG_KVM_GUEST)\t\t+= kvm.o kvmclock.o\narch/x86/kernel/Makefile-142-obj-$(CONFIG_PARAVIRT)\t\t+= paravirt.o\n--\narch/x86/kernel/asm-offsets_64.c-7-\narch/x86/kernel/asm-offsets_64.c:8:#if defined(CONFIG_KVM_GUEST)\narch/x86/kernel/asm-offsets_64.c-9-#include \u003casm/kvm_para.h\u003e\n--\narch/x86/kernel/asm-offsets_64.c=12=int main(void)\n--\narch/x86/kernel/asm-offsets_64.c-22-\narch/x86/kernel/asm-offsets_64.c:23:#if defined(CONFIG_KVM_GUEST)\narch/x86/kernel/asm-offsets_64.c-24-\tOFFSET(KVM_STEAL_TIME_preempted, kvm_steal_time, preempted);\n--\narch/x86/kernel/cpu/bugs.c=3269=void __init cpu_select_mitigations(void)\n--\narch/x86/kernel/cpu/bugs.c-3365-\narch/x86/kernel/cpu/bugs.c:3366:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/kernel/cpu/bugs.c-3367-static const char * const l1tf_vmx_states[] = {\n--\narch/x86/kernel/cpu/feat_ctl.c=122=void init_ia32_feat_ctl(struct cpuinfo_x86 *c)\n--\narch/x86/kernel/cpu/feat_ctl.c-135-\tenable_vmx = cpu_has(c, X86_FEATURE_VMX) \u0026\u0026\narch/x86/kernel/cpu/feat_ctl.c:136:\t\t IS_ENABLED(CONFIG_KVM_INTEL);\narch/x86/kernel/cpu/feat_ctl.c-137-\n--\narch/x86/kernel/cpu/feat_ctl.c-185-\t (!tboot \u0026\u0026 !(msr \u0026 FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX))) {\narch/x86/kernel/cpu/feat_ctl.c:186:\t\tif (IS_ENABLED(CONFIG_KVM_INTEL))\narch/x86/kernel/cpu/feat_ctl.c-187-\t\t\tpr_err_once(\"VMX (%s TXT) disabled by BIOS\\n\",\n--\narch/x86/kernel/cpu/hypervisor.c=29=static const __initconst struct hypervisor_x86 * const hypervisors[] =\n--\narch/x86/kernel/cpu/hypervisor.c-38-\t\u0026x86_hyper_ms_hyperv,\narch/x86/kernel/cpu/hypervisor.c:39:#ifdef CONFIG_KVM_GUEST\narch/x86/kernel/cpu/hypervisor.c-40-\t\u0026x86_hyper_kvm,\n--\narch/x86/kernel/fpu/core.c=216=void fpu_reset_from_exception_fixup(void)\n--\narch/x86/kernel/fpu/core.c-220-\narch/x86/kernel/fpu/core.c:221:#if IS_ENABLED(CONFIG_KVM)\narch/x86/kernel/fpu/core.c-222-static void __fpstate_reset(struct fpstate *fpstate);\n--\narch/x86/kernel/fpu/core.c=469=EXPORT_SYMBOL_FOR_KVM(fpu_copy_uabi_to_guest_fpstate);\narch/x86/kernel/fpu/core.c:470:#endif /* CONFIG_KVM */\narch/x86/kernel/fpu/core.c-471-\n--\narch/x86/kernel/fpu/xstate.c=1466=void xrstors(struct xregs_state *xstate, u64 mask)\n--\narch/x86/kernel/fpu/xstate.c-1476-\narch/x86/kernel/fpu/xstate.c:1477:#if IS_ENABLED(CONFIG_KVM)\narch/x86/kernel/fpu/xstate.c-1478-void fpstate_clear_xstate_component(struct fpstate *fpstate, unsigned int xfeature)\n--\narch/x86/kernel/idt.c=133=static const __initconst struct idt_data apic_idts[] = {\n--\narch/x86/kernel/idt.c-155-\tINTG(X86_PLATFORM_IPI_VECTOR,\t\tasm_sysvec_x86_platform_ipi),\narch/x86/kernel/idt.c:156:# if IS_ENABLED(CONFIG_KVM)\narch/x86/kernel/idt.c-157-\tINTG(POSTED_INTR_VECTOR,\t\tasm_sysvec_kvm_posted_intr_ipi),\n--\narch/x86/kernel/idt.c=264=void __init idt_setup_early_pf(void)\n--\narch/x86/kernel/idt.c-270-\narch/x86/kernel/idt.c:271:#if IS_ENABLED(CONFIG_KVM_INTEL) \u0026\u0026 !defined(CONFIG_X86_64)\narch/x86/kernel/idt.c-272-void idt_entry_from_kvm(unsigned int vector)\n--\narch/x86/kernel/irq.c=79=static const struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] = {\n--\narch/x86/kernel/irq.c-113-#endif\narch/x86/kernel/irq.c:114:#if IS_ENABLED(CONFIG_KVM)\narch/x86/kernel/irq.c-115-\tITS(POSTED_INTR,\t\t\"PIN\",\t\" Posted-interrupt notification event\\n\"),\n--\narch/x86/kernel/irq.c=310=DEFINE_IDTENTRY_SYSVEC(sysvec_perf_guest_mediated_pmi_handler)\n--\narch/x86/kernel/irq.c-317-\narch/x86/kernel/irq.c:318:#if IS_ENABLED(CONFIG_KVM)\narch/x86/kernel/irq.c-319-static void dummy_handler(void) {}\n--\narch/x86/kernel/nmi.c=536=DEFINE_IDTENTRY_RAW(exc_nmi)\n--\narch/x86/kernel/nmi.c-611-\narch/x86/kernel/nmi.c:612:#if IS_ENABLED(CONFIG_KVM_INTEL)\narch/x86/kernel/nmi.c-613-DEFINE_IDTENTRY_RAW(exc_nmi_kvm_vmx)\n--\narch/x86/kernel/reboot.c=533=static inline void nmi_shootdown_cpus_on_restart(void);\narch/x86/kernel/reboot.c-534-\narch/x86/kernel/reboot.c:535:#if IS_ENABLED(CONFIG_KVM_X86)\narch/x86/kernel/reboot.c-536-static void emergency_reboot_disable_virtualization(void)\n--\narch/x86/kernel/reboot.c=554=static void emergency_reboot_disable_virtualization(void) { }\narch/x86/kernel/reboot.c:555:#endif /* CONFIG_KVM_X86 */\narch/x86/kernel/reboot.c-556-\n--\narch/x86/kvm/Makefile=3=ccflags-y += -I $(srctree)/arch/x86/kvm\narch/x86/kvm/Makefile:4:ccflags-$(CONFIG_KVM_WERROR) += -Werror\narch/x86/kvm/Makefile-5-\n--\narch/x86/kvm/Makefile=11=kvm-$(CONFIG_X86_64) += mmu/tdp_iter.o mmu/tdp_mmu.o\narch/x86/kvm/Makefile:12:kvm-$(CONFIG_KVM_IOAPIC) += i8259.o i8254.o ioapic.o\narch/x86/kvm/Makefile:13:kvm-$(CONFIG_KVM_HYPERV) += hyperv.o\narch/x86/kvm/Makefile:14:kvm-$(CONFIG_KVM_XEN)\t+= xen.o\narch/x86/kvm/Makefile:15:kvm-$(CONFIG_KVM_SMM)\t+= smm.o\narch/x86/kvm/Makefile-16-\n--\narch/x86/kvm/Makefile=20=kvm-intel-$(CONFIG_X86_SGX_KVM)\t+= vmx/sgx.o\narch/x86/kvm/Makefile:21:kvm-intel-$(CONFIG_KVM_HYPERV)\t+= vmx/hyperv.o vmx/hyperv_evmcs.o\narch/x86/kvm/Makefile:22:kvm-intel-$(CONFIG_KVM_INTEL_TDX)\t+= vmx/tdx.o\narch/x86/kvm/Makefile-23-\narch/x86/kvm/Makefile=24=kvm-amd-y\t\t+= svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o\narch/x86/kvm/Makefile-25-\narch/x86/kvm/Makefile:26:kvm-amd-$(CONFIG_KVM_AMD_SEV)\t+= svm/sev.o\narch/x86/kvm/Makefile:27:kvm-amd-$(CONFIG_KVM_HYPERV)\t+= svm/hyperv.o\narch/x86/kvm/Makefile-28-\n--\narch/x86/kvm/Makefile=33=endif\narch/x86/kvm/Makefile-34-\narch/x86/kvm/Makefile:35:obj-$(CONFIG_KVM_X86)\t+= kvm.o\narch/x86/kvm/Makefile:36:obj-$(CONFIG_KVM_INTEL)\t+= kvm-intel.o\narch/x86/kvm/Makefile:37:obj-$(CONFIG_KVM_AMD)\t+= kvm-amd.o\narch/x86/kvm/Makefile-38-\n--\narch/x86/kvm/Makefile=49=clean-files += kvm-asm-offsets.h\n--\narch/x86/kvm/Makefile-55-# use EXPORT_SYMBOL_GPL, and EXPORT_SYMBOL should never be used.\narch/x86/kvm/Makefile:56:ifdef CONFIG_KVM_X86\narch/x86/kvm/Makefile-57-# Search recursively for whole words and print line numbers. Filter out the\n--\narch/x86/kvm/Makefile=95=undefine exports_grep_trailer\narch/x86/kvm/Makefile:96:endif # CONFIG_KVM_X86\n--\narch/x86/kvm/cpuid.c=327=static bool kvm_cpuid_has_hyperv(struct kvm_vcpu *vcpu)\narch/x86/kvm/cpuid.c-328-{\narch/x86/kvm/cpuid.c:329:#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/cpuid.c-330-\tstruct kvm_cpuid_entry2 *entry;\n--\narch/x86/kvm/cpuid.c=510=static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,\n--\narch/x86/kvm/cpuid.c-560-\narch/x86/kvm/cpuid.c:561:#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/cpuid.c-562-\tif (kvm_cpuid_has_hyperv(vcpu)) {\n--\narch/x86/kvm/cpuid.c-572-\narch/x86/kvm/cpuid.c:573:#ifdef CONFIG_KVM_XEN\narch/x86/kvm/cpuid.c-574-\tvcpu-\u003earch.xen.cpuid = kvm_get_hypervisor_cpuid(vcpu, XEN_SIGNATURE);\n--\narch/x86/kvm/hyperv.h-27-\narch/x86/kvm/hyperv.h:28:#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/hyperv.h-29-\n--\narch/x86/kvm/hyperv.h=378=int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu);\narch/x86/kvm/hyperv.h:379:#else /* CONFIG_KVM_HYPERV */\narch/x86/kvm/hyperv.h-380-static inline void kvm_hv_setup_tsc_page(struct kvm *kvm,\n--\narch/x86/kvm/hyperv.h=426=static inline void kvm_hv_nested_transtion_tlb_flush(struct kvm_vcpu *vcpu, bool tdp_enabled) {}\narch/x86/kvm/hyperv.h:427:#endif /* CONFIG_KVM_HYPERV */\narch/x86/kvm/hyperv.h-428-\n--\narch/x86/kvm/i8254.h-12-\narch/x86/kvm/i8254.h:13:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/i8254.h-14-struct kvm_kpit_channel_state {\n--\narch/x86/kvm/i8254.h=69=void kvm_free_pit(struct kvm *kvm);\narch/x86/kvm/i8254.h:70:#endif /* CONFIG_KVM_IOAPIC */\narch/x86/kvm/i8254.h-71-\n--\narch/x86/kvm/ioapic.h-8-\narch/x86/kvm/ioapic.h:9:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/ioapic.h-10-\n--\narch/x86/kvm/ioapic.h=117=static inline int __kvm_irq_line_state(unsigned long *irq_state,\n--\narch/x86/kvm/ioapic.h-127-}\narch/x86/kvm/ioapic.h:128:#endif /* CONFIG_KVM_IOAPIC */\narch/x86/kvm/ioapic.h-129-\n--\narch/x86/kvm/irq.c=59=int kvm_cpu_has_extint(struct kvm_vcpu *v)\n--\narch/x86/kvm/irq.c-80-\narch/x86/kvm/irq.c:81:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/irq.c-82-\tif (pic_in_kernel(v-\u003ekvm))\n--\narch/x86/kvm/irq.c=128=int kvm_cpu_get_extint(struct kvm_vcpu *v)\n--\narch/x86/kvm/irq.c-137-\narch/x86/kvm/irq.c:138:#ifdef CONFIG_KVM_XEN\narch/x86/kvm/irq.c-139-\tif (kvm_xen_has_interrupt(v))\n--\narch/x86/kvm/irq.c-142-\narch/x86/kvm/irq.c:143:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/irq.c-144-\tif (pic_in_kernel(v-\u003ekvm))\n--\narch/x86/kvm/irq.c=177=void __kvm_migrate_timers(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/irq.c-179-\t__kvm_migrate_apic_timer(vcpu);\narch/x86/kvm/irq.c:180:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/irq.c-181-\t__kvm_migrate_pit_timer(vcpu);\n--\narch/x86/kvm/irq.c=241=int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,\n--\narch/x86/kvm/irq.c-248-\tswitch (e-\u003etype) {\narch/x86/kvm/irq.c:249:#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/irq.c-250-\tcase KVM_IRQ_ROUTING_HV_SINT:\n--\narch/x86/kvm/irq.c-264-\narch/x86/kvm/irq.c:265:#ifdef CONFIG_KVM_XEN\narch/x86/kvm/irq.c-266-\tcase KVM_IRQ_ROUTING_XEN_EVTCHN:\n--\narch/x86/kvm/irq.c=296=int kvm_set_routing_entry(struct kvm *kvm,\n--\narch/x86/kvm/irq.c-304-\tswitch (ue-\u003etype) {\narch/x86/kvm/irq.c:305:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/irq.c-306-\tcase KVM_IRQ_ROUTING_IRQCHIP:\n--\narch/x86/kvm/irq.c-338-\t\tbreak;\narch/x86/kvm/irq.c:339:#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/irq.c-340-\tcase KVM_IRQ_ROUTING_HV_SINT:\n--\narch/x86/kvm/irq.c-345-#endif\narch/x86/kvm/irq.c:346:#ifdef CONFIG_KVM_XEN\narch/x86/kvm/irq.c-347-\tcase KVM_IRQ_ROUTING_XEN_EVTCHN:\n--\narch/x86/kvm/irq.c=416=void kvm_arch_irq_routing_update(struct kvm *kvm)\narch/x86/kvm/irq.c-417-{\narch/x86/kvm/irq.c:418:#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/irq.c-419-\tkvm_hv_irq_routing_update(kvm);\n--\narch/x86/kvm/irq.c=540=void kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd,\n--\narch/x86/kvm/irq.c-555-\narch/x86/kvm/irq.c:556:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/irq.c-557-#define IOAPIC_ROUTING_ENTRY(irq) \\\n--\narch/x86/kvm/irq.h-20-\narch/x86/kvm/irq.h:21:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/irq.h-22-\n--\narch/x86/kvm/irq.h=76=static inline int irqchip_full(struct kvm *kvm)\n--\narch/x86/kvm/irq.h-83-}\narch/x86/kvm/irq.h:84:#else /* CONFIG_KVM_IOAPIC */\narch/x86/kvm/irq.h-85-static __always_inline int irqchip_full(struct kvm *kvm)\n--\narch/x86/kvm/irq.h=121=static inline void kvm_warn_on_lost_irq(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/irq.h-137-\t */\narch/x86/kvm/irq.h:138:\tWARN_ON_ONCE(!pic_in_kernel(vcpu-\u003ekvm) \u0026\u0026 !IS_ENABLED(CONFIG_KVM_XEN));\narch/x86/kvm/irq.h-139-}\n--\narch/x86/kvm/kvm-asm-offsets.c=13=static void __used common(void)\narch/x86/kvm/kvm-asm-offsets.c-14-{\narch/x86/kvm/kvm-asm-offsets.c:15:\tif (IS_ENABLED(CONFIG_KVM_AMD)) {\narch/x86/kvm/kvm-asm-offsets.c-16-\t\tBLANK();\n--\narch/x86/kvm/kvm-asm-offsets.c-24-\narch/x86/kvm/kvm-asm-offsets.c:25:\tif (IS_ENABLED(CONFIG_KVM_INTEL)) {\narch/x86/kvm/kvm-asm-offsets.c-26-\t\tBLANK();\n--\narch/x86/kvm/lapic.c=1410=static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,\n--\narch/x86/kvm/lapic.c-1432-\narch/x86/kvm/lapic.c:1433:#ifdef CONFIG_KVM_IOAPIC\narch/x86/kvm/lapic.c-1434-\t\tif (rtc_status) {\n--\narch/x86/kvm/lapic.c=1555=static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector)\n--\n\n"
} |
| 76/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 53530 output: 24 thoughts: 0 |
| 77/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "config KVM_EXTERNAL_WRITE_TRACKING"
}Results: {
"Output": "arch/x86/kvm/Kconfig=217=config KVM_PROVE_MMU\n--\narch/x86/kvm/Kconfig-229-\narch/x86/kvm/Kconfig:230:config KVM_EXTERNAL_WRITE_TRACKING\narch/x86/kvm/Kconfig-231-\tbool\n"
} |
| 78/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 53657 output: 24 thoughts: 0 |
| 79/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "select KVM_EXTERNAL_WRITE_TRACKING"
}Results: {
"Output": "drivers/gpu/drm/i915/Kconfig=125=config DRM_I915_GVT_KVMGT\n--\ndrivers/gpu/drm/i915/Kconfig-131-\tselect DRM_I915_GVT\ndrivers/gpu/drm/i915/Kconfig:132:\tselect KVM_EXTERNAL_WRITE_TRACKING\ndrivers/gpu/drm/i915/Kconfig-133-\tselect VFIO_MDEV\n"
} |
| 80/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 53814 output: 22 thoughts: 0 |
| 81/2 | 2026/09/29 15:31 | tool | grepper |
0mArgs:{
"Expression": "config KVM_AMD_SEV"
}Results: {
"Output": "arch/x86/kvm/Kconfig=146=config KVM_AMD\n--\narch/x86/kvm/Kconfig-155-\narch/x86/kvm/Kconfig:156:config KVM_AMD_SEV\narch/x86/kvm/Kconfig-157-\tbool \"AMD Secure Encrypted Virtualization (SEV) support\"\n"
} |
| 82/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 53946 output: 39 thoughts: 0 |
| 83/2 | 2026/09/29 15:31 | tool | read-file |
0mArgs:{
"File": "arch/x86/kvm/Kconfig",
"FirstLine": 145,
"LineCount": 25
}Results: {
"Contents": " 145:\t\n 146:\tconfig KVM_AMD\n 147:\t\ttristate \"KVM for AMD processors support\"\n 148:\t\tdepends on KVM \u0026\u0026 (CPU_SUP_AMD || CPU_SUP_HYGON)\n 149:\t\thelp\n 150:\t\t Provides support for KVM on AMD processors equipped with the AMD-V\n 151:\t\t (SVM) extensions.\n 152:\t\n 153:\t\t To compile this as a module, choose M here: the module\n 154:\t\t will be called kvm-amd.\n 155:\t\n 156:\tconfig KVM_AMD_SEV\n 157:\t\tbool \"AMD Secure Encrypted Virtualization (SEV) support\"\n 158:\t\tdefault y\n 159:\t\tdepends on KVM_AMD \u0026\u0026 X86_64\n 160:\t\tdepends on CRYPTO_DEV_SP_PSP \u0026\u0026 !(KVM_AMD=y \u0026\u0026 CRYPTO_DEV_CCP_DD=m)\n 161:\t\tselect ARCH_HAS_CC_PLATFORM\n 162:\t\tselect KVM_GENERIC_MEMORY_ATTRIBUTES\n 163:\t\tselect HAVE_KVM_ARCH_GMEM_CONVERT\n 164:\t\tselect HAVE_KVM_ARCH_GMEM_RECLAIM\n 165:\t\tselect HAVE_KVM_ARCH_GMEM_INVALIDATE\n 166:\t\tselect HAVE_KVM_ARCH_GMEM_POPULATE\n 167:\t\thelp\n 168:\t\t Provides support for launching encrypted VMs which use Secure\n 169:\t\t Encrypted Virtualization (SEV), Secure Encrypted Virtualization with\n"
} |
| 84/2 | 2026/09/29 15:31 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 54419 output: 37 thoughts: 2401 Thoughts: **Analyzing the KVM Patch for Refactoring and Fuzzing Potential** Okay, let's break this down. My initial focus is on understanding the scope and implications of this patch. It's clear that we're dealing with a significant refactoring within the KVM subsystem, specifically concerning how KVM instances are referenced and managed across different interfaces. My expert eye immediately catches the transition from direct `struct kvm *` pointers and `kvm_get_kvm`/`kvm_put_kvm` to `struct file *` and standard file reference counting. This, on its face, looks like a good move for increased robustness and integration with the kernel's existing file-based resource management. First, I need to pinpoint the exact changes. The core idea is to replace `struct kvm *` with `struct file *`, primarily the anonymous inode file representing the KVM VM. This impacts VFIO, SEV (on x86), and page-tracking mechanisms. I have to trace through each impacted file and function. Looking at the code, `kvm_file_to_kvm_fn` is crucial. The compiler defines the symbol `file_to_kvm_x86`, which expands the `kvm_file_to_kvm_fn` macro. This function checks that the file is actually a KVM VM file (matching `&kvm_vm_fops`). VFIO changes are also interesting. The patch replaces `struct kvm *` with `struct file *` in VFIO structures and function arguments. I note the use of `get_file()` and `fput()` for reference counting, and the elimination of the dynamic `symbol_get/put` calls. `kvm_vfio_file_add` is static but linked via the `kvm_device_ops` structure. This is something I'll keep in mind for further analysis. x86-specific page-tracking code is also impacted. I have to trace through all these call sites and make sure the new file reference counting is working as expected. Similar changes appear in the x86 SEV code. The fact that the core KVM, VFIO, and x86 components are fully reachable in a QEMU/KVM environment on x86_64, coupled with the nature of the changes, strongly suggests this is "WorthFuzzing". Lifecycle management and refactoring often introduce subtle bugs. Next, I need to identify specific "FocusSymbols" – the critical symbols to target for fuzzing. I'll focus on functions involved in the KVM file object life cycle. Key symbols for fuzzing will be `file_to_kvm_x86`, `vfio_file_set_kvm`, `vfio_device_get_kvm_safe`, `vfio_device_put_kvm`, `vfio_group_set_kvm`, and the page track functions: `kvm_page_track_register_notifier`, `kvm_page_track_unregister_notifier`, `kvm_write_track_add_gfn`, `kvm_write_track_remove_gfn`, and SEV's `sev_vm_move_enc_context_from` and `sev_vm_copy_enc_context_from`. The key goal is to assess all possible file/KVM interactions, and ensure correct reference counting and object lifetime. |
| 85/2 | 2026/09/29 15:32 | tool | read-file |
0mArgs:{
"File": "virt/kvm/vfio.c",
"FirstLine": 140,
"LineCount": 45
}Results: {
"Contents": " 140:\t\t}\n 141:\t}\n 142:\t\n 143:\tstatic int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\n 144:\t{\n 145:\t\tstruct kvm_vfio *kv = dev-\u003eprivate;\n 146:\t\tstruct kvm_vfio_file *kvf;\n 147:\t\tstruct file *kvm_file __free(fput) = NULL;\n 148:\t\tstruct file *filp __free(fput) = NULL;\n 149:\t\n 150:\t\tfilp = fget(fd);\n 151:\t\tif (!filp)\n 152:\t\t\treturn -EBADF;\n 153:\t\n 154:\t\t/* Ensure the FD is a vfio FD. */\n 155:\t\tif (!kvm_vfio_file_is_valid(filp))\n 156:\t\t\treturn -EINVAL;\n 157:\t\n 158:\t\tkvm_file = get_file_active(\u0026dev-\u003ekvm-\u003efile);\n 159:\t\tif (!kvm_file)\n 160:\t\t\treturn -ENOENT;\n 161:\t\n 162:\t\tguard(mutex)(\u0026kv-\u003elock);\n 163:\t\n 164:\t\tlist_for_each_entry(kvf, \u0026kv-\u003efile_list, node) {\n 165:\t\t\tif (kvf-\u003efile == filp)\n 166:\t\t\t\treturn -EEXIST;\n 167:\t\t}\n 168:\t\n 169:\t\tkvf = kzalloc_obj(*kvf, GFP_KERNEL_ACCOUNT);\n 170:\t\tif (!kvf)\n 171:\t\t\treturn -ENOMEM;\n 172:\t\n 173:\t\tkvf-\u003efile = get_file(filp);\n 174:\t\tlist_add_tail(\u0026kvf-\u003enode, \u0026kv-\u003efile_list);\n 175:\t\n 176:\t\tkvm_vfio_file_set_kvm(kvf-\u003efile, kvm_file);\n 177:\t\tkvm_vfio_update_coherency(dev);\n 178:\t\n 179:\t\treturn 0;\n 180:\t}\n 181:\t\n 182:\tstatic void kvm_vfio_file_free(struct kvm_device *dev, struct kvm_vfio_file *kvf)\n 183:\t{\n 184:\t#ifdef CONFIG_SPAPR_TCE_IOMMU\n"
} |
| 86/2 | 2026/09/29 15:32 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 58275 output: 38 thoughts: 52 Thoughts: Here's my analysis of the provided snippet, framed as my own thought process: **Diving into the KVM/VFIO Code** Okay, so I'm looking at `kvm_vfio_file_set_kvm` – interesting, it's also declared `static` within `virt/kvm/vfio.c`. That gives me a few immediate assumptions about the scope and potential visibility of this function. Now, I need to understand its relationship to `kvm_vfio_file_add`. My next step is clear: I need to quickly identify all the call sites to `kvm_vfio_file_add`. This will show me where the function is being used, how it fits into the larger VFIO/KVM architecture, and what other components or functions are involved in setting up the environment. From that, I can infer the purpose of this particular set of interactions. |
| 87/2 | 2026/09/29 15:32 | tool | grepper |
0mArgs:{
"Expression": "kvm_vfio_file_add",
"PathPrefix": "virt/kvm/vfio.c"
}Results: {
"Output": "virt/kvm/vfio.c=120=static void kvm_vfio_update_coherency(struct kvm_device *dev)\n--\nvirt/kvm/vfio.c-142-\nvirt/kvm/vfio.c:143:static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)\nvirt/kvm/vfio.c-144-{\n--\nvirt/kvm/vfio.c=250=static int kvm_vfio_set_file(struct kvm_device *dev, long attr,\n--\nvirt/kvm/vfio.c-259-\t\t\treturn -EFAULT;\nvirt/kvm/vfio.c:260:\t\treturn kvm_vfio_file_add(dev, fd);\nvirt/kvm/vfio.c-261-\n"
} |
| 88/2 | 2026/09/29 15:32 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 58788 output: 37 thoughts: 704 Thoughts: **Analyzing KVM VFIO File Operations and Symbol Visibility** Okay, let's break this down systematically. My primary concern here is function symbol visibility, particularly in the context of KVM VFIO interactions. I'm focusing on the call chain starting with `kvm_vfio_set_file`, which is reached via `kvm_vfio_set_attr`, the `ops->set_attr` implementation for `kvm_vfio_ops`. First, I'm considering if I can utilize `kvm_vfio_file_add` within FocusSymbols. It's a static, non-inlined function. Typically, functions like this are present in the symbol table, especially in kernels built with debug options (-g or when kallsyms is enabled). However, I also know that globally exported functions such as `vfio_file_set_kvm`, `vfio_device_get_kvm_safe`, `vfio_device_put_kvm`, `vfio_group_set_kvm`, `file_to_kvm_x86`, `kvm_page_track_register_notifier`, `kvm_page_track_unregister_notifier`, `kvm_write_track_add_gfn`, `kvm_write_track_remove_gfn`, `sev_vm_move_enc_context_from`, and `sev_vm_copy_enc_context_from` are definitely valid and exposed symbols. Next, I'm drilling down into the relationship between `file_to_kvm_x86` and `kvm_file_to_kvm_fn`. My analysis of the code in `virt/kvm/kvm_main.c` indicates that the function is conditionally compiled: If `kvm_file_to_kvm_arch` is defined, `kvm_file_to_kvm_fn` expands to `file_to_kvm_x86` because of the `CONCATENATE` macro in `include/linux/kvm_host.h`. The definition of `kvm_file_to_kvm_arch` in `arch/x86/include/asm/kvm_host.h` resolves this to `x86`. Therefore, `kvm_file_to_kvm_fn` effectively becomes `file_to_kvm_x86` and it is an exported symbol. Consequently, I definitely want to include `file_to_kvm_x86`. Finally, it's crucial to understand the required Kconfig options. For KVM itself, `KVM` is the base requirement. This is likely conditioned on either `KVM_INTEL` or `KVM_AMD` on x86, or the more generic `KVM_X86`. To verify the exact dependencies, I need to check the `arch/x86/kvm/Kconfig` file. I need to ensure all relevant KVM configuration options are enabled for correct operation and symbol visibility. |
| 89/2 | 2026/09/29 15:32 | tool | read-file |
0mArgs:{
"File": "arch/x86/kvm/Kconfig",
"FirstLine": 1,
"LineCount": 55
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0\n 2:\t#\n 3:\t# KVM configuration\n 4:\t#\n 5:\t\n 6:\tsource \"virt/kvm/Kconfig\"\n 7:\t\n 8:\tmenuconfig VIRTUALIZATION\n 9:\t\tbool \"Virtualization\"\n 10:\t\tdefault y\n 11:\t\thelp\n 12:\t\t Say Y here to get to see options for using your Linux host to run other\n 13:\t\t operating systems inside virtual machines (guests).\n 14:\t\t This option alone does not add any kernel code.\n 15:\t\n 16:\t\t If you say N, all options in this submenu will be skipped and disabled.\n 17:\t\n 18:\tif VIRTUALIZATION\n 19:\t\n 20:\tconfig KVM_X86\n 21:\t\tdef_tristate KVM if (KVM_INTEL != n || KVM_AMD != n)\n 22:\t\tselect KVM_COMMON\n 23:\t\tselect KVM_ELIDE_TLB_FLUSH_IF_YOUNG\n 24:\t\tselect KVM_MMU_LOCKLESS_AGING\n 25:\t\tselect HAVE_KVM_IRQCHIP\n 26:\t\tselect HAVE_KVM_PFNCACHE\n 27:\t\tselect HAVE_KVM_DIRTY_RING_TSO\n 28:\t\tselect HAVE_KVM_DIRTY_RING_ACQ_REL\n 29:\t\tselect HAVE_KVM_IRQ_BYPASS\n 30:\t\tselect HAVE_KVM_IRQ_ROUTING\n 31:\t\tselect HAVE_KVM_READONLY_MEM\n 32:\t\tselect VHOST_TASK\n 33:\t\tselect KVM_ASYNC_PF\n 34:\t\tselect USER_RETURN_NOTIFIER\n 35:\t\tselect KVM_MMIO\n 36:\t\tselect SCHED_INFO\n 37:\t\tselect PERF_EVENTS\n 38:\t\tselect GUEST_PERF_EVENTS\n 39:\t\tselect PERF_GUEST_MEDIATED_PMU\n 40:\t\tselect HAVE_KVM_MSI\n 41:\t\tselect HAVE_KVM_CPU_RELAX_INTERCEPT\n 42:\t\tselect HAVE_KVM_NO_POLL\n 43:\t\tselect VIRT_XFER_TO_GUEST_WORK\n 44:\t\tselect KVM_GENERIC_DIRTYLOG_READ_PROTECT\n 45:\t\tselect KVM_VFIO\n 46:\t\tselect HAVE_KVM_PM_NOTIFIER if PM\n 47:\t\tselect KVM_GENERIC_HARDWARE_ENABLING\n 48:\t\tselect KVM_GENERIC_PRE_FAULT_MEMORY\n 49:\t\tselect KVM_WERROR if WERROR\n 50:\t\tselect KVM_GUEST_MEMFD if X86_64\n 51:\t\n 52:\tconfig KVM\n 53:\t\ttristate \"Kernel-based Virtual Machine (KVM) support\"\n 54:\t\tdepends on X86_LOCAL_APIC\n 55:\t\thelp\n"
} |
| 90/2 | 2026/09/29 15:32 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 60979 output: 40 thoughts: 207 Thoughts: Okay, let me break this down. **KVM Configuration Deep Dive** Alright, so the KVM module, when configured, is selecting `KVM_VFIO`. That makes sense. `KVM_VFIO` is being brought in through `KVM_X86`, which is defined as KVM if *either* KVM_INTEL *or* KVM_AMD are not disabled. Got it. And this `VFIO` configuration, naturally, lives in `drivers/vfio/Kconfig`. Standard location. Nothing surprising there. Looking at `VFIO_GROUP`, that's defaulted to 'y'. Makes sense, since VFIO is core functionality these days. I also see that `KVM_AMD` is related to SEV – which means `KVM_AMD_SEV` depends on `KVM_AMD`, obviously. Straightforward. Now, this `KVM_EXTERNAL_WRITE_TRACKING` option… that's selected by `DRM_I915_GVT_KVMGT`. Okay, that's the Intel GVT-g driver which is a good use case for external write tracking... but wait a minute... Does that mean `KVM_EXTERNAL_WRITE_TRACKING` is specifically needed for `kvm_page_track_register_notifier`? That's a key question, especially for performance. Let's quickly check `arch/x86/kvm/mmu/page_track.c` to confirm. I'll need to double check the dependency there. |
| 91/2 | 2026/09/29 15:32 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_KVM_EXTERNAL_WRITE_TRACKING",
"PathPrefix": "arch/x86/kvm/"
}Results: {
"Output": "arch/x86/kvm/mmu/page_track.c=25=static bool kvm_external_write_tracking_enabled(struct kvm *kvm)\narch/x86/kvm/mmu/page_track.c-26-{\narch/x86/kvm/mmu/page_track.c:27:#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING\narch/x86/kvm/mmu/page_track.c-28-\t/*\n--\narch/x86/kvm/mmu/page_track.c=148=bool kvm_gfn_is_write_tracked(struct kvm *kvm,\n--\narch/x86/kvm/mmu/page_track.c-172-\narch/x86/kvm/mmu/page_track.c:173:#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING\narch/x86/kvm/mmu/page_track.c-174-void kvm_page_track_cleanup(struct kvm *kvm)\n--\narch/x86/kvm/mmu/page_track.h=23=bool kvm_gfn_is_write_tracked(struct kvm *kvm,\n--\narch/x86/kvm/mmu/page_track.h-25-\narch/x86/kvm/mmu/page_track.h:26:#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING\narch/x86/kvm/mmu/page_track.h-27-int kvm_page_track_init(struct kvm *kvm);\n--\narch/x86/kvm/mmu/page_track.h=46=static inline bool kvm_page_track_has_external_user(struct kvm *kvm) { return false; }\narch/x86/kvm/mmu/page_track.h-47-\narch/x86/kvm/mmu/page_track.h:48:#endif /* CONFIG_KVM_EXTERNAL_WRITE_TRACKING */\narch/x86/kvm/mmu/page_track.h-49-\n"
} |
| 92/2 | 2026/09/29 15:32 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 62115 output: 392 thoughts: 1027 Thoughts: **Analysis of KVM External Write Tracking and VFIO/SEV Integration for Fuzzing** Okay, here's the breakdown of my thought process. I've zeroed in on the `CONFIG_KVM_EXTERNAL_WRITE_TRACKING` configuration option. Specifically, I see that it's the `DRM_I915_GVT_KVMGT` option that selects `KVM_EXTERNAL_WRITE_TRACKING`. This is key. Line 173 of `arch/x86/kvm/mmu/page_track.c` confirms that the external write tracking functions, like `kvm_page_track_register_notifier`, are guarded by this configuration. My first check was to determine which symbols might be affected by this conditional compilation. I meticulously reviewed the list of `FocusSymbols` to understand the scope of the change. This includes functions related to KVM VFIO device attachment, VFIO core entrypoints, VFIO group and device KVM reference management, file-to-KVM x86 conversion, SEV context transfers, and importantly, the page tracking notifier registration and unregistration, alongside write tracking functions. A crucial point is that none of these functions are ubiquitous. They are exclusively involved in KVM, VFIO, and SEV ioctls and device operations. This narrows down the potential attack surface. Now, let's look at the enabling conditions. I carefully verified the `EnableConfigs` list. This confirms we are dealing with KVM, KVM_AMD, VFIO, KVM_VFIO, and importantly, `DRM_I915_GVT_KVMGT`, to enable external write tracking. Finally, I validated all the requirements for this analysis: `WorthFuzzing`, the reasoning (that this code is reachable because of the refactoring of KVM reference tracking across external subsystems like VFIO, SEV, and x86 page track to use `struct file *` and file refcounting instead of direct `struct kvm *` pointer sharing and `kvm_get_kvm`/`kvm_put_kvm`, and how this affects object lifetimes and concurrency), `FocusSymbols`, and `EnableConfigs`. Everything is spot on. I'm confident in these findings. It's time to trigger `set-results`. |
| 93/2 | 2026/09/29 15:32 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"KVM",
"KVM_AMD",
"VFIO",
"KVM_VFIO",
"DRM_I915_GVT_KVMGT"
],
"FocusSymbols": [
"kvm_vfio_file_add",
"vfio_file_set_kvm",
"vfio_group_set_kvm",
"vfio_device_get_kvm_safe",
"vfio_device_put_kvm",
"file_to_kvm_x86",
"sev_vm_move_enc_context_from",
"sev_vm_copy_enc_context_from",
"kvm_page_track_register_notifier",
"kvm_page_track_unregister_notifier",
"kvm_write_track_add_gfn",
"kvm_write_track_remove_gfn"
],
"Reasoning": "The patch modifies reachable KVM and VFIO subsystem code on amd64. It refactors external subsystem integration (VFIO, SEV, and x86 page tracking) to track KVM instances by 'struct file *' instead of direct 'struct kvm *' pointers. This refactoring alters object lifetime management and reference counting (introducing get_file_active(), get_file(), fput(), and clearing kvm-\u003efile in kvm_vm_release()), as well as type-safe arch-namespaced file-to-kvm resolution (file_to_kvm_x86). These paths are reachable via standard KVM and VFIO ioctls and warrant fuzzing to uncover potential race conditions, UAFs, or refcount imbalances during concurrent VM lifecycle operations.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"KVM",
"KVM_AMD",
"VFIO",
"KVM_VFIO",
"DRM_I915_GVT_KVMGT"
],
"FocusSymbols": [
"kvm_vfio_file_add",
"vfio_file_set_kvm",
"vfio_group_set_kvm",
"vfio_device_get_kvm_safe",
"vfio_device_put_kvm",
"file_to_kvm_x86",
"sev_vm_move_enc_context_from",
"sev_vm_copy_enc_context_from",
"kvm_page_track_register_notifier",
"kvm_page_track_unregister_notifier",
"kvm_write_track_add_gfn",
"kvm_write_track_remove_gfn"
],
"Reasoning": "The patch modifies reachable KVM and VFIO subsystem code on amd64. It refactors external subsystem integration (VFIO, SEV, and x86 page tracking) to track KVM instances by 'struct file *' instead of direct 'struct kvm *' pointers. This refactoring alters object lifetime management and reference counting (introducing get_file_active(), get_file(), fput(), and clearing kvm-\u003efile in kvm_vm_release()), as well as type-safe arch-namespaced file-to-kvm resolution (file_to_kvm_x86). These paths are reachable via standard KVM and VFIO ioctls and warrant fuzzing to uncover potential race conditions, UAFs, or refcount imbalances during concurrent VM lifecycle operations.",
"WorthFuzzing": true
} |
| 94/1 | 2026/09/29 15:32 | action | If |
1mArgs:{
"WorthFuzzing": true
}Results: null |
| 95/2 | 2026/09/29 15:32 | agent | kmsan-evaluator |
1mModel:core Args: null Results: {
"KMSANReasoning": "The patch refactors the interface between KVM and external subsystems (VFIO, page tracking, s390 PCI / vfio_ap) so that external subsystems hold references to the KVM VM `struct file` (using `get_file()` and `fput()`) rather than directly holding references to `struct kvm` (using `kvm_get_kvm()` / `kvm_put_kvm()`), and resolves the VM instance using arch-namespaced helpers (`file_to_kvm_\u003carch\u003e`).\n\nThis refactoring touches object reference management, pointer passing, and lifecycle coordination. All newly introduced local variables and struct members are explicitly initialized before use. No kernel-to-user memory copy operations (e.g. copy_to_user, put_user), uninitialized struct allocations, or buffer length calculations are introduced or modified. Any risks introduced by these changes are limited to object lifetimes, use-after-free, reference leaks, or NULL pointer dereferences, which are covered by standard KASAN, LOCKDEP, and built-in kernel diagnostics. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
"NeedsKMSAN": false
}Instruction: You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.
CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
a comprehensive suite of debugging tools and sanitizers, including KASAN
(out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
(locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
or page allocations) and kernel-to-user memory info-leaks.
Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.
Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.
Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
attributes, ioctl output arguments, socket options, or BPF buffers) where fields
or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
uninitialized bytes of existing buffers.
Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
dereferences, locking deadlocks, or use-after-free bugs (these are already caught
by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.
Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 11fd22d39468642a418c5aacd0251911ee9247dc
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Sep 29 15:23:10 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/s390/include/asm/kvm_host_s390.h b/arch/s390/include/asm/kvm_host_s390.h
index cd692f8fb7643..9519b8028b104 100644
--- a/arch/s390/include/asm/kvm_host_s390.h
+++ b/arch/s390/include/asm/kvm_host_s390.h
@@ -27,6 +27,8 @@
#include <asm/isc.h>
#include <asm/guarded_storage.h>
+#define kvm_file_to_kvm_arch s390
+
#define KVM_HAVE_MMU_RWLOCK
#define KVM_MAX_VCPUS 255
@@ -720,7 +722,7 @@ static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
void kvm_arch_free_vm(struct kvm *kvm);
struct zpci_kvm_hook {
- int (*kvm_register)(void *opaque, struct kvm *kvm);
+ int (*kvm_register)(void *opaque, struct file *kvm_file);
void (*kvm_unregister)(void *opaque);
};
diff --git a/arch/s390/kvm/s390/pci.c b/arch/s390/kvm/s390/pci.c
index 82892e1e03d94..d79bd3bdc68e9 100644
--- a/arch/s390/kvm/s390/pci.c
+++ b/arch/s390/kvm/s390/pci.c
@@ -498,17 +498,22 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)
* available, enable them and let userspace indicate whether or not they will
* be used (specify SHM bit to disable).
*/
-static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
+static int kvm_s390_pci_register_kvm(void *opaque, struct file *kvm_file)
{
struct zpci_dev *zdev = opaque;
+ struct kvm *kvm;
int rc;
if (!zdev)
return -EINVAL;
+ kvm = file_to_kvm_s390(kvm_file);
+ if (!kvm)
+ return -ENOENT;
+
mutex_lock(&zdev->kzdev_lock);
- if (zdev->kzdev || zdev->gisa != 0 || !kvm) {
+ if (zdev->kzdev || zdev->gisa != 0) {
mutex_unlock(&zdev->kzdev_lock);
return -EINVAL;
}
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 683bb8bf43a94..e460073ff176d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -44,6 +44,8 @@
#include <hyperv/hvhdk.h>
+#define kvm_file_to_kvm_arch x86
+
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
/*
diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h
index 3d040741044b4..ea885dd5c9aff 100644
--- a/arch/x86/include/asm/kvm_page_track.h
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -44,13 +44,15 @@ struct kvm_page_track_notifier_node {
struct kvm_page_track_notifier_node *node);
};
-int kvm_page_track_register_notifier(struct kvm *kvm,
+struct file;
+
+int kvm_page_track_register_notifier(struct file *file,
struct kvm_page_track_notifier_node *n);
-void kvm_page_track_unregister_notifier(struct kvm *kvm,
+void kvm_page_track_unregister_notifier(struct file *file,
struct kvm_page_track_notifier_node *n);
-int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);
-int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);
+int kvm_write_track_add_gfn(struct file *file, gfn_t gfn);
+int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn);
#else
/*
* Allow defining a node in a structure even if page tracking is disabled, e.g.
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 0474604ab8a14..c6bf463f50327 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -61,9 +61,7 @@ exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/a
-e kvm_page_track_unregister_notifier \
-e kvm_write_track_add_gfn \
-e kvm_write_track_remove_gfn \
- -e kvm_get_kvm \
- -e kvm_get_kvm_safe \
- -e kvm_put_kvm
+ -e kvm_file_to_kvm_fn
# Force grep to emit a goofy group separator that can in turn be replaced with
# the above newline macro (newlines in Make are a nightmare). Note, grep only
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 7e8195a311bb0..f12558dfcd812 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -16,6 +16,8 @@
#include <linux/kvm_host.h>
#include <linux/rculist.h>
+#include <asm/kvm_page_track.h>
+
#include "mmu.h"
#include "mmu_internal.h"
#include "page_track.h"
@@ -237,10 +239,11 @@ static int kvm_enable_external_write_tracking(struct kvm *kvm)
* register the notifier so that event interception for the tracked guest
* pages can be received.
*/
-int kvm_page_track_register_notifier(struct kvm *kvm,
+int kvm_page_track_register_notifier(struct file *file,
struct kvm_page_track_notifier_node *n)
{
struct kvm_page_track_notifier_head *head;
+ struct kvm *kvm = file_to_kvm_x86(file);
int r;
if (!kvm || kvm->mm != current->mm)
@@ -252,7 +255,7 @@ int kvm_page_track_register_notifier(struct kvm *kvm,
return r;
}
- kvm_get_kvm(kvm);
+ get_file(file);
head = &kvm->arch.track_notifier_head;
@@ -267,10 +270,11 @@ EXPORT_SYMBOL_GPL(kvm_page_track_register_notifier);
* stop receiving the event interception. It is the opposed operation of
* kvm_page_track_register_notifier().
*/
-void kvm_page_track_unregister_notifier(struct kvm *kvm,
+void kvm_page_track_unregister_notifier(struct file *file,
struct kvm_page_track_notifier_node *n)
{
struct kvm_page_track_notifier_head *head;
+ struct kvm *kvm = file_to_kvm_x86(file);
head = &kvm->arch.track_notifier_head;
@@ -279,7 +283,7 @@ void kvm_page_track_unregister_notifier(struct kvm *kvm,
write_unlock(&kvm->mmu_lock);
synchronize_srcu(&head->track_srcu);
- kvm_put_kvm(kvm);
+ fput(file);
}
EXPORT_SYMBOL_GPL(kvm_page_track_unregister_notifier);
@@ -336,11 +340,12 @@ void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
* add guest page to the tracking pool so that corresponding access on that
* page will be intercepted.
*
- * @kvm: the guest instance we are interested in.
+ * @file: the VM file of the guest instance we are interested in.
* @gfn: the guest page.
*/
-int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn)
+int kvm_write_track_add_gfn(struct file *file, gfn_t gfn)
{
+ struct kvm *kvm = file_to_kvm_x86(file);
struct kvm_memory_slot *slot;
int idx;
@@ -366,11 +371,12 @@ EXPORT_SYMBOL_GPL(kvm_write_track_add_gfn);
* remove the guest page from the tracking pool which stops the interception
* of corresponding access on that page.
*
- * @kvm: the guest instance we are interested in.
+ * @file: the VM file of the guest instance we are interested in.
* @gfn: the guest page.
*/
-int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn)
+int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn)
{
+ struct kvm *kvm = file_to_kvm_x86(file);
struct kvm_memory_slot *slot;
int idx;
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 63eb2155a7749..db7ed11e9056f 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -2151,10 +2151,10 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
if (fd_empty(f))
return -EBADF;
- if (!file_is_kvm(fd_file(f)))
+ source_kvm = file_to_kvm_x86(fd_file(f));
+ if (!source_kvm)
return -EBADF;
- source_kvm = fd_file(f)->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
return ret;
@@ -2876,10 +2876,10 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
if (fd_empty(f))
return -EBADF;
- if (!file_is_kvm(fd_file(f)))
+ source_kvm = file_to_kvm_x86(fd_file(f));
+ if (!source_kvm)
return -EBADF;
- source_kvm = fd_file(f)->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
return ret;
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 4db878c18f41c..373ce574c4319 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1822,17 +1822,27 @@ static const struct attribute_group *vfio_ap_mdev_attr_groups[] = {
/**
* vfio_ap_mdev_set_kvm - sets all data for @matrix_mdev that are needed
- * to manage AP resources for the guest whose state is represented by @kvm
+ * to manage AP resources for the guest whose state is represented by
+ * @kvm_file
*
* @matrix_mdev: a mediated matrix device
- * @kvm: reference to KVM instance
+ * @kvm_file: the KVM VM file this vfio device is associated with
*
- * Return: 0 if no other mediated matrix device has a reference to @kvm;
+ * Return: 0 if no other mediated matrix device has a reference to the VM;
* otherwise, returns an -EPERM.
*/
static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
- struct kvm *kvm)
+ struct file *kvm_file)
{
+ struct kvm *kvm;
+
+ if (!kvm_file)
+ return -ENOENT;
+
+ kvm = file_to_kvm_s390(kvm_file);
+ if (!kvm)
+ return -ENOENT;
+
if (kvm->arch.crypto.crycbd) {
get_update_locks_for_kvm(kvm);
if (kvm->arch.crypto.pqap_hook) {
@@ -1841,7 +1851,6 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
}
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
- kvm_get_kvm(kvm);
matrix_mdev->kvm = kvm;
vfio_ap_mdev_update_guest_apcb(matrix_mdev);
release_update_locks_for_kvm(kvm);
@@ -1894,7 +1903,6 @@ static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
matrix_mdev->kvm = NULL;
release_update_locks_for_kvm(kvm);
- kvm_put_kvm(kvm);
}
}
diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
index b2299e5bc6df3..5bf8cbdff377c 100644
--- a/drivers/vfio/group.c
+++ b/drivers/vfio/group.c
@@ -860,11 +860,20 @@ bool vfio_group_enforced_coherent(struct vfio_group *group)
return ret;
}
-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
+void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)
{
+ struct file *old;
+
+ if (kvm)
+ get_file(kvm);
+
spin_lock(&group->kvm_ref_lock);
+ old = group->kvm;
group->kvm = kvm;
spin_unlock(&group->kvm_ref_lock);
+
+ if (old)
+ fput(old);
}
/**
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index 7728bc99b63d1..9b619951a5d0c 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -23,7 +23,7 @@ struct vfio_device_file {
u8 access_granted;
u32 devid; /* only valid when iommufd is valid */
spinlock_t kvm_ref_lock; /* protect kvm field */
- struct kvm *kvm;
+ struct file *kvm;
struct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */
};
@@ -88,7 +88,7 @@ struct vfio_group {
#endif
enum vfio_group_type type;
struct mutex group_lock;
- struct kvm *kvm;
+ struct file *kvm;
struct file *opened_file;
struct iommufd_ctx *iommufd;
spinlock_t kvm_ref_lock;
@@ -107,7 +107,7 @@ void vfio_device_group_unuse_iommu(struct vfio_device *device);
void vfio_df_group_close(struct vfio_device_file *df);
struct vfio_group *vfio_group_from_file(struct file *file);
bool vfio_group_enforced_coherent(struct vfio_group *group);
-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);
+void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm);
bool vfio_device_has_container(struct vfio_device *device);
int __init vfio_group_init(void);
void vfio_group_cleanup(void);
@@ -165,7 +165,7 @@ static inline bool vfio_group_enforced_coherent(struct vfio_group *group)
return true;
}
-static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
+static inline void vfio_group_set_kvm(struct vfio_group *group, struct file *kvm)
{
}
@@ -429,11 +429,11 @@ static inline void vfio_virqfd_exit(void)
#endif
#if IS_ENABLED(CONFIG_KVM)
-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
+void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm);
void vfio_device_put_kvm(struct vfio_device *device);
#else
static inline void vfio_device_get_kvm_safe(struct vfio_device *device,
- struct kvm *kvm)
+ struct file *kvm)
{
}
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 423ead48aafe3..ed96acfa86358 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -472,36 +472,14 @@ void vfio_unregister_group_dev(struct vfio_device *device)
EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
#if IS_ENABLED(CONFIG_KVM)
-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)
+void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)
{
- void (*pfn)(struct kvm *kvm);
- bool (*fn)(struct kvm *kvm);
- bool ret;
-
lockdep_assert_held(&device->dev_set->lock);
if (!kvm)
return;
- pfn = symbol_get(kvm_put_kvm);
- if (WARN_ON(!pfn))
- return;
-
- fn = symbol_get(kvm_get_kvm_safe);
- if (WARN_ON(!fn)) {
- symbol_put(kvm_put_kvm);
- return;
- }
-
- ret = fn(kvm);
- symbol_put(kvm_get_kvm_safe);
- if (!ret) {
- symbol_put(kvm_put_kvm);
- return;
- }
-
- device->put_kvm = pfn;
- device->kvm = kvm;
+ device->kvm = get_file(kvm);
}
void vfio_device_put_kvm(struct vfio_device *device)
@@ -511,14 +489,7 @@ void vfio_device_put_kvm(struct vfio_device *device)
if (!device->kvm)
return;
- if (WARN_ON(!device->put_kvm))
- goto clear;
-
- device->put_kvm(device->kvm);
- device->put_kvm = NULL;
- symbol_put(kvm_put_kvm);
-
-clear:
+ fput(device->kvm);
device->kvm = NULL;
}
#endif
@@ -1544,9 +1515,13 @@ bool vfio_file_enforced_coherent(struct file *file)
}
EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
-static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
+static void vfio_device_file_set_kvm(struct file *file, struct file *kvm)
{
struct vfio_device_file *df = file->private_data;
+ struct file *old;
+
+ if (kvm)
+ get_file(kvm);
/*
* The kvm is first recorded in the vfio_device_file, and will
@@ -1554,28 +1529,32 @@ static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
* iommufd successfully in the vfio device cdev path.
*/
spin_lock(&df->kvm_ref_lock);
+ old = df->kvm;
df->kvm = kvm;
spin_unlock(&df->kvm_ref_lock);
+
+ if (old)
+ fput(old);
}
/**
* vfio_file_set_kvm - Link a kvm with VFIO drivers
- * @file: VFIO group file or VFIO device file
- * @kvm: KVM to link
+ * @vfio_file: VFIO group file or VFIO device file
+ * @kvm: KVM file to link
*
* When a VFIO device is first opened the KVM will be available in
* device->kvm if one was associated with the file.
*/
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm)
+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)
{
struct vfio_group *group;
- group = vfio_group_from_file(file);
+ group = vfio_group_from_file(vfio_file);
if (group)
vfio_group_set_kvm(group, kvm);
- if (vfio_device_from_file(file))
- vfio_device_file_set_kvm(file, kvm);
+ if (vfio_device_from_file(vfio_file))
+ vfio_device_file_set_kvm(vfio_file, kvm);
}
EXPORT_SYMBOL_GPL(vfio_file_set_kvm);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index cf7fe835c4ad2..586f6e8bb81b3 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -784,6 +784,12 @@ struct kvm {
* kvm_swap_active_memslots().
*/
struct mutex slots_arch_lock;
+ /*
+ * Back-reference to the VM file for subsystems (e.g., VFIO). Holds no
+ * reference to avoid pinning the VM. Callers storing the file must
+ * take their own reference.
+ */
+ struct file *file;
struct mm_struct *mm; /* userspace tied to this vm */
unsigned long nr_memslot_pages;
/* The two memslot sets - active and inactive (per address space) */
@@ -1081,7 +1087,18 @@ void kvm_exit(void);
void kvm_get_kvm(struct kvm *kvm);
bool kvm_get_kvm_safe(struct kvm *kvm);
void kvm_put_kvm(struct kvm *kvm);
-bool file_is_kvm(struct file *file);
+
+/*
+ * Architectures define kvm_file_to_kvm_arch to <arch>
+ * to get a typed, arch-namespaced helper:
+ *
+ * struct kvm *file_to_kvm_<arch>(struct file *file)
+ */
+#ifdef kvm_file_to_kvm_arch
+#define kvm_file_to_kvm_fn CONCATENATE(file_to_kvm_, kvm_file_to_kvm_arch)
+struct kvm *kvm_file_to_kvm_fn(struct file *file);
+#endif /* kvm_file_to_kvm_arch */
+
void kvm_put_kvm_no_destroy(struct kvm *kvm);
static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 45f08986359e4..0cc91c6f96d2b 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -54,7 +54,7 @@ struct vfio_device {
struct list_head dev_set_list;
unsigned int migration_flags;
u8 precopy_info_v2;
- struct kvm *kvm;
+ struct file *kvm;
/* Members below here are private, not for driver use */
unsigned int index;
@@ -66,7 +66,6 @@ struct vfio_device {
unsigned int open_count;
struct completion comp;
struct iommufd_access *iommufd_access;
- void (*put_kvm)(struct kvm *kvm);
struct inode *inode;
#if IS_ENABLED(CONFIG_IOMMUFD)
struct iommufd_device *iommufd_device;
@@ -378,7 +377,7 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi
#endif
bool vfio_file_is_valid(struct file *file);
bool vfio_file_enforced_coherent(struct file *file);
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm);
+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm);
#define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long))
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 85f42289748dc..60e614795a36c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1314,7 +1314,7 @@ void kvm_get_kvm(struct kvm *kvm)
{
refcount_inc(&kvm->users_count);
}
-EXPORT_SYMBOL_GPL(kvm_get_kvm);
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_kvm);
/*
* Make sure the vm is not during destruction, which is a safe version of
@@ -1324,14 +1324,14 @@ bool kvm_get_kvm_safe(struct kvm *kvm)
{
return refcount_inc_not_zero(&kvm->users_count);
}
-EXPORT_SYMBOL_GPL(kvm_get_kvm_safe);
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_kvm_safe);
void kvm_put_kvm(struct kvm *kvm)
{
if (refcount_dec_and_test(&kvm->users_count))
kvm_destroy_vm(kvm);
}
-EXPORT_SYMBOL_GPL(kvm_put_kvm);
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_put_kvm);
/*
* Used to put a reference that was taken on behalf of an object associated
@@ -1352,6 +1352,8 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
kvm_irqfd_release(kvm);
+ WRITE_ONCE(kvm->file, NULL);
+
kvm_put_kvm(kvm);
return 0;
}
@@ -5513,11 +5515,16 @@ static struct file_operations kvm_vm_fops = {
KVM_COMPAT(kvm_vm_compat_ioctl),
};
-bool file_is_kvm(struct file *file)
+#ifdef kvm_file_to_kvm_arch
+struct kvm *kvm_file_to_kvm_fn(struct file *file)
{
- return file && file->f_op == &kvm_vm_fops;
+ if (!file || file->f_op != &kvm_vm_fops)
+ return NULL;
+
+ return file->private_data;
}
-EXPORT_SYMBOL_FOR_KVM_INTERNAL(file_is_kvm);
+EXPORT_SYMBOL_GPL(kvm_file_to_kvm_fn);
+#endif
static int kvm_dev_ioctl_create_vm(unsigned long type)
{
@@ -5544,6 +5551,8 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
goto put_kvm;
}
+ kvm->file = file;
+
/*
* Don't call kvm_put_kvm anymore at this point; file->f_op is
* already set, with ->release() being kvm_vm_release(). In error
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
index 6cdc4e9a333a3..19548a4309426 100644
--- a/virt/kvm/vfio.c
+++ b/virt/kvm/vfio.c
@@ -35,15 +35,15 @@ struct kvm_vfio {
bool noncoherent;
};
-static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm)
+static void kvm_vfio_file_set_kvm(struct file *vfio_file, struct file *kvm)
{
- void (*fn)(struct file *file, struct kvm *kvm);
+ void (*fn)(struct file *vfio_file, struct file *kvm);
fn = symbol_get(vfio_file_set_kvm);
if (!fn)
return;
- fn(file, kvm);
+ fn(vfio_file, kvm);
symbol_put(vfio_file_set_kvm);
}
@@ -144,6 +144,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
{
struct kvm_vfio *kv = dev->private;
struct kvm_vfio_file *kvf;
+ struct file *kvm_file __free(fput) = NULL;
struct file *filp __free(fput) = NULL;
filp = fget(fd);
@@ -154,6 +155,10 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
if (!kvm_vfio_file_is_valid(filp))
return -EINVAL;
+ kvm_file = get_file_active(&dev->kvm->file);
+ if (!kvm_file)
+ return -ENOENT;
+
guard(mutex)(&kv->lock);
list_for_each_entry(kvf, &kv->file_list, node) {
@@ -168,7 +173,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
kvf->file = get_file(filp);
list_add_tail(&kvf->node, &kv->file_list);
- kvm_vfio_file_set_kvm(kvf->file, dev->kvm);
+ kvm_vfio_file_set_kvm(kvf->file, kvm_file);
kvm_vfio_update_coherency(dev);
return 0;
|
| 96/3 | 2026/09/29 15:32 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11063 output: 31 thoughts: 1844 Thoughts: **KMSAN Fuzzing Evaluation for KVM Patch Series** Okay, let's break this down. My primary concern is whether this patch series, targeting amd64, introduces new risks for uninitialized memory accesses. I need to determine if standard KASAN fuzzing will be sufficient or if a dedicated KMSAN session is required. First, I've got to understand the changes. The patch series is refactoring KVM's interaction with `struct file` to represent KVM contexts and VFIO interfaces. It seems to be replacing direct `struct kvm *` pointers in various VFIO and KVM subsystems with `struct file *`. This mainly concerns reference counting of the `struct file` and `struct kvm` and making sure that the relevant pointers are being updated consistently. I've examined the changes and reviewed the questions. I don't see any direct indications of user-space data exposure via `copy_to_user`, `put_user`, netlink, ioctl output, sockets, or BPF buffers that might lead to uninitialized memory disclosures. I also checked for conditional logic dependent on potentially uninitialized variables. Local variables within the modified functions seem to be initialized immediately, either directly or by assignment, prior to use. I need to be sure that the `struct kvm` pointer to the `struct file` is initialized safely, too. Now I need to ensure there are no complex structures allocated with potentially uninitialized fields. It seems `kvm->file` is set in `kvm_dev_ioctl_create_vm`, but the `struct kvm` itself is allocated via `kvm_create_vm`. I need to confirm `kvm_create_vm` uses `kzalloc` to zero the struct. |
| 97/3 | 2026/09/29 15:33 | tool | grepper |
0mArgs:{
"Expression": "kvm_create_vm",
"PathPrefix": "virt/kvm/"
}Results: {
"Output": "virt/kvm/kvm_main.c=980=static void kvm_destroy_vm_debugfs(struct kvm *kvm)\n--\nvirt/kvm/kvm_main.c-997-\nvirt/kvm/kvm_main.c:998:static int kvm_create_vm_debugfs(struct kvm *kvm, const char *fdname)\nvirt/kvm/kvm_main.c-999-{\n--\nvirt/kvm/kvm_main.c=1097=static void kvm_disable_virtualization(void);\nvirt/kvm/kvm_main.c-1098-\nvirt/kvm/kvm_main.c:1099:static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)\nvirt/kvm/kvm_main.c-1100-{\n--\nvirt/kvm/kvm_main.c-1132-\t * Force subsequent debugfs file creations to fail if the VM directory\nvirt/kvm/kvm_main.c:1133:\t * is not created (by kvm_create_vm_debugfs()).\nvirt/kvm/kvm_main.c-1134-\t */\n--\nvirt/kvm/kvm_main.c-1196-\nvirt/kvm/kvm_main.c:1197:\tr = kvm_create_vm_debugfs(kvm, fdname);\nvirt/kvm/kvm_main.c-1198-\tif (r)\n--\nvirt/kvm/kvm_main.c=5529=static int kvm_dev_ioctl_create_vm(unsigned long type)\n--\nvirt/kvm/kvm_main.c-5541-\nvirt/kvm/kvm_main.c:5542:\tkvm = kvm_create_vm(type, fdname);\nvirt/kvm/kvm_main.c-5543-\tif (IS_ERR(kvm)) {\n"
} |
| 98/3 | 2026/09/29 15:33 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13831 output: 40 thoughts: 18 Thoughts: Okay, here's my attempt at summarizing the thought process, tailored for an expert audience, and written in the first person: **Diving Deep into KVM VM Creation** Right, let's get down to brass tacks. I need to understand the minutiae of how `kvm_create_vm` handles the allocation of the `kvm` structure. I'm already pretty familiar with the overall KVM architecture, so I'm not looking for a high-level overview. Instead, I'm trying to pinpoint the critical section: where does the `kvm` struct *actually* get its memory? Is it a simple `kmalloc`, or are there more intricate memory management strategies at play, perhaps involving the use of specific NUMA nodes or slab allocators? Are there any specific flags being passed during allocation that might indicate specific memory placement policies, like pinning to physical memory or handling huge pages? I'll probably start by grepping the code for calls related to memory allocation within that function, tracing back the allocation paths, and examining any supporting functions called along the way. I'm particularly interested in any potential concurrency issues related to the allocation process. I also want to check for any memory leaks or resource management issues in this function, perhaps tracking any related cleanup operations to ensure the allocation's partner gets its memory back safely. |
| 99/3 | 2026/09/29 15:33 | tool | read-file |
0mArgs:{
"File": "virt/kvm/kvm_main.c",
"FirstLine": 1099,
"LineCount": 25
}Results: {
"Contents": "1099:\tstatic struct kvm *kvm_create_vm(unsigned long type, const char *fdname)\n1100:\t{\n1101:\t\tstruct kvm *kvm = kvm_arch_alloc_vm();\n1102:\t\tstruct kvm_memslots *slots;\n1103:\t\tint r, i, j;\n1104:\t\n1105:\t\tif (!kvm)\n1106:\t\t\treturn ERR_PTR(-ENOMEM);\n1107:\t\n1108:\t\tKVM_MMU_LOCK_INIT(kvm);\n1109:\t\tmmgrab(current-\u003emm);\n1110:\t\tkvm-\u003emm = current-\u003emm;\n1111:\t\tkvm_eventfd_init(kvm);\n1112:\t\tmutex_init(\u0026kvm-\u003elock);\n1113:\t\tmutex_init(\u0026kvm-\u003eirq_lock);\n1114:\t\tmutex_init(\u0026kvm-\u003eslots_lock);\n1115:\t\tmutex_init(\u0026kvm-\u003eslots_arch_lock);\n1116:\t\tspin_lock_init(\u0026kvm-\u003emn_invalidate_lock);\n1117:\t\trcuwait_init(\u0026kvm-\u003emn_memslots_update_rcuwait);\n1118:\t\txa_init(\u0026kvm-\u003evcpu_array);\n1119:\t#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES\n1120:\t\txa_init_flags(\u0026kvm-\u003emem_attr_array, XA_FLAGS_ACCOUNT);\n1121:\t#endif\n1122:\t\n1123:\t\tINIT_LIST_HEAD(\u0026kvm-\u003egpc_list);\n"
} |
| 100/3 | 2026/09/29 15:33 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14612 output: 36 thoughts: 37 Thoughts: Here's my take on those thoughts, tailored for an expert audience: **Analyzing the KVM VM Allocation on x86** Alright, so `kvm_arch_alloc_vm()` is responsible for allocating the `kvm` structure and, crucially, initializing it to zero. That's good housekeeping – always a sensible starting point. I want to dig into the x86 implementation of that function, `kvm_arch_alloc_vm`, specifically. I'm assuming there's some architecture-specific initialization going on beyond a simple `kzalloc`. I want to confirm my expectations about the state of the `kvm` structure after this call, especially what's happening to the hypervisor's internal state. Understanding this initial state is critical to any subsequent analysis of the VM initialization and operation. I'm keen to look for any hidden flags or fields, or potentially architecture-specific data structures embedded within the zeroed structure. |
| 101/3 | 2026/09/29 15:33 | tool | grepper |
0mError:no matches Args: {
"Expression": "kvm_arch_alloc_vm",
"PathPrefix": "arch/x86/kvm"
}Results: {
"error": "no matches"
} |
| 102/3 | 2026/09/29 15:33 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14898 output: 33 thoughts: 21 Thoughts: Here's a summary of my thought process, as requested: **Navigating the KVM Codebase: x86 Specific Allocation** Okay, so I need to track down the function `kvm_arch_alloc_vm`. I know it's related to KVM, the Kernel-based Virtual Machine, so that's my starting point. The name itself suggests that it's responsible for allocating virtual machine-specific resources from an architectural perspective, likely specific to the processor family in question. My gut tells me this will be architecture dependent, so I’m going to focus my search within the `arch/` directory structure. Given that I'm dealing with the x86 architecture, the most logical place to begin is, naturally, `arch/x86/`. That’s where I’ll start looking for this allocation function, `kvm_arch_alloc_vm`. |
| 103/3 | 2026/09/29 15:33 | tool | grepper |
0mArgs:{
"Expression": "kvm_arch_alloc_vm",
"PathPrefix": "arch/x86"
}Results: {
"Output": "arch/x86/include/asm/kvm_host.h=1796=extern struct kvm_x86_nested_ops kvm_nested_ops __read_mostly;\n--\narch/x86/include/asm/kvm_host.h-1814-#define __KVM_HAVE_ARCH_VM_ALLOC\narch/x86/include/asm/kvm_host.h:1815:static inline struct kvm *kvm_arch_alloc_vm(void)\narch/x86/include/asm/kvm_host.h-1816-{\n"
} |
| 104/3 | 2026/09/29 15:33 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15300 output: 45 thoughts: 29 Thoughts: Okay, let's dive into this. I'm going to grab `arch/x86/include/asm/kvm_host.h`, specifically around line 1815. I need to understand what's happening in that area of the KVM host code, so I'll probably be looking for data structures or function definitions that are central to the virtualization process. Given the file's name, I'm expecting to find core components related to the interaction between the hypervisor and the underlying hardware, probably focusing on x86-specific details. My initial hunch is that I'll find something related to interrupt handling, memory management, or maybe even the handling of specific CPU features that are critical for virtual machine operation. I'm ready to dig in and piece it together. |
| 105/3 | 2026/09/29 15:33 | tool | read-file |
0mArgs:{
"File": "arch/x86/include/asm/kvm_host.h",
"FirstLine": 1814,
"LineCount": 10
}Results: {
"Contents": "1814:\t#define __KVM_HAVE_ARCH_VM_ALLOC\n1815:\tstatic inline struct kvm *kvm_arch_alloc_vm(void)\n1816:\t{\n1817:\t\treturn kvzalloc(kvm_x86_ops.vm_size, GFP_KERNEL_ACCOUNT);\n1818:\t}\n1819:\t\n1820:\t#define __KVM_HAVE_ARCH_VM_FREE\n1821:\tvoid kvm_arch_free_vm(struct kvm *kvm);\n1822:\t\n1823:\t#if IS_ENABLED(CONFIG_HYPERV)\n"
} |
| 106/3 | 2026/09/29 15:33 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15724 output: 266 thoughts: 1637 Thoughts: **KMSAN Assessment: NeedsKMSAN = false** Okay, so `kvzalloc` is in play here. My job is to determine if this patch necessitates a KMSAN run. It seems we're refactoring how external subsystems interact with KVM instances, specifically VFIO, s390 PCI, and page tracking. Previously, these subsystems directly held pointers to `struct kvm *kvm`, using `kvm_get_kvm` and `kvm_put_kvm` for reference counting. This caused some lifecycle problems. Now, it looks like the shift is to have these subsystems hold a reference to `struct file *kvm_file` instead. They'll use `get_file()` and `fput()` for refcounting, and when they need the `struct kvm`, they'll use an architecture-specific helper like `file_to_kvm_x86(file)`. `kvm->file` is a back-reference. Pretty clean, I like that. I need to meticulously check for potential uninitialized memory risks. Let's see: are there any new allocations where we might have uninitialized data? No, nothing new. Are any structs or data copied to user space? Nope. Are any uninitialized fields being read? Not in any of the logic. Is there any chance a logic change or bound check will create an uninitialized read? No, it's just about pointer type conversions and reference counting now. So, what kind of bugs could *theoretically* slip through? Use-after-free or refcount leaks (file vs. kvm) – caught by KASAN/refcount/VFS checks. NULL pointer dereferences (e.g., if `file_to_kvm_x86` returns NULL) – also caught by standard bug detectors/KASAN. Locking deadlocks? LOCKDEP has that covered. None of these are uninitialized memory bugs that KMSAN would catch. This seems to match the criteria for `NeedsKMSAN=false` perfectly. The patch's primary risks are related to refcounting, object lifetimes, synchronization, or potential NULL pointer dereferences – all of which are handled by the standard kernel bug detectors. Let me go through each file in detail, just to be *completely* certain: 1. `arch/s390/...`: Changes the `kvm_register` to take `struct file *kvm_file`, using `file_to_kvm_s390` with NULL checking and error returns. 2. `arch/x86/...`: `kvm_page_track` changes to use `struct file *file` and `get_file` / `fput`. 3. `arch/x86/kvm/svm/sev.c`: Replaces a check with the `file_to_kvm_x86` function. 4. `drivers/s390/crypto/vfio_ap_ops.c`: Takes a `struct file *kvm_file` and validates it. 5. `drivers/vfio/...`: VFIO uses `struct file *kvm` and `get_file` / `fput` for lifecycle management. 6. `include/linux/kvm_host.h`, `virt/kvm/kvm_main.c`: Initializes the back-reference `kvm->file`. Defines the `file_to_kvm_` macros and implementations. 7. `virt/kvm/vfio.c`: Gets `kvm_file` using `get_file_active`. Everything is explicitly initialized before use, and no new kernel-to-user copies or logic that reads uninitialized memory. All looks good, every pointer initialized, no KMSAN concerns. `NeedsKMSAN=false`. Time to call `set-results`. |
| 107/3 | 2026/09/29 15:34 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch refactors the interface between KVM and external subsystems (VFIO, page tracking, s390 PCI / vfio_ap) so that external subsystems hold references to the KVM VM `struct file` (using `get_file()` and `fput()`) rather than directly holding references to `struct kvm` (using `kvm_get_kvm()` / `kvm_put_kvm()`), and resolves the VM instance using arch-namespaced helpers (`file_to_kvm_\u003carch\u003e`).\n\nThis refactoring touches object reference management, pointer passing, and lifecycle coordination. All newly introduced local variables and struct members are explicitly initialized before use. No kernel-to-user memory copy operations (e.g. copy_to_user, put_user), uninitialized struct allocations, or buffer length calculations are introduced or modified. Any risks introduced by these changes are limited to object lifetimes, use-after-free, reference leaks, or NULL pointer dereferences, which are covered by standard KASAN, LOCKDEP, and built-in kernel diagnostics. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch refactors the interface between KVM and external subsystems (VFIO, page tracking, s390 PCI / vfio_ap) so that external subsystems hold references to the KVM VM `struct file` (using `get_file()` and `fput()`) rather than directly holding references to `struct kvm` (using `kvm_get_kvm()` / `kvm_put_kvm()`), and resolves the VM instance using arch-namespaced helpers (`file_to_kvm_\u003carch\u003e`).\n\nThis refactoring touches object reference management, pointer passing, and lifecycle coordination. All newly introduced local variables and struct members are explicitly initialized before use. No kernel-to-user memory copy operations (e.g. copy_to_user, put_user), uninitialized struct allocations, or buffer length calculations are introduced or modified. Any risks introduced by these changes are limited to object lifetimes, use-after-free, reference leaks, or NULL pointer dereferences, which are covered by standard KASAN, LOCKDEP, and built-in kernel diagnostics. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|