diff options
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 12 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/i8259.c | 18 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 13 | ||||
-rw-r--r-- | include/linux/kvm.h | 7 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 4 | ||||
-rw-r--r-- | virt/kvm/ioapic.c | 23 | ||||
-rw-r--r-- | virt/kvm/ioapic.h | 2 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 41 |
9 files changed, 88 insertions, 34 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 9c77e3939e97..076b00d1dbff 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -182,7 +182,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
182 | switch (ext) { | 182 | switch (ext) { |
183 | case KVM_CAP_IRQCHIP: | 183 | case KVM_CAP_IRQCHIP: |
184 | case KVM_CAP_MP_STATE: | 184 | case KVM_CAP_MP_STATE: |
185 | 185 | case KVM_CAP_IRQ_INJECT_STATUS: | |
186 | r = 1; | 186 | r = 1; |
187 | break; | 187 | break; |
188 | case KVM_CAP_COALESCED_MMIO: | 188 | case KVM_CAP_COALESCED_MMIO: |
@@ -927,6 +927,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
927 | goto out; | 927 | goto out; |
928 | } | 928 | } |
929 | break; | 929 | break; |
930 | case KVM_IRQ_LINE_STATUS: | ||
930 | case KVM_IRQ_LINE: { | 931 | case KVM_IRQ_LINE: { |
931 | struct kvm_irq_level irq_event; | 932 | struct kvm_irq_level irq_event; |
932 | 933 | ||
@@ -934,10 +935,17 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
934 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) | 935 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) |
935 | goto out; | 936 | goto out; |
936 | if (irqchip_in_kernel(kvm)) { | 937 | if (irqchip_in_kernel(kvm)) { |
938 | __s32 status; | ||
937 | mutex_lock(&kvm->lock); | 939 | mutex_lock(&kvm->lock); |
938 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 940 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
939 | irq_event.irq, irq_event.level); | 941 | irq_event.irq, irq_event.level); |
940 | mutex_unlock(&kvm->lock); | 942 | mutex_unlock(&kvm->lock); |
943 | if (ioctl == KVM_IRQ_LINE_STATUS) { | ||
944 | irq_event.status = status; | ||
945 | if (copy_to_user(argp, &irq_event, | ||
946 | sizeof irq_event)) | ||
947 | goto out; | ||
948 | } | ||
941 | r = 0; | 949 | r = 0; |
942 | } | 950 | } |
943 | break; | 951 | break; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 55fd4c5fd388..f0faf58044ff 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -616,7 +616,7 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); | |||
616 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, | 616 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, |
617 | u32 error_code); | 617 | u32 error_code); |
618 | 618 | ||
619 | void kvm_pic_set_irq(void *opaque, int irq, int level); | 619 | int kvm_pic_set_irq(void *opaque, int irq, int level); |
620 | 620 | ||
621 | void kvm_inject_nmi(struct kvm_vcpu *vcpu); | 621 | void kvm_inject_nmi(struct kvm_vcpu *vcpu); |
622 | 622 | ||
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 93160375c841..b4e662e94ddc 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -77,12 +77,13 @@ void kvm_pic_clear_isr_ack(struct kvm *kvm) | |||
77 | /* | 77 | /* |
78 | * set irq level. If an edge is detected, then the IRR is set to 1 | 78 | * set irq level. If an edge is detected, then the IRR is set to 1 |
79 | */ | 79 | */ |
80 | static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level) | 80 | static inline int pic_set_irq1(struct kvm_kpic_state *s, int irq, int level) |
81 | { | 81 | { |
82 | int mask; | 82 | int mask, ret = 1; |
83 | mask = 1 << irq; | 83 | mask = 1 << irq; |
84 | if (s->elcr & mask) /* level triggered */ | 84 | if (s->elcr & mask) /* level triggered */ |
85 | if (level) { | 85 | if (level) { |
86 | ret = !(s->irr & mask); | ||
86 | s->irr |= mask; | 87 | s->irr |= mask; |
87 | s->last_irr |= mask; | 88 | s->last_irr |= mask; |
88 | } else { | 89 | } else { |
@@ -91,11 +92,15 @@ static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level) | |||
91 | } | 92 | } |
92 | else /* edge triggered */ | 93 | else /* edge triggered */ |
93 | if (level) { | 94 | if (level) { |
94 | if ((s->last_irr & mask) == 0) | 95 | if ((s->last_irr & mask) == 0) { |
96 | ret = !(s->irr & mask); | ||
95 | s->irr |= mask; | 97 | s->irr |= mask; |
98 | } | ||
96 | s->last_irr |= mask; | 99 | s->last_irr |= mask; |
97 | } else | 100 | } else |
98 | s->last_irr &= ~mask; | 101 | s->last_irr &= ~mask; |
102 | |||
103 | return (s->imr & mask) ? -1 : ret; | ||
99 | } | 104 | } |
100 | 105 | ||
101 | /* | 106 | /* |
@@ -172,16 +177,19 @@ void kvm_pic_update_irq(struct kvm_pic *s) | |||
172 | pic_unlock(s); | 177 | pic_unlock(s); |
173 | } | 178 | } |
174 | 179 | ||
175 | void kvm_pic_set_irq(void *opaque, int irq, int level) | 180 | int kvm_pic_set_irq(void *opaque, int irq, int level) |
176 | { | 181 | { |
177 | struct kvm_pic *s = opaque; | 182 | struct kvm_pic *s = opaque; |
183 | int ret = -1; | ||
178 | 184 | ||
179 | pic_lock(s); | 185 | pic_lock(s); |
180 | if (irq >= 0 && irq < PIC_NUM_PINS) { | 186 | if (irq >= 0 && irq < PIC_NUM_PINS) { |
181 | pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); | 187 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); |
182 | pic_update_irq(s); | 188 | pic_update_irq(s); |
183 | } | 189 | } |
184 | pic_unlock(s); | 190 | pic_unlock(s); |
191 | |||
192 | return ret; | ||
185 | } | 193 | } |
186 | 194 | ||
187 | /* | 195 | /* |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 05d7be89b5eb..e4db5be7c953 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1019,6 +1019,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
1019 | case KVM_CAP_MP_STATE: | 1019 | case KVM_CAP_MP_STATE: |
1020 | case KVM_CAP_SYNC_MMU: | 1020 | case KVM_CAP_SYNC_MMU: |
1021 | case KVM_CAP_REINJECT_CONTROL: | 1021 | case KVM_CAP_REINJECT_CONTROL: |
1022 | case KVM_CAP_IRQ_INJECT_STATUS: | ||
1022 | r = 1; | 1023 | r = 1; |
1023 | break; | 1024 | break; |
1024 | case KVM_CAP_COALESCED_MMIO: | 1025 | case KVM_CAP_COALESCED_MMIO: |
@@ -1877,6 +1878,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1877 | create_pit_unlock: | 1878 | create_pit_unlock: |
1878 | mutex_unlock(&kvm->lock); | 1879 | mutex_unlock(&kvm->lock); |
1879 | break; | 1880 | break; |
1881 | case KVM_IRQ_LINE_STATUS: | ||
1880 | case KVM_IRQ_LINE: { | 1882 | case KVM_IRQ_LINE: { |
1881 | struct kvm_irq_level irq_event; | 1883 | struct kvm_irq_level irq_event; |
1882 | 1884 | ||
@@ -1884,10 +1886,17 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1884 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) | 1886 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) |
1885 | goto out; | 1887 | goto out; |
1886 | if (irqchip_in_kernel(kvm)) { | 1888 | if (irqchip_in_kernel(kvm)) { |
1889 | __s32 status; | ||
1887 | mutex_lock(&kvm->lock); | 1890 | mutex_lock(&kvm->lock); |
1888 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 1891 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
1889 | irq_event.irq, irq_event.level); | 1892 | irq_event.irq, irq_event.level); |
1890 | mutex_unlock(&kvm->lock); | 1893 | mutex_unlock(&kvm->lock); |
1894 | if (ioctl == KVM_IRQ_LINE_STATUS) { | ||
1895 | irq_event.status = status; | ||
1896 | if (copy_to_user(argp, &irq_event, | ||
1897 | sizeof irq_event)) | ||
1898 | goto out; | ||
1899 | } | ||
1891 | r = 0; | 1900 | r = 0; |
1892 | } | 1901 | } |
1893 | break; | 1902 | break; |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 2163b3dd36e7..dd48225d1824 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -48,7 +48,10 @@ struct kvm_irq_level { | |||
48 | * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47.. | 48 | * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47.. |
49 | * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23.. | 49 | * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23.. |
50 | */ | 50 | */ |
51 | __u32 irq; | 51 | union { |
52 | __u32 irq; | ||
53 | __s32 status; | ||
54 | }; | ||
52 | __u32 level; | 55 | __u32 level; |
53 | }; | 56 | }; |
54 | 57 | ||
@@ -402,6 +405,7 @@ struct kvm_trace_rec { | |||
402 | #ifdef __KVM_HAVE_IOAPIC | 405 | #ifdef __KVM_HAVE_IOAPIC |
403 | #define KVM_CAP_IRQ_ROUTING 25 | 406 | #define KVM_CAP_IRQ_ROUTING 25 |
404 | #endif | 407 | #endif |
408 | #define KVM_CAP_IRQ_INJECT_STATUS 26 | ||
405 | 409 | ||
406 | #ifdef KVM_CAP_IRQ_ROUTING | 410 | #ifdef KVM_CAP_IRQ_ROUTING |
407 | 411 | ||
@@ -465,6 +469,7 @@ struct kvm_irq_routing { | |||
465 | #define KVM_CREATE_PIT _IO(KVMIO, 0x64) | 469 | #define KVM_CREATE_PIT _IO(KVMIO, 0x64) |
466 | #define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state) | 470 | #define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state) |
467 | #define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state) | 471 | #define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state) |
472 | #define KVM_IRQ_LINE_STATUS _IOWR(KVMIO, 0x67, struct kvm_irq_level) | ||
468 | #define KVM_REGISTER_COALESCED_MMIO \ | 473 | #define KVM_REGISTER_COALESCED_MMIO \ |
469 | _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone) | 474 | _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone) |
470 | #define KVM_UNREGISTER_COALESCED_MMIO \ | 475 | #define KVM_UNREGISTER_COALESCED_MMIO \ |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 18b4df8264cf..894a56e365e8 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -110,7 +110,7 @@ struct kvm_memory_slot { | |||
110 | 110 | ||
111 | struct kvm_kernel_irq_routing_entry { | 111 | struct kvm_kernel_irq_routing_entry { |
112 | u32 gsi; | 112 | u32 gsi; |
113 | void (*set)(struct kvm_kernel_irq_routing_entry *e, | 113 | int (*set)(struct kvm_kernel_irq_routing_entry *e, |
114 | struct kvm *kvm, int level); | 114 | struct kvm *kvm, int level); |
115 | union { | 115 | union { |
116 | struct { | 116 | struct { |
@@ -352,7 +352,7 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, | |||
352 | struct kvm_irq_mask_notifier *kimn); | 352 | struct kvm_irq_mask_notifier *kimn); |
353 | void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask); | 353 | void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask); |
354 | 354 | ||
355 | void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); | 355 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); |
356 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); | 356 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); |
357 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | 357 | void kvm_register_irq_ack_notifier(struct kvm *kvm, |
358 | struct kvm_irq_ack_notifier *kian); | 358 | struct kvm_irq_ack_notifier *kian); |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 1c986ac59ad6..c3b99def9cbc 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -83,19 +83,22 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, | |||
83 | return result; | 83 | return result; |
84 | } | 84 | } |
85 | 85 | ||
86 | static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) | 86 | static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) |
87 | { | 87 | { |
88 | union ioapic_redir_entry *pent; | 88 | union ioapic_redir_entry *pent; |
89 | int injected = -1; | ||
89 | 90 | ||
90 | pent = &ioapic->redirtbl[idx]; | 91 | pent = &ioapic->redirtbl[idx]; |
91 | 92 | ||
92 | if (!pent->fields.mask) { | 93 | if (!pent->fields.mask) { |
93 | int injected = ioapic_deliver(ioapic, idx); | 94 | injected = ioapic_deliver(ioapic, idx); |
94 | if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) | 95 | if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) |
95 | pent->fields.remote_irr = 1; | 96 | pent->fields.remote_irr = 1; |
96 | } | 97 | } |
97 | if (!pent->fields.trig_mode) | 98 | if (!pent->fields.trig_mode) |
98 | ioapic->irr &= ~(1 << idx); | 99 | ioapic->irr &= ~(1 << idx); |
100 | |||
101 | return injected; | ||
99 | } | 102 | } |
100 | 103 | ||
101 | static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) | 104 | static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) |
@@ -207,7 +210,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
207 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; | 210 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; |
208 | u32 deliver_bitmask; | 211 | u32 deliver_bitmask; |
209 | struct kvm_vcpu *vcpu; | 212 | struct kvm_vcpu *vcpu; |
210 | int vcpu_id, r = 0; | 213 | int vcpu_id, r = -1; |
211 | 214 | ||
212 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " | 215 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " |
213 | "vector=%x trig_mode=%x\n", | 216 | "vector=%x trig_mode=%x\n", |
@@ -247,7 +250,9 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
247 | deliver_bitmask &= ~(1 << vcpu_id); | 250 | deliver_bitmask &= ~(1 << vcpu_id); |
248 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 251 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
249 | if (vcpu) { | 252 | if (vcpu) { |
250 | r = ioapic_inj_irq(ioapic, vcpu, vector, | 253 | if (r < 0) |
254 | r = 0; | ||
255 | r += ioapic_inj_irq(ioapic, vcpu, vector, | ||
251 | trig_mode, delivery_mode); | 256 | trig_mode, delivery_mode); |
252 | } | 257 | } |
253 | } | 258 | } |
@@ -258,8 +263,10 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
258 | continue; | 263 | continue; |
259 | deliver_bitmask &= ~(1 << vcpu_id); | 264 | deliver_bitmask &= ~(1 << vcpu_id); |
260 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 265 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
261 | if (vcpu) | 266 | if (vcpu) { |
262 | ioapic_inj_nmi(vcpu); | 267 | ioapic_inj_nmi(vcpu); |
268 | r = 1; | ||
269 | } | ||
263 | else | 270 | else |
264 | ioapic_debug("NMI to vcpu %d failed\n", | 271 | ioapic_debug("NMI to vcpu %d failed\n", |
265 | vcpu->vcpu_id); | 272 | vcpu->vcpu_id); |
@@ -273,11 +280,12 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
273 | return r; | 280 | return r; |
274 | } | 281 | } |
275 | 282 | ||
276 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | 283 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) |
277 | { | 284 | { |
278 | u32 old_irr = ioapic->irr; | 285 | u32 old_irr = ioapic->irr; |
279 | u32 mask = 1 << irq; | 286 | u32 mask = 1 << irq; |
280 | union ioapic_redir_entry entry; | 287 | union ioapic_redir_entry entry; |
288 | int ret = 1; | ||
281 | 289 | ||
282 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { | 290 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { |
283 | entry = ioapic->redirtbl[irq]; | 291 | entry = ioapic->redirtbl[irq]; |
@@ -288,9 +296,10 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | |||
288 | ioapic->irr |= mask; | 296 | ioapic->irr |= mask; |
289 | if ((!entry.fields.trig_mode && old_irr != ioapic->irr) | 297 | if ((!entry.fields.trig_mode && old_irr != ioapic->irr) |
290 | || !entry.fields.remote_irr) | 298 | || !entry.fields.remote_irr) |
291 | ioapic_service(ioapic, irq); | 299 | ret = ioapic_service(ioapic, irq); |
292 | } | 300 | } |
293 | } | 301 | } |
302 | return ret; | ||
294 | } | 303 | } |
295 | 304 | ||
296 | static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int pin, | 305 | static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int pin, |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 49c9581d2586..a34bd5e6436b 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
@@ -83,7 +83,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | |||
83 | unsigned long bitmap); | 83 | unsigned long bitmap); |
84 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); | 84 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); |
85 | int kvm_ioapic_init(struct kvm *kvm); | 85 | int kvm_ioapic_init(struct kvm *kvm); |
86 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 86 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
87 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); | 87 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |
88 | u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | 88 | u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, |
89 | u8 dest_mode); | 89 | u8 dest_mode); |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 6bc7439eff6e..be8aba791554 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -29,22 +29,24 @@ | |||
29 | 29 | ||
30 | #include "ioapic.h" | 30 | #include "ioapic.h" |
31 | 31 | ||
32 | static void kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, | 32 | static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, |
33 | struct kvm *kvm, int level) | 33 | struct kvm *kvm, int level) |
34 | { | 34 | { |
35 | #ifdef CONFIG_X86 | 35 | #ifdef CONFIG_X86 |
36 | kvm_pic_set_irq(pic_irqchip(kvm), e->irqchip.pin, level); | 36 | return kvm_pic_set_irq(pic_irqchip(kvm), e->irqchip.pin, level); |
37 | #else | ||
38 | return -1; | ||
37 | #endif | 39 | #endif |
38 | } | 40 | } |
39 | 41 | ||
40 | static void kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, | 42 | static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, |
41 | struct kvm *kvm, int level) | 43 | struct kvm *kvm, int level) |
42 | { | 44 | { |
43 | kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level); | 45 | return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level); |
44 | } | 46 | } |
45 | 47 | ||
46 | static void kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | 48 | static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, |
47 | struct kvm *kvm, int level) | 49 | struct kvm *kvm, int level) |
48 | { | 50 | { |
49 | int vcpu_id; | 51 | int vcpu_id; |
50 | struct kvm_vcpu *vcpu; | 52 | struct kvm_vcpu *vcpu; |
@@ -88,13 +90,20 @@ static void kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
88 | default: | 90 | default: |
89 | break; | 91 | break; |
90 | } | 92 | } |
93 | return 1; | ||
91 | } | 94 | } |
92 | 95 | ||
93 | /* This should be called with the kvm->lock mutex held */ | 96 | /* This should be called with the kvm->lock mutex held |
94 | void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level) | 97 | * Return value: |
98 | * < 0 Interrupt was ignored (masked or not delivered for other reasons) | ||
99 | * = 0 Interrupt was coalesced (previous irq is still pending) | ||
100 | * > 0 Number of CPUs interrupt was delivered to | ||
101 | */ | ||
102 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level) | ||
95 | { | 103 | { |
96 | struct kvm_kernel_irq_routing_entry *e; | 104 | struct kvm_kernel_irq_routing_entry *e; |
97 | unsigned long *irq_state, sig_level; | 105 | unsigned long *irq_state, sig_level; |
106 | int ret = -1; | ||
98 | 107 | ||
99 | if (irq < KVM_IOAPIC_NUM_PINS) { | 108 | if (irq < KVM_IOAPIC_NUM_PINS) { |
100 | irq_state = (unsigned long *)&kvm->arch.irq_states[irq]; | 109 | irq_state = (unsigned long *)&kvm->arch.irq_states[irq]; |
@@ -113,8 +122,14 @@ void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level) | |||
113 | * writes to the unused one. | 122 | * writes to the unused one. |
114 | */ | 123 | */ |
115 | list_for_each_entry(e, &kvm->irq_routing, link) | 124 | list_for_each_entry(e, &kvm->irq_routing, link) |
116 | if (e->gsi == irq) | 125 | if (e->gsi == irq) { |
117 | e->set(e, kvm, sig_level); | 126 | int r = e->set(e, kvm, sig_level); |
127 | if (r < 0) | ||
128 | continue; | ||
129 | |||
130 | ret = r + ((ret < 0) ? 0 : ret); | ||
131 | } | ||
132 | return ret; | ||
118 | } | 133 | } |
119 | 134 | ||
120 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) | 135 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) |
@@ -232,7 +247,7 @@ int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e, | |||
232 | e->set = kvm_set_pic_irq; | 247 | e->set = kvm_set_pic_irq; |
233 | break; | 248 | break; |
234 | case KVM_IRQCHIP_PIC_SLAVE: | 249 | case KVM_IRQCHIP_PIC_SLAVE: |
235 | e->set = kvm_set_pic_irq; | 250 | e->set = kvm_set_pic_irq; |
236 | delta = 8; | 251 | delta = 8; |
237 | break; | 252 | break; |
238 | case KVM_IRQCHIP_IOAPIC: | 253 | case KVM_IRQCHIP_IOAPIC: |