aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-02-04 10:28:14 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:03:11 -0400
commit4925663a079c77d95d8685228ad6675fc5639c8e (patch)
tree52e93df78b23a44ed21d015f835688f673dd351a /arch
parent452425dbaa1974e9fc489e64a8de46a47b4c2754 (diff)
KVM: Report IRQ injection status to userspace.
IRQ injection status is either -1 (if there was no CPU found that should except the interrupt because IRQ was masked or ioapic was misconfigured or ...) or >= 0 in that case the number indicates to how many CPUs interrupt was injected. If the value is 0 it means that the interrupt was coalesced and probably should be reinjected. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/kvm/kvm-ia64.c12
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/i8259.c18
-rw-r--r--arch/x86/kvm/x86.c13
4 files changed, 35 insertions, 10 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);
616void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, 616void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
617 u32 error_code); 617 u32 error_code);
618 618
619void kvm_pic_set_irq(void *opaque, int irq, int level); 619int kvm_pic_set_irq(void *opaque, int irq, int level);
620 620
621void kvm_inject_nmi(struct kvm_vcpu *vcpu); 621void 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 */
80static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level) 80static 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
175void kvm_pic_set_irq(void *opaque, int irq, int level) 180int 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;