summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/ml
diff options
context:
space:
mode:
authorTodd Clayton <Todd.Clayton@Sun.COM>2009-10-24 11:04:55 -0700
committerTodd Clayton <Todd.Clayton@Sun.COM>2009-10-24 11:04:55 -0700
commit530f2c280d739b194cfbb75f25352b75bb99b4b2 (patch)
tree00097103202108aead1536c3d0fe39685516b93f /usr/src/uts/i86pc/ml
parentfcc214c383d20beb968b623b83d851672e174702 (diff)
downloadillumos-joyent-530f2c280d739b194cfbb75f25352b75bb99b4b2.tar.gz
6818123 booting sn1 branded zone in 64-bit dom0 causes xvm panic
Diffstat (limited to 'usr/src/uts/i86pc/ml')
-rw-r--r--usr/src/uts/i86pc/ml/syscall_asm_amd64.s47
1 files changed, 37 insertions, 10 deletions
diff --git a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
index c8ed8ecaaf..d8aa1396c9 100644
--- a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
+++ b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
@@ -366,12 +366,11 @@ __no_rupdate_msg:
* [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 @@ noprod_sys_syscall:
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 @@ _syscall_invoke:
* 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)