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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to