aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2012-08-14 12:20:28 -0400
committerMarcelo Tosatti <mtosatti@redhat.com>2012-08-14 21:35:22 -0400
commit28a6fdabb3ea775d3d707afd9d2728b3ced2c34d (patch)
tree13e8ec656afd83c2a8064256668ae665c81d4912
parentdbcb4e798072d114fe68813f39a9efd239ab99c0 (diff)
KVM: x86: drop parameter validation in ioapic/pic
We validate irq pin number when routing is setup, so code handling illegal irq # in pic and ioapic on each injection is never called. Drop it, replace with BUG_ON to catch out of bounds access bugs. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/x86/kvm/i8259.c18
-rw-r--r--virt/kvm/ioapic.c37
2 files changed, 28 insertions, 27 deletions
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index e498b18f010c..90c84f947d45 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -190,17 +190,17 @@ void kvm_pic_update_irq(struct kvm_pic *s)
190 190
191int kvm_pic_set_irq(struct kvm_pic *s, int irq, int irq_source_id, int level) 191int kvm_pic_set_irq(struct kvm_pic *s, int irq, int irq_source_id, int level)
192{ 192{
193 int ret = -1; 193 int ret, irq_level;
194
195 BUG_ON(irq < 0 || irq >= PIC_NUM_PINS);
194 196
195 pic_lock(s); 197 pic_lock(s);
196 if (irq >= 0 && irq < PIC_NUM_PINS) { 198 irq_level = __kvm_irq_line_state(&s->irq_states[irq],
197 int irq_level = __kvm_irq_line_state(&s->irq_states[irq], 199 irq_source_id, level);
198 irq_source_id, level); 200 ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, irq_level);
199 ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, irq_level); 201 pic_update_irq(s);
200 pic_update_irq(s); 202 trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
201 trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, 203 s->pics[irq >> 3].imr, ret == 0);
202 s->pics[irq >> 3].imr, ret == 0);
203 }
204 pic_unlock(s); 204 pic_unlock(s);
205 205
206 return ret; 206 return ret;
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;