From cbf3825140c6ba7017ceb65be4e948c9fb12c820 Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Mon, 5 Jul 2021 11:39:17 -0700 Subject: [PATCH] hv: Pass-through IA32_TSC_AUX MSR to L1 guest Use an unused MSR on host to save ACRN pcpu ID and avoid saving and restoring TSC AUX MSR on VMX transitions. Tracked-On: #6289 Signed-off-by: Sainath Grandhi Signed-off-by: Zide Chen Reviewed-by: Eddie Dong --- hypervisor/arch/x86/cpu.c | 2 +- hypervisor/arch/x86/guest/vmcs.c | 4 +++- hypervisor/arch/x86/guest/vmsr.c | 6 ------ hypervisor/include/arch/x86/asm/cpu.h | 8 ++++---- hypervisor/include/arch/x86/asm/guest/vcpu.h | 3 +-- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 242eac2e4..bcbeb6d6e 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -490,7 +490,7 @@ void cpu_dead(void) static void set_current_pcpu_id(uint16_t pcpu_id) { /* Write TSC AUX register */ - msr_write(MSR_IA32_TSC_AUX, (uint64_t) pcpu_id); + msr_write(ACRN_PSEUDO_PCPUID_MSR, (uint32_t) pcpu_id); } static void print_hv_banner(void) diff --git a/hypervisor/arch/x86/guest/vmcs.c b/hypervisor/arch/x86/guest/vmcs.c index e7f66a24b..3befea2e4 100644 --- a/hypervisor/arch/x86/guest/vmcs.c +++ b/hypervisor/arch/x86/guest/vmcs.c @@ -204,9 +204,11 @@ void init_host_state(void) pr_dbg("vm exit return address = %016lx ", value64); /* As a type I hypervisor, just init sysenter fields to 0 */ - exec_vmwrite32(VMX_HOST_IA32_SYSENTER_CS, 0U); exec_vmwrite(VMX_HOST_IA32_SYSENTER_ESP, 0UL); exec_vmwrite(VMX_HOST_IA32_SYSENTER_EIP, 0UL); + + /* We use IA32_SYSENTER_CS MSR to cache pCPU ID. */ + exec_vmwrite32(VMX_HOST_IA32_SYSENTER_CS, msr_read(ACRN_PSEUDO_PCPUID_MSR)); } static uint32_t check_vmx_ctrl(uint32_t msr, uint32_t ctrl_req) diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 28b37763e..96ce15151 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -314,12 +314,6 @@ static void prepare_auto_msr_area (struct acrn_vcpu *vcpu) vcpu->arch.msr_area.count = 0U; - vcpu->arch.msr_area.guest[MSR_AREA_TSC_AUX].msr_index = MSR_IA32_TSC_AUX; - vcpu->arch.msr_area.guest[MSR_AREA_TSC_AUX].value = vcpu->vcpu_id; - vcpu->arch.msr_area.host[MSR_AREA_TSC_AUX].msr_index = MSR_IA32_TSC_AUX; - vcpu->arch.msr_area.host[MSR_AREA_TSC_AUX].value = pcpuid_from_vcpu(vcpu); - vcpu->arch.msr_area.count++; - /* only load/restore MSR IA32_PQR_ASSOC when hv and guest have differnt settings */ if (is_platform_rdt_capable() && (vcpu_clos != hv_clos)) { vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC; diff --git a/hypervisor/include/arch/x86/asm/cpu.h b/hypervisor/include/arch/x86/asm/cpu.h index 999caea24..8152ba405 100644 --- a/hypervisor/include/arch/x86/asm/cpu.h +++ b/hypervisor/include/arch/x86/asm/cpu.h @@ -39,6 +39,7 @@ #define CPU_H #include #include +#include /* Define CPU stack alignment */ #define CPU_STACK_ALIGN 16UL @@ -630,16 +631,15 @@ cpu_rdtscp_execute(uint64_t *timestamp_ptr, uint32_t *cpu_id_ptr) CPU_RFLAGS_RESTORE(rflags); \ } +#define ACRN_PSEUDO_PCPUID_MSR MSR_IA32_SYSENTER_CS + /* * Macro to get CPU ID * @pre: the return CPU ID would never equal or large than phys_cpu_num. */ static inline uint16_t get_pcpu_id(void) { - uint32_t tsl, tsh, cpu_id; - - asm volatile ("rdtscp":"=a" (tsl), "=d"(tsh), "=c"(cpu_id)::); - return (uint16_t)cpu_id; + return (uint16_t)cpu_msr_read(ACRN_PSEUDO_PCPUID_MSR); } static inline uint64_t cpu_rsp_get(void) diff --git a/hypervisor/include/arch/x86/asm/guest/vcpu.h b/hypervisor/include/arch/x86/asm/guest/vcpu.h index 16403fbf9..807e8f7fb 100644 --- a/hypervisor/include/arch/x86/asm/guest/vcpu.h +++ b/hypervisor/include/arch/x86/asm/guest/vcpu.h @@ -197,8 +197,7 @@ struct msr_store_entry { } __aligned(16); enum { - MSR_AREA_TSC_AUX = 0, - MSR_AREA_IA32_PQR_ASSOC, + MSR_AREA_IA32_PQR_ASSOC = 0, MSR_AREA_COUNT, };