]> Pileus Git - ~andy/linux/blobdiff - drivers/lguest/interrupts_and_traps.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched
[~andy/linux] / drivers / lguest / interrupts_and_traps.c
index 3d9830322646a0b02f647b07e1955725882e305a..49aa55577d0dec0e2543c2a8801b91ebc98b1359 100644 (file)
@@ -175,6 +175,13 @@ void maybe_do_interrupt(struct lguest *lg)
                 * the stack as well: virtual interrupts never do. */
                set_guest_interrupt(lg, idt->a, idt->b, 0);
        }
+
+       /* Every time we deliver an interrupt, we update the timestamp in the
+        * Guest's lguest_data struct.  It would be better for the Guest if we
+        * did this more often, but it can actually be quite slow: doing it
+        * here is a compromise which means at least it gets updated every
+        * timer interrupt. */
+       write_timestamp(lg);
 }
 
 /*H:220 Now we've got the routines to deliver interrupts, delivering traps
@@ -188,13 +195,16 @@ 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)
 {
-       u32 lo = lg->idt[num].a, hi = lg->idt[num].b;
+       /* 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->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(lo, hi))
+       if (!idt_present(lg->idt[num].a, lg->idt[num].b))
                return 0;
-       set_guest_interrupt(lg, lo, hi, has_err(num));
+       set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num));
        return 1;
 }
 
@@ -231,6 +241,20 @@ static int direct_trap(const struct lguest *lg,
         * go direct, of course 8) */
        return idt_type(trap->a, trap->b) == 0xF;
 }
+/*:*/
+
+/*M:005 The Guest has the ability to turn its interrupt gates into trap gates,
+ * if it is careful.  The Host will let trap gates can go directly to the
+ * Guest, but the Guest needs the interrupts atomically disabled for an
+ * interrupt gate.  It can do this by pointing the trap gate at instructions
+ * within noirq_start and noirq_end, where it can safely disable interrupts. */
+
+/*M:006 The Guests do not use the sysenter (fast system call) instruction,
+ * because it's hardcoded to enter privilege level 0 and so can't go direct.
+ * It's about twice as fast as the older "int 0x80" system call, so it might
+ * still be worthwhile to handle it in the Switcher and lcall down to the
+ * Guest.  The sysenter semantics are hairy tho: search for that keyword in
+ * entry.S :*/
 
 /*H:260 When we make traps go directly into the Guest, we need to make sure
  * the kernel stack is valid (ie. mapped in the page tables).  Otherwise, the