summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2011-07-04 15:54:24 +0000
committerguenther <guenther@openbsd.org>2011-07-04 15:54:24 +0000
commit1396572dbc2406b717937a7e52f80e062def9901 (patch)
treedf4f5f493913e516e716015583120451cfcd62a7
parent- Take into account padding for the IEEE extended shape types. It (diff)
downloadwireguard-openbsd-1396572dbc2406b717937a7e52f80e062def9901.tar.xz
wireguard-openbsd-1396572dbc2406b717937a7e52f80e062def9901.zip
Force the sigreturn syscall to return to userspace via iretq by setting
the MDP_IRET flag in md_proc, then switch sigcode to enter the kernel via syscall instead of int$80. Rearrange the return paths in both the sysretq and iretq paths to reduce how long interrupts are blocked and shave instructions. ok kettenis@, extra testing krw@
-rw-r--r--sys/arch/amd64/amd64/locore.S70
-rw-r--r--sys/arch/amd64/amd64/machdep.c12
-rw-r--r--sys/arch/amd64/include/frameasm.h20
3 files changed, 59 insertions, 43 deletions
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index 9ab0e28127f..b23921787bb 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.47 2011/04/13 02:49:12 guenther Exp $ */
+/* $OpenBSD: locore.S,v 1.48 2011/07/04 15:54:24 guenther Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
@@ -637,12 +637,6 @@ longmode_hi:
/*
* Signal trampoline; copied to top of user stack.
- *
- * Note, the "system call" to sigreturn() needs to be an 'int $0x80' one
- * so that the kernel returns using 'iretq' method. This way if a process
- * was interrupted (by tick) as opposed to in the kernel when a signal was
- * being delivered, the process will be completely restored, including the
- * userland %rcx register, which the 'sysret' instruction can not restore.
*/
NENTRY(sigcode)
call *%rax
@@ -650,7 +644,7 @@ NENTRY(sigcode)
movq %rsp,%rdi
pushq %rdi /* fake return address */
movq $SYS_sigreturn,%rax
- int $0x80
+ syscall
movq $SYS_exit,%rax
syscall
.globl _C_LABEL(esigcode)
@@ -958,17 +952,28 @@ syscall_return:
#ifdef DIAGNOSTIC
cmpl $IPL_NONE,CPUVAR(ILEVEL)
jne 3f
-#endif
- /*
- * XXX interrupts off longer than they should be here.
- */
+#endif /* DIAGNOSTIC */
+
+ movq TF_RDI(%rsp),%rdi
+ movq TF_RSI(%rsp),%rsi
+ movq TF_R8(%rsp),%r8
+ movq TF_R9(%rsp),%r9
+ movq TF_R10(%rsp),%r10
+ movq TF_R12(%rsp),%r12
+ movq TF_R13(%rsp),%r13
+ movq TF_R14(%rsp),%r14
+ movq TF_R15(%rsp),%r15
+ movq TF_RBP(%rsp),%rbp
+ movq TF_RBX(%rsp),%rbx
+
INTR_RESTORE_SELECTORS
- INTR_RESTORE_GPRS
- addq $48,%rsp
- popq %rcx /* return rip */
- addq $8,%rsp
- popq %r11 /* flags as set by sysret insn */
- movq %ss:(%rsp),%rsp
+
+ movq TF_RDX(%rsp),%rdx
+ movq TF_RAX(%rsp),%rax
+
+ movq TF_RIP(%rsp),%rcx
+ movq TF_RFLAGS(%rsp),%r11
+ movq TF_RSP(%rsp),%rsp
sysretq
#ifdef DIAGNOSTIC
@@ -1007,11 +1012,9 @@ NENTRY(child_trampoline)
call *%r12
jmp syscall_return
- .globl _C_LABEL(osyscall_return)
-
/*
- * Trap gate entry for int $80 syscall, also used by sigreturn.
+ * Trap gate entry for old int $80 syscall (used to be used by sigreturn)
*/
IDTVEC(osyscall)
pushq $2 # size of instruction for restart
@@ -1035,6 +1038,9 @@ _C_LABEL(osyscall_return):
call _C_LABEL(trap)
jmp 2b
+/*
+ * Return via iretq, for real interrupts and signal returns
+ */
iret_return:
1:
#ifdef DIAGNOSTIC
@@ -1043,11 +1049,29 @@ iret_return:
#endif /* DIAGNOSTIC */
.globl intr_fast_exit
intr_fast_exit:
+ movq TF_RDI(%rsp),%rdi
+ movq TF_RSI(%rsp),%rsi
+ movq TF_R8(%rsp),%r8
+ movq TF_R9(%rsp),%r9
+ movq TF_R10(%rsp),%r10
+ movq TF_R12(%rsp),%r12
+ movq TF_R13(%rsp),%r13
+ movq TF_R14(%rsp),%r14
+ movq TF_R15(%rsp),%r15
+ movq TF_RBP(%rsp),%rbp
+ movq TF_RBX(%rsp),%rbx
+
testq $SEL_UPL,TF_CS(%rsp)
je 5f
+
INTR_RESTORE_SELECTORS
-5: INTR_RESTORE_GPRS
- addq $48,%rsp
+
+5: movq TF_RDX(%rsp),%rdx
+ movq TF_RCX(%rsp),%rcx
+ movq TF_R11(%rsp),%r11
+ movq TF_RAX(%rsp),%rax
+ addq $TF_RIP,%rsp
+
.globl _C_LABEL(doreti_iret)
_C_LABEL(doreti_iret):
iretq
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 321859c3889..d18fd2ed792 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.146 2011/07/04 06:05:56 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.147 2011/07/04 15:54:24 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -670,6 +670,16 @@ sys_sigreturn(struct proc *p, void *v, register_t *retval)
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ksc.sc_mask & ~sigcantmask;
+ /*
+ * sigreturn() needs to return to userspace via the 'iretq'
+ * method, so that if the process was interrupted (by tick,
+ * an IPI, whatever) as opposed to already being in the kernel
+ * when a signal was being delivered, the process will be
+ * completely restored, including the userland %rcx and %r11
+ * registers which the 'sysretq' instruction cannot restore.
+ */
+ p->p_md.md_flags |= MDP_IRET;
+
return (EJUSTRETURN);
}
diff --git a/sys/arch/amd64/include/frameasm.h b/sys/arch/amd64/include/frameasm.h
index 57fb5bff2c8..83388ab874d 100644
--- a/sys/arch/amd64/include/frameasm.h
+++ b/sys/arch/amd64/include/frameasm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: frameasm.h,v 1.5 2011/04/13 02:49:12 guenther Exp $ */
+/* $OpenBSD: frameasm.h,v 1.6 2011/07/04 15:54:24 guenther Exp $ */
/* $NetBSD: frameasm.h,v 1.1 2003/04/26 18:39:40 fvdl Exp $ */
#ifndef _AMD64_MACHINE_FRAMEASM_H
@@ -30,24 +30,6 @@
movq %rcx,TF_RCX(%rsp) ; \
movq %rax,TF_RAX(%rsp)
-#define INTR_RESTORE_GPRS \
- movq TF_R15(%rsp),%r15 ; \
- movq TF_R14(%rsp),%r14 ; \
- movq TF_R13(%rsp),%r13 ; \
- movq TF_R12(%rsp),%r12 ; \
- movq TF_R11(%rsp),%r11 ; \
- movq TF_R10(%rsp),%r10 ; \
- movq TF_R9(%rsp),%r9 ; \
- movq TF_R8(%rsp),%r8 ; \
- movq TF_RDI(%rsp),%rdi ; \
- movq TF_RSI(%rsp),%rsi ; \
- movq TF_RBP(%rsp),%rbp ; \
- movq TF_RBX(%rsp),%rbx ; \
- movq TF_RDX(%rsp),%rdx ; \
- movq TF_RCX(%rsp),%rcx ; \
- movq TF_RAX(%rsp),%rax ; \
- addq $120,%rsp
-
#define INTRENTRY \
subq $32,%rsp ; \
testq $SEL_UPL,56(%rsp) ; \