Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9576730d authored by Suresh Warrier's avatar Suresh Warrier Committed by Paul Mackerras
Browse files

KVM: PPC: select IRQ_BYPASS_MANAGER



Select IRQ_BYPASS_MANAGER for PPC when CONFIG_KVM is set.
Add the PPC producer functions for add and del producer.

[paulus@ozlabs.org - Moved new functions from book3s.c to powerpc.c
 so booke compiles; added kvm_arch_has_irq_bypass implementation.]

Signed-off-by: default avatarSuresh Warrier <warrier@linux.vnet.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 37f55d30
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -287,6 +287,10 @@ struct kvmppc_ops {
	long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl,
			      unsigned long arg);
	int (*hcall_implemented)(unsigned long hcall);
	int (*irq_bypass_add_producer)(struct irq_bypass_consumer *,
				       struct irq_bypass_producer *);
	void (*irq_bypass_del_producer)(struct irq_bypass_consumer *,
					struct irq_bypass_producer *);
};

extern struct kvmppc_ops *kvmppc_hv_ops;
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ config KVM
	select HAVE_KVM_EVENTFD
	select SRCU
	select KVM_VFIO
	select IRQ_BYPASS_MANAGER
	select HAVE_KVM_IRQ_BYPASS

config KVM_BOOK3S_HANDLER
	bool
+38 −0
Original line number Diff line number Diff line
@@ -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)
{