aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
authorSheng Yang <sheng@linux.intel.com>2009-02-10 00:57:06 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:03:09 -0400
commit79950e1073150909619b7c0f9a39a2fea83a42d8 (patch)
tree5dc96ee5d69029d61b90bc18d44cb42baaa925cd /virt/kvm/kvm_main.c
parent34c33d163fe509da8414a736c6328855f8c164e5 (diff)
KVM: Use irq routing API for MSI
Merge MSI userspace interface with IRQ routing table. Notice the API have been changed, and using IRQ routing table would be the only interface kvm-userspace supported. Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c70
1 files changed, 5 insertions, 65 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c65484b471c6..266bdaf0ce44 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -47,10 +47,6 @@
47#include <asm/uaccess.h> 47#include <asm/uaccess.h>
48#include <asm/pgtable.h> 48#include <asm/pgtable.h>
49 49
50#ifdef CONFIG_X86
51#include <asm/msidef.h>
52#endif
53
54#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 50#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
55#include "coalesced_mmio.h" 51#include "coalesced_mmio.h"
56#endif 52#endif
@@ -85,57 +81,6 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
85static bool kvm_rebooting; 81static bool kvm_rebooting;
86 82
87#ifdef KVM_CAP_DEVICE_ASSIGNMENT 83#ifdef KVM_CAP_DEVICE_ASSIGNMENT
88
89#ifdef CONFIG_X86
90static void assigned_device_msi_dispatch(struct kvm_assigned_dev_kernel *dev)
91{
92 int vcpu_id;
93 struct kvm_vcpu *vcpu;
94 struct kvm_ioapic *ioapic = ioapic_irqchip(dev->kvm);
95 int dest_id = (dev->guest_msi.address_lo & MSI_ADDR_DEST_ID_MASK)
96 >> MSI_ADDR_DEST_ID_SHIFT;
97 int vector = (dev->guest_msi.data & MSI_DATA_VECTOR_MASK)
98 >> MSI_DATA_VECTOR_SHIFT;
99 int dest_mode = test_bit(MSI_ADDR_DEST_MODE_SHIFT,
100 (unsigned long *)&dev->guest_msi.address_lo);
101 int trig_mode = test_bit(MSI_DATA_TRIGGER_SHIFT,
102 (unsigned long *)&dev->guest_msi.data);
103 int delivery_mode = test_bit(MSI_DATA_DELIVERY_MODE_SHIFT,
104 (unsigned long *)&dev->guest_msi.data);
105 u32 deliver_bitmask;
106
107 BUG_ON(!ioapic);
108
109 deliver_bitmask = kvm_ioapic_get_delivery_bitmask(ioapic,
110 dest_id, dest_mode);
111 /* IOAPIC delivery mode value is the same as MSI here */
112 switch (delivery_mode) {
113 case IOAPIC_LOWEST_PRIORITY:
114 vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector,
115 deliver_bitmask);
116 if (vcpu != NULL)
117 kvm_apic_set_irq(vcpu, vector, trig_mode);
118 else
119 printk(KERN_INFO "kvm: null lowest priority vcpu!\n");
120 break;
121 case IOAPIC_FIXED:
122 for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
123 if (!(deliver_bitmask & (1 << vcpu_id)))
124 continue;
125 deliver_bitmask &= ~(1 << vcpu_id);
126 vcpu = ioapic->kvm->vcpus[vcpu_id];
127 if (vcpu)
128 kvm_apic_set_irq(vcpu, vector, trig_mode);
129 }
130 break;
131 default:
132 printk(KERN_INFO "kvm: unsupported MSI delivery mode\n");
133 }
134}
135#else
136static void assigned_device_msi_dispatch(struct kvm_assigned_dev_kernel *dev) {}
137#endif
138
139static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, 84static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
140 int assigned_dev_id) 85 int assigned_dev_id)
141{ 86{
@@ -162,13 +107,10 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
162 * finer-grained lock, update this 107 * finer-grained lock, update this
163 */ 108 */
164 mutex_lock(&assigned_dev->kvm->lock); 109 mutex_lock(&assigned_dev->kvm->lock);
165 if (assigned_dev->irq_requested_type & KVM_ASSIGNED_DEV_GUEST_INTX) 110 kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
166 kvm_set_irq(assigned_dev->kvm, 111 assigned_dev->guest_irq, 1);
167 assigned_dev->irq_source_id, 112
168 assigned_dev->guest_irq, 1); 113 if (assigned_dev->irq_requested_type & KVM_ASSIGNED_DEV_GUEST_MSI) {
169 else if (assigned_dev->irq_requested_type &
170 KVM_ASSIGNED_DEV_GUEST_MSI) {
171 assigned_device_msi_dispatch(assigned_dev);
172 enable_irq(assigned_dev->host_irq); 114 enable_irq(assigned_dev->host_irq);
173 assigned_dev->host_irq_disabled = false; 115 assigned_dev->host_irq_disabled = false;
174 } 116 }
@@ -331,17 +273,15 @@ static int assigned_device_update_msi(struct kvm *kvm,
331{ 273{
332 int r; 274 int r;
333 275
276 adev->guest_irq = airq->guest_irq;
334 if (airq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI) { 277 if (airq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI) {
335 /* x86 don't care upper address of guest msi message addr */ 278 /* x86 don't care upper address of guest msi message addr */
336 adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_MSI; 279 adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_MSI;
337 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_INTX; 280 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_INTX;
338 adev->guest_msi.address_lo = airq->guest_msi.addr_lo;
339 adev->guest_msi.data = airq->guest_msi.data;
340 adev->ack_notifier.gsi = -1; 281 adev->ack_notifier.gsi = -1;
341 } else if (msi2intx) { 282 } else if (msi2intx) {
342 adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_INTX; 283 adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_INTX;
343 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_MSI; 284 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_MSI;
344 adev->guest_irq = airq->guest_irq;
345 adev->ack_notifier.gsi = airq->guest_irq; 285 adev->ack_notifier.gsi = airq->guest_irq;
346 } else { 286 } else {
347 /* 287 /*