]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/lguest/boot.c
Merge git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6-omap-h63xx.git] / arch / x86 / lguest / boot.c
index 136d9df0295ec5a297388ba22abe0ea5f538d205..5afdde4895dcefe823e0e500df57d977a7ffa350 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
 #include <linux/virtio_console.h>
+#include <linux/pm.h>
 #include <asm/paravirt.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -66,6 +67,7 @@
 #include <asm/mce.h>
 #include <asm/io.h>
 #include <asm/i387.h>
+#include <asm/reboot.h>                /* for struct machine_ops */
 
 /*G:010 Welcome to the Guest!
  *
@@ -92,38 +94,7 @@ struct lguest_data lguest_data = {
 };
 static cycle_t clock_base;
 
-/*G:035 Notice the lazy_hcall() above, rather than hcall().  This is our first
- * real optimization trick!
- *
- * When lazy_mode is set, it means we're allowed to defer all hypercalls and do
- * them as a batch when lazy_mode is eventually turned off.  Because hypercalls
- * are reasonably expensive, batching them up makes sense.  For example, a
- * large mmap might update dozens of page table entries: that code calls
- * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
- * lguest_leave_lazy_mode().
- *
- * So, when we're in lazy mode, we call async_hypercall() to store the call for
- * future processing.  When lazy mode is turned off we issue a hypercall to
- * flush the stored calls.
- */
-static void lguest_leave_lazy_mode(void)
-{
-       paravirt_leave_lazy(paravirt_get_lazy_mode());
-       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
-}
-
-static void lazy_hcall(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3)
-{
-       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               hcall(call, arg1, arg2, arg3);
-       else
-               async_hcall(call, arg1, arg2, arg3);
-}
-
-/* async_hcall() is pretty simple: I'm quite proud of it really.  We have a
+/*G:037 async_hcall() is pretty simple: I'm quite proud of it really.  We have a
  * ring buffer of stored hypercalls which the Host will run though next time we
  * do a normal hypercall.  Each entry in the ring has 4 slots for the hypercall
  * arguments, and a "hcall_status" word which is 0 if the call is ready to go,
@@ -133,8 +104,8 @@ static void lazy_hcall(unsigned long call,
  * full and we just make the hypercall directly.  This has the nice side
  * effect of causing the Host to run all the stored calls in the ring buffer
  * which empties it for next time! */
-void async_hcall(unsigned long call,
-                unsigned long arg1, unsigned long arg2, unsigned long arg3)
+static void async_hcall(unsigned long call, unsigned long arg1,
+                       unsigned long arg2, unsigned long arg3)
 {
        /* Note: This code assumes we're uniprocessor. */
        static unsigned int next_call;
@@ -160,11 +131,41 @@ void async_hcall(unsigned long call,
        }
        local_irq_restore(flags);
 }
-/*:*/
+
+/*G:035 Notice the lazy_hcall() above, rather than hcall().  This is our first
+ * real optimization trick!
+ *
+ * When lazy_mode is set, it means we're allowed to defer all hypercalls and do
+ * them as a batch when lazy_mode is eventually turned off.  Because hypercalls
+ * are reasonably expensive, batching them up makes sense.  For example, a
+ * large munmap might update dozens of page table entries: that code calls
+ * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
+ * lguest_leave_lazy_mode().
+ *
+ * So, when we're in lazy mode, we call async_hcall() to store the call for
+ * future processing. */
+static void lazy_hcall(unsigned long call,
+                      unsigned long arg1,
+                      unsigned long arg2,
+                      unsigned long arg3)
+{
+       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
+               hcall(call, arg1, arg2, arg3);
+       else
+               async_hcall(call, arg1, arg2, arg3);
+}
+
+/* When lazy mode is turned off reset the per-cpu lazy mode variable and then
+ * issue a hypercall to flush any stored calls. */
+static void lguest_leave_lazy_mode(void)
+{
+       paravirt_leave_lazy(paravirt_get_lazy_mode());
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
+}
 
 /*G:033
- * Here are our first native-instruction replacements: four functions for
- * interrupt control.
+ * After that diversion we return to our first native-instruction
+ * replacements: four functions for interrupt control.
  *
  * The simplest way of implementing these would be to have "turn interrupts
  * off" and "turn interrupts on" hypercalls.  Unfortunately, this is too slow:
@@ -175,15 +176,15 @@ void async_hcall(unsigned long call,
  * check there when it wants to deliver an interrupt.
  */
 
-/* save_flags() is expected to return the processor state (ie. "eflags").  The
- * eflags word contains all kind of stuff, but in practice Linux only cares
+/* save_flags() is expected to return the processor state (ie. "flags").  The
+ * flags word contains all kind of stuff, but in practice Linux only cares
  * about the interrupt flag.  Our "save_flags()" just returns that. */
 static unsigned long save_fl(void)
 {
        return lguest_data.irq_enabled;
 }
 
-/* "restore_flags" just sets the flags back to the value given. */
+/* restore_flags() just sets the flags back to the value given. */
 static void restore_fl(unsigned long flags)
 {
        lguest_data.irq_enabled = flags;
@@ -217,19 +218,20 @@ static void irq_enable(void)
  * address of the handler, and... well, who cares?  The Guest just asks the
  * Host to make the change anyway, because the Host controls the real IDT.
  */
-static void lguest_write_idt_entry(struct desc_struct *dt,
-                                  int entrynum, u32 low, u32 high)
+static void lguest_write_idt_entry(gate_desc *dt,
+                                  int entrynum, const gate_desc *g)
 {
+       u32 *desc = (u32 *)g;
        /* Keep the local copy up to date. */
-       write_dt_entry(dt, entrynum, low, high);
+       native_write_idt_entry(dt, entrynum, g);
        /* Tell Host about this new entry. */
-       hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, low, high);
+       hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
 }
 
 /* Changing to a different IDT is very rare: we keep the IDT up-to-date every
  * time it is written, so we can simply loop through all entries and tell the
  * Host about them. */
-static void lguest_load_idt(const struct Xgt_desc_struct *desc)
+static void lguest_load_idt(const struct desc_ptr *desc)
 {
        unsigned int i;
        struct desc_struct *idt = (void *)desc->address;
@@ -252,7 +254,7 @@ static void lguest_load_idt(const struct Xgt_desc_struct *desc)
  * hypercall and use that repeatedly to load a new IDT.  I don't think it
  * really matters, but wouldn't it be nice if they were the same?
  */
-static void lguest_load_gdt(const struct Xgt_desc_struct *desc)
+static void lguest_load_gdt(const struct desc_ptr *desc)
 {
        BUG_ON((desc->size+1)/8 != GDT_ENTRIES);
        hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0);
@@ -261,10 +263,10 @@ static void lguest_load_gdt(const struct Xgt_desc_struct *desc)
 /* For a single GDT entry which changes, we do the lazy thing: alter our GDT,
  * then tell the Host to reload the entire thing.  This operation is so rare
  * that this naive implementation is reasonable. */
-static void lguest_write_gdt_entry(struct desc_struct *dt,
-                                  int entrynum, u32 low, u32 high)
+static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
+                                  const void *desc, int type)
 {
-       write_dt_entry(dt, entrynum, low, high);
+       native_write_gdt_entry(dt, entrynum, desc, type);
        hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0);
 }
 
@@ -323,30 +325,30 @@ static void lguest_load_tr_desc(void)
  * anyone (including userspace) can just use the raw "cpuid" instruction and
  * the Host won't even notice since it isn't privileged.  So we try not to get
  * too worked up about it. */
-static void lguest_cpuid(unsigned int *eax, unsigned int *ebx,
-                        unsigned int *ecx, unsigned int *edx)
+static void lguest_cpuid(unsigned int *ax, unsigned int *bx,
+                        unsigned int *cx, unsigned int *dx)
 {
-       int function = *eax;
+       int function = *ax;
 
-       native_cpuid(eax, ebx, ecx, edx);
+       native_cpuid(ax, bx, cx, dx);
        switch (function) {
        case 1: /* Basic feature request. */
                /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */
-               *ecx &= 0x00002201;
+               *cx &= 0x00002201;
                /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */
-               *edx &= 0x07808101;
+               *dx &= 0x07808101;
                /* The Host can do a nice optimization if it knows that the
                 * kernel mappings (addresses above 0xC0000000 or whatever
                 * PAGE_OFFSET is set to) haven't changed.  But Linux calls
                 * flush_tlb_user() for both user and kernel mappings unless
                 * the Page Global Enable (PGE) feature bit is set. */
-               *edx |= 0x00002000;
+               *dx |= 0x00002000;
                break;
        case 0x80000000:
                /* Futureproof this a little: if they ask how much extended
                 * processor information there is, limit it to known fields. */
-               if (*eax > 0x80000008)
-                       *eax = 0x80000008;
+               if (*ax > 0x80000008)
+                       *ax = 0x80000008;
                break;
        }
 }
@@ -356,7 +358,7 @@ static void lguest_cpuid(unsigned int *eax, unsigned int *ebx,
  * it.  The Host needs to know when the Guest wants to change them, so we have
  * a whole series of functions like read_cr0() and write_cr0().
  *
- * We start with CR0.  CR0 allows you to turn on and off all kinds of basic
+ * We start with cr0.  cr0 allows you to turn on and off all kinds of basic
  * features, but Linux only really cares about one: the horrifically-named Task
  * Switched (TS) bit at bit 3 (ie. 8)
  *
@@ -389,7 +391,7 @@ static void lguest_clts(void)
        current_cr0 &= ~X86_CR0_TS;
 }
 
-/* CR2 is the virtual address of the last page fault, which the Guest only ever
+/* cr2 is the virtual address of the last page fault, which the Guest only ever
  * reads.  The Host kindly writes this into our "struct lguest_data", so we
  * just read it out of there. */
 static unsigned long lguest_read_cr2(void)
@@ -397,7 +399,7 @@ static unsigned long lguest_read_cr2(void)
        return lguest_data.cr2;
 }
 
-/* CR3 is the current toplevel pagetable page: the principle is the same as
+/* cr3 is the current toplevel pagetable page: the principle is the same as
  * cr0.  Keep a local copy, and tell the Host when it changes. */
 static void lguest_write_cr3(unsigned long cr3)
 {
@@ -410,7 +412,7 @@ static unsigned long lguest_read_cr3(void)
        return current_cr3;
 }
 
-/* CR4 is used to enable and disable PGE, but we don't care. */
+/* cr4 is used to enable and disable PGE, but we don't care. */
 static unsigned long lguest_read_cr4(void)
 {
        return 0;
@@ -431,7 +433,7 @@ static void lguest_write_cr4(unsigned long val)
  * maps virtual addresses to physical addresses using "page tables".  We could
  * use one huge index of 1 million entries: each address is 4 bytes, so that's
  * 1024 pages just to hold the page tables.   But since most virtual addresses
- * are unused, we use a two level index which saves space.  The CR3 register
+ * are unused, we use a two level index which saves space.  The cr3 register
  * contains the physical address of the top level "page directory" page, which
  * contains physical addresses of up to 1024 second-level pages.  Each of these
  * second level pages contains up to 1024 physical addresses of actual pages,
@@ -439,7 +441,7 @@ static void lguest_write_cr4(unsigned long val)
  *
  * Here's a diagram, where arrows indicate physical addresses:
  *
- * CR3 ---> +---------+
+ * cr3 ---> +---------+
  *         |      --------->+---------+
  *         |         |      | PADDR1  |
  *       Top-level   |      | PADDR2  |
@@ -497,8 +499,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
  *
  * ... except in early boot when the kernel sets up the initial pagetables,
  * which makes booting astonishingly slow.  So we don't even tell the Host
- * anything changed until we've done the first page table switch.
- */
+ * anything changed until we've done the first page table switch. */
 static void lguest_set_pte(pte_t *ptep, pte_t pteval)
 {
        *ptep = pteval;
@@ -719,10 +720,10 @@ static void lguest_time_init(void)
        /* Set up the timer interrupt (0) to go to our simple timer routine */
        set_irq_handler(0, lguest_time_irq);
 
-       /* Our clock structure look like arch/i386/kernel/tsc.c if we can use
-        * the TSC, otherwise it's a dumb nanosecond-resolution clock.  Either
-        * way, the "rating" is initialized so high that it's always chosen
-        * over any other clocksource. */
+       /* Our clock structure looks like arch/x86/kernel/tsc_32.c if we can
+        * use the TSC, otherwise it's a dumb nanosecond-resolution clock.
+        * Either way, the "rating" is set so high that it's always chosen over
+        * any other clocksource. */
        if (lguest_data.tsc_khz)
                lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
                                                         lguest_clock.shift);
@@ -748,7 +749,7 @@ static void lguest_time_init(void)
  * to work.  They're pretty simple.
  */
 
-/* The Guest needs to tell the host what stack it expects traps to use.  For
+/* The Guest needs to tell the Host what stack it expects traps to use.  For
  * native hardware, this is part of the Task State Segment mentioned above in
  * lguest_load_tr_desc(), but to help hypervisors there's this special call.
  *
@@ -756,10 +757,10 @@ static void lguest_time_init(void)
  * segment), the privilege level (we're privilege level 1, the Host is 0 and
  * will not tolerate us trying to use that), the stack pointer, and the number
  * of pages in the stack. */
-static void lguest_load_esp0(struct tss_struct *tss,
+static void lguest_load_sp0(struct tss_struct *tss,
                                     struct thread_struct *thread)
 {
-       lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->esp0,
+       lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0,
                   THREAD_SIZE/PAGE_SIZE);
 }
 
@@ -789,11 +790,11 @@ static void lguest_wbinvd(void)
  * code qualifies for Advanced.  It will also never interrupt anything.  It
  * does, however, allow us to get through the Linux boot code. */
 #ifdef CONFIG_X86_LOCAL_APIC
-static void lguest_apic_write(unsigned long reg, unsigned long v)
+static void lguest_apic_write(unsigned long reg, u32 v)
 {
 }
 
-static unsigned long lguest_apic_read(unsigned long reg)
+static u32 lguest_apic_read(unsigned long reg)
 {
        return 0;
 }
@@ -813,7 +814,7 @@ static void lguest_safe_halt(void)
  * rather than virtual addresses, so we use __pa() here. */
 static void lguest_power_off(void)
 {
-       hcall(LHCALL_CRASH, __pa("Power down"), 0, 0);
+       hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0);
 }
 
 /*
@@ -823,7 +824,7 @@ static void lguest_power_off(void)
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-       hcall(LHCALL_CRASH, __pa(p), 0, 0);
+       hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0);
        /* The hcall won't return, but to keep gcc happy, we're "done". */
        return NOTIFY_DONE;
 }
@@ -849,13 +850,16 @@ static __init char *lguest_memory_setup(void)
        return "LGUEST";
 }
 
-/* Before virtqueues are set up, we use LHCALL_NOTIFY on normal memory to
- * produce console output. */
+/* We will eventually use the virtio console device to produce console output,
+ * but before that is set up we use LHCALL_NOTIFY on normal memory to produce
+ * console output. */
 static __init int early_put_chars(u32 vtermno, const char *buf, int count)
 {
        char scratch[17];
        unsigned int len = count;
 
+       /* We use a nul-terminated string, so we have to make a copy.  Icky,
+        * huh? */
        if (len > sizeof(scratch) - 1)
                len = sizeof(scratch) - 1;
        scratch[len] = '\0';
@@ -882,7 +886,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
  * Our current solution is to allow the paravirt back end to optionally patch
  * over the indirect calls to replace them with something more efficient.  We
  * patch the four most commonly called functions: disable interrupts, enable
- * interrupts, restore interrupts and save interrupts.  We usually have 10
+ * interrupts, restore interrupts and save interrupts.  We usually have 6 or 10
  * bytes to patch into: the Guest versions of these operations are small enough
  * that we can fit comfortably.
  *
@@ -924,6 +928,11 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
        return insn_len;
 }
 
+static void lguest_restart(char *reason)
+{
+       hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
+}
+
 /*G:030 Once we get to lguest_init(), we know we're a Guest.  The pv_ops
  * structures in the kernel provide points for (almost) every routine we have
  * to override to avoid privileged instructions. */
@@ -955,7 +964,7 @@ __init void lguest_init(void)
        pv_cpu_ops.cpuid = lguest_cpuid;
        pv_cpu_ops.load_idt = lguest_load_idt;
        pv_cpu_ops.iret = lguest_iret;
-       pv_cpu_ops.load_esp0 = lguest_load_esp0;
+       pv_cpu_ops.load_sp0 = lguest_load_sp0;
        pv_cpu_ops.load_tr_desc = lguest_load_tr_desc;
        pv_cpu_ops.set_ldt = lguest_set_ldt;
        pv_cpu_ops.load_tls = lguest_load_tls;
@@ -1014,7 +1023,7 @@ __init void lguest_init(void)
        asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
 
        /* The Host uses the top of the Guest's virtual address space for the
-        * Host<->Guest Switcher, and it tells us how much it needs in
+        * Host<->Guest Switcher, and it tells us how big that is in
         * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
        reserve_top_address(lguest_data.reserve_mem);
 
@@ -1057,6 +1066,7 @@ __init void lguest_init(void)
         * the Guest routine to power off. */
        pm_power_off = lguest_power_off;
 
+       machine_ops.restart = lguest_restart;
        /* Now we're set up, call start_kernel() in init/main.c and we proceed
         * to boot as normal.  It never returns. */
        start_kernel();
@@ -1064,6 +1074,6 @@ __init void lguest_init(void)
 /*
  * This marks the end of stage II of our journey, The Guest.
  *
- * It is now time for us to explore the nooks and crannies of the three Guest
- * devices and complete our understanding of the Guest in "make Drivers".
+ * It is now time for us to explore the layer of virtual drivers and complete
+ * our understanding of the Guest in "make Drivers".
  */