diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index ee892fbee..9a50a33fb 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -862,9 +862,9 @@ vlapic_trigger_lvt(struct acrn_vlapic *vlapic, uint32_t lvt_index) { uint32_t lvt; int32_t ret = 0; + struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic); if (!vlapic_enabled(vlapic)) { - struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic); /* * When the local APIC is global/hardware disabled, * LINT[1:0] pins are configured as INTR and NMI pins, @@ -906,7 +906,12 @@ vlapic_trigger_lvt(struct acrn_vlapic *vlapic, uint32_t lvt_index) lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_PERF_LVT); break; case APIC_LVT_THERMAL: - lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_THERM_LVT); + if (is_vtm_configured(vcpu->vm)) { + lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_THERM_LVT); + } else { + lvt = 0U; + ret = -EINVAL; + } break; case APIC_LVT_CMCI: lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_CMCI_LVT); @@ -1530,7 +1535,6 @@ static int32_t vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset, uint64_ break; } /* falls through */ - default: ret = -EACCES; /* Read only */ @@ -2123,6 +2127,7 @@ int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val) switch (msr) { case MSR_IA32_EXT_APIC_LDR: case MSR_IA32_EXT_XAPICID: + case MSR_IA32_EXT_APIC_LVT_THERMAL: offset = x2apic_msr_to_regoff(msr); error = vlapic_read(vlapic, offset, val); break; @@ -2158,6 +2163,10 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val) case MSR_IA32_EXT_APIC_ICR: error = vlapic_x2apic_pt_icr_access(vcpu, val); break; + case MSR_IA32_EXT_APIC_LVT_THERMAL: + offset = x2apic_msr_to_regoff(msr); + error = vlapic_write(vlapic, offset, val); + break; default: pr_err("%s: unexpected MSR[0x%x] write with lapic_pt", __func__, msr); break; diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 4a60f8326..96fec9143 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -223,6 +223,16 @@ bool is_vhwp_configured(const struct acrn_vm *vm) return ((vm_config->guest_flags & GUEST_FLAG_VHWP) != 0U); } +/** + * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM + */ +bool is_vtm_configured(const struct acrn_vm *vm) +{ + struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); + + return ((vm_config->guest_flags & GUEST_FLAG_VTM) != 0U); +} + /** * @brief VT-d PI posted mode can possibly be used for PTDEVs assigned * to this VM if platform supports VT-d PI AND lapic passthru is not configured diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 715b29735..3d9670464 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -1314,5 +1314,8 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu) enable_msr_interception(msr_bitmap, MSR_IA32_EXT_XAPICID, INTERCEPT_READ); enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_LDR, INTERCEPT_READ); enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_ICR, INTERCEPT_WRITE); + if (!is_vtm_configured(vcpu->vm)) { + enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_LVT_THERMAL, INTERCEPT_READ_WRITE); + } set_tsc_msr_interception(vcpu, exec_vmread64(VMX_TSC_OFFSET_FULL) != 0UL); } diff --git a/hypervisor/include/arch/x86/asm/guest/vm.h b/hypervisor/include/arch/x86/asm/guest/vm.h index de7cd090c..d77f8e3c2 100644 --- a/hypervisor/include/arch/x86/asm/guest/vm.h +++ b/hypervisor/include/arch/x86/asm/guest/vm.h @@ -275,6 +275,7 @@ bool vm_hide_mtrr(const struct acrn_vm *vm); void update_vm_vlapic_state(struct acrn_vm *vm); enum vm_vlapic_mode check_vm_vlapic_mode(const struct acrn_vm *vm); bool is_vhwp_configured(const struct acrn_vm *vm); +bool is_vtm_configured(const struct acrn_vm *vm); /* * @pre vm != NULL */ diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index 3c6e4e87a..7c769f28c 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -64,6 +64,7 @@ #define GUEST_FLAG_REE (1UL << 10U) /* Whether the VM is REE VM */ #define GUEST_FLAG_PMU_PASSTHROUGH (1UL << 11U) /* Whether PMU is passed through */ #define GUEST_FLAG_VHWP (1UL << 12U) /* Whether the VM supports vHWP */ +#define GUEST_FLAG_VTM (1UL << 13U) /* Whether the VM supports virtual thermal monitor */ /* TODO: We may need to get this addr from guest ACPI instead of hardcode here */ #define VIRTUAL_SLEEP_CTL_ADDR 0x400U /* Pre-launched VM uses ACPI reduced HW mode and sleep control register */