Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Nov 2012 02:43:41 +0000 (UTC)
From:      Peter Grehan <grehan@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r242654 - projects/bhyve/sys/amd64/vmm/intel
Message-ID:  <201211060243.qA62hfcc057117@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: grehan
Date: Tue Nov  6 02:43:41 2012
New Revision: 242654
URL: http://svnweb.freebsd.org/changeset/base/242654

Log:
  Fix issue found with clang build. Avoid code insertion by the compiler
  between inline asm statements that would in turn modify the flags
  value set by the first asm, and used by the second.
  
  Solve by making the common error block a string that can be pulled
  into the first inline asm, and using symbolic labels for asm variables.
  
  bhyve can now build/run fine when compiled with clang.
  
  Reviewed by:	neel
  Obtained from:	NetApp

Modified:
  projects/bhyve/sys/amd64/vmm/intel/vmx_cpufunc.h

Modified: projects/bhyve/sys/amd64/vmm/intel/vmx_cpufunc.h
==============================================================================
--- projects/bhyve/sys/amd64/vmm/intel/vmx_cpufunc.h	Tue Nov  6 02:20:44 2012	(r242653)
+++ projects/bhyve/sys/amd64/vmm/intel/vmx_cpufunc.h	Tue Nov  6 02:43:41 2012	(r242654)
@@ -42,18 +42,15 @@ struct vmcs;
 #define	VM_SUCCESS		0
 #define	VM_FAIL_INVALID		1
 #define	VM_FAIL_VALID		2
-#define	VMX_SET_ERROR_CODE(varname)					\
-	do {								\
-	__asm __volatile("	jnc 1f;"				\
-			 "	mov $1, %0;"	/* CF: error = 1 */	\
-			 "	jmp 3f;"				\
-			 "1:	jnz 2f;"				\
-			 "	mov $2, %0;"	/* ZF: error = 2 */	\
-			 "	jmp 3f;"				\
-			 "2:	mov $0, %0;"				\
-			 "3:	nop"					\
-			 :"=r" (varname));				\
-	} while (0)
+#define	VMX_SET_ERROR_CODE \
+	"	jnc 1f;"						\
+	"	mov $1, %[error];"	/* CF: error = 1 */		\
+	"	jmp 3f;"						\
+	"1:	jnz 2f;"						\
+	"	mov $2, %[error];"	/* ZF: error = 2 */		\
+	"	jmp 3f;"						\
+	"2:	mov $0, %[error];"					\
+	"3:"
 
 /* returns 0 on success and non-zero on failure */
 static __inline int
@@ -63,8 +60,12 @@ vmxon(char *region)
 	uint64_t addr;
 
 	addr = vtophys(region);
-	__asm __volatile("vmxon %0" : : "m" (*(uint64_t *)&addr) : "memory");
-	VMX_SET_ERROR_CODE(error);
+	__asm __volatile("vmxon %[addr];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [addr] "m" (*(uint64_t *)&addr)
+			 : "memory");
+
 	return (error);
 }
 
@@ -76,21 +77,26 @@ vmclear(struct vmcs *vmcs)
 	uint64_t addr;
 
 	addr = vtophys(vmcs);
-	__asm __volatile("vmclear %0" : : "m" (*(uint64_t *)&addr) : "memory");
-	VMX_SET_ERROR_CODE(error);
+	__asm __volatile("vmclear %[addr];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [addr] "m" (*(uint64_t *)&addr)
+			 : "memory");
 	return (error);
 }
 
 static __inline void
 vmxoff(void)
 {
+
 	__asm __volatile("vmxoff");
 }
 
 static __inline void
 vmptrst(uint64_t *addr)
 {
-	__asm __volatile("vmptrst %0" : : "m" (*addr) : "memory");
+
+	__asm __volatile("vmptrst %[addr]" :: [addr]"m" (*addr) : "memory");
 }
 
 static __inline int
@@ -100,8 +106,11 @@ vmptrld(struct vmcs *vmcs)
 	uint64_t addr;
 
 	addr = vtophys(vmcs);
-	__asm __volatile("vmptrld %0" : : "m" (*(uint64_t *)&addr) : "memory");
-	VMX_SET_ERROR_CODE(error);
+	__asm __volatile("vmptrld %[addr];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [addr] "m" (*(uint64_t *)&addr)
+			 : "memory");
 	return (error);
 }
 
@@ -110,9 +119,11 @@ vmwrite(uint64_t reg, uint64_t val)
 {
 	int error;
 
-	__asm __volatile("vmwrite %0, %1" : : "r" (val), "r" (reg) : "memory");
-
-	VMX_SET_ERROR_CODE(error);
+	__asm __volatile("vmwrite %[val], %[reg];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [val] "r" (val), [reg] "r" (reg)
+			 : "memory");
 
 	return (error);
 }
@@ -122,9 +133,11 @@ vmread(uint64_t r, uint64_t *addr)
 {
 	int error;
 
-	__asm __volatile("vmread %0, %1" : : "r" (r), "m" (*addr) : "memory");
-
-	VMX_SET_ERROR_CODE(error);
+	__asm __volatile("vmread %[r], %[addr];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [r] "r" (r), [addr] "m" (*addr)
+			 : "memory");
 
 	return (error);
 }
@@ -170,9 +183,12 @@ invvpid(uint64_t type, struct invvpid_de
 {
 	int error;
 
-	__asm __volatile("invvpid %0, %1" :: "m" (desc), "r" (type) : "memory");
+	__asm __volatile("invvpid %[desc], %[type];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [desc] "m" (desc), [type] "r" (type)
+			 : "memory");
 
-	VMX_SET_ERROR_CODE(error);
 	if (error)
 		panic("invvpid error %d", error);
 }
@@ -190,9 +206,12 @@ invept(uint64_t type, struct invept_desc
 {
 	int error;
 
-	__asm __volatile("invept %0, %1" :: "m" (desc), "r" (type) : "memory");
+	__asm __volatile("invept %[desc], %[type];"
+			 VMX_SET_ERROR_CODE
+			 : [error] "=r" (error)
+			 : [desc] "m" (desc), [type] "r" (type)
+			 : "memory");
 
-	VMX_SET_ERROR_CODE(error);
 	if (error)
 		panic("invept error %d", error);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211060243.qA62hfcc057117>