svn commit: r338837 - head/sys/amd64/amd64

Mateusz Guzik mjg at FreeBSD.org
Thu Sep 20 18:30:18 UTC 2018


Author: mjg
Date: Thu Sep 20 18:30:17 2018
New Revision: 338837
URL: https://svnweb.freebsd.org/changeset/base/338837

Log:
  amd64: macroify copyin/copyout and provide erms variants
  
  Reviewed by:	kib
  Approved by:	re (gjb)
  Differential Revision:	https://reviews.freebsd.org/D17257

Modified:
  head/sys/amd64/amd64/copyout.c
  head/sys/amd64/amd64/support.S

Modified: head/sys/amd64/amd64/copyout.c
==============================================================================
--- head/sys/amd64/amd64/copyout.c	Thu Sep 20 18:29:55 2018	(r338836)
+++ head/sys/amd64/amd64/copyout.c	Thu Sep 20 18:30:17 2018	(r338837)
@@ -159,20 +159,41 @@ DEFINE_IFUNC(, int, copyinstr, (const void *, void *, 
 	    copyinstr_smap : copyinstr_nosmap);
 }
 
-int	copyin_nosmap(const void *udaddr, void *kaddr, size_t len);
-int	copyin_smap(const void *udaddr, void *kaddr, size_t len);
+int	copyin_nosmap_std(const void *udaddr, void *kaddr, size_t len);
+int	copyin_smap_std(const void *udaddr, void *kaddr, size_t len);
+int	copyin_nosmap_erms(const void *udaddr, void *kaddr, size_t len);
+int	copyin_smap_erms(const void *udaddr, void *kaddr, size_t len);
 DEFINE_IFUNC(, int, copyin, (const void *, void *, size_t), static)
 {
 
-	return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ?
-	    copyin_smap : copyin_nosmap);
+	switch (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS)) {
+	case CPUID_STDEXT_SMAP:
+		return (copyin_smap_std);
+	case CPUID_STDEXT_ERMS:
+		return (copyin_nosmap_erms);
+	case CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS:
+		return (copyin_smap_erms);
+	default:
+		return (copyin_nosmap_std);
+
+	}
 }
 
-int	copyout_nosmap(const void *kaddr, void *udaddr, size_t len);
-int	copyout_smap(const void *kaddr, void *udaddr, size_t len);
+int	copyout_nosmap_std(const void *kaddr, void *udaddr, size_t len);
+int	copyout_smap_std(const void *kaddr, void *udaddr, size_t len);
+int	copyout_nosmap_erms(const void *kaddr, void *udaddr, size_t len);
+int	copyout_smap_erms(const void *kaddr, void *udaddr, size_t len);
 DEFINE_IFUNC(, int, copyout, (const void *, void *, size_t), static)
 {
 
-	return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ?
-	    copyout_smap : copyout_nosmap);
+	switch (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS)) {
+	case CPUID_STDEXT_SMAP:
+		return (copyout_smap_std);
+	case CPUID_STDEXT_ERMS:
+		return (copyout_nosmap_erms);
+	case CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS:
+		return (copyout_smap_erms);
+	default:
+		return (copyout_nosmap_std);
+	}
 }

Modified: head/sys/amd64/amd64/support.S
==============================================================================
--- head/sys/amd64/amd64/support.S	Thu Sep 20 18:29:55 2018	(r338836)
+++ head/sys/amd64/amd64/support.S	Thu Sep 20 18:30:17 2018	(r338837)
@@ -281,62 +281,30 @@ END(fillw)
  * returns to *curpcb->pcb_onfault instead of the function.
  */
 
+.macro SMAP_DISABLE smap
+.if	\smap
+	stac
+.endif
+.endmacro
+
+
+.macro SMAP_ENABLE smap
+.if	\smap
+	clac
+.endif
+.endmacro
+
 /*
  * copyout(from_kernel, to_user, len)
  *         %rdi,        %rsi,    %rdx
  */
-ENTRY(copyout_nosmap)
+.macro	COPYOUT smap erms
 	PUSH_FRAME_POINTER
 	movq	PCPU(CURPCB),%rax
-	movq	$copyout_fault,PCB_ONFAULT(%rax)
-	testq	%rdx,%rdx			/* anything to do? */
-	jz	done_copyout
-
-	/*
-	 * Check explicitly for non-user addresses.  This check is essential
-	 * because it prevents usermode from writing into the kernel.  We do
-	 * not verify anywhere else that the user did not specify a rogue
-	 * address.
-	 */
-	/*
-	 * First, prevent address wrapping.
-	 */
-	movq	%rsi,%rax
-	addq	%rdx,%rax
-	jc	copyout_fault
-/*
- * XXX STOP USING VM_MAXUSER_ADDRESS.
- * It is an end address, not a max, so every time it is used correctly it
- * looks like there is an off by one error, and of course it caused an off
- * by one error in several places.
- */
-	movq	$VM_MAXUSER_ADDRESS,%rcx
-	cmpq	%rcx,%rax
-	ja	copyout_fault
-
-	xchgq	%rdi,%rsi
-	/* bcopy(%rsi, %rdi, %rdx) */
-	movq	%rdx,%rcx
-
-	shrq	$3,%rcx
-	rep
-	movsq
-	movb	%dl,%cl
-	andb	$7,%cl
-	je	done_copyout
-	rep
-	movsb
-
-	jmp	done_copyout
-END(copyout_nosmap)
-
-ENTRY(copyout_smap)
-	PUSH_FRAME_POINTER
-	movq	PCPU(CURPCB),%rax
 	/* Trap entry clears PSL.AC */
 	movq	$copyout_fault,PCB_ONFAULT(%rax)
 	testq	%rdx,%rdx			/* anything to do? */
-	jz	done_copyout
+	jz	2f
 
 	/*
 	 * Check explicitly for non-user addresses.  If 486 write protection
@@ -365,24 +333,43 @@ ENTRY(copyout_smap)
 	/* bcopy(%rsi, %rdi, %rdx) */
 	movq	%rdx,%rcx
 
+	SMAP_DISABLE \smap
+.if	\erms == 0
 	shrq	$3,%rcx
-	stac
 	rep
 	movsq
 	movb	%dl,%cl
 	andb	$7,%cl
 	je	1f
+.endif
 	rep
 	movsb
-1:	clac
-
-done_copyout:
+1:
+	SMAP_ENABLE \smap
+2:
 	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rdx
 	movq	%rax,PCB_ONFAULT(%rdx)
 	POP_FRAME_POINTER
 	ret
+.endmacro
 
+ENTRY(copyout_nosmap_std)
+	COPYOUT smap=0 erms=0
+END(copyout_nosmap_std)
+
+ENTRY(copyout_smap_std)
+	COPYOUT smap=1 erms=0
+END(copyout_smap_std)
+
+ENTRY(copyout_nosmap_erms)
+	COPYOUT smap=0 erms=1
+END(copyout_nosmap_erms)
+
+ENTRY(copyout_smap_erms)
+	COPYOUT smap=1 erms=1
+END(copyout_smap_erms)
+
 	ALIGN_TEXT
 copyout_fault:
 	movq	PCPU(CURPCB),%rdx
@@ -390,18 +377,17 @@ copyout_fault:
 	movq	$EFAULT,%rax
 	POP_FRAME_POINTER
 	ret
-END(copyout_smap)
 
 /*
  * copyin(from_user, to_kernel, len)
  *        %rdi,      %rsi,      %rdx
  */
-ENTRY(copyin_nosmap)
+.macro	COPYIN smap erms
 	PUSH_FRAME_POINTER
 	movq	PCPU(CURPCB),%rax
 	movq	$copyin_fault,PCB_ONFAULT(%rax)
 	testq	%rdx,%rdx			/* anything to do? */
-	jz	done_copyin
+	jz	2f
 
 	/*
 	 * make sure address is valid
@@ -416,56 +402,44 @@ ENTRY(copyin_nosmap)
 	xchgq	%rdi,%rsi
 	movq	%rdx,%rcx
 	movb	%cl,%al
-	shrq	$3,%rcx				/* copy longword-wise */
-	rep
-	movsq
-	movb	%al,%cl
-	andb	$7,%cl				/* copy remaining bytes */
-	je	done_copyin
-	rep
-	movsb
 
-	jmp	done_copyin
-END(copyin_nosmap)
-
-ENTRY(copyin_smap)
-	PUSH_FRAME_POINTER
-	movq	PCPU(CURPCB),%rax
-	movq	$copyin_fault,PCB_ONFAULT(%rax)
-	testq	%rdx,%rdx			/* anything to do? */
-	jz	done_copyin
-
-	/*
-	 * make sure address is valid
-	 */
-	movq	%rdi,%rax
-	addq	%rdx,%rax
-	jc	copyin_fault
-	movq	$VM_MAXUSER_ADDRESS,%rcx
-	cmpq	%rcx,%rax
-	ja	copyin_fault
-
-	xchgq	%rdi,%rsi
-	movq	%rdx,%rcx
-	movb	%cl,%al
+	SMAP_DISABLE \smap
+.if \erms == 0
 	shrq	$3,%rcx				/* copy longword-wise */
-	stac
 	rep
 	movsq
 	movb	%al,%cl
 	andb	$7,%cl				/* copy remaining bytes */
-	je	1f
+	je	1
+.endif
 	rep
 	movsb
-1:	clac
 
-done_copyin:
+1:
+	SMAP_ENABLE \smap
+2:
 	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rdx
 	movq	%rax,PCB_ONFAULT(%rdx)
 	POP_FRAME_POINTER
 	ret
-END(copyin_smap)
+.endmacro
+
+ENTRY(copyin_nosmap_std)
+	COPYIN smap=0 erms=0
+END(copyin_nosmap_std)
+
+ENTRY(copyin_smap_std)
+	COPYIN smap=1 erms=0
+END(copyin_smap_std)
+
+ENTRY(copyin_nosmap_erms)
+	COPYIN smap=0 erms=1
+END(copyin_nosmap_erms)
+
+ENTRY(copyin_smap_erms)
+	COPYIN smap=1 erms=1
+END(copyin_smap_erms)
 
 	ALIGN_TEXT
 copyin_fault:


More information about the svn-src-head mailing list