Mercurial > illumos > illumos-gate
changeset 10856:1620845e5d2c
6818123 booting sn1 branded zone in 64-bit dom0 causes xvm panic
author | Todd Clayton <Todd.Clayton@Sun.COM> |
---|---|
date | Sat, 24 Oct 2009 11:04:55 -0700 |
parents | ff1573ed949f |
children | 2c20a0bd87cd |
files | usr/src/uts/i86pc/ml/syscall_asm_amd64.s usr/src/uts/i86xpv/sys/machprivregs.h |
diffstat | 2 files changed, 48 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s Sat Oct 24 10:19:53 2009 -0400 +++ b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s Sat Oct 24 11:04:55 2009 -0700 @@ -366,12 +366,11 @@ * [1] They used to, and we relied on it, but this was broken in 3.1.1. * Sigh. */ - #if defined(__xpv) -#define XPV_SYSCALL_PROD \ - XPV_TRAP_POP; \ - movq (%rsp), %rcx; \ - movq 0x10(%rsp), %r11 +#define XPV_SYSCALL_PROD \ + movq 0x10(%rsp), %rcx; \ + movq 0x20(%rsp), %r11; \ + movq 0x28(%rsp), %rsp #else #define XPV_SYSCALL_PROD /* nothing */ #endif @@ -409,12 +408,7 @@ ASSERT_UPCALL_MASK_IS_SET movq %r15, %gs:CPU_RTMP_R15 -#if defined(__xpv) - movq 0x18(%rsp), %r15 /* save user stack */ - movq %r15, %gs:CPU_RTMP_RSP -#else movq %rsp, %gs:CPU_RTMP_RSP -#endif /* __xpv */ movq %gs:CPU_THREAD, %r15 movq T_STACK(%r15), %rsp @@ -589,9 +583,42 @@ * in sn1_brand_syscall_callback for an example. */ ASSERT_UPCALL_MASK_IS_SET +#if defined(__xpv) + SYSRETQ + ALTENTRY(nopop_sys_syscall_swapgs_sysretq) + + /* + * We can only get here after executing a brand syscall + * interposition callback handler and simply need to + * "sysretq" back to userland. On the hypervisor this + * involves the iret hypercall which requires us to construct + * just enough of the stack needed for the hypercall. + * (rip, cs, rflags, rsp, ss). + */ + movq %rsp, %gs:CPU_RTMP_RSP /* save user's rsp */ + movq %gs:CPU_THREAD, %r11 + movq T_STACK(%r11), %rsp + + movq %rcx, REGOFF_RIP(%rsp) + movl $UCS_SEL, REGOFF_CS(%rsp) + movq %gs:CPU_RTMP_RSP, %r11 + movq %r11, REGOFF_RSP(%rsp) + pushfq + popq %r11 /* hypercall enables ints */ + movq %r11, REGOFF_RFL(%rsp) + movl $UDS_SEL, REGOFF_SS(%rsp) + addq $REGOFF_RIP, %rsp + /* + * XXPV: see comment in SYSRETQ definition for future optimization + * we could take. + */ + ASSERT_UPCALL_MASK_IS_SET + SYSRETQ +#else ALTENTRY(nopop_sys_syscall_swapgs_sysretq) SWAPGS /* user gsbase */ SYSRETQ +#endif /*NOTREACHED*/ SET_SIZE(nopop_sys_syscall_swapgs_sysretq)
--- a/usr/src/uts/i86xpv/sys/machprivregs.h Sat Oct 24 10:19:53 2009 -0400 +++ b/usr/src/uts/i86xpv/sys/machprivregs.h Sat Oct 24 11:04:55 2009 -0700 @@ -372,7 +372,17 @@ ud2 /* die nastily if we return! */ #define IRET HYPERVISOR_IRET(0) -#define SYSRETQ HYPERVISOR_IRET(VGCF_IN_KERNEL) + +/* + * XXPV: Normally we would expect to use sysret to return from kernel to + * user mode when using the syscall instruction. The iret hypercall + * does support both iret and sysret semantics. For us to use sysret + * style would require that we use the hypervisor's private descriptors + * that obey syscall instruction's imposed segment selector ordering. + * With iret we can use whatever %cs value we choose. We should fix + * this to use sysret one day. + */ +#define SYSRETQ HYPERVISOR_IRET(0) #define SYSRETL ud2 /* 32-bit syscall/sysret not supported */ #define SWAPGS /* empty - handled in hypervisor */