From 2fd6e119ca9e01e2bc530e2db187b3a4d80f318e Mon Sep 17 00:00:00 2001 From: Binbin Wu Date: Fri, 15 Feb 2019 16:23:18 +0800 Subject: [PATCH] hv: vmcall: hv should not change guest RAX vmcall is undefined HV passes the return value of vmcall by register RAX unconditionally. However, if the vmcall is undefined for a guest, RAX value of guest vcpu should not be changed. According to SDM Vol. 3C 30-9, VMCALL is allowed from any CPL in guest. VMCALL is NOT allowed from CPL > 0 in vmx root mode. ACRN hypervisor doesn't call VMCALL in vmx root mode, though. In current code, ACRN also deny VMCALL from CPL > 0 in guest. So for this case, #GP will not be injected, instead, modify the RAX to notify the return value. Tracked-On: #2405 Signed-off-by: Binbin Wu Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vmcall.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hypervisor/arch/x86/guest/vmcall.c b/hypervisor/arch/x86/guest/vmcall.c index 0e7747723..8ab2c6e43 100644 --- a/hypervisor/arch/x86/guest/vmcall.c +++ b/hypervisor/arch/x86/guest/vmcall.c @@ -197,17 +197,16 @@ int32_t vmcall_vmexit_handler(struct acrn_vcpu *vcpu) (hypcall_id != HC_SAVE_RESTORE_SWORLD_CTX)) { vcpu_inject_ud(vcpu); pr_err("hypercall %d is only allowed from SOS_VM!\n", hypcall_id); - ret = -EACCES; } else if (!is_hypercall_from_ring0()) { pr_err("hypercall is only allowed from RING-0!\n"); ret = -EACCES; + vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)ret); } else { /* Dispatch the hypercall handler */ ret = dispatch_hypercall(vcpu); + vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)ret); } - vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)ret); - TRACE_2L(TRACE_VMEXIT_VMCALL, vm->vm_id, hypcall_id); return 0;