aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/ioapic.c
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@Intel.com>2013-04-11 07:21:40 -0400
committerMarcelo Tosatti <mtosatti@redhat.com>2013-04-15 22:20:34 -0400
commitaa2fbe6d44892070d78995f0df875ce930904e29 (patch)
treebc2350a65c4e656df5597ebe4111bcfd98116bfe /virt/kvm/ioapic.c
parentf3bff6318fa0f54956b02ed451d9b120441006ea (diff)
KVM: Let ioapic know the irq line status
Userspace may deliver RTC interrupt without query the status. So we want to track RTC EOI for this case. Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com> Reviewed-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'virt/kvm/ioapic.c')
-rw-r--r--virt/kvm/ioapic.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 76528fff252d..a49fcd55b378 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -50,7 +50,8 @@
50#else 50#else
51#define ioapic_debug(fmt, arg...) 51#define ioapic_debug(fmt, arg...)
52#endif 52#endif
53static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq); 53static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq,
54 bool line_status);
54 55
55static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, 56static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
56 unsigned long addr, 57 unsigned long addr,
@@ -146,7 +147,8 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)
146 __rtc_irq_eoi_tracking_restore_one(vcpu); 147 __rtc_irq_eoi_tracking_restore_one(vcpu);
147} 148}
148 149
149static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) 150static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx,
151 bool line_status)
150{ 152{
151 union kvm_ioapic_redirect_entry *pent; 153 union kvm_ioapic_redirect_entry *pent;
152 int injected = -1; 154 int injected = -1;
@@ -154,7 +156,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
154 pent = &ioapic->redirtbl[idx]; 156 pent = &ioapic->redirtbl[idx];
155 157
156 if (!pent->fields.mask) { 158 if (!pent->fields.mask) {
157 injected = ioapic_deliver(ioapic, idx); 159 injected = ioapic_deliver(ioapic, idx, line_status);
158 if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) 160 if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
159 pent->fields.remote_irr = 1; 161 pent->fields.remote_irr = 1;
160 } 162 }
@@ -248,13 +250,13 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
248 kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after); 250 kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after);
249 if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG 251 if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG
250 && ioapic->irr & (1 << index)) 252 && ioapic->irr & (1 << index))
251 ioapic_service(ioapic, index); 253 ioapic_service(ioapic, index, false);
252 kvm_ioapic_make_eoibitmap_request(ioapic->kvm); 254 kvm_ioapic_make_eoibitmap_request(ioapic->kvm);
253 break; 255 break;
254 } 256 }
255} 257}
256 258
257static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) 259static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq, bool line_status)
258{ 260{
259 union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq]; 261 union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
260 struct kvm_lapic_irq irqe; 262 struct kvm_lapic_irq irqe;
@@ -277,7 +279,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
277} 279}
278 280
279int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, 281int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,
280 int level) 282 int level, bool line_status)
281{ 283{
282 u32 old_irr; 284 u32 old_irr;
283 u32 mask = 1 << irq; 285 u32 mask = 1 << irq;
@@ -300,7 +302,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,
300 ioapic->irr |= mask; 302 ioapic->irr |= mask;
301 if ((edge && old_irr != ioapic->irr) || 303 if ((edge && old_irr != ioapic->irr) ||
302 (!edge && !entry.fields.remote_irr)) 304 (!edge && !entry.fields.remote_irr))
303 ret = ioapic_service(ioapic, irq); 305 ret = ioapic_service(ioapic, irq, line_status);
304 else 306 else
305 ret = 0; /* report coalesced interrupt */ 307 ret = 0; /* report coalesced interrupt */
306 } 308 }
@@ -349,7 +351,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
349 ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); 351 ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
350 ent->fields.remote_irr = 0; 352 ent->fields.remote_irr = 0;
351 if (!ent->fields.mask && (ioapic->irr & (1 << i))) 353 if (!ent->fields.mask && (ioapic->irr & (1 << i)))
352 ioapic_service(ioapic, i); 354 ioapic_service(ioapic, i, false);
353 } 355 }
354} 356}
355 357