projects
/
deliverable
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
KVM: Report IRQ injection status to userspace.
[deliverable/linux.git]
/
arch
/
x86
/
kvm
/
i8259.c
diff --git
a/arch/x86/kvm/i8259.c
b/arch/x86/kvm/i8259.c
index 179dcb0103fdcf7b2a59c27ee399fdd4302fe67a..b4e662e94ddca13db723bb5bd99b0e7d621b2053 100644
(file)
--- a/
arch/x86/kvm/i8259.c
+++ b/
arch/x86/kvm/i8259.c
@@
-49,7
+49,8
@@
static void pic_unlock(struct kvm_pic *s)
spin_unlock(&s->lock);
while (acks) {
spin_unlock(&s->lock);
while (acks) {
- kvm_notify_acked_irq(kvm, __ffs(acks));
+ kvm_notify_acked_irq(kvm, SELECT_PIC(__ffs(acks)),
+ __ffs(acks));
acks &= acks - 1;
}
acks &= acks - 1;
}
@@
-76,12
+77,13
@@
void kvm_pic_clear_isr_ack(struct kvm *kvm)
/*
* set irq level. If an edge is detected, then the IRR is set to 1
*/
/*
* set irq level. If an edge is detected, then the IRR is set to 1
*/
-static inline
void
pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
+static inline
int
pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
{
{
- int mask;
+ int mask
, ret = 1
;
mask = 1 << irq;
if (s->elcr & mask) /* level triggered */
if (level) {
mask = 1 << irq;
if (s->elcr & mask) /* level triggered */
if (level) {
+ ret = !(s->irr & mask);
s->irr |= mask;
s->last_irr |= mask;
} else {
s->irr |= mask;
s->last_irr |= mask;
} else {
@@
-90,11
+92,15
@@
static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
}
else /* edge triggered */
if (level) {
}
else /* edge triggered */
if (level) {
- if ((s->last_irr & mask) == 0)
+ if ((s->last_irr & mask) == 0) {
+ ret = !(s->irr & mask);
s->irr |= mask;
s->irr |= mask;
+ }
s->last_irr |= mask;
} else
s->last_irr &= ~mask;
s->last_irr |= mask;
} else
s->last_irr &= ~mask;
+
+ return (s->imr & mask) ? -1 : ret;
}
/*
}
/*
@@
-171,16
+177,19
@@
void kvm_pic_update_irq(struct kvm_pic *s)
pic_unlock(s);
}
pic_unlock(s);
}
-
void
kvm_pic_set_irq(void *opaque, int irq, int level)
+
int
kvm_pic_set_irq(void *opaque, int irq, int level)
{
struct kvm_pic *s = opaque;
{
struct kvm_pic *s = opaque;
+ int ret = -1;
pic_lock(s);
if (irq >= 0 && irq < PIC_NUM_PINS) {
pic_lock(s);
if (irq >= 0 && irq < PIC_NUM_PINS) {
- pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
+
ret =
pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
pic_update_irq(s);
}
pic_unlock(s);
pic_update_irq(s);
}
pic_unlock(s);
+
+ return ret;
}
/*
}
/*
@@
-232,7
+241,7
@@
int kvm_pic_read_irq(struct kvm *kvm)
}
pic_update_irq(s);
pic_unlock(s);
}
pic_update_irq(s);
pic_unlock(s);
- kvm_notify_acked_irq(kvm, irq);
+ kvm_notify_acked_irq(kvm,
SELECT_PIC(irq),
irq);
return intno;
}
return intno;
}
This page took
0.02698 seconds
and
5
git commands to generate.