@@ -7052,34 +7052,24 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu)
70527052static int handle_vmon (struct kvm_vcpu * vcpu )
70537053{
70547054 int ret ;
7055- struct kvm_segment cs ;
70567055 struct vcpu_vmx * vmx = to_vmx (vcpu );
70577056 const u64 VMXON_NEEDED_FEATURES = FEATURE_CONTROL_LOCKED
70587057 | FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX ;
70597058
7060- /* The Intel VMX Instruction Reference lists a bunch of bits that
7061- * are prerequisite to running VMXON, most notably cr4.VMXE must be
7062- * set to 1 (see vmx_set_cr4() for when we allow the guest to set this).
7063- * Otherwise, we should fail with #UD. We test these now:
7059+ /*
7060+ * The Intel VMX Instruction Reference lists a bunch of bits that are
7061+ * prerequisite to running VMXON, most notably cr4.VMXE must be set to
7062+ * 1 (see vmx_set_cr4() for when we allow the guest to set this).
7063+ * Otherwise, we should fail with #UD. But most faulting conditions
7064+ * have already been checked by hardware, prior to the VM-exit for
7065+ * VMXON. We do test guest cr4.VMXE because processor CR4 always has
7066+ * that bit set to 1 in non-root mode.
70647067 */
7065- if (!kvm_read_cr4_bits (vcpu , X86_CR4_VMXE ) ||
7066- !kvm_read_cr0_bits (vcpu , X86_CR0_PE ) ||
7067- (vmx_get_rflags (vcpu ) & X86_EFLAGS_VM )) {
7068- kvm_queue_exception (vcpu , UD_VECTOR );
7069- return 1 ;
7070- }
7071-
7072- vmx_get_segment (vcpu , & cs , VCPU_SREG_CS );
7073- if (is_long_mode (vcpu ) && !cs .l ) {
7068+ if (!kvm_read_cr4_bits (vcpu , X86_CR4_VMXE )) {
70747069 kvm_queue_exception (vcpu , UD_VECTOR );
70757070 return 1 ;
70767071 }
70777072
7078- if (vmx_get_cpl (vcpu )) {
7079- kvm_inject_gp (vcpu , 0 );
7080- return 1 ;
7081- }
7082-
70837073 if (vmx -> nested .vmxon ) {
70847074 nested_vmx_failValid (vcpu , VMXERR_VMXON_IN_VMX_ROOT_OPERATION );
70857075 return kvm_skip_emulated_instruction (vcpu );
@@ -7106,29 +7096,15 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
71067096 * Intel's VMX Instruction Reference specifies a common set of prerequisites
71077097 * for running VMX instructions (except VMXON, whose prerequisites are
71087098 * slightly different). It also specifies what exception to inject otherwise.
7099+ * Note that many of these exceptions have priority over VM exits, so they
7100+ * don't have to be checked again here.
71097101 */
71107102static int nested_vmx_check_permission (struct kvm_vcpu * vcpu )
71117103{
7112- struct kvm_segment cs ;
7113- struct vcpu_vmx * vmx = to_vmx (vcpu );
7114-
7115- if (!vmx -> nested .vmxon ) {
7104+ if (!to_vmx (vcpu )-> nested .vmxon ) {
71167105 kvm_queue_exception (vcpu , UD_VECTOR );
71177106 return 0 ;
71187107 }
7119-
7120- vmx_get_segment (vcpu , & cs , VCPU_SREG_CS );
7121- if ((vmx_get_rflags (vcpu ) & X86_EFLAGS_VM ) ||
7122- (is_long_mode (vcpu ) && !cs .l )) {
7123- kvm_queue_exception (vcpu , UD_VECTOR );
7124- return 0 ;
7125- }
7126-
7127- if (vmx_get_cpl (vcpu )) {
7128- kvm_inject_gp (vcpu , 0 );
7129- return 0 ;
7130- }
7131-
71327108 return 1 ;
71337109}
71347110
@@ -7472,7 +7448,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
74727448 if (get_vmx_mem_address (vcpu , exit_qualification ,
74737449 vmx_instruction_info , true, & gva ))
74747450 return 1 ;
7475- /* _system ok, as nested_vmx_check_permission verified cpl=0 */
7451+ /* _system ok, as hardware has verified cpl=0 */
74767452 kvm_write_guest_virt_system (& vcpu -> arch .emulate_ctxt , gva ,
74777453 & field_value , (is_long_mode (vcpu ) ? 8 : 4 ), NULL );
74787454 }
@@ -7605,7 +7581,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
76057581 if (get_vmx_mem_address (vcpu , exit_qualification ,
76067582 vmx_instruction_info , true, & vmcs_gva ))
76077583 return 1 ;
7608- /* ok to use *_system, as nested_vmx_check_permission verified cpl=0 */
7584+ /* ok to use *_system, as hardware has verified cpl=0 */
76097585 if (kvm_write_guest_virt_system (& vcpu -> arch .emulate_ctxt , vmcs_gva ,
76107586 (void * )& to_vmx (vcpu )-> nested .current_vmptr ,
76117587 sizeof (u64 ), & e )) {
@@ -7638,11 +7614,6 @@ static int handle_invept(struct kvm_vcpu *vcpu)
76387614 if (!nested_vmx_check_permission (vcpu ))
76397615 return 1 ;
76407616
7641- if (!kvm_read_cr0_bits (vcpu , X86_CR0_PE )) {
7642- kvm_queue_exception (vcpu , UD_VECTOR );
7643- return 1 ;
7644- }
7645-
76467617 vmx_instruction_info = vmcs_read32 (VMX_INSTRUCTION_INFO );
76477618 type = kvm_register_readl (vcpu , (vmx_instruction_info >> 28 ) & 0xf );
76487619
0 commit comments