diff options
Diffstat (limited to 'virt/kvm/ioapic.c')
| -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) |
