[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Switching to user mode from domU kernel



On Mon, Oct 01, 2007 at 06:24:07AM +0100, Keir Fraser wrote:
> On 30/9/07 21:11, "Trammell Hudson" <hudson@xxxxxxxxxxxxxx> wrote:
> > Am I not jumping into user space correctly?  Is there something
> > else that my code should do to make the transition?
> 
> It sounds like event delivery is masked before the iret, and then you have
> IF set in the RFLAGS value in the iret frame, which causes event delivery to
> be unmasked during iret.

That makes sense, although the event channel pending array is
all zero and the shared_info->vcpu_info[0].evtchn_upcall_pending
value is also zero.

If I do not set IF in RFLAGS, Xen crashes when it tries to handle
a GPF:

(XEN) traps.c:1587: GPF (001c): ffff830000165555 -> ffff83000016556b
(XEN) ----[ Xen-3.0.4-1  x86_64  debug=n  Not tainted ]----
(XEN) CPU:    0
(XEN) RIP:    e010:[<ffff83000016364b>] restore_all_xen+0x1b/0x20
(XEN) RFLAGS: 0000000000010282   CONTEXT: hypervisor
(XEN) rax: 000000400001c480   rbx: 000000600053dde8   rcx: 0000000000000017
(XEN) rdx: 00000000decafbad   rsi: 0000000000012345   rdi: 000000000badbabe
(XEN) rbp: 00000040005fffc0   rsp: ffff83000074ffa8   r8:  000000000000001f
(XEN) r9:  0000000000000017   r10: 00000040005fffc0   r11: 0000000000000000
(XEN) r12: 0000006000017000   r13: 0000000000000000   r14: 0000000000000000
(XEN) r15: ffff830000163726   cr0: 000000008005003b   cr4: 00000000000006f0
(XEN) cr3: 000000002734d000   cr2: ffff820000001000
(XEN) ds: 0000   es: 0000   fs: 0000   gs: 0000   ss: e018   cs: e010
(XEN) Xen stack trace from rsp=ffff83000074ffa8:
(XEN)    000001000001c480 0000006000101000 000000000000e033 000000400058bec0
(XEN)    0000006000102fa8 000000000000e02b 0000000000000000 0000000000000000
(XEN)    0000000000000000 0000000000000000 ffff830000744080
(XEN) Xen call trace:
(XEN)    [<ffff83000016364b>] restore_all_xen+0x1b/0x20
(XEN) 
(XEN) ****************************************
(XEN) Panic on CPU 0:
(XEN) GENERAL PROTECTION FAULT
(XEN) [error_code=1000]
(XEN) ****************************************
(XEN) 
(XEN) Reboot in five seconds...

> > I am passing flags==0 and only push the values for flags, CS:RIP,
> > RFLAGS, and SS:RSP.  If I push values for RAX, R11, and RCX on the
> > stack the kernel ends up in all sorts of weird places rather than
> > my intended RIP and RSP.
> 
> That doesn't make sense. The iret implementation (for an x86/64 guest)
> always expects RAX/R11/RCX on the stack.

That was my expectation as well, but if I push the three extra values
onto the stack then it jumps to the wrong place:

        context.rax     = 0x12345;
        context.r11     = 0xdecafbad;
        context.rcx     = 0xbadbabe;
        context.rflags  = 0x200;
        context.rip     = start_addr; // 01f:000000400001c480
        context.cs      = USER_CS;
        context.flags   = 0;
        context.rsp     = (uintptr_t) stack; // 017:00000040005fffc0
        context.ss      = USER_DS;

        __asm__ __volatile__ (
                "push   %0\n"
                "push   %1\n"
                "push   %2\n"
                "push   %3\n"
                "push   %4\n"
                "push   %5\n"
                "push   %6\n"
                "push   %7\n"
                "push   %8\n"
                "jmp hypercall_page + __HYPERVISOR_iret*32\n"
                :
                : "r" (context.ss),
                "r" (context.rsp),
                "r" (context.rflags),
                "r" (context.cs),
                "r" (context.rip),
                "r" (context.flags),
                "r" (context.rcx),
                "r" (context.r11),
                "r" (context.rax),
                "r" (USER_DS)
        );

Ends up with RIP e033:00000000decafbad and RSP e02b:000000400001c480:

(XEN) domain_crash_sync called from entry.S
(XEN) Domain 147 (vcpu#0) crashed on cpu#0:
(XEN) ----[ Xen-3.0.4-1  x86_64  debug=n  Not tainted ]----
(XEN) CPU:    0
(XEN) RIP:    e033:[<00000000decafbad>]
(XEN) RFLAGS: 0000000000010202   CONTEXT: guest
(XEN) rax: 0000000000000017   rbx: 0000000000000200   rcx: 00000000decafbad
(XEN) rdx: 0000000000012345   rsi: 000000000badbabe   rdi: 0000000000000000
(XEN) rbp: 000000600053dde8   rsp: 000000400001c480   r8:  000000400001c480
(XEN) r9:  000000000000001f   r10: 0000000000000017   r11: 0000000000000200
(XEN) r12: 00000040005fffc0   r13: 0000006000017000   r14: 0000000000000000
(XEN) r15: 0000000000000000   cr0: 000000008005003b   cr4: 00000000000006f0
(XEN) cr3: 0000000026ae5000   cr2: 00000000decafbad
(XEN) ds: 0000   es: 0000   fs: 0000   gs: 0000   ss: e02b   cs: e033

Looking in hypercall_page_initialise_ring3_kernel() it appears that
the hypervisor call does the rcx, r11 and rax pushing, not the
domU kernel calling the hypercall:

    /*
     * HYPERVISOR_iret is special because it doesn't return and expects a
     * special stack frame. Guests jump at this transfer point instead of
     * calling it.
     */
    p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32));
    *(u8  *)(p+ 0) = 0x51;    /* push %rcx */
    *(u16 *)(p+ 1) = 0x5341;  /* push %r11 */
    *(u8  *)(p+ 3) = 0x50;    /* push %rax */
    *(u8  *)(p+ 4) = 0xb8;    /* mov  $__HYPERVISOR_iret,%eax */
    *(u32 *)(p+ 5) = __HYPERVISOR_iret;
    *(u16 *)(p+ 9) = 0x050f;  /* syscall */

-- Trammell

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.