mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-23 09:47:44 +00:00
hv: nested: support for VMXON emulation
This patch emulates VMXON instruction. Basically checks some prerequisites to enable VMX operation on L1 guest (next patch), and prepares some virtual hardware environment in L0. Tracked-On: #5923 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <logmsg.h>
|
||||
#include <asm/guest/virq.h>
|
||||
#include <asm/guest/vcpu.h>
|
||||
#include <asm/guest/vm.h>
|
||||
#include <asm/guest/nested.h>
|
||||
@@ -220,3 +221,43 @@ int32_t read_vmx_msr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
|
||||
*val = v;
|
||||
return err;
|
||||
}
|
||||
|
||||
void nested_vmx_result(enum VMXResult result, int error_number)
|
||||
{
|
||||
uint64_t rflags = exec_vmread(VMX_GUEST_RFLAGS);
|
||||
|
||||
/* ISDM: section 30.2 CONVENTIONS */
|
||||
rflags &= ~(RFLAGS_C | RFLAGS_P | RFLAGS_A | RFLAGS_Z | RFLAGS_S | RFLAGS_O);
|
||||
|
||||
if (result == VMfailValid) {
|
||||
rflags |= RFLAGS_Z;
|
||||
exec_vmwrite(VMX_INSTR_ERROR, error_number);
|
||||
} else if (result == VMfailInvalid) {
|
||||
rflags |= RFLAGS_C;
|
||||
} else {
|
||||
/* VMsucceed, do nothing */
|
||||
}
|
||||
|
||||
if (result != VMsucceed) {
|
||||
pr_err("VMX failed: %d/%d", result, error_number);
|
||||
}
|
||||
|
||||
exec_vmwrite(VMX_GUEST_RFLAGS, rflags);
|
||||
}
|
||||
|
||||
/*
|
||||
* @pre vcpu != NULL
|
||||
*/
|
||||
int32_t vmxon_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
/* Will do permission check in next patch */
|
||||
if (is_nvmx_configured(vcpu->vm)) {
|
||||
vcpu->arch.nested.vmxon = true;
|
||||
|
||||
nested_vmx_result(VMsucceed, 0);
|
||||
} else {
|
||||
vcpu_inject_ud(vcpu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -94,8 +94,14 @@ static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
||||
.handler = undefined_vmexit_handler},
|
||||
[VMX_EXIT_REASON_VMXOFF] = {
|
||||
.handler = undefined_vmexit_handler},
|
||||
#ifndef CONFIG_NVMX_ENABLED
|
||||
[VMX_EXIT_REASON_VMXON] = {
|
||||
.handler = undefined_vmexit_handler},
|
||||
#else
|
||||
[VMX_EXIT_REASON_VMXON] = {
|
||||
.handler = vmxon_vmexit_handler,
|
||||
.need_exit_qualification = 1},
|
||||
#endif
|
||||
[VMX_EXIT_REASON_CR_ACCESS] = {
|
||||
.handler = cr_access_vmexit_handler,
|
||||
.need_exit_qualification = 1},
|
||||
@@ -460,10 +466,8 @@ static int32_t loadiwkey_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vmexit handler for just injecting a #UD exception
|
||||
*
|
||||
* ACRN doesn't support nested virtualization, the following VMExit will inject #UD
|
||||
* VMCLEAR/VMLAUNCH/VMPTRST/VMREAD/VMRESUME/VMWRITE/VMXOFF/VMXON.
|
||||
/*
|
||||
* vmexit handler for just injecting a #UD exception
|
||||
* ACRN doesn't enable VMFUNC, VMFUNC treated as undefined.
|
||||
*/
|
||||
static int32_t undefined_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
|
Reference in New Issue
Block a user