svn commit: r267300 - in head/sys/amd64/vmm: intel io

Neel Natu neel at FreeBSD.org
Mon Jun 9 20:51:10 UTC 2014


Author: neel
Date: Mon Jun  9 20:51:08 2014
New Revision: 267300
URL: http://svnweb.freebsd.org/changeset/base/267300

Log:
  Add reserved bit checking when doing %CR8 emulation and inject #GP if required.
  
  Pointed out by:	grehan
  Reviewed by:	tychon

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

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c	Mon Jun  9 20:50:49 2014	(r267299)
+++ head/sys/amd64/vmm/intel/vmx.c	Mon Jun  9 20:51:08 2014	(r267300)
@@ -1602,20 +1602,23 @@ vmx_emulate_cr4_access(struct vmx *vmx, 
 static int
 vmx_emulate_cr8_access(struct vmx *vmx, int vcpu, uint64_t exitqual)
 {
-	uint64_t regval;
+	struct vlapic *vlapic;
+	uint64_t cr8;
+	int regnum;
 
 	/* We only handle mov %cr8 to/from a register at this time. */
 	if ((exitqual & 0xe0) != 0x00) {
 		return (UNHANDLED);
 	}
 
+	vlapic = vm_lapic(vmx->vm, vcpu);
+	regnum = (exitqual >> 8) & 0xf;
 	if (exitqual & 0x10) {
-		regval = vlapic_get_tpr(vm_lapic(vmx->vm, vcpu));
-		vmx_set_guest_reg(vmx, vcpu, (exitqual >> 8) & 0xf,
-				  regval >> 4);
+		cr8 = vlapic_get_cr8(vlapic);
+		vmx_set_guest_reg(vmx, vcpu, regnum, cr8);
 	} else {
-		regval = vmx_get_guest_reg(vmx, vcpu, (exitqual >> 8) & 0xf);
-		vlapic_set_tpr(vm_lapic(vmx->vm, vcpu), regval << 4);
+		cr8 = vmx_get_guest_reg(vmx, vcpu, regnum);
+		vlapic_set_cr8(vlapic, cr8);
 	}
 
 	return (HANDLED);

Modified: head/sys/amd64/vmm/io/vlapic.c
==============================================================================
--- head/sys/amd64/vmm/io/vlapic.c	Mon Jun  9 20:50:49 2014	(r267299)
+++ head/sys/amd64/vmm/io/vlapic.c	Mon Jun  9 20:51:08 2014	(r267300)
@@ -906,6 +906,46 @@ vlapic_calcdest(struct vm *vm, cpuset_t 
 
 static VMM_STAT_ARRAY(IPIS_SENT, VM_MAXCPU, "ipis sent to vcpu");
 
+static void
+vlapic_set_tpr(struct vlapic *vlapic, uint8_t val)
+{
+	struct LAPIC *lapic = vlapic->apic_page;
+
+	lapic->tpr = val;
+	vlapic_update_ppr(vlapic);
+}
+
+static uint8_t
+vlapic_get_tpr(struct vlapic *vlapic)
+{
+	struct LAPIC *lapic = vlapic->apic_page;
+
+	return (lapic->tpr);
+}
+
+void
+vlapic_set_cr8(struct vlapic *vlapic, uint64_t val)
+{
+	uint8_t tpr;
+
+	if (val & ~0xf) {
+		vm_inject_gp(vlapic->vm, vlapic->vcpuid);
+		return;
+	}
+
+	tpr = val << 4;
+	vlapic_set_tpr(vlapic, tpr);
+}
+
+uint64_t
+vlapic_get_cr8(struct vlapic *vlapic)
+{
+	uint8_t tpr;
+
+	tpr = vlapic_get_tpr(vlapic);
+	return (tpr >> 4);
+}
+
 int
 vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu)
 {
@@ -1610,20 +1650,3 @@ vlapic_set_tmr_level(struct vlapic *vlap
 	VLAPIC_CTR1(vlapic, "vector %d set to level-triggered", vector);
 	vlapic_set_tmr(vlapic, vector, true);
 }
-
-void
-vlapic_set_tpr(struct vlapic *vlapic, uint8_t val)
-{
-	struct LAPIC	*lapic = vlapic->apic_page;
-
-	lapic->tpr = val;
-	vlapic_update_ppr(vlapic);
-}
-
-uint8_t
-vlapic_get_tpr(struct vlapic *vlapic)
-{
-	struct LAPIC	*lapic = vlapic->apic_page;
-
-	return (lapic->tpr);
-}

Modified: head/sys/amd64/vmm/io/vlapic.h
==============================================================================
--- head/sys/amd64/vmm/io/vlapic.h	Mon Jun  9 20:50:49 2014	(r267299)
+++ head/sys/amd64/vmm/io/vlapic.h	Mon Jun  9 20:51:08 2014	(r267300)
@@ -92,8 +92,8 @@ void vlapic_reset_tmr(struct vlapic *vla
 void vlapic_set_tmr_level(struct vlapic *vlapic, uint32_t dest, bool phys,
     int delmode, int vector);
 
-void vlapic_set_tpr(struct vlapic *vlapic, uint8_t val);
-uint8_t vlapic_get_tpr(struct vlapic *vlapic);
+void vlapic_set_cr8(struct vlapic *vlapic, uint64_t val);
+uint64_t vlapic_get_cr8(struct vlapic *vlapic);
 
 /* APIC write handlers */
 void vlapic_id_write_handler(struct vlapic *vlapic);


More information about the svn-src-all mailing list