hv: nested: support for VMXOFF emulation
This patch implements the VMXOFF instruction. By issuing VMXOFF, L1 guest Leaves VMX Operation. - cleanup VCPU nested virtualization context states in VMXOFF handler. - implement check_vmx_permission() to check permission for VMX operation for VMXOFF and other VMX instructions. 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:
parent
3fdad3c6d1
commit
0a1ac2f4a0
|
@ -6,7 +6,9 @@
|
|||
|
||||
#include <types.h>
|
||||
#include <logmsg.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/guest/virq.h>
|
||||
#include <asm/guest/ept.h>
|
||||
#include <asm/guest/vcpu.h>
|
||||
#include <asm/guest/vm.h>
|
||||
#include <asm/guest/nested.h>
|
||||
|
@ -438,3 +440,40 @@ int32_t vmxon_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @pre vcpu != NULL
|
||||
*/
|
||||
bool check_vmx_permission(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
bool permit = true;
|
||||
|
||||
/* If this VM is not nVMX enabled, it implies that 'vmxon == false' */
|
||||
if ((vcpu->arch.nested.vmxon == false)
|
||||
|| ((vcpu_get_cr0(vcpu) & CR0_PE) == 0UL)
|
||||
|| ((vcpu_get_rflags(vcpu) & RFLAGS_VM) != 0U)) {
|
||||
/* We rely on hardware to check "IA32_EFER.LMA = 1 and CS.L = 0" */
|
||||
vcpu_inject_ud(vcpu);
|
||||
permit = false;
|
||||
} else if (get_guest_cpl() != 0) {
|
||||
vcpu_inject_gp(vcpu, 0U);
|
||||
permit = false;
|
||||
}
|
||||
|
||||
return permit;
|
||||
}
|
||||
|
||||
/*
|
||||
* @pre vcpu != NULL
|
||||
* @pre vcpu->vm != NULL
|
||||
*/
|
||||
int32_t vmxoff_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
if (check_vmx_permission(vcpu)) {
|
||||
vcpu->arch.nested.vmxon = false;
|
||||
|
||||
nested_vmx_result(VMsucceed, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -92,12 +92,14 @@ static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
|||
.handler = undefined_vmexit_handler},
|
||||
[VMX_EXIT_REASON_VMWRITE] = {
|
||||
.handler = undefined_vmexit_handler},
|
||||
#ifndef CONFIG_NVMX_ENABLED
|
||||
[VMX_EXIT_REASON_VMXOFF] = {
|
||||
.handler = undefined_vmexit_handler},
|
||||
#ifndef CONFIG_NVMX_ENABLED
|
||||
[VMX_EXIT_REASON_VMXON] = {
|
||||
.handler = undefined_vmexit_handler},
|
||||
#else
|
||||
[VMX_EXIT_REASON_VMXOFF] = {
|
||||
.handler = vmxoff_vmexit_handler},
|
||||
[VMX_EXIT_REASON_VMXON] = {
|
||||
.handler = vmxon_vmexit_handler,
|
||||
.need_exit_qualification = 1},
|
||||
|
|
|
@ -82,6 +82,7 @@ enum VMXResult {
|
|||
};
|
||||
void nested_vmx_result(enum VMXResult, int error_number);
|
||||
int32_t vmxon_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
int32_t vmxoff_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
|
||||
#ifdef CONFIG_NVMX_ENABLED
|
||||
struct acrn_nested {
|
||||
|
|
Loading…
Reference in New Issue