hv: tlfs: add tlfs TSC freq MSR support for WaaG

TLFS defined 2 vMSRs which can be used by Windows guest to get the
TSC/APIC frequencies from hypervisor. This patch adds the support
of HV_X64_MSR_TSC_FREQUENCY/HV_X64_MSR_APIC_FREQUENCY vMSRS whose
availability is exposed by CPUID.0x40000003:EAX[bit11] and EDX[bit8].

v1->v2:
- revise commit message to highlight that the changes are for WaaG

Tracked-On: #7876
Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
This commit is contained in:
Jian Jun Chen 2022-07-05 15:51:32 +08:00 committed by acrnsi-robot
parent 97a2919138
commit c88860250e
3 changed files with 22 additions and 2 deletions

View File

@ -24,6 +24,10 @@
#define CPUID3A_VP_INDEX_MSR (1U << 6U)
/* Partition reference TSC MSR (HV_X64_MSR_REFERENCE_TSC) */
#define CPUID3A_REFERENCE_TSC_MSR (1U << 9U)
/* Partition local APIC and TSC frequency registers (HV_X64_MSR_TSC_FREQUENCY/HV_X64_MSR_APIC_FREQUENCY) */
#define CPUID3A_ACCESS_FREQUENCY_MSRS (1U << 11U)
/* Frequency MSRs available */
#define CPUID3D_FREQ_MSRS_AVAILABLE (1U << 8U)
struct HV_REFERENCE_TSC_PAGE {
uint32_t tsc_sequence;
@ -167,6 +171,8 @@ hyperv_wrmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t wval)
break;
case HV_X64_MSR_VP_INDEX:
case HV_X64_MSR_TIME_REF_COUNT:
case HV_X64_MSR_TSC_FREQUENCY:
case HV_X64_MSR_APIC_FREQUENCY:
/* read only */
/* fallthrough */
default:
@ -202,6 +208,13 @@ hyperv_rdmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *rval)
case HV_X64_MSR_REFERENCE_TSC:
*rval = vcpu->vm->arch_vm.hyperv.ref_tsc_page.val64;
break;
case HV_X64_MSR_TSC_FREQUENCY:
*rval = get_tsc_khz() * 1000UL;
break;
case HV_X64_MSR_APIC_FREQUENCY:
/* both KVM and XEN hardcode the APIC freq as 1GHz ... */
*rval = 1000000000UL;
break;
default:
pr_err("hv: %s: unexpected MSR[0x%x] read", __func__, msr);
ret = -1;
@ -264,10 +277,11 @@ hyperv_init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, uint32_t flags,
break;
case 0x40000003U: /* HV supported feature */
entry->eax = CPUID3A_HYPERCALL_MSR | CPUID3A_VP_INDEX_MSR |
CPUID3A_TIME_REF_COUNT_MSR | CPUID3A_REFERENCE_TSC_MSR;
CPUID3A_TIME_REF_COUNT_MSR | CPUID3A_REFERENCE_TSC_MSR |
CPUID3A_ACCESS_FREQUENCY_MSRS;
entry->ebx = 0U;
entry->ecx = 0U;
entry->edx = 0U;
entry->edx = CPUID3D_FREQ_MSRS_AVAILABLE;
break;
case 0x40000004U: /* HV Recommended hypercall usage */
entry->eax = 0U;

View File

@ -581,6 +581,8 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
case HV_X64_MSR_VP_INDEX:
case HV_X64_MSR_REFERENCE_TSC:
case HV_X64_MSR_TIME_REF_COUNT:
case HV_X64_MSR_TSC_FREQUENCY:
case HV_X64_MSR_APIC_FREQUENCY:
{
err = hyperv_rdmsr(vcpu, msr, &v);
break;
@ -943,6 +945,8 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu)
case HV_X64_MSR_VP_INDEX:
case HV_X64_MSR_REFERENCE_TSC:
case HV_X64_MSR_TIME_REF_COUNT:
case HV_X64_MSR_TSC_FREQUENCY:
case HV_X64_MSR_APIC_FREQUENCY:
{
err = hyperv_wrmsr(vcpu, msr, v);
break;

View File

@ -16,6 +16,8 @@
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020U
#define HV_X64_MSR_REFERENCE_TSC 0x40000021U
#define HV_X64_MSR_TSC_FREQUENCY 0x40000022U
#define HV_X64_MSR_APIC_FREQUENCY 0x40000023U
union hyperv_ref_tsc_page_msr {
uint64_t val64;