diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 78a82b98c..9ec000d0d 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -427,8 +427,18 @@ static void vlapic_icrtmr_write_handler(struct acrn_vlapic *vlapic) uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic) { uint64_t ret; + if (is_lapic_pt_enabled(vlapic->vcpu)) { - ret = msr_read(MSR_IA32_TSC_DEADLINE) + exec_vmread64(VMX_TSC_OFFSET_FULL); + /* If physical TSC_DEADLINE is zero which means it's not armed (automatically disarmed + * after timer triggered), return 0 and reset the virtual TSC_DEADLINE; + * If physical TSC_DEADLINE is not zero, return the virtual TSC_DEADLINE value. + */ + if (msr_read(MSR_IA32_TSC_DEADLINE) == 0UL) { + vcpu_set_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE, 0UL); + ret = 0UL; + } else { + ret = vcpu_get_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE); + } } else if (!vlapic_lvtt_tsc_deadline(vlapic)) { ret = 0UL; } else { @@ -437,7 +447,6 @@ uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic) } return ret; - } void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg) @@ -447,8 +456,21 @@ void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg) if (is_lapic_pt_enabled(vlapic->vcpu)) { vcpu_set_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE, val); - val -= exec_vmread64(VMX_TSC_OFFSET_FULL); - msr_write(MSR_IA32_TSC_DEADLINE, val); + /* If val is not zero, which mean guest intends to arm the tsc_deadline timer, + * if the calculated value to write to the physical TSC_DEADLINE msr is zero, + * we plus 1 to not disarm the physcial timer falsely; + * If val is zero, which means guest intends to disarm the tsc_deadline timer, + * we disarm the physical timer. + */ + if (val != 0UL) { + val -= exec_vmread64(VMX_TSC_OFFSET_FULL); + if (val == 0UL) { + val += 1UL; + } + msr_write(MSR_IA32_TSC_DEADLINE, val); + } else { + msr_write(MSR_IA32_TSC_DEADLINE, 0); + } } else if (vlapic_lvtt_tsc_deadline(vlapic)) { vcpu_set_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE, val);