diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/ioapic.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 4232fd75dd20..98778cb69c6e 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #else | 45 | #else |
46 | #define ioapic_debug(fmt, arg...) | 46 | #define ioapic_debug(fmt, arg...) |
47 | #endif | 47 | #endif |
48 | static void ioapic_deliver(struct kvm_ioapic *vioapic, int irq); | 48 | static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq); |
49 | 49 | ||
50 | static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, | 50 | static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, |
51 | unsigned long addr, | 51 | unsigned long addr, |
@@ -89,8 +89,8 @@ static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) | |||
89 | pent = &ioapic->redirtbl[idx]; | 89 | pent = &ioapic->redirtbl[idx]; |
90 | 90 | ||
91 | if (!pent->fields.mask) { | 91 | if (!pent->fields.mask) { |
92 | ioapic_deliver(ioapic, idx); | 92 | int injected = ioapic_deliver(ioapic, idx); |
93 | if (pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) | 93 | if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) |
94 | pent->fields.remote_irr = 1; | 94 | pent->fields.remote_irr = 1; |
95 | } | 95 | } |
96 | if (!pent->fields.trig_mode) | 96 | if (!pent->fields.trig_mode) |
@@ -133,7 +133,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | static void ioapic_inj_irq(struct kvm_ioapic *ioapic, | 136 | static int ioapic_inj_irq(struct kvm_ioapic *ioapic, |
137 | struct kvm_vcpu *vcpu, | 137 | struct kvm_vcpu *vcpu, |
138 | u8 vector, u8 trig_mode, u8 delivery_mode) | 138 | u8 vector, u8 trig_mode, u8 delivery_mode) |
139 | { | 139 | { |
@@ -143,7 +143,7 @@ static void ioapic_inj_irq(struct kvm_ioapic *ioapic, | |||
143 | ASSERT((delivery_mode == IOAPIC_FIXED) || | 143 | ASSERT((delivery_mode == IOAPIC_FIXED) || |
144 | (delivery_mode == IOAPIC_LOWEST_PRIORITY)); | 144 | (delivery_mode == IOAPIC_LOWEST_PRIORITY)); |
145 | 145 | ||
146 | kvm_apic_set_irq(vcpu, vector, trig_mode); | 146 | return kvm_apic_set_irq(vcpu, vector, trig_mode); |
147 | } | 147 | } |
148 | 148 | ||
149 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | 149 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, |
@@ -186,7 +186,7 @@ static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | |||
186 | return mask; | 186 | return mask; |
187 | } | 187 | } |
188 | 188 | ||
189 | static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | 189 | static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) |
190 | { | 190 | { |
191 | u8 dest = ioapic->redirtbl[irq].fields.dest_id; | 191 | u8 dest = ioapic->redirtbl[irq].fields.dest_id; |
192 | u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode; | 192 | u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode; |
@@ -195,7 +195,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
195 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; | 195 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; |
196 | u32 deliver_bitmask; | 196 | u32 deliver_bitmask; |
197 | struct kvm_vcpu *vcpu; | 197 | struct kvm_vcpu *vcpu; |
198 | int vcpu_id; | 198 | int vcpu_id, r = 0; |
199 | 199 | ||
200 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " | 200 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " |
201 | "vector=%x trig_mode=%x\n", | 201 | "vector=%x trig_mode=%x\n", |
@@ -204,7 +204,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
204 | deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode); | 204 | deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode); |
205 | if (!deliver_bitmask) { | 205 | if (!deliver_bitmask) { |
206 | ioapic_debug("no target on destination\n"); | 206 | ioapic_debug("no target on destination\n"); |
207 | return; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | switch (delivery_mode) { | 210 | switch (delivery_mode) { |
@@ -216,7 +216,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
216 | vcpu = ioapic->kvm->vcpus[0]; | 216 | vcpu = ioapic->kvm->vcpus[0]; |
217 | #endif | 217 | #endif |
218 | if (vcpu != NULL) | 218 | if (vcpu != NULL) |
219 | ioapic_inj_irq(ioapic, vcpu, vector, | 219 | r = ioapic_inj_irq(ioapic, vcpu, vector, |
220 | trig_mode, delivery_mode); | 220 | trig_mode, delivery_mode); |
221 | else | 221 | else |
222 | ioapic_debug("null lowest prio vcpu: " | 222 | ioapic_debug("null lowest prio vcpu: " |
@@ -234,7 +234,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
234 | deliver_bitmask &= ~(1 << vcpu_id); | 234 | deliver_bitmask &= ~(1 << vcpu_id); |
235 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 235 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
236 | if (vcpu) { | 236 | if (vcpu) { |
237 | ioapic_inj_irq(ioapic, vcpu, vector, | 237 | r = ioapic_inj_irq(ioapic, vcpu, vector, |
238 | trig_mode, delivery_mode); | 238 | trig_mode, delivery_mode); |
239 | } | 239 | } |
240 | } | 240 | } |
@@ -246,6 +246,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
246 | delivery_mode); | 246 | delivery_mode); |
247 | break; | 247 | break; |
248 | } | 248 | } |
249 | return r; | ||
249 | } | 250 | } |
250 | 251 | ||
251 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | 252 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) |