static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages) { unsigned int clobber; copy_in_guest_info(cpu, pages); cpu->regs->trapnum = 256; asm volatile("pushf; lcall *lguest_entry" : "=a"(clobber), "=b"(clobber) : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)) : "memory", "%edx", "%ecx", "%edi", "%esi"); }
/* Finally: the code to actually call into the Switcher to run the Guest. */ 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; /* * Copy the guest-specific information into this CPU's "struct * lguest_pages". */ copy_in_guest_info(cpu, pages); /* * Set the trap number to 256 (impossible value). If we fault while * switching to the Guest (bad segment registers or bug), this will * cause us to abort the Guest. */ cpu->regs->trapnum = 256; /* * Now: we push the "eflags" register on the stack, then do an "lcall". * This is how we change from using the kernel code segment to using * the dedicated lguest code segment, as well as jumping into the * Switcher. * * The lcall also pushes the old code segment (KERNEL_CS) onto the * stack, then the address of this call. This stack layout happens to * exactly match the stack layout created by an interrupt... */ asm volatile("pushf; lcall *%4" /* * This is how we tell GCC that %eax ("a") and %ebx ("b") * are changed by this routine. The "=" means output. */ : "=a"(clobber), "=b"(clobber) /* * %eax contains the pages pointer. ("0" refers to the * 0-th argument above, ie "a"). %ebx contains the * physical address of the Guest's top-level page * directory. */ : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)), "m"(lguest_entry) /* * We tell gcc that all these registers could change, * which means we don't have to save and restore them in * the Switcher. */ : "memory", "%edx", "%ecx", "%edi", "%esi"); }