HV: Enable vART support by intercepting TSC_ADJUST MSR

The policy of vART is that software in native can run in
VM too. And in native side, the relationship between the
ART hardware and TSC is:

  pTSC = (pART * M) / N + pAdjust

The vART solution is:
  - Present the ART capability to guest through CPUID leaf
    15H for M/N which identical to the physical values.
  - PT devices see the pART (vART = pART).
  - Guest expect: vTSC = vART * M / N + vAdjust.
  - VMCS.OFFSET = vTSC - pTSC = vAdjust - pAdjust.

So to support vART, we should do the following:
  1. if vAdjust and vTSC are changed by guest, we should change
     VMCS.OFFSET accordingly.
  2. Make the assumption that the pAjust is never touched by ACRN.

For #1, commit "a958fea hv: emulate IA32_TSC_ADJUST MSR" has implementation
it. And for #2, acrn never touch pAdjust.

--
 v2 -> v3:
   - Add comment when handle guest TSC_ADJUST and TSC accessing.
   - Initialize the VMCS.OFFSET = vAdjust - pAdjust.

 v1 -> v2
   Refine commit message to describe the whole vART solution.

Tracked-On: #3501
Signed-off-by: Kaige Fu <kaige.fu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Kaige Fu 2019-07-24 13:37:59 +00:00 committed by ACRN System Integration
parent 4adc8102fd
commit accdadce98
2 changed files with 32 additions and 3 deletions

View File

@ -437,8 +437,11 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu)
/* Set up executive VMCS pointer - pg 2905 24.6.10 */
exec_vmwrite64(VMX_EXECUTIVE_VMCS_PTR_FULL, 0UL);
/* Setup Time stamp counter offset - pg 2902 24.6.5 */
exec_vmwrite64(VMX_TSC_OFFSET_FULL, 0UL);
/* Setup Time stamp counter offset - pg 2902 24.6.5
* VMCS.OFFSET = vAdjust - pAdjust
*/
value64 = vcpu_get_guest_msr(vcpu, MSR_IA32_TSC_ADJUST) - cpu_msr_read(MSR_IA32_TSC_ADJUST);
exec_vmwrite64(VMX_TSC_OFFSET_FULL, value64);
/* Set up the link pointer */
exec_vmwrite64(VMX_VMS_LINK_PTR_FULL, 0xFFFFFFFFFFFFFFFFUL);

View File

@ -456,6 +456,10 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
* IA32_TIME_STAMP_COUNTER MSR adds (or subtracts) value X from the
* TSC, the logical processor also adds (or subtracts) value X from
* the IA32_TSC_ADJUST MSR.
*
* So, here we should update VMCS.OFFSET and vAdjust accordingly.
* - VMCS.OFFSET = vTSC - pTSC
* - vAdjust += VMCS.OFFSET's delta
*/
/**
@ -478,10 +482,33 @@ static void set_guest_tsc(struct acrn_vcpu *vcpu, uint64_t guest_tsc)
exec_vmwrite64(VMX_TSC_OFFSET_FULL, tsc_delta);
}
/*
* The policy of vART is that software in native can run in VM too. And in native side,
* the relationship between the ART hardware and TSC is:
*
* pTSC = (pART * M) / N + pAdjust
*
* The vART solution is:
* - Present the ART capability to guest through CPUID leaf
* 15H for M/N which identical to the physical values.
* - PT devices see the pART (vART = pART).
* - Guest expect: vTSC = vART * M / N + vAdjust.
* - VMCS.OFFSET = vTSC - pTSC = vAdjust - pAdjust.
*
* So to support vART, we should do the following:
* 1. if vAdjust and vTSC are changed by guest, we should change
* VMCS.OFFSET accordingly.
* 2. Make the assumption that the pAjust is never touched by ACRN.
*/
/*
* Intel SDM 17.17.3: "If an execution of WRMSR to the IA32_TSC_ADJUST
* MSR adds (or subtracts) value X from that MSR, the logical
* processor also adds (or subtracts) value X from the TSC."
*
* So, here we should update VMCS.OFFSET and vAdjust accordingly.
* - VMCS.OFFSET += vAdjust's delta
* - vAdjust = new vAdjust set by guest
*/
/**
@ -728,5 +755,4 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu)
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_LDR, INTERCEPT_READ);
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_ICR, INTERCEPT_WRITE);
enable_msr_interception(msr_bitmap, MSR_IA32_TSC_DEADLINE, INTERCEPT_DISABLE);
enable_msr_interception(msr_bitmap, MSR_IA32_TSC_ADJUST, INTERCEPT_DISABLE);
}