on_each_cpu(): kill unused 'retry' parameter
[safe/jmp/linux-2.6] / drivers / lguest / x86 / core.c
index 8c72355..95dfda5 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+/*P:450 This file contains the x86-specific lguest code.  It used to be all
+ * mixed in with drivers/lguest/core.c but several foolhardy code slashers
+ * wrestled most of the dependencies out to here in preparation for porting
+ * lguest to other architectures (see what I mean by foolhardy?).
+ *
+ * This also contains a couple of non-obvious setup and teardown pieces which
+ * were implemented after days of debugging pain. :*/
 #include <linux/kernel.h>
 #include <linux/start_kernel.h>
 #include <linux/string.h>
@@ -60,7 +67,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu)
                  (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
 }
 
-static DEFINE_PER_CPU(struct lguest *, last_guest);
+static DEFINE_PER_CPU(struct lg_cpu *, last_cpu);
 
 /*S:010
  * We approach the Switcher.
@@ -75,15 +82,14 @@ static DEFINE_PER_CPU(struct lguest *, last_guest);
  */
 static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
 {
-       struct lguest *lg = cpu->lg;
        /* Copying all this data can be quite expensive.  We usually run the
         * same Guest we ran last time (and that Guest hasn't run anywhere else
         * meanwhile).  If that's not the case, we pretend everything in the
         * Guest has changed. */
-       if (__get_cpu_var(last_guest) != lg || lg->last_pages != pages) {
-               __get_cpu_var(last_guest) = lg;
-               lg->last_pages = pages;
-               lg->changed = CHANGED_ALL;
+       if (__get_cpu_var(last_cpu) != cpu || cpu->last_pages != pages) {
+               __get_cpu_var(last_cpu) = cpu;
+               cpu->last_pages = pages;
+               cpu->changed = CHANGED_ALL;
        }
 
        /* These copies are pretty cheap, so we do them unconditionally: */
@@ -95,22 +101,22 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
        /* Set up the two "TSS" members which tell the CPU what stack to use
         * for traps which do directly into the Guest (ie. traps at privilege
         * level 1). */
-       pages->state.guest_tss.esp1 = cpu->esp1;
+       pages->state.guest_tss.sp1 = cpu->esp1;
        pages->state.guest_tss.ss1 = cpu->ss1;
 
        /* Copy direct-to-Guest trap entries. */
-       if (lg->changed & CHANGED_IDT)
+       if (cpu->changed & CHANGED_IDT)
                copy_traps(cpu, pages->state.guest_idt, default_idt_entries);
 
        /* Copy all GDT entries which the Guest can change. */
-       if (lg->changed & CHANGED_GDT)
+       if (cpu->changed & CHANGED_GDT)
                copy_gdt(cpu, pages->state.guest_gdt);
        /* If only the TLS entries have changed, copy them. */
-       else if (lg->changed & CHANGED_GDT_TLS)
+       else if (cpu->changed & CHANGED_GDT_TLS)
                copy_gdt_tls(cpu, pages->state.guest_gdt);
 
        /* Mark the Guest as unchanged for next time. */
-       lg->changed = 0;
+       cpu->changed = 0;
 }
 
 /* Finally: the code to actually call into the Switcher to run the Guest. */
@@ -118,7 +124,6 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
 {
        /* This is a dummy value we need for GCC's sake. */
        unsigned int clobber;
-       struct lguest *lg = cpu->lg;
 
        /* Copy the guest-specific information into this CPU's "struct
         * lguest_pages". */
@@ -145,7 +150,7 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
                      * 0-th argument above, ie "a").  %ebx contains the
                      * physical address of the Guest's top-level page
                      * directory. */
-                    : "0"(pages), "1"(__pa(lg->pgdirs[cpu->cpu_pgd].pgdir))
+                    : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir))
                     /* We tell gcc that all these registers could change,
                      * which means we don't have to save and restore them in
                      * the Switcher. */
@@ -159,6 +164,8 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
  * also simplify copy_in_guest_info().  Note that we'd still need to restore
  * things when we exit to Launcher userspace, but that's fairly easy.
  *
+ * We could also try using this hooks for PGE, but that might be too expensive.
+ *
  * The hooks were designed for KVM, but we can also put them to good use. :*/
 
 /*H:040 This is the i386-specific code to setup and run the Guest.  Interrupts
@@ -169,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
         * we set it now, so we can trap and pass that trap to the Guest if it
         * uses the FPU. */
        if (cpu->ts)
-               lguest_set_ts();
+               unlazy_fpu(current);
 
        /* SYSENTER is an optimized way of doing system calls.  We can't allow
         * it because it always jumps to privilege level 0.  A normal Guest
@@ -184,11 +191,15 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
         * was doing. */
        run_guest_once(cpu, lguest_pages(raw_smp_processor_id()));
 
-       /* Note that the "regs" pointer contains two extra entries which are
+       /* Note that the "regs" structure contains two extra entries which are
         * not really registers: a trap number which says what interrupt or
         * trap made the switcher code come back, and an error code which some
         * traps set.  */
 
+        /* Restore SYSENTER if it's supposed to be on. */
+        if (boot_cpu_has(X86_FEATURE_SEP))
+               wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+
        /* If the Guest page faulted, then the cr2 register will tell us the
         * bad virtual address.  We have to grab this now, because once we
         * re-enable interrupts an interrupt could fault and thus overwrite
@@ -196,13 +207,12 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
        if (cpu->regs->trapnum == 14)
                cpu->arch.last_pagefault = read_cr2();
        /* Similarly, if we took a trap because the Guest used the FPU,
-        * we have to restore the FPU it expects to see. */
+        * we have to restore the FPU it expects to see.
+        * math_state_restore() may sleep and we may even move off to
+        * a different CPU. So all the critical stuff should be done
+        * before this.  */
        else if (cpu->regs->trapnum == 7)
                math_state_restore();
-
-       /* Restore SYSENTER if it's supposed to be on. */
-       if (boot_cpu_has(X86_FEATURE_SEP))
-               wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
 }
 
 /*H:130 Now we've examined the hypercall code; our Guest can make requests.
@@ -218,7 +228,6 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
  * instructions and skip over it.  We return true if we did. */
 static int emulate_insn(struct lg_cpu *cpu)
 {
-       struct lguest *lg = cpu->lg;
        u8 insn;
        unsigned int insnlen = 0, in = 0, shift = 0;
        /* The eip contains the *virtual* address of the Guest's instruction:
@@ -232,7 +241,7 @@ static int emulate_insn(struct lg_cpu *cpu)
                return 0;
 
        /* Decoding x86 instructions is icky. */
-       insn = lgread(lg, physaddr, u8);
+       insn = lgread(cpu, physaddr, u8);
 
        /* 0x66 is an "operand prefix".  It means it's using the upper 16 bits
           of the eax register. */
@@ -240,7 +249,7 @@ static int emulate_insn(struct lg_cpu *cpu)
                shift = 16;
                /* The instruction is 1 byte so far, read the next byte. */
                insnlen = 1;
-               insn = lgread(lg, physaddr + insnlen, u8);
+               insn = lgread(cpu, physaddr + insnlen, u8);
        }
 
        /* We can ignore the lower bit for the moment and decode the 4 opcodes
@@ -284,7 +293,6 @@ static int emulate_insn(struct lg_cpu *cpu)
 /*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
 void lguest_arch_handle_trap(struct lg_cpu *cpu)
 {
-       struct lguest *lg = cpu->lg;
        switch (cpu->regs->trapnum) {
        case 13: /* We've intercepted a General Protection Fault. */
                /* Check if this was one of those annoying IN or OUT
@@ -297,11 +305,10 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
                break;
        case 14: /* We've intercepted a Page Fault. */
                /* The Guest accessed a virtual address that wasn't mapped.
-                * This happens a lot: we don't actually set up most of the
-                * page tables for the Guest at all when we start: as it runs
-                * it asks for more and more, and we set them up as
-                * required. In this case, we don't even tell the Guest that
-                * the fault happened.
+                * This happens a lot: we don't actually set up most of the page
+                * tables for the Guest at all when we start: as it runs it asks
+                * for more and more, and we set them up as required. In this
+                * case, we don't even tell the Guest that the fault happened.
                 *
                 * The errcode tells whether this was a read or a write, and
                 * whether kernel or userspace code. */
@@ -316,9 +323,10 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
                 * Note that if the Guest were really messed up, this could
                 * happen before it's done the LHCALL_LGUEST_INIT hypercall, so
                 * lg->lguest_data could be NULL */
-               if (lg->lguest_data &&
-                   put_user(cpu->arch.last_pagefault, &lg->lguest_data->cr2))
-                       kill_guest(lg, "Writing cr2");
+               if (cpu->lg->lguest_data &&
+                   put_user(cpu->arch.last_pagefault,
+                            &cpu->lg->lguest_data->cr2))
+                       kill_guest(cpu, "Writing cr2");
                break;
        case 7: /* We've intercepted a Device Not Available fault. */
                /* If the Guest doesn't want to know, we already restored the
@@ -345,8 +353,8 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
        if (!deliver_trap(cpu, cpu->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. */
-               kill_guest(lg, "unhandled trap %li at %#lx (%#lx)",
+                * it handle), it dies with this cryptic error message. */
+               kill_guest(cpu, "unhandled trap %li at %#lx (%#lx)",
                           cpu->regs->trapnum, cpu->regs->eip,
                           cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault
                           : cpu->regs->errcode);
@@ -378,8 +386,8 @@ void __init lguest_arch_host_init(void)
         * The only exception is the interrupt handlers in switcher.S: their
         * addresses are placed in a table (default_idt_entries), so we need to
         * update the table with the new addresses.  switcher_offset() is a
-        * convenience function which returns the distance between the builtin
-        * switcher code and the high-mapped copy we just made. */
+        * convenience function which returns the distance between the
+        * compiled-in switcher code and the high-mapped copy we just made. */
        for (i = 0; i < IDT_ENTRIES; i++)
                default_idt_entries[i] += switcher_offset();
 
@@ -419,9 +427,9 @@ void __init lguest_arch_host_init(void)
                state->guest_gdt_desc.address = (long)&state->guest_gdt;
 
                /* We know where we want the stack to be when the Guest enters
-                * the switcher: in pages->regs.  The stack grows upwards, so
+                * the Switcher: in pages->regs.  The stack grows upwards, so
                 * we start it at the end of that structure. */
-               state->guest_tss.esp0 = (long)(&pages->regs + 1);
+               state->guest_tss.sp0 = (long)(&pages->regs + 1);
                /* And this is the GDT entry to use for the stack: we keep a
                 * couple of special LGUEST entries. */
                state->guest_tss.ss0 = LGUEST_DS;
@@ -470,7 +478,7 @@ void __init lguest_arch_host_init(void)
                cpu_had_pge = 1;
                /* adjust_pge is a helper function which sets or unsets the PGE
                 * bit on its CPU, depending on the argument (0 == unset). */
-               on_each_cpu(adjust_pge, (void *)0, 0, 1);
+               on_each_cpu(adjust_pge, (void *)0, 1);
                /* Turn off the feature in the global feature set. */
                clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
        }
@@ -485,7 +493,7 @@ void __exit lguest_arch_host_fini(void)
        if (cpu_had_pge) {
                set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
                /* adjust_pge's argument "1" means set PGE. */
-               on_each_cpu(adjust_pge, (void *)1, 0, 1);
+               on_each_cpu(adjust_pge, (void *)1, 1);
        }
        put_online_cpus();
 }
@@ -515,11 +523,11 @@ int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
 int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
 {
        u32 tsc_speed;
-       struct lguest *lg = cpu->lg;
 
-       /* The pointer to the Guest's "struct lguest_data" is the only
-        * argument.  We check that address now. */
-       if (!lguest_address_ok(lg, cpu->hcall->arg1, sizeof(*lg->lguest_data)))
+       /* The pointer to the Guest's "struct lguest_data" is the only argument.
+        * We check that address now. */
+       if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1,
+                              sizeof(*cpu->lg->lguest_data)))
                return -EFAULT;
 
        /* Having checked it, we simply set lg->lguest_data to point straight
@@ -527,7 +535,7 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
         * copy_to_user/from_user from now on, instead of lgread/write.  I put
         * this in to show that I'm not immune to writing stupid
         * optimizations. */
-       lg->lguest_data = lg->mem_base + cpu->hcall->arg1;
+       cpu->lg->lguest_data = cpu->lg->mem_base + cpu->hcall->arg1;
 
        /* We insist that the Time Stamp Counter exist and doesn't change with
         * cpu frequency.  Some devious chip manufacturers decided that TSC
@@ -540,15 +548,16 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
                tsc_speed = tsc_khz;
        else
                tsc_speed = 0;
-       if (put_user(tsc_speed, &lg->lguest_data->tsc_khz))
+       if (put_user(tsc_speed, &cpu->lg->lguest_data->tsc_khz))
                return -EFAULT;
 
        /* The interrupt code might not like the system call vector. */
-       if (!check_syscall_vector(lg))
-               kill_guest(lg, "bad syscall vector");
+       if (!check_syscall_vector(cpu->lg))
+               kill_guest(cpu, "bad syscall vector");
 
        return 0;
 }
+/*:*/
 
 /*L:030 lguest_arch_setup_regs()
  *