Module Name:    src
Committed By:   maxv
Date:           Fri Sep 15 17:32:12 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: amd64_trap.S locore.S
        src/sys/arch/amd64/include: frameasm.h

Log Message:
Declare INTRFASTEXIT as a function, so that there is only one iretq in the
kernel. Then, check %rip against the address of this iretq instead of
disassembling (%rip) - which could fault again, or point at some random
address which happens to contain the iretq opcode. The same is true for gs
below, but I'll fix that in another commit.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/amd64/amd64/amd64_trap.S
cvs rdiff -u -r1.128 -r1.129 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/amd64/include/frameasm.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/amd64_trap.S
diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.10 src/sys/arch/amd64/amd64/amd64_trap.S:1.11
--- src/sys/arch/amd64/amd64/amd64_trap.S:1.10	Sun Sep  3 08:52:18 2017
+++ src/sys/arch/amd64/amd64/amd64_trap.S	Fri Sep 15 17:32:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: amd64_trap.S,v 1.10 2017/09/03 08:52:18 maxv Exp $	*/
+/*	$NetBSD: amd64_trap.S,v 1.11 2017/09/15 17:32:12 maxv Exp $	*/
 
 /*
  * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
 
 #if 0
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.10 2017/09/03 08:52:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.11 2017/09/15 17:32:12 maxv Exp $");
 #endif
 
 /*
@@ -385,9 +385,9 @@ NENTRY(check_swapgs)
 	je	1b
 
 	/* Case 2: fault on iretq? */
-	movq	TF_RIP(%rsp),%rax
-	cmpw	$0xcf48,(%rax)		/* Faulting instruction is iretq ? */
-	jne	5f			/* Jump if not */
+	leaq	do_iret(%rip),%rdi
+	cmpq	%rdi,TF_RIP(%rsp)
+	jne	5f
 	movq	TF_RSP(%rsp),%rax	/* Must read %rsp, may be a pad word */
 	testb	$SEL_UPL,8(%rax)	/* Check %cs of outer iret frame */
 	je	2b			/* jump if iret was to kernel  */
@@ -395,6 +395,7 @@ NENTRY(check_swapgs)
 5:
 
 	/* Case 3: move to %gs? */
+	movq	TF_RIP(%rsp),%rax
 	movw	(%rax),%ax
 	andb	$070,%ah		/* mask mod/rm from mod/reg/rm */
 	cmpw	$0x8e+050*256,%ax	/* Any move to %gs (reg 5) */

Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.128 src/sys/arch/amd64/amd64/locore.S:1.129
--- src/sys/arch/amd64/amd64/locore.S:1.128	Thu Aug 31 10:30:58 2017
+++ src/sys/arch/amd64/amd64/locore.S	Fri Sep 15 17:32:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.128 2017/08/31 10:30:58 maxv Exp $	*/
+/*	$NetBSD: locore.S,v 1.129 2017/09/15 17:32:12 maxv Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -329,6 +329,7 @@
 	.globl	_C_LABEL(biosbasemem)
 	.globl	_C_LABEL(biosextmem)
 	.globl	do_sysret
+	.globl	do_iret
 
 	.type	_C_LABEL(tablesize), @object
 _C_LABEL(tablesize):	.long	TABLESIZE
@@ -1304,12 +1305,19 @@ do_syscall:
 	jne	spl_error
 #endif
 
+	/*
+	 * If the syscall might have modified some registers, or we are a 32bit
+	 * process we must return to user with an 'iret' instruction.
+	 * If the iret faults in kernel (assumed due to illegal register values)
+	 * then a SIGSEGV will be signalled.
+	 */
 	testl	$(MDL_IRET|MDL_COMPAT32),L_MD_FLAGS(%r14)
 	INTR_RESTORE_GPRS
 	movw	TF_ES(%rsp),%es
 	movw	TF_DS(%rsp),%ds
 	SWAPGS
-	jnz	2f
+	jnz	.Lkexit
+
 #ifndef XEN
 	movq	TF_RIP(%rsp),%rcx	/* %rip for sysret */
 	movq	TF_RFLAGS(%rsp),%r11	/* %flags for sysret */
@@ -1322,16 +1330,6 @@ do_sysret:
 	jmp	HYPERVISOR_iret
 #endif
 
-/*
- * If the syscall might have modified some registers, or we are a 32bit
- * process we must return to user with an 'iret' instruction.
- * If the iret faults in kernel (assumed due to illegal register values)
- * then a SIGSEGV will be signalled.
- */
-2:
-	addq	$TF_RIP,%rsp
-	iretq
-
 #ifdef DIAGNOSTIC
 	/* Report SPL error */
 spl_error:
@@ -1441,7 +1439,6 @@ END(sse2_idlezero_page)
  *
  * Zero a page without polluting the cache.
  */
-
 ENTRY(pagezero)
 	movq	$-PAGE_SIZE,%rdx
 	subq	%rdx,%rdi
@@ -1460,3 +1457,21 @@ ENTRY(pagezero)
 	sfence
 	ret
 END(pagezero)
+
+ENTRY(intrfastexit)
+	INTR_RESTORE_GPRS
+	testq	$SEL_UPL,TF_CS(%rsp)	/* interrupted %cs */
+	jz	.Lkexit
+
+	/* Disable interrupts until the 'iret', user registers loaded. */
+	NOT_XEN(cli;)
+	movw	TF_ES(%rsp),%es
+	movw	TF_DS(%rsp),%ds
+	SWAPGS
+
+.Lkexit:
+	addq	$TF_REGSIZE+16,%rsp	/* + T_xxx and error code */
+do_iret:
+	iretq
+END(intrfastexit)
+

Index: src/sys/arch/amd64/include/frameasm.h
diff -u src/sys/arch/amd64/include/frameasm.h:1.20 src/sys/arch/amd64/include/frameasm.h:1.21
--- src/sys/arch/amd64/include/frameasm.h:1.20	Sun Jul 15 15:17:56 2012
+++ src/sys/arch/amd64/include/frameasm.h	Fri Sep 15 17:32:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: frameasm.h,v 1.20 2012/07/15 15:17:56 dsl Exp $	*/
+/*	$NetBSD: frameasm.h,v 1.21 2017/09/15 17:32:12 maxv Exp $	*/
 
 #ifndef _AMD64_MACHINE_FRAMEASM_H
 #define _AMD64_MACHINE_FRAMEASM_H
@@ -92,16 +92,7 @@ usertrap				; \
 98:
 
 #define INTRFASTEXIT \
-	INTR_RESTORE_GPRS 		; \
-	testq	$SEL_UPL,TF_CS(%rsp)	/* Interrupted %cs */ ; \
-	je	99f			; \
-/* Disable interrupts until the 'iret', user registers loaded. */ \
-	NOT_XEN(cli;)			  \
-	movw	TF_ES(%rsp),%es		; \
-	movw	TF_DS(%rsp),%ds		; \
-	SWAPGS				; \
-99:	addq	$TF_REGSIZE+16,%rsp	/* + T_xxx and error code */ ; \
-	iretq
+	jmp	intrfastexit
 
 #define INTR_RECURSE_HWFRAME \
 	movq	%rsp,%r10		; \

Reply via email to