kvm: Allow build-time configuration of KVM device assignment
Alex Williamson [Tue, 16 Apr 2013 19:49:18 +0000 (13:49 -0600)]
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>

arch/ia64/include/uapi/asm/kvm.h
arch/ia64/kvm/Kconfig
arch/ia64/kvm/Makefile
arch/ia64/kvm/kvm-ia64.c
arch/x86/include/uapi/asm/kvm.h
arch/x86/kvm/Kconfig
arch/x86/kvm/Makefile
arch/x86/kvm/x86.c
include/linux/kvm_host.h
include/uapi/linux/kvm.h

index ec6c6b3..99503c2 100644 (file)
@@ -27,7 +27,6 @@
 /* Select x86 specific features in <linux/kvm.h> */
 #define __KVM_HAVE_IOAPIC
 #define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_DEVICE_ASSIGNMENT
 
 /* Architectural interrupt line count. */
 #define KVM_NR_INTERRUPTS 256
index 043183a..990b864 100644 (file)
@@ -21,8 +21,6 @@ config KVM
        tristate "Kernel-based Virtual Machine (KVM) support"
        depends on BROKEN
        depends on HAVE_KVM && MODULES
-       # for device assignment:
-       depends on PCI
        depends on BROKEN
        select PREEMPT_NOTIFIERS
        select ANON_INODES
@@ -51,6 +49,17 @@ config KVM_INTEL
          Provides support for KVM on Itanium 2 processors equipped with the VT
          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
 
 endif # VIRTUALIZATION
index 511f64a..1a40537 100644 (file)
@@ -49,10 +49,10 @@ ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/
 asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/
 
 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)
-common-objs += $(addprefix ../../../virt/kvm/, iommu.o)
+ifeq ($(CONFIG_KVM_DEVICE_ASSIGNMENT),y)
+common-objs += $(addprefix ../../../virt/kvm/, assigned-dev.o iommu.o)
 endif
 
 kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
index 032c54d..dcc5607 100644 (file)
@@ -1368,9 +1368,7 @@ void kvm_arch_sync_events(struct kvm *kvm)
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
        kvm_iommu_unmap_guest(kvm);
-#ifdef  KVM_CAP_DEVICE_ASSIGNMENT
        kvm_free_all_assigned_devices(kvm);
-#endif
        kfree(kvm->arch.vioapic);
        kvm_release_vm_pages(kvm);
 }
index a65ec29..5d9a303 100644 (file)
@@ -29,7 +29,6 @@
 #define __KVM_HAVE_PIT
 #define __KVM_HAVE_IOAPIC
 #define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_DEVICE_ASSIGNMENT
 #define __KVM_HAVE_MSI
 #define __KVM_HAVE_USER_NMI
 #define __KVM_HAVE_GUEST_DEBUG
index 9d50efd..a47a3e5 100644 (file)
@@ -21,8 +21,6 @@ config KVM
        tristate "Kernel-based Virtual Machine (KVM) support"
        depends on HAVE_KVM
        depends on HIGH_RES_TIMERS
-       # for device assignment:
-       depends on PCI
        # for TASKSTATS/TASK_DELAY_ACCT:
        depends on NET
        select PREEMPT_NOTIFIERS
@@ -83,6 +81,17 @@ config KVM_MMU_AUDIT
         This option adds a R/W kVM module parameter 'mmu_audit', which allows
         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
 # the virtualization menu.
 source drivers/vhost/Kconfig
index a797b8e..d609e1d 100644 (file)
@@ -7,8 +7,9 @@ CFLAGS_vmx.o := -I.
 
 kvm-y                  += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
                                coalesced_mmio.o irq_comm.o eventfd.o \
-                               assigned-dev.o irqchip.o)
-kvm-$(CONFIG_IOMMU_API)        += $(addprefix ../../../virt/kvm/, iommu.o)
+                               irqchip.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-y                  += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
index 145b1c8..8747fef 100644 (file)
@@ -2501,7 +2501,6 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_USER_NMI:
        case KVM_CAP_REINJECT_CONTROL:
        case KVM_CAP_IRQ_INJECT_STATUS:
-       case KVM_CAP_ASSIGN_DEV_IRQ:
        case KVM_CAP_IRQFD:
        case KVM_CAP_IOEVENTFD:
        case KVM_CAP_PIT2:
@@ -2519,9 +2518,12 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_XSAVE:
        case KVM_CAP_ASYNC_PF:
        case KVM_CAP_GET_TSC_KHZ:
-       case KVM_CAP_PCI_2_3:
        case KVM_CAP_KVMCLOCK_CTRL:
        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;
                break;
        case KVM_CAP_COALESCED_MMIO:
index 3097747..996661e 100644 (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);
 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);
 
 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 */
 #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);
 void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
 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);
 int kvm_deassign_device(struct kvm *kvm,
                        struct kvm_assigned_dev_kernel *assigned_dev);
-#else /* CONFIG_IOMMU_API */
+#else
 static inline int kvm_iommu_map_pages(struct kvm *kvm,
                                      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)
 {
        return 0;
 }
-
-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 */
+#endif
 
 static inline void __guest_enter(void)
 {
@@ -1032,11 +1014,13 @@ static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; }
 
 #endif
 
-#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
+#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
 
 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 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;
 }
 
+static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {}
+
 #endif
 
 static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)
index d400519..965e5b5 100644 (file)
@@ -561,9 +561,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_MP_STATE 14
 #define KVM_CAP_COALESCED_MMIO 15
 #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
-#endif
 #define KVM_CAP_IOMMU 18
 #ifdef __KVM_HAVE_MSI
 #define KVM_CAP_DEVICE_MSI 20
@@ -581,9 +579,7 @@ struct kvm_ppc_smmu_info {
 #endif
 #define KVM_CAP_IRQ_ROUTING 25
 #define KVM_CAP_IRQ_INJECT_STATUS 26
-#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
 #define KVM_CAP_DEVICE_DEASSIGNMENT 27
-#endif
 #ifdef __KVM_HAVE_MSIX
 #define KVM_CAP_DEVICE_MSIX 28
 #endif