summaryrefslogtreecommitdiff
path: root/usr/src
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
parentfcc214c383d20beb968b623b83d851672e174702 (diff)
downloadillumos-gate-530f2c280d739b194cfbb75f25352b75bb99b4b2.tar.gz
6818123 booting sn1 branded zone in 64-bit dom0 causes xvm panic
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/ml/syscall_asm_amd64.s47
-rw-r--r--usr/src/uts/i86xpv/sys/machprivregs.h12
2 files changed, 48 insertions, 11 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)
diff --git a/usr/src/uts/i86xpv/sys/machprivregs.h b/usr/src/uts/i86xpv/sys/machprivregs.h
index 35df0b99e9..64780f0c4e 100644
--- a/usr/src/uts/i86xpv/sys/machprivregs.h
+++ b/usr/src/uts/i86xpv/sys/machprivregs.h
@@ -372,7 +372,17 @@ extern "C" {
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 */