diff options
Diffstat (limited to 'drivers/lguest/interrupts_and_traps.c')
-rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index 9ea26ad88c9d..a8c966fee1e4 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c | |||
@@ -128,30 +128,38 @@ static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, | |||
128 | /*H:205 | 128 | /*H:205 |
129 | * Virtual Interrupts. | 129 | * Virtual Interrupts. |
130 | * | 130 | * |
131 | * maybe_do_interrupt() gets called before every entry to the Guest, to see if | 131 | * interrupt_pending() returns the first pending interrupt which isn't blocked |
132 | * we should divert the Guest to running an interrupt handler. */ | 132 | * by the Guest. It is called before every entry to the Guest, and just before |
133 | void maybe_do_interrupt(struct lg_cpu *cpu) | 133 | * we go to sleep when the Guest has halted itself. */ |
134 | unsigned int interrupt_pending(struct lg_cpu *cpu) | ||
134 | { | 135 | { |
135 | unsigned int irq; | 136 | unsigned int irq; |
136 | DECLARE_BITMAP(blk, LGUEST_IRQS); | 137 | DECLARE_BITMAP(blk, LGUEST_IRQS); |
137 | struct desc_struct *idt; | ||
138 | 138 | ||
139 | /* If the Guest hasn't even initialized yet, we can do nothing. */ | 139 | /* If the Guest hasn't even initialized yet, we can do nothing. */ |
140 | if (!cpu->lg->lguest_data) | 140 | if (!cpu->lg->lguest_data) |
141 | return; | 141 | return LGUEST_IRQS; |
142 | 142 | ||
143 | /* Take our "irqs_pending" array and remove any interrupts the Guest | 143 | /* Take our "irqs_pending" array and remove any interrupts the Guest |
144 | * wants blocked: the result ends up in "blk". */ | 144 | * wants blocked: the result ends up in "blk". */ |
145 | if (copy_from_user(&blk, cpu->lg->lguest_data->blocked_interrupts, | 145 | if (copy_from_user(&blk, cpu->lg->lguest_data->blocked_interrupts, |
146 | sizeof(blk))) | 146 | sizeof(blk))) |
147 | return; | 147 | return LGUEST_IRQS; |
148 | bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS); | 148 | bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS); |
149 | 149 | ||
150 | /* Find the first interrupt. */ | 150 | /* Find the first interrupt. */ |
151 | irq = find_first_bit(blk, LGUEST_IRQS); | 151 | irq = find_first_bit(blk, LGUEST_IRQS); |
152 | /* None? Nothing to do */ | 152 | |
153 | if (irq >= LGUEST_IRQS) | 153 | return irq; |
154 | return; | 154 | } |
155 | |||
156 | /* This actually diverts the Guest to running an interrupt handler, once an | ||
157 | * interrupt has been identified by interrupt_pending(). */ | ||
158 | void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq) | ||
159 | { | ||
160 | struct desc_struct *idt; | ||
161 | |||
162 | BUG_ON(irq >= LGUEST_IRQS); | ||
155 | 163 | ||
156 | /* They may be in the middle of an iret, where they asked us never to | 164 | /* They may be in the middle of an iret, where they asked us never to |
157 | * deliver interrupts. */ | 165 | * deliver interrupts. */ |