|
@@ -27,6 +27,8 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/file.h>
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/irqbypass.h>
|
|
|
+#include <linux/kvm_irqfd.h>
|
|
|
#include <asm/cputable.h>
|
|
|
#include <asm/uaccess.h>
|
|
|
#include <asm/kvm_ppc.h>
|
|
@@ -739,6 +741,42 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * irq_bypass_add_producer and irq_bypass_del_producer are only
|
|
|
+ * useful if the architecture supports PCI passthrough.
|
|
|
+ * irq_bypass_stop and irq_bypass_start are not needed and so
|
|
|
+ * kvm_ops are not defined for them.
|
|
|
+ */
|
|
|
+bool kvm_arch_has_irq_bypass(void)
|
|
|
+{
|
|
|
+ return ((kvmppc_hv_ops && kvmppc_hv_ops->irq_bypass_add_producer) ||
|
|
|
+ (kvmppc_pr_ops && kvmppc_pr_ops->irq_bypass_add_producer));
|
|
|
+}
|
|
|
+
|
|
|
+int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
|
|
|
+ struct irq_bypass_producer *prod)
|
|
|
+{
|
|
|
+ struct kvm_kernel_irqfd *irqfd =
|
|
|
+ container_of(cons, struct kvm_kernel_irqfd, consumer);
|
|
|
+ struct kvm *kvm = irqfd->kvm;
|
|
|
+
|
|
|
+ if (kvm->arch.kvm_ops->irq_bypass_add_producer)
|
|
|
+ return kvm->arch.kvm_ops->irq_bypass_add_producer(cons, prod);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
|
|
|
+ struct irq_bypass_producer *prod)
|
|
|
+{
|
|
|
+ struct kvm_kernel_irqfd *irqfd =
|
|
|
+ container_of(cons, struct kvm_kernel_irqfd, consumer);
|
|
|
+ struct kvm *kvm = irqfd->kvm;
|
|
|
+
|
|
|
+ if (kvm->arch.kvm_ops->irq_bypass_del_producer)
|
|
|
+ kvm->arch.kvm_ops->irq_bypass_del_producer(cons, prod);
|
|
|
+}
|
|
|
+
|
|
|
static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
|
|
|
struct kvm_run *run)
|
|
|
{
|