From: Trammell Hudson <hudson@osresearch.net>
To: xen-devel@lists.xensource.com
Subject: Re: Switching to user mode from domU kernel
Date: Mon, 1 Oct 2007 14:43:06 -0400 [thread overview]
Message-ID: <20071001184306.GC10059@osresearch.net> (raw)
In-Reply-To: <C3264307.E410%Keir.Fraser@cl.cam.ac.uk>
On Mon, Oct 01, 2007 at 06:24:07AM +0100, Keir Fraser wrote:
> On 30/9/07 21:11, "Trammell Hudson" <hudson@osresearch.net> 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
next prev parent reply other threads:[~2007-10-01 18:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-30 20:11 Switching to user mode from domU kernel Trammell Hudson
2007-10-01 5:24 ` Keir Fraser
2007-10-01 18:43 ` Trammell Hudson [this message]
2007-10-02 5:33 ` Keir Fraser
2007-10-22 19:52 ` Trammell Hudson
2007-10-22 20:12 ` Keir Fraser
2007-10-22 22:00 ` Trammell Hudson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071001184306.GC10059@osresearch.net \
--to=hudson@osresearch.net \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.