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 <binbin.wu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Binbin Wu 2019-02-15 16:23:18 +08:00 committed by wenlingz
parent 3e0c0550a4
commit 2fd6e119ca
1 changed files with 2 additions and 3 deletions

View File

@ -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;