mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 13:37:10 +00:00
hv: save/restore TSC in host's suspend/resume path
TSC would be reset to 0 when enter suspend state on some platform. This will fail the secure timer checking in secure world because secure world leverage the TSC as source of secure timer which should be increased monotonously. This patch save/restore TSC in host suspend/resume path to guarantee the mono increasing TSC. Note: There should no timer setup before TSC resumed. Tracked-On: #3698 Signed-off-by: Qi Yadong <yadong.qi@intel.com> Reviewed-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
89ef00c689
commit
21af6c84a4
@ -120,6 +120,16 @@ void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
|
||||
} while ((s1 & (1U << BIT_WAK_STS)) == 0U);
|
||||
}
|
||||
|
||||
static void suspend_tsc(__unused void *data)
|
||||
{
|
||||
per_cpu(tsc_suspend, get_cpu_id()) = rdtsc();
|
||||
}
|
||||
|
||||
static void resume_tsc(__unused void *data)
|
||||
{
|
||||
msr_write(MSR_IA32_TIME_STAMP_COUNTER, per_cpu(tsc_suspend, get_cpu_id()));
|
||||
}
|
||||
|
||||
void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
{
|
||||
uint64_t pmain_entry_saved;
|
||||
@ -144,6 +154,10 @@ void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
(uint32_t) trampoline_start16_paddr;
|
||||
|
||||
clac();
|
||||
|
||||
/* Save TSC on all PCPU */
|
||||
smp_call_function(pcpu_active_bitmap, suspend_tsc, NULL);
|
||||
|
||||
/* offline all APs */
|
||||
stop_cpus();
|
||||
|
||||
@ -171,7 +185,6 @@ void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
resume_lapic();
|
||||
resume_iommu();
|
||||
resume_ioapic();
|
||||
resume_console();
|
||||
|
||||
exec_vmxon_instr(pcpu_id);
|
||||
CPU_IRQ_ENABLE();
|
||||
@ -184,6 +197,14 @@ void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
/* online all APs again */
|
||||
start_cpus();
|
||||
|
||||
/* Restore TSC on all PCPU
|
||||
* Caution: There should no timer setup before TSC resumed.
|
||||
*/
|
||||
smp_call_function(pcpu_active_bitmap, resume_tsc, NULL);
|
||||
|
||||
/* console must be resumed after TSC restored since it will setup timer base on TSC */
|
||||
resume_console();
|
||||
|
||||
/* jump back to vm */
|
||||
resume_vm_from_s3(vm, guest_wakeup_vec32);
|
||||
} else {
|
||||
|
@ -51,6 +51,7 @@ struct per_cpu_region {
|
||||
#ifdef PROFILING_ON
|
||||
struct profiling_info_wrapper profiling_info;
|
||||
#endif
|
||||
uint64_t tsc_suspend;
|
||||
} __aligned(PAGE_SIZE); /* per_cpu_region size aligned with PAGE_SIZE */
|
||||
|
||||
extern struct per_cpu_region per_cpu_data[];
|
||||
|
Loading…
Reference in New Issue
Block a user