Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 May 2014 17:22:37 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r266550 - head/sys/amd64/vmm/intel
Message-ID:  <201405221722.s4MHMbBW064319@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Thu May 22 17:22:37 2014
New Revision: 266550
URL: http://svnweb.freebsd.org/changeset/base/266550

Log:
  Allow vmx_getdesc() and vmx_setdesc() to be called for a vcpu that is in the
  VCPU_RUNNING state. This will let the VMX exit handler inspect the vcpu's
  segment descriptors without having to exit the critical section.

Modified:
  head/sys/amd64/vmm/intel/vmcs.c
  head/sys/amd64/vmm/intel/vmcs.h
  head/sys/amd64/vmm/intel/vmx.c

Modified: head/sys/amd64/vmm/intel/vmcs.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmcs.c	Thu May 22 16:36:01 2014	(r266549)
+++ head/sys/amd64/vmm/intel/vmcs.c	Thu May 22 17:22:37 2014	(r266550)
@@ -231,7 +231,7 @@ vmcs_setreg(struct vmcs *vmcs, int runni
 }
 
 int
-vmcs_setdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc)
+vmcs_setdesc(struct vmcs *vmcs, int running, int seg, struct seg_desc *desc)
 {
 	int error;
 	uint32_t base, limit, access;
@@ -240,7 +240,8 @@ vmcs_setdesc(struct vmcs *vmcs, int seg,
 	if (error != 0)
 		panic("vmcs_setdesc: invalid segment register %d", seg);
 
-	VMPTRLD(vmcs);
+	if (!running)
+		VMPTRLD(vmcs);
 	if ((error = vmwrite(base, desc->base)) != 0)
 		goto done;
 
@@ -252,12 +253,13 @@ vmcs_setdesc(struct vmcs *vmcs, int seg,
 			goto done;
 	}
 done:
-	VMCLEAR(vmcs);
+	if (!running)
+		VMCLEAR(vmcs);
 	return (error);
 }
 
 int
-vmcs_getdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc)
+vmcs_getdesc(struct vmcs *vmcs, int running, int seg, struct seg_desc *desc)
 {
 	int error;
 	uint32_t base, limit, access;
@@ -267,7 +269,8 @@ vmcs_getdesc(struct vmcs *vmcs, int seg,
 	if (error != 0)
 		panic("vmcs_getdesc: invalid segment register %d", seg);
 
-	VMPTRLD(vmcs);
+	if (!running)
+		VMPTRLD(vmcs);
 	if ((error = vmread(base, &u64)) != 0)
 		goto done;
 	desc->base = u64;
@@ -282,7 +285,8 @@ vmcs_getdesc(struct vmcs *vmcs, int seg,
 		desc->access = u64;
 	}
 done:
-	VMCLEAR(vmcs);
+	if (!running)
+		VMCLEAR(vmcs);
 	return (error);
 }
 

Modified: head/sys/amd64/vmm/intel/vmcs.h
==============================================================================
--- head/sys/amd64/vmm/intel/vmcs.h	Thu May 22 16:36:01 2014	(r266549)
+++ head/sys/amd64/vmm/intel/vmcs.h	Thu May 22 17:22:37 2014	(r266550)
@@ -49,9 +49,9 @@ int vmcs_set_msr_save(struct vmcs *vmcs,
 int	vmcs_init(struct vmcs *vmcs);
 int	vmcs_getreg(struct vmcs *vmcs, int running, int ident, uint64_t *rv);
 int	vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val);
-int	vmcs_getdesc(struct vmcs *vmcs, int ident,
+int	vmcs_getdesc(struct vmcs *vmcs, int running, int ident,
 		     struct seg_desc *desc);
-int	vmcs_setdesc(struct vmcs *vmcs, int ident,
+int	vmcs_setdesc(struct vmcs *vmcs, int running, int ident,
 		     struct seg_desc *desc);
 
 static __inline uint64_t

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c	Thu May 22 16:36:01 2014	(r266549)
+++ head/sys/amd64/vmm/intel/vmx.c	Thu May 22 17:22:37 2014	(r266550)
@@ -2409,17 +2409,27 @@ vmx_setreg(void *arg, int vcpu, int reg,
 static int
 vmx_getdesc(void *arg, int vcpu, int reg, struct seg_desc *desc)
 {
+	int hostcpu, running;
 	struct vmx *vmx = arg;
 
-	return (vmcs_getdesc(&vmx->vmcs[vcpu], reg, desc));
+	running = vcpu_is_running(vmx->vm, vcpu, &hostcpu);
+	if (running && hostcpu != curcpu)
+		panic("vmx_getdesc: %s%d is running", vm_name(vmx->vm), vcpu);
+
+	return (vmcs_getdesc(&vmx->vmcs[vcpu], running, reg, desc));
 }
 
 static int
 vmx_setdesc(void *arg, int vcpu, int reg, struct seg_desc *desc)
 {
+	int hostcpu, running;
 	struct vmx *vmx = arg;
 
-	return (vmcs_setdesc(&vmx->vmcs[vcpu], reg, desc));
+	running = vcpu_is_running(vmx->vm, vcpu, &hostcpu);
+	if (running && hostcpu != curcpu)
+		panic("vmx_setdesc: %s%d is running", vm_name(vmx->vm), vcpu);
+
+	return (vmcs_setdesc(&vmx->vmcs[vcpu], running, reg, desc));
 }
 
 static int



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