kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
@ 2008-09-29  5:26 Zhang, Xiantao
  2008-10-03  7:09 ` Amit Shah
  0 siblings, 1 reply; 10+ messages in thread
From: Zhang, Xiantao @ 2008-09-29  5:26 UTC (permalink / raw)
  To: kvm, kvm-ia64; +Cc: avi

[-- Attachment #1: Type: text/plain, Size: 17097 bytes --]

>From 6840c86b777e4a561cc3df7222cf5eb0b0bb9226 Mon Sep 17 00:00:00 2001
From: Xiantao Zhang <xiantao.zhang@intel.com>
Date: Sat, 27 Sep 2008 10:59:36 +0800
Subject: [PATCH] kvm: Moving device_assignment logic to kvm_main.c

To share with other archs, this patch moves device_assignment
logic to common parts.
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
---
 arch/x86/kvm/x86.c       |  255
-------------------------------------------
 include/linux/kvm.h      |    2 +
 include/linux/kvm_host.h |    1 +
 virt/kvm/kvm_main.c      |  268
+++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 269 insertions(+), 257 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4cfdd1b..aee0e37 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>
 #include <linux/kvm.h>
 #include <linux/fs.h>
-#include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/mman.h>
@@ -107,238 +106,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] =
{
 	{ NULL }
 };
 
-static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct
list_head *head,
-						      int
assigned_dev_id)
-{
-	struct list_head *ptr;
-	struct kvm_assigned_dev_kernel *match;
-
-	list_for_each(ptr, head) {
-		match = list_entry(ptr, struct kvm_assigned_dev_kernel,
list);
-		if (match->assigned_dev_id == assigned_dev_id)
-			return match;
-	}
-	return NULL;
-}
-
-static void kvm_assigned_dev_interrupt_work_handler(struct work_struct
*work)
-{
-	struct kvm_assigned_dev_kernel *assigned_dev;
-
-	assigned_dev = container_of(work, struct
kvm_assigned_dev_kernel,
-				    interrupt_work);
-
-	/* This is taken to safely inject irq inside the guest. When
-	 * the interrupt injection (or the ioapic code) uses a
-	 * finer-grained lock, update this
-	 */
-	mutex_lock(&assigned_dev->kvm->lock);
-	kvm_set_irq(assigned_dev->kvm,
-		    assigned_dev->guest_irq, 1);
-	mutex_unlock(&assigned_dev->kvm->lock);
-	kvm_put_kvm(assigned_dev->kvm);
-}
-
-/* FIXME: Implement the OR logic needed to make shared interrupts on
- * this line behave properly
- */
-static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
-{
-	struct kvm_assigned_dev_kernel *assigned_dev =
-		(struct kvm_assigned_dev_kernel *) dev_id;
-
-	kvm_get_kvm(assigned_dev->kvm);
-	schedule_work(&assigned_dev->interrupt_work);
-	disable_irq_nosync(irq);
-	return IRQ_HANDLED;
-}
-
-/* Ack the irq line for an assigned device */
-static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
-{
-	struct kvm_assigned_dev_kernel *dev;
-
-	if (kian->gsi == -1)
-		return;
-
-	dev = container_of(kian, struct kvm_assigned_dev_kernel,
-			   ack_notifier);
-	kvm_set_irq(dev->kvm, dev->guest_irq, 0);
-	enable_irq(dev->host_irq);
-}
-
-static void kvm_free_assigned_device(struct kvm *kvm,
-				     struct kvm_assigned_dev_kernel
-				     *assigned_dev)
-{
-	if (irqchip_in_kernel(kvm) && assigned_dev->irq_requested)
-		free_irq(assigned_dev->host_irq, (void *)assigned_dev);
-
-	kvm_unregister_irq_ack_notifier(kvm,
&assigned_dev->ack_notifier);
-
-	if (cancel_work_sync(&assigned_dev->interrupt_work))
-		/* We had pending work. That means we will have to take
-		 * care of kvm_put_kvm.
-		 */
-		kvm_put_kvm(kvm);
-
-	pci_release_regions(assigned_dev->dev);
-	pci_disable_device(assigned_dev->dev);
-	pci_dev_put(assigned_dev->dev);
-
-	list_del(&assigned_dev->list);
-	kfree(assigned_dev);
-}
-
-static void kvm_free_all_assigned_devices(struct kvm *kvm)
-{
-	struct list_head *ptr, *ptr2;
-	struct kvm_assigned_dev_kernel *assigned_dev;
-
-	list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
-		assigned_dev = list_entry(ptr,
-					  struct
kvm_assigned_dev_kernel,
-					  list);
-
-		kvm_free_assigned_device(kvm, assigned_dev);
-	}
-}
-
-static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
-				   struct kvm_assigned_irq
-				   *assigned_irq)
-{
-	int r = 0;
-	struct kvm_assigned_dev_kernel *match;
-
-	mutex_lock(&kvm->lock);
-
-	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
-				      assigned_irq->assigned_dev_id);
-	if (!match) {
-		mutex_unlock(&kvm->lock);
-		return -EINVAL;
-	}
-
-	if (match->irq_requested) {
-		match->guest_irq = assigned_irq->guest_irq;
-		match->ack_notifier.gsi = assigned_irq->guest_irq;
-		mutex_unlock(&kvm->lock);
-		return 0;
-	}
-
-	INIT_WORK(&match->interrupt_work,
-		  kvm_assigned_dev_interrupt_work_handler);
-
-	if (irqchip_in_kernel(kvm)) {
-		if (!capable(CAP_SYS_RAWIO)) {
-			r = -EPERM;
-			goto out_release;
-		}
-
-		if (assigned_irq->host_irq)
-			match->host_irq = assigned_irq->host_irq;
-		else
-			match->host_irq = match->dev->irq;
-		match->guest_irq = assigned_irq->guest_irq;
-		match->ack_notifier.gsi = assigned_irq->guest_irq;
-		match->ack_notifier.irq_acked =
kvm_assigned_dev_ack_irq;
-		kvm_register_irq_ack_notifier(kvm,
&match->ack_notifier);
-
-		/* Even though this is PCI, we don't want to use shared
-		 * interrupts. Sharing host devices with guest-assigned
devices
-		 * on the same interrupt line is not a happy situation:
there
-		 * are going to be long delays in accepting, acking,
etc.
-		 */
-		if (request_irq(match->host_irq, kvm_assigned_dev_intr,
0,
-				"kvm_assigned_device", (void *)match)) {
-			r = -EIO;
-			goto out_release;
-		}
-	}
-
-	match->irq_requested = true;
-	mutex_unlock(&kvm->lock);
-	return r;
-out_release:
-	mutex_unlock(&kvm->lock);
-	kvm_free_assigned_device(kvm, match);
-	return r;
-}
-
-static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
-				      struct kvm_assigned_pci_dev
*assigned_dev)
-{
-	int r = 0;
-	struct kvm_assigned_dev_kernel *match;
-	struct pci_dev *dev;
-
-	mutex_lock(&kvm->lock);
-
-	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
-				      assigned_dev->assigned_dev_id);
-	if (match) {
-		/* device already assigned */
-		r = -EINVAL;
-		goto out;
-	}
-
-	match = kzalloc(sizeof(struct kvm_assigned_dev_kernel),
GFP_KERNEL);
-	if (match == NULL) {
-		printk(KERN_INFO "%s: Couldn't allocate memory\n",
-		       __func__);
-		r = -ENOMEM;
-		goto out;
-	}
-	dev = pci_get_bus_and_slot(assigned_dev->busnr,
-				   assigned_dev->devfn);
-	if (!dev) {
-		printk(KERN_INFO "%s: host device not found\n",
__func__);
-		r = -EINVAL;
-		goto out_free;
-	}
-	if (pci_enable_device(dev)) {
-		printk(KERN_INFO "%s: Could not enable PCI device\n",
__func__);
-		r = -EBUSY;
-		goto out_put;
-	}
-	r = pci_request_regions(dev, "kvm_assigned_device");
-	if (r) {
-		printk(KERN_INFO "%s: Could not get access to device
regions\n",
-		       __func__);
-		goto out_disable;
-	}
-	match->assigned_dev_id = assigned_dev->assigned_dev_id;
-	match->host_busnr = assigned_dev->busnr;
-	match->host_devfn = assigned_dev->devfn;
-	match->dev = dev;
-
-	match->kvm = kvm;
-
-	list_add(&match->list, &kvm->arch.assigned_dev_head);
-
-	if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
-		r = kvm_iommu_map_guest(kvm, match);
-		if (r)
-			goto out_list_del;
-	}
-
-out:
-	mutex_unlock(&kvm->lock);
-	return r;
-out_list_del:
-	list_del(&match->list);
-	pci_release_regions(dev);
-out_disable:
-	pci_disable_device(dev);
-out_put:
-	pci_dev_put(dev);
-out_free:
-	kfree(match);
-	mutex_unlock(&kvm->lock);
-	return r;
-}
-
 unsigned long segment_base(u16 selector)
 {
 	struct descriptor_table gdt;
@@ -2030,28 +1797,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
 			goto out;
 		break;
 	}
-	case KVM_ASSIGN_PCI_DEVICE: {
-		struct kvm_assigned_pci_dev assigned_dev;
-
-		r = -EFAULT;
-		if (copy_from_user(&assigned_dev, argp, sizeof
assigned_dev))
-			goto out;
-		r = kvm_vm_ioctl_assign_device(kvm, &assigned_dev);
-		if (r)
-			goto out;
-		break;
-	}
-	case KVM_ASSIGN_IRQ: {
-		struct kvm_assigned_irq assigned_irq;
-
-		r = -EFAULT;
-		if (copy_from_user(&assigned_irq, argp, sizeof
assigned_irq))
-			goto out;
-		r = kvm_vm_ioctl_assign_irq(kvm, &assigned_irq);
-		if (r)
-			goto out;
-		break;
-	}
 	case KVM_GET_PIT: {
 		r = -EFAULT;
 		if (copy_from_user(&u.ps, argp, sizeof(struct
kvm_pit_state)))
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 4269be1..9acf34a 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -383,7 +383,9 @@ struct kvm_trace_rec {
 #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 CONFIG_X86
 #define KVM_CAP_DEVICE_ASSIGNMENT 17
+#endif
 #define KVM_CAP_IOMMU 18
 
 /*
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 73b7c52..10c1146 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -281,6 +281,7 @@ void kvm_free_physmem(struct kvm *kvm);
 
 struct  kvm *kvm_arch_create_vm(void);
 void kvm_arch_destroy_vm(struct kvm *kvm);
+void kvm_free_all_assigned_devices(struct kvm *kvm);
 
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6cf0427..59e08a4 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -51,6 +51,12 @@
 #include "coalesced_mmio.h"
 #endif
 
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include "irq.h"
+#endif
+
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
 
@@ -71,6 +77,240 @@ static long kvm_vcpu_ioctl(struct file *file,
unsigned int ioctl,
 
 bool kvm_rebooting;
 
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct
list_head *head,
+						      int
assigned_dev_id)
+{
+	struct list_head *ptr;
+	struct kvm_assigned_dev_kernel *match;
+
+	list_for_each(ptr, head) {
+		match = list_entry(ptr, struct kvm_assigned_dev_kernel,
list);
+		if (match->assigned_dev_id == assigned_dev_id)
+			return match;
+	}
+	return NULL;
+}
+
+static void kvm_assigned_dev_interrupt_work_handler(struct work_struct
*work)
+{
+	struct kvm_assigned_dev_kernel *assigned_dev;
+
+	assigned_dev = container_of(work, struct
kvm_assigned_dev_kernel,
+				    interrupt_work);
+
+	/* This is taken to safely inject irq inside the guest. When
+	 * the interrupt injection (or the ioapic code) uses a
+	 * finer-grained lock, update this
+	 */
+	mutex_lock(&assigned_dev->kvm->lock);
+	kvm_set_irq(assigned_dev->kvm,
+		    assigned_dev->guest_irq, 1);
+	mutex_unlock(&assigned_dev->kvm->lock);
+	kvm_put_kvm(assigned_dev->kvm);
+}
+
+/* FIXME: Implement the OR logic needed to make shared interrupts on
+ * this line behave properly
+ */
+static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
+{
+	struct kvm_assigned_dev_kernel *assigned_dev =
+		(struct kvm_assigned_dev_kernel *) dev_id;
+
+	kvm_get_kvm(assigned_dev->kvm);
+	schedule_work(&assigned_dev->interrupt_work);
+	disable_irq_nosync(irq);
+	return IRQ_HANDLED;
+}
+
+/* Ack the irq line for an assigned device */
+static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
+{
+	struct kvm_assigned_dev_kernel *dev;
+
+	if (kian->gsi == -1)
+		return;
+
+	dev = container_of(kian, struct kvm_assigned_dev_kernel,
+			   ack_notifier);
+	kvm_set_irq(dev->kvm, dev->guest_irq, 0);
+	enable_irq(dev->host_irq);
+}
+
+static void kvm_free_assigned_device(struct kvm *kvm,
+				     struct kvm_assigned_dev_kernel
+				     *assigned_dev)
+{
+	if (irqchip_in_kernel(kvm) && assigned_dev->irq_requested)
+		free_irq(assigned_dev->host_irq, (void *)assigned_dev);
+
+	kvm_unregister_irq_ack_notifier(kvm,
&assigned_dev->ack_notifier);
+
+	if (cancel_work_sync(&assigned_dev->interrupt_work))
+		/* We had pending work. That means we will have to take
+		 * care of kvm_put_kvm.
+		 */
+		kvm_put_kvm(kvm);
+
+	pci_release_regions(assigned_dev->dev);
+	pci_disable_device(assigned_dev->dev);
+	pci_dev_put(assigned_dev->dev);
+
+	list_del(&assigned_dev->list);
+	kfree(assigned_dev);
+}
+
+void kvm_free_all_assigned_devices(struct kvm *kvm)
+{
+	struct list_head *ptr, *ptr2;
+	struct kvm_assigned_dev_kernel *assigned_dev;
+
+	list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
+		assigned_dev = list_entry(ptr,
+					  struct
kvm_assigned_dev_kernel,
+					  list);
+
+		kvm_free_assigned_device(kvm, assigned_dev);
+	}
+}
+
+static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
+				   struct kvm_assigned_irq
+				   *assigned_irq)
+{
+	int r = 0;
+	struct kvm_assigned_dev_kernel *match;
+
+	mutex_lock(&kvm->lock);
+
+	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+				      assigned_irq->assigned_dev_id);
+	if (!match) {
+		mutex_unlock(&kvm->lock);
+		return -EINVAL;
+	}
+
+	if (match->irq_requested) {
+		match->guest_irq = assigned_irq->guest_irq;
+		match->ack_notifier.gsi = assigned_irq->guest_irq;
+		mutex_unlock(&kvm->lock);
+		return 0;
+	}
+
+	INIT_WORK(&match->interrupt_work,
+		  kvm_assigned_dev_interrupt_work_handler);
+
+	if (irqchip_in_kernel(kvm)) {
+		if (!capable(CAP_SYS_RAWIO)) {
+			r = -EPERM;
+			goto out_release;
+		}
+
+		if (assigned_irq->host_irq)
+			match->host_irq = assigned_irq->host_irq;
+		else
+			match->host_irq = match->dev->irq;
+		match->guest_irq = assigned_irq->guest_irq;
+		match->ack_notifier.gsi = assigned_irq->guest_irq;
+		match->ack_notifier.irq_acked =
kvm_assigned_dev_ack_irq;
+		kvm_register_irq_ack_notifier(kvm,
&match->ack_notifier);
+
+		/* Even though this is PCI, we don't want to use shared
+		 * interrupts. Sharing host devices with guest-assigned
devices
+		 * on the same interrupt line is not a happy situation:
there
+		 * are going to be long delays in accepting, acking,
etc.
+		 */
+		if (request_irq(match->host_irq, kvm_assigned_dev_intr,
0,
+				"kvm_assigned_device", (void *)match)) {
+			r = -EIO;
+			goto out_release;
+		}
+	}
+
+	match->irq_requested = true;
+	mutex_unlock(&kvm->lock);
+	return r;
+out_release:
+	mutex_unlock(&kvm->lock);
+	kvm_free_assigned_device(kvm, match);
+	return r;
+}
+
+static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
+				      struct kvm_assigned_pci_dev
*assigned_dev)
+{
+	int r = 0;
+	struct kvm_assigned_dev_kernel *match;
+	struct pci_dev *dev;
+
+	mutex_lock(&kvm->lock);
+
+	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+				      assigned_dev->assigned_dev_id);
+	if (match) {
+		/* device already assigned */
+		r = -EINVAL;
+		goto out;
+	}
+
+	match = kzalloc(sizeof(struct kvm_assigned_dev_kernel),
GFP_KERNEL);
+	if (match == NULL) {
+		printk(KERN_INFO "%s: Couldn't allocate memory\n",
+		       __func__);
+		r = -ENOMEM;
+		goto out;
+	}
+	dev = pci_get_bus_and_slot(assigned_dev->busnr,
+				   assigned_dev->devfn);
+	if (!dev) {
+		printk(KERN_INFO "%s: host device not found\n",
__func__);
+		r = -EINVAL;
+		goto out_free;
+	}
+	if (pci_enable_device(dev)) {
+		printk(KERN_INFO "%s: Could not enable PCI device\n",
__func__);
+		r = -EBUSY;
+		goto out_put;
+	}
+	r = pci_request_regions(dev, "kvm_assigned_device");
+	if (r) {
+		printk(KERN_INFO "%s: Could not get access to device
regions\n",
+		       __func__);
+		goto out_disable;
+	}
+	match->assigned_dev_id = assigned_dev->assigned_dev_id;
+	match->host_busnr = assigned_dev->busnr;
+	match->host_devfn = assigned_dev->devfn;
+	match->dev = dev;
+
+	match->kvm = kvm;
+
+	list_add(&match->list, &kvm->arch.assigned_dev_head);
+
+	if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
+		r = kvm_iommu_map_guest(kvm, match);
+		if (r)
+			goto out_list_del;
+	}
+
+out:
+	mutex_unlock(&kvm->lock);
+	return r;
+out_list_del:
+	list_del(&match->list);
+	pci_release_regions(dev);
+out_disable:
+	pci_disable_device(dev);
+out_put:
+	pci_dev_put(dev);
+out_free:
+	kfree(match);
+	mutex_unlock(&kvm->lock);
+	return r;
+}
+#endif
+
 static inline int valid_vcpu(int n)
 {
 	return likely(n >= 0 && n < KVM_MAX_VCPUS);
@@ -1383,6 +1623,30 @@ static long kvm_vm_ioctl(struct file *filp,
 		break;
 	}
 #endif
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+	case KVM_ASSIGN_PCI_DEVICE: {
+		struct kvm_assigned_pci_dev assigned_dev;
+
+		r = -EFAULT;
+		if (copy_from_user(&assigned_dev, argp, sizeof
assigned_dev))
+			goto out;
+		r = kvm_vm_ioctl_assign_device(kvm, &assigned_dev);
+		if (r)
+			goto out;
+		break;
+	}
+	case KVM_ASSIGN_IRQ: {
+		struct kvm_assigned_irq assigned_irq;
+
+		r = -EFAULT;
+		if (copy_from_user(&assigned_irq, argp, sizeof
assigned_irq))
+			goto out;
+		r = kvm_vm_ioctl_assign_irq(kvm, &assigned_irq);
+		if (r)
+			goto out;
+		break;
+	}
+#endif
 	default:
 		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
 	}
-- 
1.5.1


[-- Attachment #2: 0002-kvm-Moving-device_assignment-logic-to-kvm_main.c.patch --]
[-- Type: application/octet-stream, Size: 16437 bytes --]

From 6840c86b777e4a561cc3df7222cf5eb0b0bb9226 Mon Sep 17 00:00:00 2001
From: Xiantao Zhang <xiantao.zhang@intel.com>
Date: Sat, 27 Sep 2008 10:59:36 +0800
Subject: [PATCH] kvm: Moving device_assignment logic to kvm_main.c

To share with other archs, this patch moves device_assignment
logic to common parts.
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
---
 arch/x86/kvm/x86.c       |  255 -------------------------------------------
 include/linux/kvm.h      |    2 +
 include/linux/kvm_host.h |    1 +
 virt/kvm/kvm_main.c      |  268 +++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 269 insertions(+), 257 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4cfdd1b..aee0e37 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>
 #include <linux/kvm.h>
 #include <linux/fs.h>
-#include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/mman.h>
@@ -107,238 +106,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ NULL }
 };
 
-static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
-						      int assigned_dev_id)
-{
-	struct list_head *ptr;
-	struct kvm_assigned_dev_kernel *match;
-
-	list_for_each(ptr, head) {
-		match = list_entry(ptr, struct kvm_assigned_dev_kernel, list);
-		if (match->assigned_dev_id == assigned_dev_id)
-			return match;
-	}
-	return NULL;
-}
-
-static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
-{
-	struct kvm_assigned_dev_kernel *assigned_dev;
-
-	assigned_dev = container_of(work, struct kvm_assigned_dev_kernel,
-				    interrupt_work);
-
-	/* This is taken to safely inject irq inside the guest. When
-	 * the interrupt injection (or the ioapic code) uses a
-	 * finer-grained lock, update this
-	 */
-	mutex_lock(&assigned_dev->kvm->lock);
-	kvm_set_irq(assigned_dev->kvm,
-		    assigned_dev->guest_irq, 1);
-	mutex_unlock(&assigned_dev->kvm->lock);
-	kvm_put_kvm(assigned_dev->kvm);
-}
-
-/* FIXME: Implement the OR logic needed to make shared interrupts on
- * this line behave properly
- */
-static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
-{
-	struct kvm_assigned_dev_kernel *assigned_dev =
-		(struct kvm_assigned_dev_kernel *) dev_id;
-
-	kvm_get_kvm(assigned_dev->kvm);
-	schedule_work(&assigned_dev->interrupt_work);
-	disable_irq_nosync(irq);
-	return IRQ_HANDLED;
-}
-
-/* Ack the irq line for an assigned device */
-static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
-{
-	struct kvm_assigned_dev_kernel *dev;
-
-	if (kian->gsi == -1)
-		return;
-
-	dev = container_of(kian, struct kvm_assigned_dev_kernel,
-			   ack_notifier);
-	kvm_set_irq(dev->kvm, dev->guest_irq, 0);
-	enable_irq(dev->host_irq);
-}
-
-static void kvm_free_assigned_device(struct kvm *kvm,
-				     struct kvm_assigned_dev_kernel
-				     *assigned_dev)
-{
-	if (irqchip_in_kernel(kvm) && assigned_dev->irq_requested)
-		free_irq(assigned_dev->host_irq, (void *)assigned_dev);
-
-	kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier);
-
-	if (cancel_work_sync(&assigned_dev->interrupt_work))
-		/* We had pending work. That means we will have to take
-		 * care of kvm_put_kvm.
-		 */
-		kvm_put_kvm(kvm);
-
-	pci_release_regions(assigned_dev->dev);
-	pci_disable_device(assigned_dev->dev);
-	pci_dev_put(assigned_dev->dev);
-
-	list_del(&assigned_dev->list);
-	kfree(assigned_dev);
-}
-
-static void kvm_free_all_assigned_devices(struct kvm *kvm)
-{
-	struct list_head *ptr, *ptr2;
-	struct kvm_assigned_dev_kernel *assigned_dev;
-
-	list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
-		assigned_dev = list_entry(ptr,
-					  struct kvm_assigned_dev_kernel,
-					  list);
-
-		kvm_free_assigned_device(kvm, assigned_dev);
-	}
-}
-
-static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
-				   struct kvm_assigned_irq
-				   *assigned_irq)
-{
-	int r = 0;
-	struct kvm_assigned_dev_kernel *match;
-
-	mutex_lock(&kvm->lock);
-
-	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
-				      assigned_irq->assigned_dev_id);
-	if (!match) {
-		mutex_unlock(&kvm->lock);
-		return -EINVAL;
-	}
-
-	if (match->irq_requested) {
-		match->guest_irq = assigned_irq->guest_irq;
-		match->ack_notifier.gsi = assigned_irq->guest_irq;
-		mutex_unlock(&kvm->lock);
-		return 0;
-	}
-
-	INIT_WORK(&match->interrupt_work,
-		  kvm_assigned_dev_interrupt_work_handler);
-
-	if (irqchip_in_kernel(kvm)) {
-		if (!capable(CAP_SYS_RAWIO)) {
-			r = -EPERM;
-			goto out_release;
-		}
-
-		if (assigned_irq->host_irq)
-			match->host_irq = assigned_irq->host_irq;
-		else
-			match->host_irq = match->dev->irq;
-		match->guest_irq = assigned_irq->guest_irq;
-		match->ack_notifier.gsi = assigned_irq->guest_irq;
-		match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq;
-		kvm_register_irq_ack_notifier(kvm, &match->ack_notifier);
-
-		/* Even though this is PCI, we don't want to use shared
-		 * interrupts. Sharing host devices with guest-assigned devices
-		 * on the same interrupt line is not a happy situation: there
-		 * are going to be long delays in accepting, acking, etc.
-		 */
-		if (request_irq(match->host_irq, kvm_assigned_dev_intr, 0,
-				"kvm_assigned_device", (void *)match)) {
-			r = -EIO;
-			goto out_release;
-		}
-	}
-
-	match->irq_requested = true;
-	mutex_unlock(&kvm->lock);
-	return r;
-out_release:
-	mutex_unlock(&kvm->lock);
-	kvm_free_assigned_device(kvm, match);
-	return r;
-}
-
-static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
-				      struct kvm_assigned_pci_dev *assigned_dev)
-{
-	int r = 0;
-	struct kvm_assigned_dev_kernel *match;
-	struct pci_dev *dev;
-
-	mutex_lock(&kvm->lock);
-
-	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
-				      assigned_dev->assigned_dev_id);
-	if (match) {
-		/* device already assigned */
-		r = -EINVAL;
-		goto out;
-	}
-
-	match = kzalloc(sizeof(struct kvm_assigned_dev_kernel), GFP_KERNEL);
-	if (match == NULL) {
-		printk(KERN_INFO "%s: Couldn't allocate memory\n",
-		       __func__);
-		r = -ENOMEM;
-		goto out;
-	}
-	dev = pci_get_bus_and_slot(assigned_dev->busnr,
-				   assigned_dev->devfn);
-	if (!dev) {
-		printk(KERN_INFO "%s: host device not found\n", __func__);
-		r = -EINVAL;
-		goto out_free;
-	}
-	if (pci_enable_device(dev)) {
-		printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
-		r = -EBUSY;
-		goto out_put;
-	}
-	r = pci_request_regions(dev, "kvm_assigned_device");
-	if (r) {
-		printk(KERN_INFO "%s: Could not get access to device regions\n",
-		       __func__);
-		goto out_disable;
-	}
-	match->assigned_dev_id = assigned_dev->assigned_dev_id;
-	match->host_busnr = assigned_dev->busnr;
-	match->host_devfn = assigned_dev->devfn;
-	match->dev = dev;
-
-	match->kvm = kvm;
-
-	list_add(&match->list, &kvm->arch.assigned_dev_head);
-
-	if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
-		r = kvm_iommu_map_guest(kvm, match);
-		if (r)
-			goto out_list_del;
-	}
-
-out:
-	mutex_unlock(&kvm->lock);
-	return r;
-out_list_del:
-	list_del(&match->list);
-	pci_release_regions(dev);
-out_disable:
-	pci_disable_device(dev);
-out_put:
-	pci_dev_put(dev);
-out_free:
-	kfree(match);
-	mutex_unlock(&kvm->lock);
-	return r;
-}
-
 unsigned long segment_base(u16 selector)
 {
 	struct descriptor_table gdt;
@@ -2030,28 +1797,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
 			goto out;
 		break;
 	}
-	case KVM_ASSIGN_PCI_DEVICE: {
-		struct kvm_assigned_pci_dev assigned_dev;
-
-		r = -EFAULT;
-		if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev))
-			goto out;
-		r = kvm_vm_ioctl_assign_device(kvm, &assigned_dev);
-		if (r)
-			goto out;
-		break;
-	}
-	case KVM_ASSIGN_IRQ: {
-		struct kvm_assigned_irq assigned_irq;
-
-		r = -EFAULT;
-		if (copy_from_user(&assigned_irq, argp, sizeof assigned_irq))
-			goto out;
-		r = kvm_vm_ioctl_assign_irq(kvm, &assigned_irq);
-		if (r)
-			goto out;
-		break;
-	}
 	case KVM_GET_PIT: {
 		r = -EFAULT;
 		if (copy_from_user(&u.ps, argp, sizeof(struct kvm_pit_state)))
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 4269be1..9acf34a 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -383,7 +383,9 @@ struct kvm_trace_rec {
 #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 CONFIG_X86
 #define KVM_CAP_DEVICE_ASSIGNMENT 17
+#endif
 #define KVM_CAP_IOMMU 18
 
 /*
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 73b7c52..10c1146 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -281,6 +281,7 @@ void kvm_free_physmem(struct kvm *kvm);
 
 struct  kvm *kvm_arch_create_vm(void);
 void kvm_arch_destroy_vm(struct kvm *kvm);
+void kvm_free_all_assigned_devices(struct kvm *kvm);
 
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6cf0427..59e08a4 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -51,6 +51,12 @@
 #include "coalesced_mmio.h"
 #endif
 
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include "irq.h"
+#endif
+
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
 
@@ -71,6 +77,240 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
 
 bool kvm_rebooting;
 
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
+						      int assigned_dev_id)
+{
+	struct list_head *ptr;
+	struct kvm_assigned_dev_kernel *match;
+
+	list_for_each(ptr, head) {
+		match = list_entry(ptr, struct kvm_assigned_dev_kernel, list);
+		if (match->assigned_dev_id == assigned_dev_id)
+			return match;
+	}
+	return NULL;
+}
+
+static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
+{
+	struct kvm_assigned_dev_kernel *assigned_dev;
+
+	assigned_dev = container_of(work, struct kvm_assigned_dev_kernel,
+				    interrupt_work);
+
+	/* This is taken to safely inject irq inside the guest. When
+	 * the interrupt injection (or the ioapic code) uses a
+	 * finer-grained lock, update this
+	 */
+	mutex_lock(&assigned_dev->kvm->lock);
+	kvm_set_irq(assigned_dev->kvm,
+		    assigned_dev->guest_irq, 1);
+	mutex_unlock(&assigned_dev->kvm->lock);
+	kvm_put_kvm(assigned_dev->kvm);
+}
+
+/* FIXME: Implement the OR logic needed to make shared interrupts on
+ * this line behave properly
+ */
+static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
+{
+	struct kvm_assigned_dev_kernel *assigned_dev =
+		(struct kvm_assigned_dev_kernel *) dev_id;
+
+	kvm_get_kvm(assigned_dev->kvm);
+	schedule_work(&assigned_dev->interrupt_work);
+	disable_irq_nosync(irq);
+	return IRQ_HANDLED;
+}
+
+/* Ack the irq line for an assigned device */
+static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
+{
+	struct kvm_assigned_dev_kernel *dev;
+
+	if (kian->gsi == -1)
+		return;
+
+	dev = container_of(kian, struct kvm_assigned_dev_kernel,
+			   ack_notifier);
+	kvm_set_irq(dev->kvm, dev->guest_irq, 0);
+	enable_irq(dev->host_irq);
+}
+
+static void kvm_free_assigned_device(struct kvm *kvm,
+				     struct kvm_assigned_dev_kernel
+				     *assigned_dev)
+{
+	if (irqchip_in_kernel(kvm) && assigned_dev->irq_requested)
+		free_irq(assigned_dev->host_irq, (void *)assigned_dev);
+
+	kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier);
+
+	if (cancel_work_sync(&assigned_dev->interrupt_work))
+		/* We had pending work. That means we will have to take
+		 * care of kvm_put_kvm.
+		 */
+		kvm_put_kvm(kvm);
+
+	pci_release_regions(assigned_dev->dev);
+	pci_disable_device(assigned_dev->dev);
+	pci_dev_put(assigned_dev->dev);
+
+	list_del(&assigned_dev->list);
+	kfree(assigned_dev);
+}
+
+void kvm_free_all_assigned_devices(struct kvm *kvm)
+{
+	struct list_head *ptr, *ptr2;
+	struct kvm_assigned_dev_kernel *assigned_dev;
+
+	list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
+		assigned_dev = list_entry(ptr,
+					  struct kvm_assigned_dev_kernel,
+					  list);
+
+		kvm_free_assigned_device(kvm, assigned_dev);
+	}
+}
+
+static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
+				   struct kvm_assigned_irq
+				   *assigned_irq)
+{
+	int r = 0;
+	struct kvm_assigned_dev_kernel *match;
+
+	mutex_lock(&kvm->lock);
+
+	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+				      assigned_irq->assigned_dev_id);
+	if (!match) {
+		mutex_unlock(&kvm->lock);
+		return -EINVAL;
+	}
+
+	if (match->irq_requested) {
+		match->guest_irq = assigned_irq->guest_irq;
+		match->ack_notifier.gsi = assigned_irq->guest_irq;
+		mutex_unlock(&kvm->lock);
+		return 0;
+	}
+
+	INIT_WORK(&match->interrupt_work,
+		  kvm_assigned_dev_interrupt_work_handler);
+
+	if (irqchip_in_kernel(kvm)) {
+		if (!capable(CAP_SYS_RAWIO)) {
+			r = -EPERM;
+			goto out_release;
+		}
+
+		if (assigned_irq->host_irq)
+			match->host_irq = assigned_irq->host_irq;
+		else
+			match->host_irq = match->dev->irq;
+		match->guest_irq = assigned_irq->guest_irq;
+		match->ack_notifier.gsi = assigned_irq->guest_irq;
+		match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq;
+		kvm_register_irq_ack_notifier(kvm, &match->ack_notifier);
+
+		/* Even though this is PCI, we don't want to use shared
+		 * interrupts. Sharing host devices with guest-assigned devices
+		 * on the same interrupt line is not a happy situation: there
+		 * are going to be long delays in accepting, acking, etc.
+		 */
+		if (request_irq(match->host_irq, kvm_assigned_dev_intr, 0,
+				"kvm_assigned_device", (void *)match)) {
+			r = -EIO;
+			goto out_release;
+		}
+	}
+
+	match->irq_requested = true;
+	mutex_unlock(&kvm->lock);
+	return r;
+out_release:
+	mutex_unlock(&kvm->lock);
+	kvm_free_assigned_device(kvm, match);
+	return r;
+}
+
+static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
+				      struct kvm_assigned_pci_dev *assigned_dev)
+{
+	int r = 0;
+	struct kvm_assigned_dev_kernel *match;
+	struct pci_dev *dev;
+
+	mutex_lock(&kvm->lock);
+
+	match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+				      assigned_dev->assigned_dev_id);
+	if (match) {
+		/* device already assigned */
+		r = -EINVAL;
+		goto out;
+	}
+
+	match = kzalloc(sizeof(struct kvm_assigned_dev_kernel), GFP_KERNEL);
+	if (match == NULL) {
+		printk(KERN_INFO "%s: Couldn't allocate memory\n",
+		       __func__);
+		r = -ENOMEM;
+		goto out;
+	}
+	dev = pci_get_bus_and_slot(assigned_dev->busnr,
+				   assigned_dev->devfn);
+	if (!dev) {
+		printk(KERN_INFO "%s: host device not found\n", __func__);
+		r = -EINVAL;
+		goto out_free;
+	}
+	if (pci_enable_device(dev)) {
+		printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
+		r = -EBUSY;
+		goto out_put;
+	}
+	r = pci_request_regions(dev, "kvm_assigned_device");
+	if (r) {
+		printk(KERN_INFO "%s: Could not get access to device regions\n",
+		       __func__);
+		goto out_disable;
+	}
+	match->assigned_dev_id = assigned_dev->assigned_dev_id;
+	match->host_busnr = assigned_dev->busnr;
+	match->host_devfn = assigned_dev->devfn;
+	match->dev = dev;
+
+	match->kvm = kvm;
+
+	list_add(&match->list, &kvm->arch.assigned_dev_head);
+
+	if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
+		r = kvm_iommu_map_guest(kvm, match);
+		if (r)
+			goto out_list_del;
+	}
+
+out:
+	mutex_unlock(&kvm->lock);
+	return r;
+out_list_del:
+	list_del(&match->list);
+	pci_release_regions(dev);
+out_disable:
+	pci_disable_device(dev);
+out_put:
+	pci_dev_put(dev);
+out_free:
+	kfree(match);
+	mutex_unlock(&kvm->lock);
+	return r;
+}
+#endif
+
 static inline int valid_vcpu(int n)
 {
 	return likely(n >= 0 && n < KVM_MAX_VCPUS);
@@ -1383,6 +1623,30 @@ static long kvm_vm_ioctl(struct file *filp,
 		break;
 	}
 #endif
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+	case KVM_ASSIGN_PCI_DEVICE: {
+		struct kvm_assigned_pci_dev assigned_dev;
+
+		r = -EFAULT;
+		if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev))
+			goto out;
+		r = kvm_vm_ioctl_assign_device(kvm, &assigned_dev);
+		if (r)
+			goto out;
+		break;
+	}
+	case KVM_ASSIGN_IRQ: {
+		struct kvm_assigned_irq assigned_irq;
+
+		r = -EFAULT;
+		if (copy_from_user(&assigned_irq, argp, sizeof assigned_irq))
+			goto out;
+		r = kvm_vm_ioctl_assign_irq(kvm, &assigned_irq);
+		if (r)
+			goto out;
+		break;
+	}
+#endif
 	default:
 		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
 	}
-- 
1.5.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-09-29  5:26 [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c Zhang, Xiantao
@ 2008-10-03  7:09 ` Amit Shah
  2008-10-03  7:32   ` Zhang, Xiantao
  0 siblings, 1 reply; 10+ messages in thread
From: Amit Shah @ 2008-10-03  7:09 UTC (permalink / raw)
  To: Zhang, Xiantao; +Cc: kvm, kvm-ia64, avi

* On Monday 29 Sep 2008 10:56:29 Zhang, Xiantao wrote:
> From: Xiantao Zhang <xiantao.zhang@intel.com>
> Date: Sat, 27 Sep 2008 10:59:36 +0800
> Subject: [PATCH] kvm: Moving device_assignment logic to kvm_main.c
>
> To share with other archs, this patch moves device_assignment
> logic to common parts.
> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 4269be1..9acf34a 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -383,7 +383,9 @@ struct kvm_trace_rec {
>  #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 CONFIG_X86
>  #define KVM_CAP_DEVICE_ASSIGNMENT 17
> +#endif

I didn't see this changed to also accomodate IA64 in the patchset.

>  /*
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 73b7c52..10c1146 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -281,6 +281,7 @@ void kvm_free_physmem(struct kvm *kvm);
>
>  struct  kvm *kvm_arch_create_vm(void);
>  void kvm_arch_destroy_vm(struct kvm *kvm);
> +void kvm_free_all_assigned_devices(struct kvm *kvm);
>
>  int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
>  int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 6cf0427..59e08a4 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -51,6 +51,12 @@
>  #include "coalesced_mmio.h"
>  #endif
>
> +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> +#include <linux/pci.h>
> +#include <linux/interrupt.h>
> +#include "irq.h"
> +#endif
> +
>  MODULE_AUTHOR("Qumranet");
>  MODULE_LICENSE("GPL");
>
> @@ -71,6 +77,240 @@ static long kvm_vcpu_ioctl(struct file *file,
> unsigned int ioctl,
>
>  bool kvm_rebooting;
>
> +#ifdef KVM_CAP_DEVICE_ASSIGNMENT

Since you're doing this, you should also put the kvm_free_all_assigned_devices 
in the #ifdef for x86.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-03  7:09 ` Amit Shah
@ 2008-10-03  7:32   ` Zhang, Xiantao
  2008-10-03  7:42     ` Amit Shah
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Zhang, Xiantao @ 2008-10-03  7:32 UTC (permalink / raw)
  To: Amit Shah; +Cc: kvm, kvm-ia64, avi

Amit Shah wrote:
> * On Monday 29 Sep 2008 10:56:29 Zhang, Xiantao wrote:
>> From: Xiantao Zhang <xiantao.zhang@intel.com>
>> Date: Sat, 27 Sep 2008 10:59:36 +0800
>> Subject: [PATCH] kvm: Moving device_assignment logic to kvm_main.c
>> 
>> To share with other archs, this patch moves device_assignment
>> logic to common parts.
>> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
> 
>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>> index 4269be1..9acf34a 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -383,7 +383,9 @@ struct kvm_trace_rec {
>>  #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 CONFIG_X86
>>  #define KVM_CAP_DEVICE_ASSIGNMENT 17
>> +#endif
> 
> I didn't see this changed to also accomodate IA64 in the patchset.

Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
linux-ia64.git. So it should be in kvm.git once Avi merged with
upstream, so I didn't enable it for kvm/ia64 now.  You know, S390 has no
pci support, so if we put the code in kvm_mainc, we should use the macro
to exclude other arch which doesn't need device assignments.  If DMAR is
ready for kvm.git, I will change this macro as following:
#if defined(CONFIG_X86) || defined(CONFIG_IA64) 
#define KVM_CAP_DEVICE_ASSIGNMENT 17
#endif

>>  /*
>> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>> index 73b7c52..10c1146 100644 --- a/include/linux/kvm_host.h
>> +++ b/include/linux/kvm_host.h
>> @@ -281,6 +281,7 @@ void kvm_free_physmem(struct kvm *kvm);
>> 
>>  struct  kvm *kvm_arch_create_vm(void);
>>  void kvm_arch_destroy_vm(struct kvm *kvm);
>> +void kvm_free_all_assigned_devices(struct kvm *kvm);
>> 
>>  int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
>>  int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index 6cf0427..59e08a4 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -51,6 +51,12 @@
>>  #include "coalesced_mmio.h"
>>  #endif
>> 
>> +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
>> +#include <linux/pci.h>
>> +#include <linux/interrupt.h>
>> +#include "irq.h"
>> +#endif
>> +
>>  MODULE_AUTHOR("Qumranet");
>>  MODULE_LICENSE("GPL");
>> 
>> @@ -71,6 +77,240 @@ static long kvm_vcpu_ioctl(struct file *file,
>> unsigned int ioctl, 
>> 
>>  bool kvm_rebooting;
>> 
>> +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> 
> Since you're doing this, you should also put the
> kvm_free_all_assigned_devices in the #ifdef for x86.

This function has been wrapped by KVM_CAP_DEVICE_ASSIGNMENT. 
Xiantao

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-03  7:32   ` Zhang, Xiantao
@ 2008-10-03  7:42     ` Amit Shah
  2008-10-03 14:04       ` Zhang, Xiantao
  2008-10-05  9:39     ` Avi Kivity
  2008-10-07 13:16     ` Avi Kivity
  2 siblings, 1 reply; 10+ messages in thread
From: Amit Shah @ 2008-10-03  7:42 UTC (permalink / raw)
  To: Zhang, Xiantao; +Cc: kvm, kvm-ia64, avi

* On Friday 03 Oct 2008 13:02:05 Zhang, Xiantao wrote:
> Amit Shah wrote:
> > * On Monday 29 Sep 2008 10:56:29 Zhang, Xiantao wrote:
> >> From: Xiantao Zhang <xiantao.zhang@intel.com>
> >> Date: Sat, 27 Sep 2008 10:59:36 +0800
> >> Subject: [PATCH] kvm: Moving device_assignment logic to kvm_main.c
> >>
> >> To share with other archs, this patch moves device_assignment
> >> logic to common parts.
> >> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
> >>
> >> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> >> index 4269be1..9acf34a 100644
> >> --- a/include/linux/kvm.h
> >> +++ b/include/linux/kvm.h
> >> @@ -383,7 +383,9 @@ struct kvm_trace_rec {
> >>  #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 CONFIG_X86
> >>  #define KVM_CAP_DEVICE_ASSIGNMENT 17
> >> +#endif
> >
> > I didn't see this changed to also accomodate IA64 in the patchset.
>
> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
> linux-ia64.git. So it should be in kvm.git once Avi merged with

OK; Does Linus' tree currently have the necessary support?

Also, I think you'll have to redo the patch 1/8 after Weidong's mmio patch got 
merged.

> upstream, so I didn't enable it for kvm/ia64 now.  You know, S390 has no
> pci support, so if we put the code in kvm_mainc, we should use the macro
> to exclude other arch which doesn't need device assignments.  If DMAR is
> ready for kvm.git, I will change this macro as following:
> #if defined(CONFIG_X86) || defined(CONFIG_IA64)
> #define KVM_CAP_DEVICE_ASSIGNMENT 17
> #endif

Yes, that's what I meant.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-03  7:42     ` Amit Shah
@ 2008-10-03 14:04       ` Zhang, Xiantao
  2008-10-03 14:12         ` Amit Shah
  0 siblings, 1 reply; 10+ messages in thread
From: Zhang, Xiantao @ 2008-10-03 14:04 UTC (permalink / raw)
  To: Amit Shah; +Cc: kvm, kvm-ia64, avi

Amit Shah wrote:
> * On Friday 03 Oct 2008 13:02:05 Zhang, Xiantao wrote:
>> Amit Shah wrote:
>>> * On Monday 29 Sep 2008 10:56:29 Zhang, Xiantao wrote:
>>>> From: Xiantao Zhang <xiantao.zhang@intel.com>
>>>> Date: Sat, 27 Sep 2008 10:59:36 +0800
>>>> Subject: [PATCH] kvm: Moving device_assignment logic to kvm_main.c
>>>> 
>>>> To share with other archs, this patch moves device_assignment
>>>> logic to common parts. Signed-off-by: Xiantao Zhang
>>>> <xiantao.zhang@intel.com> 
>>>> 
>>>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>>>> index 4269be1..9acf34a 100644
>>>> --- a/include/linux/kvm.h
>>>> +++ b/include/linux/kvm.h
>>>> @@ -383,7 +383,9 @@ struct kvm_trace_rec {
>>>>  #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 CONFIG_X86
>>>>  #define KVM_CAP_DEVICE_ASSIGNMENT 17
>>>> +#endif
>>> 
>>> I didn't see this changed to also accomodate IA64 in the patchset.
>> 
>> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
>> linux-ia64.git. So it should be in kvm.git once Avi merged with

> OK; Does Linus' tree currently have the necessary support?

If Linus's tree has picked up it from linux-ia64, it should be ready. 

> Also, I think you'll have to redo the patch 1/8 after Weidong's mmio
> patch got merged.
Yes, if weidong's patch merged first,  the patch should be regenerated
:)
>> upstream, so I didn't enable it for kvm/ia64 now.  You know, S390
>> has no pci support, so if we put the code in kvm_mainc, we should
>> use the macro to exclude other arch which doesn't need device
>> assignments.  If DMAR is ready for kvm.git, I will change this macro
>> as following: #if defined(CONFIG_X86) || defined(CONFIG_IA64)
>> #define KVM_CAP_DEVICE_ASSIGNMENT 17
>> #endif
> 
> Yes, that's what I meant.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-03 14:04       ` Zhang, Xiantao
@ 2008-10-03 14:12         ` Amit Shah
  0 siblings, 0 replies; 10+ messages in thread
From: Amit Shah @ 2008-10-03 14:12 UTC (permalink / raw)
  To: Zhang, Xiantao; +Cc: kvm, kvm-ia64, avi

* On Friday 03 Oct 2008 19:34:42 Zhang, Xiantao wrote:
> >> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
> >> linux-ia64.git. So it should be in kvm.git once Avi merged with
> >
> > OK; Does Linus' tree currently have the necessary support?
>
> If Linus's tree has picked up it from linux-ia64, it should be ready.

So is that planned for 2.6.28?

> > Also, I think you'll have to redo the patch 1/8 after Weidong's mmio
> > patch got merged.
>
> Yes, if weidong's patch merged first,  the patch should be regenerated
>
> :)

Yes, it's already been merged by Avi.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-03  7:32   ` Zhang, Xiantao
  2008-10-03  7:42     ` Amit Shah
@ 2008-10-05  9:39     ` Avi Kivity
  2008-10-06  3:15       ` Zhang, Xiantao
  2008-10-07 13:16     ` Avi Kivity
  2 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2008-10-05  9:39 UTC (permalink / raw)
  To: Zhang, Xiantao; +Cc: Amit Shah, kvm, kvm-ia64

Zhang, Xiantao wrote:
>>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>>> index 4269be1..9acf34a 100644
>>> --- a/include/linux/kvm.h
>>> +++ b/include/linux/kvm.h
>>> @@ -383,7 +383,9 @@ struct kvm_trace_rec {
>>>  #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 CONFIG_X86
>>>  #define KVM_CAP_DEVICE_ASSIGNMENT 17
>>> +#endif
>>>       
>> I didn't see this changed to also accomodate IA64 in the patchset.
>>     
>
> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
> linux-ia64.git. So it should be in kvm.git once Avi merged with
> upstream, so I didn't enable it for kvm/ia64 now.  You know, S390 has no
> pci support, so if we put the code in kvm_mainc, we should use the macro
> to exclude other arch which doesn't need device assignments.  If DMAR is
> ready for kvm.git, I will change this macro as following:
> #if defined(CONFIG_X86) || defined(CONFIG_IA64) 
> #define KVM_CAP_DEVICE_ASSIGNMENT 17
> #endif
>   

What does this mean?  Does the patchset compile on top of kvm.git or not?


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-05  9:39     ` Avi Kivity
@ 2008-10-06  3:15       ` Zhang, Xiantao
  0 siblings, 0 replies; 10+ messages in thread
From: Zhang, Xiantao @ 2008-10-06  3:15 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Amit Shah, kvm, kvm-ia64

Avi Kivity wrote:
> Zhang, Xiantao wrote:
>>>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>>>> index 4269be1..9acf34a 100644
>>>> --- a/include/linux/kvm.h
>>>> +++ b/include/linux/kvm.h
>>>> @@ -383,7 +383,9 @@ struct kvm_trace_rec {
>>>>  #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 CONFIG_X86
>>>>  #define KVM_CAP_DEVICE_ASSIGNMENT 17
>>>> +#endif
>>>> 
>>> I didn't see this changed to also accomodate IA64 in the patchset.
>>> 
>> 
>> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
>> linux-ia64.git. So it should be in kvm.git once Avi merged with
>> upstream, so I didn't enable it for kvm/ia64 now.  You know, S390
>> has no pci support, so if we put the code in kvm_mainc, we should
>> use the macro to exclude other arch which doesn't need device
>> assignments.  If DMAR is ready for kvm.git, I will change this macro
>> as following: #if defined(CONFIG_X86) || defined(CONFIG_IA64)
>> #define KVM_CAP_DEVICE_ASSIGNMENT 17
>> #endif
>> 
> 
> What does this mean?  Does the patchset compile on top of kvm.git or
> not? 
Hi, Avi 
	This patchset can compile on kvm.git. But,  you know, since DMAR
support is only going into liux-ia64.git, and before you merging with
linux-ia64.git, we can't enable it.  In addition, we also need this
macro to exclude some archs, for example, s390 can't use current
device-assignment logic because it doesn't support pci.  So, once you
get merge with linux-ia64.git, we can define this macro for kvm/ia64.
Thanks
Xiantao

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-03  7:32   ` Zhang, Xiantao
  2008-10-03  7:42     ` Amit Shah
  2008-10-05  9:39     ` Avi Kivity
@ 2008-10-07 13:16     ` Avi Kivity
  2008-10-07 23:52       ` Zhang, Xiantao
  2 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2008-10-07 13:16 UTC (permalink / raw)
  To: Zhang, Xiantao; +Cc: Amit Shah, kvm, kvm-ia64

Zhang, Xiantao wrote:
> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
> linux-ia64.git. So it should be in kvm.git once Avi merged with
> upstream, so I didn't enable it for kvm/ia64 now.  You know, S390 has no
> pci support, so if we put the code in kvm_mainc, we should use the macro
> to exclude other arch which doesn't need device assignments.  If DMAR is
> ready for kvm.git, I will change this macro as following:
> #if defined(CONFIG_X86) || defined(CONFIG_IA64) 
> #define KVM_CAP_DEVICE_ASSIGNMENT 17
> #endif
>
>   

Okay; please resend the patchset once kvm.git has all the prerequisites.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c
  2008-10-07 13:16     ` Avi Kivity
@ 2008-10-07 23:52       ` Zhang, Xiantao
  0 siblings, 0 replies; 10+ messages in thread
From: Zhang, Xiantao @ 2008-10-07 23:52 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Amit Shah, kvm, kvm-ia64

Avi Kivity wrote:
> Zhang, Xiantao wrote:
>> Since linux-ia64 DMAR is not ready in kvm.git, and it should be in
>> linux-ia64.git. So it should be in kvm.git once Avi merged with
>> upstream, so I didn't enable it for kvm/ia64 now.  You know, S390
>> has no pci support, so if we put the code in kvm_mainc, we should
>> use the macro to exclude other arch which doesn't need device
>> assignments.  If DMAR is ready for kvm.git, I will change this macro
>> as following: #if defined(CONFIG_X86) || defined(CONFIG_IA64)
>> #define KVM_CAP_DEVICE_ASSIGNMENT 17
>> #endif
>> 
>> 
> 
> Okay; please resend the patchset once kvm.git has all the
> prerequisites. 
Hi, Avi 
     Currently, kvm.git should be ready to pickup the patchset even if
DMAR is not ready, since DMAR is not  prerequistites for device
assignment but for vt-d.  I will enable this macro for kvm/ia64 in the
subsequent patchset. Thank you!
Xiantao

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-10-07 23:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-29  5:26 [PATCH 2/8]kvm: Moving device_assignment logic to kvm_main.c Zhang, Xiantao
2008-10-03  7:09 ` Amit Shah
2008-10-03  7:32   ` Zhang, Xiantao
2008-10-03  7:42     ` Amit Shah
2008-10-03 14:04       ` Zhang, Xiantao
2008-10-03 14:12         ` Amit Shah
2008-10-05  9:39     ` Avi Kivity
2008-10-06  3:15       ` Zhang, Xiantao
2008-10-07 13:16     ` Avi Kivity
2008-10-07 23:52       ` Zhang, Xiantao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).