summary refs log tree commit diff
path: root/drivers/lguest
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-07 11:05:29 -0200
committerRusty Russell <rusty@rustcorp.com.au>2008-01-30 22:50:09 +1100
commit177e449dc5bd4cf8dc48d66abee61ddf34b126b9 (patch)
treef0aaea9407971d8f6b9ad4e177a834f1be3aa993 /drivers/lguest
parentad8d8f3bc61ec712dd141e1029ae68c47fadc4a7 (diff)
downloadlinux-177e449dc5bd4cf8dc48d66abee61ddf34b126b9.tar.gz
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')
-rw-r--r--drivers/lguest/core.c2
-rw-r--r--drivers/lguest/interrupts_and_traps.c24
-rw-r--r--drivers/lguest/lg.h10
-rw-r--r--drivers/lguest/lguest_user.c8
-rw-r--r--drivers/lguest/x86/core.c2
5 files changed, 24 insertions, 22 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 0ea67cb0cc0b..d8e1ac305dc6 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -203,7 +203,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
 		/* Check if there are any interrupts which can be delivered
 		 * now: if so, this sets up the hander to be executed when we
 		 * next run the Guest. */
-		maybe_do_interrupt(lg);
+		maybe_do_interrupt(cpu);
 
 		/* All long-lived kernel loops need to check with this horrible
 		 * thing called the freezer.  If the Host is trying to suspend,
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)
  * We set up the stack just like the CPU does for a real interrupt, so it's
  * identical for the Guest (and the standard "iret" instruction will undo
  * it). */
-static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
+static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err)
 {
 	unsigned long gstack, origstack;
 	u32 eflags, ss, irq_enable;
 	unsigned long virtstack;
+	struct lguest *lg = cpu->lg;
 
 	/* There are two cases for interrupts: one where the Guest is already
 	 * 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)
  *
  * maybe_do_interrupt() gets called before every entry to the Guest, to see if
  * we should divert the Guest to running an interrupt handler. */
-void maybe_do_interrupt(struct lguest *lg)
+void maybe_do_interrupt(struct lg_cpu *cpu)
 {
 	unsigned int irq;
+	struct lguest *lg = cpu->lg;
 	DECLARE_BITMAP(blk, LGUEST_IRQS);
 	struct desc_struct *idt;
 
@@ -145,7 +147,7 @@ void maybe_do_interrupt(struct lguest *lg)
 			   sizeof(blk)))
 		return;
 
-	bitmap_andnot(blk, lg->irqs_pending, blk, LGUEST_IRQS);
+	bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS);
 
 	/* Find the first interrupt. */
 	irq = find_first_bit(blk, LGUEST_IRQS);
@@ -180,11 +182,11 @@ void maybe_do_interrupt(struct lguest *lg)
 	/* If they don't have a handler (yet?), we just ignore it */
 	if (idt_present(idt->a, idt->b)) {
 		/* OK, mark it no longer pending and deliver it. */
-		clear_bit(irq, lg->irqs_pending);
+		clear_bit(irq, cpu->irqs_pending);
 		/* set_guest_interrupt() takes the interrupt descriptor and a
 		 * flag to say whether this interrupt pushes an error code onto
 		 * the stack as well: virtual interrupts never do. */
-		set_guest_interrupt(lg, idt->a, idt->b, 0);
+		set_guest_interrupt(cpu, idt->a, idt->b, 0);
 	}
 
 	/* Every time we deliver an interrupt, we update the timestamp in the
@@ -245,19 +247,19 @@ static int has_err(unsigned int trap)
 }
 
 /* deliver_trap() returns true if it could deliver the trap. */
-int deliver_trap(struct lguest *lg, unsigned int num)
+int deliver_trap(struct lg_cpu *cpu, unsigned int num)
 {
 	/* Trap numbers are always 8 bit, but we set an impossible trap number
 	 * for traps inside the Switcher, so check that here. */
-	if (num >= ARRAY_SIZE(lg->arch.idt))
+	if (num >= ARRAY_SIZE(cpu->lg->arch.idt))
 		return 0;
 
 	/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 	 * bogus one in): if we fail here, the Guest will be killed. */
-	if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b))
+	if (!idt_present(cpu->lg->arch.idt[num].a, cpu->lg->arch.idt[num].b))
 		return 0;
-	set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b,
-			    has_err(num));
+	set_guest_interrupt(cpu, cpu->lg->arch.idt[num].a,
+			    cpu->lg->arch.idt[num].b, has_err(num));
 	return 1;
 }
 
@@ -493,7 +495,7 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 	struct lg_cpu *cpu = container_of(timer, struct lg_cpu, hrt);
 
 	/* Remember the first interrupt is the timer interrupt. */
-	set_bit(0, cpu->lg->irqs_pending);
+	set_bit(0, cpu->irqs_pending);
 	/* If the Guest is actually stopped, we need to wake it up. */
 	if (cpu->lg->halted)
 		wake_up_process(cpu->lg->tsk);
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 7da7b3f68da8..29e03d588a8d 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -50,6 +50,9 @@ struct lg_cpu {
 
 	/* Virtual clock device */
 	struct hrtimer hrt;
+
+	/* Pending virtual interrupts */
+	DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
 
 /* The private info the thread maintains about the guest. */
@@ -97,9 +100,6 @@ struct lguest
 	const char *dead;
 
 	struct lguest_arch arch;
-
-	/* Pending virtual interrupts */
-	DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
 
 extern struct mutex lguest_lock;
@@ -136,8 +136,8 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user);
 #define pgd_pfn(x)	(pgd_val(x) >> PAGE_SHIFT)
 
 /* interrupts_and_traps.c: */
-void maybe_do_interrupt(struct lguest *lg);
-int deliver_trap(struct lguest *lg, unsigned int num);
+void maybe_do_interrupt(struct lg_cpu *cpu);
+int deliver_trap(struct lg_cpu *cpu, unsigned int num);
 void load_guest_idt_entry(struct lguest *lg, unsigned int i, u32 low, u32 hi);
 void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages);
 void pin_stack_pages(struct lguest *lg);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index f231b9be0b64..605db5c49e7f 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -36,7 +36,7 @@ static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
 
 /*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt
  * number to /dev/lguest. */
-static int user_send_irq(struct lguest *lg, const unsigned long __user *input)
+static int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input)
 {
 	unsigned long irq;
 
@@ -46,7 +46,7 @@ static int user_send_irq(struct lguest *lg, const unsigned long __user *input)
 		return -EINVAL;
 	/* Next time the Guest runs, the core code will see if it can deliver
 	 * this interrupt. */
-	set_bit(irq, lg->irqs_pending);
+	set_bit(irq, cpu->irqs_pending);
 	return 0;
 }
 
@@ -225,7 +225,7 @@ static ssize_t write(struct file *file, const char __user *in,
 	struct lguest *lg = file->private_data;
 	const unsigned long __user *input = (const unsigned long __user *)in;
 	unsigned long req;
-	struct lg_cpu *cpu;
+	struct lg_cpu *uninitialized_var(cpu);
 	unsigned int cpu_id = *off;
 
 	if (get_user(req, input) != 0)
@@ -253,7 +253,7 @@ static ssize_t write(struct file *file, const char __user *in,
 	case LHREQ_INITIALIZE:
 		return initialize(file, input);
 	case LHREQ_IRQ:
-		return user_send_irq(lg, input);
+		return user_send_irq(cpu, input);
 	case LHREQ_BREAK:
 		return break_guest_out(lg, input);
 	default:
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 5962160aff3d..66f48fcc1196 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -342,7 +342,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
 	}
 
 	/* We didn't handle the trap, so it needs to go to the Guest. */
-	if (!deliver_trap(lg, lg->regs->trapnum))
+	if (!deliver_trap(cpu, lg->regs->trapnum))
 		/* If the Guest doesn't have a handler (either it hasn't
 		 * registered any yet, or it's one of the faults we don't let
 		 * it handle), it dies with a cryptic error message. */