hv: nested: enable nested virtualization

Allow guest set CR4_VMXE if CONFIG_NVMX_ENABLED is set:

- move CR4_VMXE from CR4_EMULATED_RESERVE_BITS to CR4_TRAP_AND_EMULATE_BITS
  so that CR4_VMXE is removed from cr4_reserved_bits_mask.
- force CR4_VMXE to be removed from cr4_rsv_bits_guest_value so that CR4_VMXE
  is able to be set.

Expose VMX feature (CPUID01.01H:ECX[5]) to L1 guests whose GUEST_FLAG_NVMX_ENABLED
is set.

Assuming guest hypervisor (L1) is KVM, and KVM uses EPT for L2 guests.

Constraints on ACRN VM.
- LAPIC passthrough should be enabled.
- use SCHED_NOOP scheduler.

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:
Zide Chen 2021-03-30 20:19:21 -07:00 committed by wenlingz
parent dd90eccc25
commit ccfdf9cdd7
4 changed files with 27 additions and 2 deletions

View File

@ -460,8 +460,10 @@ static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx
/* mask SDBG for silicon debug */
*ecx &= ~CPUID_ECX_SDBG;
/*mask vmx to guest os */
/* mask VMX to guest OS */
if (!is_nvmx_configured(vcpu->vm)) {
*ecx &= ~CPUID_ECX_VMX;
}
/* set Hypervisor Present Bit */
*ecx |= CPUID_ECX_HV;

View File

@ -57,10 +57,18 @@ static uint64_t cr4_passthru_mask = CR4_PASSTHRU_BITS; /* bound to flexible bits
#define CR4_TRAP_AND_PASSTHRU_BITS (CR4_PSE | CR4_PAE | CR4_SMEP | CR4_SMAP | CR4_PKE | CR4_PKS | CR4_KL)
static uint64_t cr4_trap_and_passthru_mask = CR4_TRAP_AND_PASSTHRU_BITS; /* bound to flexible bits */
#ifdef CONFIG_NVMX_ENABLED
#define CR4_TRAP_AND_EMULATE_BITS (CR4_VMXE | CR4_MCE) /* software emulated bits even if host is fixed */
#else
#define CR4_TRAP_AND_EMULATE_BITS CR4_MCE /* software emulated bits even if host is fixed */
#endif
/* Change of these bits should change vcpuid too */
#ifdef CONFIG_NVMX_ENABLED
#define CR4_EMULATED_RESERVE_BITS (CR4_CET | CR4_SMXE)
#else
#define CR4_EMULATED_RESERVE_BITS (CR4_VMXE | CR4_CET | CR4_SMXE)
#endif
/* The physical CR4 value for bits of CR4_EMULATED_RESERVE_BITS */
#define CR4_EMRSV_BITS_PHYS_VALUE CR4_VMXE
@ -484,6 +492,10 @@ void init_cr0_cr4_flexible_bits(void)
* Refer SDM Appendix A.8
*/
cr4_rsv_bits_guest_value = (fixed0 & ~cr4_flexible_bits);
#ifdef CONFIG_NVMX_ENABLED
cr4_rsv_bits_guest_value &= ~CR4_VMXE;
#endif
initial_guest_cr4 = (cr4_rsv_bits_guest_value & ~CR4_EMULATED_RESERVE_BITS) | CR4_EMRSV_BITS_PHYS_VALUE;
cr4_rsv_bits_guest_value = (cr4_rsv_bits_guest_value & ~CR4_EMULATED_RESERVE_BITS) | CR4_EMRSV_BITS_VIRT_VALUE;

View File

@ -137,6 +137,16 @@ bool is_rt_vm(const struct acrn_vm *vm)
return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U);
}
/**
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
*/
bool is_nvmx_configured(const struct acrn_vm *vm)
{
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
return ((vm_config->guest_flags & GUEST_FLAG_NVMX_ENABLED) != 0U);
}
/**
* @brief VT-d PI posted mode can possibly be used for PTDEVs assigned
* to this VM if platform supports VT-d PI AND lapic passthru is not configured

View File

@ -255,6 +255,7 @@ void vrtc_init(struct acrn_vm *vm);
bool is_lapic_pt_configured(const struct acrn_vm *vm);
bool is_rt_vm(const struct acrn_vm *vm);
bool is_nvmx_configured(const struct acrn_vm *vm);
bool is_pi_capable(const struct acrn_vm *vm);
bool has_rt_vm(void);
struct acrn_vm *get_highest_severity_vm(bool runtime);