@@ -61,4 +61,8 @@ struct kvm_kernel_irqfd {
struct irq_bypass_producer *producer;
};
+struct kvm_kernel_irqfd *kvm_arch_irqfd_alloc(void);
+void kvm_arch_irqfd_free(struct kvm_kernel_irqfd *irqfd);
+int kvm_arch_irqfd_init(struct kvm_kernel_irqfd *irqfd);
+
#endif /* __LINUX_KVM_IRQFD_H */
@@ -32,6 +32,24 @@
static struct workqueue_struct *irqfd_cleanup_wq;
+struct kvm_kernel_irqfd __attribute__((weak))
+*kvm_arch_irqfd_alloc(void)
+{
+ return kzalloc(sizeof(struct kvm_kernel_irqfd), GFP_KERNEL_ACCOUNT);
+}
+
+void __attribute__((weak))
+kvm_arch_irqfd_free(struct kvm_kernel_irqfd *irqfd)
+{
+ kfree(irqfd);
+}
+
+int __attribute__((weak))
+kvm_arch_irqfd_init(struct kvm_kernel_irqfd *irqfd)
+{
+ return 0;
+}
+
bool __attribute__((weak))
kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
{
@@ -153,7 +171,7 @@ irqfd_shutdown(struct work_struct *work)
irq_bypass_unregister_consumer(&irqfd->consumer);
#endif
eventfd_ctx_put(irqfd->eventfd);
- kfree(irqfd);
+ kvm_arch_irqfd_free(irqfd);
}
@@ -315,7 +333,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
if (!kvm_arch_irqfd_allowed(kvm, args))
return -EINVAL;
- irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL_ACCOUNT);
+ irqfd = kvm_arch_irqfd_alloc();
if (!irqfd)
return -ENOMEM;
@@ -396,6 +414,13 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
+ /*
+ * Give a chance to archiectures to finish initilization.
+ * E.g. Gunyah needs to register a resource ticket for this irq.
+ */
+ if (kvm_arch_irqfd_init(irqfd))
+ goto fail;
+
spin_lock_irq(&kvm->irqfds.lock);
ret = 0;
@@ -452,7 +477,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
eventfd_ctx_put(eventfd);
out:
- kfree(irqfd);
+ kvm_arch_irqfd_free(irqfd);
return ret;
}
Some KVM backends, such as Gunyah, require irqfd structures to carry platform-specific state or setup logic. To support these use cases, introduce three weakly-defined functions: - kvm_arch_irqfd_alloc() - kvm_arch_irqfd_free() - kvm_arch_irqfd_init() These allow KVM backends to override irqfd allocation, teardown, and initialization logic. The default implementations simply allocate/finalize a standard `struct kvm_kernel_irqfd`, maintaining existing behaviour. This change is required by the Gunyah backend, which uses these hooks to associate irqfd objects with Gunyah-specific bell resource handles for IRQ injection via hypercalls. Signed-off-by: Karim Manaouil <karim.manaouil@linaro.org> --- include/linux/kvm_irqfd.h | 4 ++++ virt/kvm/eventfd.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-)