aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/interrupts_and_traps.c
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-07 08:05:29 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-01-30 06:50:09 -0500
commit177e449dc5bd4cf8dc48d66abee61ddf34b126b9 (patch)
treef0aaea9407971d8f6b9ad4e177a834f1be3aa993 /drivers/lguest/interrupts_and_traps.c
parentad8d8f3bc61ec712dd141e1029ae68c47fadc4a7 (diff)
lguest: per-vcpu interrupt processing.
This patch adapts interrupt processing for using the vcpu struct. Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/lguest/interrupts_and_traps.c')
-rw-r--r--drivers/lguest/interrupts_and_traps.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 22c692aae51c..8f59232f458b 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -60,11 +60,12 @@ static void push_guest_stack(struct lguest *lg, unsigned long *gstack, u32 val)
60 * We set up the stack just like the CPU does for a real interrupt, so it's 60 * We set up the stack just like the CPU does for a real interrupt, so it's
61 * identical for the Guest (and the standard "iret" instruction will undo 61 * identical for the Guest (and the standard "iret" instruction will undo
62 * it). */ 62 * it). */
63static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err) 63static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err)
64{ 64{
65 unsigned long gstack, origstack; 65 unsigned long gstack, origstack;
66 u32 eflags, ss, irq_enable; 66 u32 eflags, ss, irq_enable;
67 unsigned long virtstack; 67 unsigned long virtstack;
68 struct lguest *lg = cpu->lg;
68 69
69 /* There are two cases for interrupts: one where the Guest is already 70 /* There are two cases for interrupts: one where the Guest is already
70 * in the kernel, and a more complex one where the Guest is in 71 * in the kernel, and a more complex one where the Guest is in
@@ -129,9 +130,10 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
129 * 130 *
130 * maybe_do_interrupt() gets called before every entry to the Guest, to see if 131 * maybe_do_interrupt() gets called before every entry to the Guest, to see if
131 * we should divert the Guest to running an interrupt handler. */ 132 * we should divert the Guest to running an interrupt handler. */
132void maybe_do_interrupt(struct lguest *lg) 133void maybe_do_interrupt(struct lg_cpu *cpu)
133{ 134{
134 unsigned int irq; 135 unsigned int irq;
136 struct lguest *lg = cpu->lg;
135 DECLARE_BITMAP(blk, LGUEST_IRQS); 137 DECLARE_BITMAP(blk, LGUEST_IRQS);
136 struct desc_struct *idt; 138 struct desc_struct *idt;
137 139
@@ -145,7 +147,7 @@ void maybe_do_interrupt(struct lguest *lg)
145 sizeof(blk))) 147 sizeof(blk)))
146 return; 148 return;
147 149
148 bitmap_andnot(blk, lg->irqs_pending, blk, LGUEST_IRQS); 150 bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS);
149 151
150 /* Find the first interrupt. */ 152 /* Find the first interrupt. */
151 irq = find_first_bit(blk, LGUEST_IRQS); 153 irq = find_first_bit(blk, LGUEST_IRQS);
@@ -180,11 +182,11 @@ void maybe_do_interrupt(struct lguest *lg)
180 /* If they don't have a handler (yet?), we just ignore it */ 182 /* If they don't have a handler (yet?), we just ignore it */
181 if (idt_present(idt->a, idt->b)) { 183 if (idt_present(idt->a, idt->b)) {
182 /* OK, mark it no longer pending and deliver it. */ 184 /* OK, mark it no longer pending and deliver it. */
183 clear_bit(irq, lg->irqs_pending); 185 clear_bit(irq, cpu->irqs_pending);
184 /* set_guest_interrupt() takes the interrupt descriptor and a 186 /* set_guest_interrupt() takes the interrupt descriptor and a
185 * flag to say whether this interrupt pushes an error code onto 187 * flag to say whether this interrupt pushes an error code onto
186 * the stack as well: virtual interrupts never do. */ 188 * the stack as well: virtual interrupts never do. */
187 set_guest_interrupt(lg, idt->a, idt->b, 0); 189 set_guest_interrupt(cpu, idt->a, idt->b, 0);
188 } 190 }
189 191
190 /* Every time we deliver an interrupt, we update the timestamp in the 192 /* Every time we deliver an interrupt, we update the timestamp in the
@@ -245,19 +247,19 @@ static int has_err(unsigned int trap)
245} 247}
246 248
247/* deliver_trap() returns true if it could deliver the trap. */ 249/* deliver_trap() returns true if it could deliver the trap. */
248int deliver_trap(struct lguest *lg, unsigned int num) 250int deliver_trap(struct lg_cpu *cpu, unsigned int num)
249{ 251{
250 /* Trap numbers are always 8 bit, but we set an impossible trap number 252 /* Trap numbers are always 8 bit, but we set an impossible trap number
251 * for traps inside the Switcher, so check that here. */ 253 * for traps inside the Switcher, so check that here. */
252 if (num >= ARRAY_SIZE(lg->arch.idt)) 254 if (num >= ARRAY_SIZE(cpu->lg->arch.idt))
253 return 0; 255 return 0;
254 256
255 /* Early on the Guest hasn't set the IDT entries (or maybe it put a 257 /* Early on the Guest hasn't set the IDT entries (or maybe it put a
256 * bogus one in): if we fail here, the Guest will be killed. */ 258 * bogus one in): if we fail here, the Guest will be killed. */
257 if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b)) 259 if (!idt_present(cpu->lg->arch.idt[num].a, cpu->lg->arch.idt[num].b))
258 return 0; 260 return 0;
259 set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, 261 set_guest_interrupt(cpu, cpu->lg->arch.idt[num].a,
260 has_err(num)); 262 cpu->lg->arch.idt[num].b, has_err(num));
261 return 1; 263 return 1;
262} 264}
263 265
@@ -493,7 +495,7 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
493 struct lg_cpu *cpu = container_of(timer, struct lg_cpu, hrt); 495 struct lg_cpu *cpu = container_of(timer, struct lg_cpu, hrt);
494 496
495 /* Remember the first interrupt is the timer interrupt. */ 497 /* Remember the first interrupt is the timer interrupt. */
496 set_bit(0, cpu->lg->irqs_pending); 498 set_bit(0, cpu->irqs_pending);
497 /* If the Guest is actually stopped, we need to wake it up. */ 499 /* If the Guest is actually stopped, we need to wake it up. */
498 if (cpu->lg->halted) 500 if (cpu->lg->halted)
499 wake_up_process(cpu->lg->tsk); 501 wake_up_process(cpu->lg->tsk);