diff options
Diffstat (limited to 'virt/kvm/ioapic.c')
-rw-r--r-- | virt/kvm/ioapic.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 1dcf9f3d1107..c0d22870ee9c 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -146,6 +146,11 @@ static int ioapic_inj_irq(struct kvm_ioapic *ioapic, | |||
146 | return kvm_apic_set_irq(vcpu, vector, trig_mode); | 146 | return kvm_apic_set_irq(vcpu, vector, trig_mode); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void ioapic_inj_nmi(struct kvm_vcpu *vcpu) | ||
150 | { | ||
151 | kvm_inject_nmi(vcpu); | ||
152 | } | ||
153 | |||
149 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | 154 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, |
150 | u8 dest_mode) | 155 | u8 dest_mode) |
151 | { | 156 | { |
@@ -239,8 +244,19 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
239 | } | 244 | } |
240 | } | 245 | } |
241 | break; | 246 | break; |
242 | 247 | case IOAPIC_NMI: | |
243 | /* TODO: NMI */ | 248 | for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) { |
249 | if (!(deliver_bitmask & (1 << vcpu_id))) | ||
250 | continue; | ||
251 | deliver_bitmask &= ~(1 << vcpu_id); | ||
252 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | ||
253 | if (vcpu) | ||
254 | ioapic_inj_nmi(vcpu); | ||
255 | else | ||
256 | ioapic_debug("NMI to vcpu %d failed\n", | ||
257 | vcpu->vcpu_id); | ||
258 | } | ||
259 | break; | ||
244 | default: | 260 | default: |
245 | printk(KERN_WARNING "Unsupported delivery mode %d\n", | 261 | printk(KERN_WARNING "Unsupported delivery mode %d\n", |
246 | delivery_mode); | 262 | delivery_mode); |
@@ -278,7 +294,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi) | |||
278 | 294 | ||
279 | ent->fields.remote_irr = 0; | 295 | ent->fields.remote_irr = 0; |
280 | if (!ent->fields.mask && (ioapic->irr & (1 << gsi))) | 296 | if (!ent->fields.mask && (ioapic->irr & (1 << gsi))) |
281 | ioapic_deliver(ioapic, gsi); | 297 | ioapic_service(ioapic, gsi); |
282 | } | 298 | } |
283 | 299 | ||
284 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) | 300 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) |
@@ -291,7 +307,8 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) | |||
291 | __kvm_ioapic_update_eoi(ioapic, i); | 307 | __kvm_ioapic_update_eoi(ioapic, i); |
292 | } | 308 | } |
293 | 309 | ||
294 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr) | 310 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr, |
311 | int len, int is_write) | ||
295 | { | 312 | { |
296 | struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; | 313 | struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; |
297 | 314 | ||