diff options
Diffstat (limited to 'virt/kvm/ioapic.c')
-rw-r--r-- | virt/kvm/ioapic.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index ef61d529a6c4..cfb7e4d52dc2 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -197,28 +197,29 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, | |||
197 | u32 old_irr; | 197 | u32 old_irr; |
198 | u32 mask = 1 << irq; | 198 | u32 mask = 1 << irq; |
199 | union kvm_ioapic_redirect_entry entry; | 199 | union kvm_ioapic_redirect_entry entry; |
200 | int ret = 1; | 200 | int ret, irq_level; |
201 | |||
202 | BUG_ON(irq < 0 || irq >= IOAPIC_NUM_PINS); | ||
201 | 203 | ||
202 | spin_lock(&ioapic->lock); | 204 | spin_lock(&ioapic->lock); |
203 | old_irr = ioapic->irr; | 205 | old_irr = ioapic->irr; |
204 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { | 206 | irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq], |
205 | int irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq], | 207 | irq_source_id, level); |
206 | irq_source_id, level); | 208 | entry = ioapic->redirtbl[irq]; |
207 | entry = ioapic->redirtbl[irq]; | 209 | irq_level ^= entry.fields.polarity; |
208 | irq_level ^= entry.fields.polarity; | 210 | if (!irq_level) { |
209 | if (!irq_level) | 211 | ioapic->irr &= ~mask; |
210 | ioapic->irr &= ~mask; | 212 | ret = 1; |
211 | else { | 213 | } else { |
212 | int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); | 214 | int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); |
213 | ioapic->irr |= mask; | 215 | ioapic->irr |= mask; |
214 | if ((edge && old_irr != ioapic->irr) || | 216 | if ((edge && old_irr != ioapic->irr) || |
215 | (!edge && !entry.fields.remote_irr)) | 217 | (!edge && !entry.fields.remote_irr)) |
216 | ret = ioapic_service(ioapic, irq); | 218 | ret = ioapic_service(ioapic, irq); |
217 | else | 219 | else |
218 | ret = 0; /* report coalesced interrupt */ | 220 | ret = 0; /* report coalesced interrupt */ |
219 | } | ||
220 | trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); | ||
221 | } | 221 | } |
222 | trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); | ||
222 | spin_unlock(&ioapic->lock); | 223 | spin_unlock(&ioapic->lock); |
223 | 224 | ||
224 | return ret; | 225 | return ret; |