diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 5c74a6b42119..ddda13a17c47 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -1602,20 +1602,23 @@ vmx_emulate_cr4_access(struct vmx *vmx, int vcpu, uint64_t exitqual) 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); diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c index c4b5e210079a..3c9346334f5a 100644 --- a/sys/amd64/vmm/io/vlapic.c +++ b/sys/amd64/vmm/io/vlapic.c @@ -906,6 +906,46 @@ vlapic_calcdest(struct vm *vm, cpuset_t *dmask, uint32_t dest, bool phys, 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 *vlapic, uint32_t dest, bool phys, 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); -} diff --git a/sys/amd64/vmm/io/vlapic.h b/sys/amd64/vmm/io/vlapic.h index ba7b8d1daa62..0e68b2fe8243 100644 --- a/sys/amd64/vmm/io/vlapic.h +++ b/sys/amd64/vmm/io/vlapic.h @@ -92,8 +92,8 @@ void vlapic_reset_tmr(struct vlapic *vlapic); 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);