diff options
author | Avi Kivity <avi@qumranet.com> | 2008-12-21 15:48:32 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:55:48 -0500 |
commit | 3f353858c98dbe0240dac558a89870f4600f81bb (patch) | |
tree | 95cdddb90777c332f747dfff041e1caf1fe78673 /arch/x86/kvm/irq.h | |
parent | 25e2343246fe135fce672f41abe61e9d2c38caac (diff) |
KVM: Add locking to virtual i8259 interrupt controller
While most accesses to the i8259 are with the kvm mutex taken, the call
to kvm_pic_read_irq() is not. We can't easily take the kvm mutex there
since the function is called with interrupts disabled.
Fix by adding a spinlock to the virtual interrupt controller. Since we
can't send an IPI under the spinlock (we also take the same spinlock in
an irq disabled context), we defer the IPI until the spinlock is released.
Similarly, we defer irq ack notifications until after spinlock release to
avoid lock recursion.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/irq.h')
-rw-r--r-- | arch/x86/kvm/irq.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index b9e9051650ea..2bf32a03ceec 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mm_types.h> | 25 | #include <linux/mm_types.h> |
26 | #include <linux/hrtimer.h> | 26 | #include <linux/hrtimer.h> |
27 | #include <linux/kvm_host.h> | 27 | #include <linux/kvm_host.h> |
28 | #include <linux/spinlock.h> | ||
28 | 29 | ||
29 | #include "iodev.h" | 30 | #include "iodev.h" |
30 | #include "ioapic.h" | 31 | #include "ioapic.h" |
@@ -59,6 +60,10 @@ struct kvm_kpic_state { | |||
59 | }; | 60 | }; |
60 | 61 | ||
61 | struct kvm_pic { | 62 | struct kvm_pic { |
63 | spinlock_t lock; | ||
64 | bool wakeup_needed; | ||
65 | unsigned pending_acks; | ||
66 | struct kvm *kvm; | ||
62 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ | 67 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ |
63 | irq_request_func *irq_request; | 68 | irq_request_func *irq_request; |
64 | void *irq_request_opaque; | 69 | void *irq_request_opaque; |