mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-27 13:05:03 +08:00
KVM: nVMX: Move the checks for VM-Execution Control Fields to a separate helper function
.. to improve readability and maintainability, and to align the code as per the layout of the checks in chapter "VM Entries" in Intel SDM vol 3C. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com> Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com> Reviewed-by: Mark Kanda <mark.kanda@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
16322a3b5e
commit
461b4ba4c7
@ -2444,8 +2444,63 @@ static bool valid_ept_address(struct kvm_vcpu *vcpu, u64 address)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks related to VM-Execution Control Fields
|
||||
*/
|
||||
static int nested_check_vm_execution_controls(struct kvm_vcpu *vcpu,
|
||||
struct vmcs12 *vmcs12)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
|
||||
if (!vmx_control_verify(vmcs12->pin_based_vm_exec_control,
|
||||
vmx->nested.msrs.pinbased_ctls_low,
|
||||
vmx->nested.msrs.pinbased_ctls_high) ||
|
||||
!vmx_control_verify(vmcs12->cpu_based_vm_exec_control,
|
||||
vmx->nested.msrs.procbased_ctls_low,
|
||||
vmx->nested.msrs.procbased_ctls_high))
|
||||
return -EINVAL;
|
||||
|
||||
if (nested_cpu_has(vmcs12, CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) &&
|
||||
!vmx_control_verify(vmcs12->secondary_vm_exec_control,
|
||||
vmx->nested.msrs.secondary_ctls_low,
|
||||
vmx->nested.msrs.secondary_ctls_high))
|
||||
return -EINVAL;
|
||||
|
||||
if (vmcs12->cr3_target_count > nested_cpu_vmx_misc_cr3_count(vcpu) ||
|
||||
nested_vmx_check_io_bitmap_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_tpr_shadow_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_apic_access_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_apicv_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_nmi_controls(vmcs12) ||
|
||||
nested_vmx_check_pml_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_unrestricted_guest_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_mode_based_ept_exec_controls(vcpu, vmcs12) ||
|
||||
nested_vmx_check_shadow_vmcs_controls(vcpu, vmcs12) ||
|
||||
(nested_cpu_has_vpid(vmcs12) && !vmcs12->virtual_processor_id))
|
||||
return -EINVAL;
|
||||
|
||||
if (nested_cpu_has_ept(vmcs12) &&
|
||||
!valid_ept_address(vcpu, vmcs12->ept_pointer))
|
||||
return -EINVAL;
|
||||
|
||||
if (nested_cpu_has_vmfunc(vmcs12)) {
|
||||
if (vmcs12->vm_function_control &
|
||||
~vmx->nested.msrs.vmfunc_controls)
|
||||
return -EINVAL;
|
||||
|
||||
if (nested_cpu_has_eptp_switching(vmcs12)) {
|
||||
if (!nested_cpu_has_ept(vmcs12) ||
|
||||
!page_address_valid(vcpu, vmcs12->eptp_list_address))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nested_vmx_check_vmentry_prereqs(struct kvm_vcpu *vcpu,
|
||||
struct vmcs12 *vmcs12)
|
||||
struct vmcs12 *vmcs12)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
bool ia32e;
|
||||
@ -2454,54 +2509,18 @@ static int nested_vmx_check_vmentry_prereqs(struct kvm_vcpu *vcpu,
|
||||
vmcs12->guest_activity_state != GUEST_ACTIVITY_HLT)
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_cpu_has_vpid(vmcs12) && !vmcs12->virtual_processor_id)
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_io_bitmap_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_apic_access_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_tpr_shadow_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_apicv_controls(vcpu, vmcs12))
|
||||
if (nested_check_vm_execution_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_msr_switch_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (!nested_host_cr0_valid(vcpu, vmcs12->host_cr0) ||
|
||||
!nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
|
||||
!nested_cr3_valid(vcpu, vmcs12->host_cr3))
|
||||
return VMXERR_ENTRY_INVALID_HOST_STATE_FIELD;
|
||||
|
||||
if (!nested_cpu_has_preemption_timer(vmcs12) &&
|
||||
nested_cpu_has_save_preemption_timer(vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_pml_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_unrestricted_guest_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_mode_based_ept_exec_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_shadow_vmcs_controls(vcpu, vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (!vmx_control_verify(vmcs12->cpu_based_vm_exec_control,
|
||||
vmx->nested.msrs.procbased_ctls_low,
|
||||
vmx->nested.msrs.procbased_ctls_high) ||
|
||||
(nested_cpu_has(vmcs12, CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) &&
|
||||
!vmx_control_verify(vmcs12->secondary_vm_exec_control,
|
||||
vmx->nested.msrs.secondary_ctls_low,
|
||||
vmx->nested.msrs.secondary_ctls_high)) ||
|
||||
!vmx_control_verify(vmcs12->pin_based_vm_exec_control,
|
||||
vmx->nested.msrs.pinbased_ctls_low,
|
||||
vmx->nested.msrs.pinbased_ctls_high) ||
|
||||
!vmx_control_verify(vmcs12->vm_exit_controls,
|
||||
if (!vmx_control_verify(vmcs12->vm_exit_controls,
|
||||
vmx->nested.msrs.exit_ctls_low,
|
||||
vmx->nested.msrs.exit_ctls_high) ||
|
||||
!vmx_control_verify(vmcs12->vm_entry_controls,
|
||||
@ -2509,29 +2528,6 @@ static int nested_vmx_check_vmentry_prereqs(struct kvm_vcpu *vcpu,
|
||||
vmx->nested.msrs.entry_ctls_high))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_vmx_check_nmi_controls(vmcs12))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_cpu_has_vmfunc(vmcs12)) {
|
||||
if (vmcs12->vm_function_control &
|
||||
~vmx->nested.msrs.vmfunc_controls)
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (nested_cpu_has_eptp_switching(vmcs12)) {
|
||||
if (!nested_cpu_has_ept(vmcs12) ||
|
||||
!page_address_valid(vcpu, vmcs12->eptp_list_address))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
}
|
||||
}
|
||||
|
||||
if (vmcs12->cr3_target_count > nested_cpu_vmx_misc_cr3_count(vcpu))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
if (!nested_host_cr0_valid(vcpu, vmcs12->host_cr0) ||
|
||||
!nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
|
||||
!nested_cr3_valid(vcpu, vmcs12->host_cr3))
|
||||
return VMXERR_ENTRY_INVALID_HOST_STATE_FIELD;
|
||||
|
||||
/*
|
||||
* If the load IA32_EFER VM-exit control is 1, bits reserved in the
|
||||
* IA32_EFER MSR must be 0 in the field for that register. In addition,
|
||||
@ -2603,10 +2599,6 @@ static int nested_vmx_check_vmentry_prereqs(struct kvm_vcpu *vcpu,
|
||||
}
|
||||
}
|
||||
|
||||
if (nested_cpu_has_ept(vmcs12) &&
|
||||
!valid_ept_address(vcpu, vmcs12->ept_pointer))
|
||||
return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2638,7 +2630,8 @@ static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu,
|
||||
}
|
||||
|
||||
static int nested_vmx_check_vmentry_postreqs(struct kvm_vcpu *vcpu,
|
||||
struct vmcs12 *vmcs12, u32 *exit_qual)
|
||||
struct vmcs12 *vmcs12,
|
||||
u32 *exit_qual)
|
||||
{
|
||||
bool ia32e;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user