From 2aace19346708cc5a2d60b03a73cb8496443cc4a Mon Sep 17 00:00:00 2001 From: andi6 Date: Mon, 27 May 2024 15:12:07 +0800 Subject: [PATCH] hv: fix using cpuid does not clear the upper 32-bit registers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In HV, cpuid uses the lower 32 bits of rax\rbx\rcx\rdx registers to pass parameters, But the software does not clear the upper 32-bit registers, if the guest uses 64-bit variables to pass parameters to cpuid,guest will use rax\rbx\rcx\rdx, not eax\ebx\ecx\edx, the previous value of the high 32 registers will affect the guest. Tracked-On: #8605 Reviewed-by: Junjie Mao Signed-off-by: andi6 --- hypervisor/arch/x86/guest/vmexit.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index ed48c5736a..6138663a3a 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -354,19 +354,18 @@ static int32_t hlt_vmexit_handler(struct acrn_vcpu *vcpu) int32_t cpuid_vmexit_handler(struct acrn_vcpu *vcpu) { - uint64_t rax, rbx, rcx, rdx; - - rax = vcpu_get_gpreg(vcpu, CPU_REG_RAX); - rbx = vcpu_get_gpreg(vcpu, CPU_REG_RBX); - rcx = vcpu_get_gpreg(vcpu, CPU_REG_RCX); - rdx = vcpu_get_gpreg(vcpu, CPU_REG_RDX); - TRACE_2L(TRACE_VMEXIT_CPUID, rax, rcx); - guest_cpuid(vcpu, (uint32_t *)&rax, (uint32_t *)&rbx, - (uint32_t *)&rcx, (uint32_t *)&rdx); - vcpu_set_gpreg(vcpu, CPU_REG_RAX, rax); - vcpu_set_gpreg(vcpu, CPU_REG_RBX, rbx); - vcpu_set_gpreg(vcpu, CPU_REG_RCX, rcx); - vcpu_set_gpreg(vcpu, CPU_REG_RDX, rdx); + uint32_t eax, ebx, ecx, edx; + + eax = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RAX); + ebx = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RBX); + ecx = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RCX); + edx = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RDX); + TRACE_2L(TRACE_VMEXIT_CPUID, (uint64_t)eax, (uint64_t)ecx); + guest_cpuid(vcpu, &eax, &ebx, &ecx, &edx); + vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)eax); + vcpu_set_gpreg(vcpu, CPU_REG_RBX, (uint64_t)ebx); + vcpu_set_gpreg(vcpu, CPU_REG_RCX, (uint64_t)ecx); + vcpu_set_gpreg(vcpu, CPU_REG_RDX, (uint64_t)edx); return 0; }