diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 70 |
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, | |||
85 | static bool kvm_rebooting; | 81 | static bool kvm_rebooting; |
86 | 82 | ||
87 | #ifdef KVM_CAP_DEVICE_ASSIGNMENT | 83 | #ifdef KVM_CAP_DEVICE_ASSIGNMENT |
88 | |||
89 | #ifdef CONFIG_X86 | ||
90 | static 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 | ||
136 | static void assigned_device_msi_dispatch(struct kvm_assigned_dev_kernel *dev) {} | ||
137 | #endif | ||
138 | |||
139 | static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, | 84 | static 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 | /* |