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

Commit c9eab58f authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

KVM: x86: move device assignment out of kvm_host.h



Create a new header, and hide the device assignment functions there.
Move struct kvm_assigned_dev_kernel to assigned-dev.c by modifying
arch/x86/kvm/iommu.c to take a PCI device struct.

Based on a patch by Radim Krcmar <rkrcmark@redhat.com>.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent b65d6e17
Loading
Loading
Loading
Loading
+0 −23
Original line number Diff line number Diff line
@@ -1112,27 +1112,4 @@ int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data);
void kvm_handle_pmu_event(struct kvm_vcpu *vcpu);
void kvm_deliver_pmi(struct kvm_vcpu *vcpu);

#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
int kvm_iommu_map_guest(struct kvm *kvm);
int kvm_iommu_unmap_guest(struct kvm *kvm);

long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
				  unsigned long arg);

void kvm_free_all_assigned_devices(struct kvm *kvm);
#else
static inline int kvm_iommu_unmap_guest(struct kvm *kvm)
{
	return 0;
}

static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
						unsigned long arg)
{
	return -ENOTTY;
}

static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {}
#endif

#endif /* _ASM_X86_KVM_HOST_H */
+28 −2
Original line number Diff line number Diff line
@@ -20,6 +20,32 @@
#include <linux/namei.h>
#include <linux/fs.h>
#include "irq.h"
#include "assigned-dev.h"

struct kvm_assigned_dev_kernel {
	struct kvm_irq_ack_notifier ack_notifier;
	struct list_head list;
	int assigned_dev_id;
	int host_segnr;
	int host_busnr;
	int host_devfn;
	unsigned int entries_nr;
	int host_irq;
	bool host_irq_disabled;
	bool pci_2_3;
	struct msix_entry *host_msix_entries;
	int guest_irq;
	struct msix_entry *guest_msix_entries;
	unsigned long irq_requested_type;
	int irq_source_id;
	int flags;
	struct pci_dev *dev;
	struct kvm *kvm;
	spinlock_t intx_lock;
	spinlock_t intx_mask_lock;
	char irq_name[32];
	struct pci_saved_state *pci_saved_state;
};

static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
						      int assigned_dev_id)
@@ -748,7 +774,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
		if (r)
			goto out_list_del;
	}
	r = kvm_assign_device(kvm, match);
	r = kvm_assign_device(kvm, match->dev);
	if (r)
		goto out_list_del;

@@ -790,7 +816,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm,
		goto out;
	}

	kvm_deassign_device(kvm, match);
	kvm_deassign_device(kvm, match->dev);

	kvm_free_assigned_device(kvm, match);

+32 −0
Original line number Diff line number Diff line
#ifndef ARCH_X86_KVM_ASSIGNED_DEV_H
#define ARCH_X86_KVM_ASSIGNED_DEV_H

#include <linux/kvm_host.h>

#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
int kvm_assign_device(struct kvm *kvm, struct pci_dev *pdev);
int kvm_deassign_device(struct kvm *kvm, struct pci_dev *pdev);

int kvm_iommu_map_guest(struct kvm *kvm);
int kvm_iommu_unmap_guest(struct kvm *kvm);

long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
				  unsigned long arg);

void kvm_free_all_assigned_devices(struct kvm *kvm);
#else
static inline int kvm_iommu_unmap_guest(struct kvm *kvm)
{
	return 0;
}

static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
						unsigned long arg)
{
	return -ENOTTY;
}

static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {}
#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */

#endif /* ARCH_X86_KVM_ASSIGNED_DEV_H */
+3 −8
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/dmar.h>
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
#include "assigned-dev.h"

static bool allow_unsafe_assigned_interrupts;
module_param_named(allow_unsafe_assigned_interrupts,
@@ -169,10 +170,8 @@ static int kvm_iommu_map_memslots(struct kvm *kvm)
	return r;
}

int kvm_assign_device(struct kvm *kvm,
		      struct kvm_assigned_dev_kernel *assigned_dev)
int kvm_assign_device(struct kvm *kvm, struct pci_dev *pdev)
{
	struct pci_dev *pdev = NULL;
	struct iommu_domain *domain = kvm->arch.iommu_domain;
	int r;
	bool noncoherent;
@@ -181,7 +180,6 @@ int kvm_assign_device(struct kvm *kvm,
	if (!domain)
		return 0;

	pdev = assigned_dev->dev;
	if (pdev == NULL)
		return -ENODEV;

@@ -212,17 +210,14 @@ int kvm_assign_device(struct kvm *kvm,
	return r;
}

int kvm_deassign_device(struct kvm *kvm,
			struct kvm_assigned_dev_kernel *assigned_dev)
int kvm_deassign_device(struct kvm *kvm, struct pci_dev *pdev)
{
	struct iommu_domain *domain = kvm->arch.iommu_domain;
	struct pci_dev *pdev = NULL;

	/* check if iommu exists and in use */
	if (!domain)
		return 0;

	pdev = assigned_dev->dev;
	if (pdev == NULL)
		return -ENODEV;

+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "kvm_cache_regs.h"
#include "x86.h"
#include "cpuid.h"
#include "assigned-dev.h"

#include <linux/clocksource.h>
#include <linux/interrupt.h>
Loading