kvm: Allow build-time configuration of KVM device assignment

We hope to at some point deprecate KVM legacy device assignment in
favor of VFIO-based assignment.  Towards that end, allow legacy
device assignment to be deconfigured.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
This commit is contained in:
Alex Williamson 2013-04-16 13:49:18 -06:00 committed by Gleb Natapov
parent 064d1afaa5
commit 2a5bab1004
10 changed files with 40 additions and 41 deletions

View File

@ -27,7 +27,6 @@
/* Select x86 specific features in <linux/kvm.h> */ /* Select x86 specific features in <linux/kvm.h> */
#define __KVM_HAVE_IOAPIC #define __KVM_HAVE_IOAPIC
#define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_DEVICE_ASSIGNMENT
/* Architectural interrupt line count. */ /* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256 #define KVM_NR_INTERRUPTS 256

View File

@ -21,8 +21,6 @@ config KVM
tristate "Kernel-based Virtual Machine (KVM) support" tristate "Kernel-based Virtual Machine (KVM) support"
depends on BROKEN depends on BROKEN
depends on HAVE_KVM && MODULES depends on HAVE_KVM && MODULES
# for device assignment:
depends on PCI
depends on BROKEN depends on BROKEN
select PREEMPT_NOTIFIERS select PREEMPT_NOTIFIERS
select ANON_INODES select ANON_INODES
@ -51,6 +49,17 @@ config KVM_INTEL
Provides support for KVM on Itanium 2 processors equipped with the VT Provides support for KVM on Itanium 2 processors equipped with the VT
extensions. extensions.
config KVM_DEVICE_ASSIGNMENT
bool "KVM legacy PCI device assignment support"
depends on KVM && PCI && IOMMU_API
default y
---help---
Provide support for legacy PCI device assignment through KVM. The
kernel now also supports a full featured userspace device driver
framework through VFIO, which supersedes much of this support.
If unsure, say Y.
source drivers/vhost/Kconfig source drivers/vhost/Kconfig
endif # VIRTUALIZATION endif # VIRTUALIZATION

View File

@ -49,10 +49,10 @@ ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/
asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
coalesced_mmio.o irq_comm.o assigned-dev.o irqchip.o) coalesced_mmio.o irq_comm.o)
ifeq ($(CONFIG_IOMMU_API),y) ifeq ($(CONFIG_KVM_DEVICE_ASSIGNMENT),y)
common-objs += $(addprefix ../../../virt/kvm/, iommu.o) common-objs += $(addprefix ../../../virt/kvm/, assigned-dev.o iommu.o)
endif endif
kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o

View File

@ -1368,9 +1368,7 @@ void kvm_arch_sync_events(struct kvm *kvm)
void kvm_arch_destroy_vm(struct kvm *kvm) void kvm_arch_destroy_vm(struct kvm *kvm)
{ {
kvm_iommu_unmap_guest(kvm); kvm_iommu_unmap_guest(kvm);
#ifdef KVM_CAP_DEVICE_ASSIGNMENT
kvm_free_all_assigned_devices(kvm); kvm_free_all_assigned_devices(kvm);
#endif
kfree(kvm->arch.vioapic); kfree(kvm->arch.vioapic);
kvm_release_vm_pages(kvm); kvm_release_vm_pages(kvm);
} }

View File

@ -29,7 +29,6 @@
#define __KVM_HAVE_PIT #define __KVM_HAVE_PIT
#define __KVM_HAVE_IOAPIC #define __KVM_HAVE_IOAPIC
#define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_DEVICE_ASSIGNMENT
#define __KVM_HAVE_MSI #define __KVM_HAVE_MSI
#define __KVM_HAVE_USER_NMI #define __KVM_HAVE_USER_NMI
#define __KVM_HAVE_GUEST_DEBUG #define __KVM_HAVE_GUEST_DEBUG

View File

@ -21,8 +21,6 @@ config KVM
tristate "Kernel-based Virtual Machine (KVM) support" tristate "Kernel-based Virtual Machine (KVM) support"
depends on HAVE_KVM depends on HAVE_KVM
depends on HIGH_RES_TIMERS depends on HIGH_RES_TIMERS
# for device assignment:
depends on PCI
# for TASKSTATS/TASK_DELAY_ACCT: # for TASKSTATS/TASK_DELAY_ACCT:
depends on NET depends on NET
select PREEMPT_NOTIFIERS select PREEMPT_NOTIFIERS
@ -83,6 +81,17 @@ config KVM_MMU_AUDIT
This option adds a R/W kVM module parameter 'mmu_audit', which allows This option adds a R/W kVM module parameter 'mmu_audit', which allows
audit KVM MMU at runtime. audit KVM MMU at runtime.
config KVM_DEVICE_ASSIGNMENT
bool "KVM legacy PCI device assignment support"
depends on KVM && PCI && IOMMU_API
default y
---help---
Provide support for legacy PCI device assignment through KVM. The
kernel now also supports a full featured userspace device driver
framework through VFIO, which supersedes much of this support.
If unsure, say Y.
# OK, it's a little counter-intuitive to do this, but it puts it neatly under # OK, it's a little counter-intuitive to do this, but it puts it neatly under
# the virtualization menu. # the virtualization menu.
source drivers/vhost/Kconfig source drivers/vhost/Kconfig

View File

@ -7,8 +7,9 @@ CFLAGS_vmx.o := -I.
kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
coalesced_mmio.o irq_comm.o eventfd.o \ coalesced_mmio.o irq_comm.o eventfd.o \
assigned-dev.o irqchip.o) irqchip.o)
kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += $(addprefix ../../../virt/kvm/, \
assigned-dev.o iommu.o)
kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o)
kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \

View File

@ -2501,7 +2501,6 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_USER_NMI: case KVM_CAP_USER_NMI:
case KVM_CAP_REINJECT_CONTROL: case KVM_CAP_REINJECT_CONTROL:
case KVM_CAP_IRQ_INJECT_STATUS: case KVM_CAP_IRQ_INJECT_STATUS:
case KVM_CAP_ASSIGN_DEV_IRQ:
case KVM_CAP_IRQFD: case KVM_CAP_IRQFD:
case KVM_CAP_IOEVENTFD: case KVM_CAP_IOEVENTFD:
case KVM_CAP_PIT2: case KVM_CAP_PIT2:
@ -2519,9 +2518,12 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_XSAVE: case KVM_CAP_XSAVE:
case KVM_CAP_ASYNC_PF: case KVM_CAP_ASYNC_PF:
case KVM_CAP_GET_TSC_KHZ: case KVM_CAP_GET_TSC_KHZ:
case KVM_CAP_PCI_2_3:
case KVM_CAP_KVMCLOCK_CTRL: case KVM_CAP_KVMCLOCK_CTRL:
case KVM_CAP_READONLY_MEM: case KVM_CAP_READONLY_MEM:
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
case KVM_CAP_ASSIGN_DEV_IRQ:
case KVM_CAP_PCI_2_3:
#endif
r = 1; r = 1;
break; break;
case KVM_CAP_COALESCED_MMIO: case KVM_CAP_COALESCED_MMIO:

View File

@ -667,7 +667,6 @@ static inline wait_queue_head_t *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type); int kvm_arch_init_vm(struct kvm *kvm, unsigned long type);
void kvm_arch_destroy_vm(struct kvm *kvm); void kvm_arch_destroy_vm(struct kvm *kvm);
void kvm_free_all_assigned_devices(struct kvm *kvm);
void kvm_arch_sync_events(struct kvm *kvm); void kvm_arch_sync_events(struct kvm *kvm);
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu);
@ -736,7 +735,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
/* For vcpu->arch.iommu_flags */ /* For vcpu->arch.iommu_flags */
#define KVM_IOMMU_CACHE_COHERENCY 0x1 #define KVM_IOMMU_CACHE_COHERENCY 0x1
#ifdef CONFIG_IOMMU_API #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
int kvm_iommu_map_guest(struct kvm *kvm); int kvm_iommu_map_guest(struct kvm *kvm);
@ -745,7 +744,7 @@ int kvm_assign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev); struct kvm_assigned_dev_kernel *assigned_dev);
int kvm_deassign_device(struct kvm *kvm, int kvm_deassign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev); struct kvm_assigned_dev_kernel *assigned_dev);
#else /* CONFIG_IOMMU_API */ #else
static inline int kvm_iommu_map_pages(struct kvm *kvm, static inline int kvm_iommu_map_pages(struct kvm *kvm,
struct kvm_memory_slot *slot) struct kvm_memory_slot *slot)
{ {
@ -757,28 +756,11 @@ static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
{ {
} }
static inline int kvm_iommu_map_guest(struct kvm *kvm)
{
return -ENODEV;
}
static inline int kvm_iommu_unmap_guest(struct kvm *kvm) static inline int kvm_iommu_unmap_guest(struct kvm *kvm)
{ {
return 0; return 0;
} }
#endif
static inline int kvm_assign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev)
{
return 0;
}
static inline int kvm_deassign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev)
{
return 0;
}
#endif /* CONFIG_IOMMU_API */
static inline void __guest_enter(void) static inline void __guest_enter(void)
{ {
@ -1032,11 +1014,13 @@ static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; }
#endif #endif
#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
unsigned long arg); unsigned long arg);
void kvm_free_all_assigned_devices(struct kvm *kvm);
#else #else
static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
@ -1045,6 +1029,8 @@ static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
return -ENOTTY; return -ENOTTY;
} }
static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {}
#endif #endif
static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)

View File

@ -561,9 +561,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_MP_STATE 14 #define KVM_CAP_MP_STATE 14
#define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_COALESCED_MMIO 15
#define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */
#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
#define KVM_CAP_DEVICE_ASSIGNMENT 17 #define KVM_CAP_DEVICE_ASSIGNMENT 17
#endif
#define KVM_CAP_IOMMU 18 #define KVM_CAP_IOMMU 18
#ifdef __KVM_HAVE_MSI #ifdef __KVM_HAVE_MSI
#define KVM_CAP_DEVICE_MSI 20 #define KVM_CAP_DEVICE_MSI 20
@ -581,9 +579,7 @@ struct kvm_ppc_smmu_info {
#endif #endif
#define KVM_CAP_IRQ_ROUTING 25 #define KVM_CAP_IRQ_ROUTING 25
#define KVM_CAP_IRQ_INJECT_STATUS 26 #define KVM_CAP_IRQ_INJECT_STATUS 26
#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
#define KVM_CAP_DEVICE_DEASSIGNMENT 27 #define KVM_CAP_DEVICE_DEASSIGNMENT 27
#endif
#ifdef __KVM_HAVE_MSIX #ifdef __KVM_HAVE_MSIX
#define KVM_CAP_DEVICE_MSIX 28 #define KVM_CAP_DEVICE_MSIX 28
#endif #endif