Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-microblaze.git] / arch / x86 / kvm / vmx / nested.c
index e405e75..23b58c2 100644 (file)
@@ -6118,6 +6118,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
            ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON))
                return -EINVAL;
 
+       if (kvm_state->hdr.vmx.flags & ~KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE)
+               return -EINVAL;
+
        /*
         * SMM temporarily disables VMX, so we cannot be in guest mode,
         * nor can VMLAUNCH/VMRESUME be pending.  Outside SMM, SMM flags
@@ -6147,9 +6150,16 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
        if (ret)
                return ret;
 
-       /* Empty 'VMXON' state is permitted */
-       if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12))
-               return 0;
+       /* Empty 'VMXON' state is permitted if no VMCS loaded */
+       if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12)) {
+               /* See vmx_has_valid_vmcs12.  */
+               if ((kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE) ||
+                   (kvm_state->flags & KVM_STATE_NESTED_EVMCS) ||
+                   (kvm_state->hdr.vmx.vmcs12_pa != -1ull))
+                       return -EINVAL;
+               else
+                       return 0;
+       }
 
        if (kvm_state->hdr.vmx.vmcs12_pa != -1ull) {
                if (kvm_state->hdr.vmx.vmcs12_pa == kvm_state->hdr.vmx.vmxon_pa ||
@@ -6215,6 +6225,7 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
                        goto error_guest_mode;
        }
 
+       vmx->nested.has_preemption_timer_deadline = false;
        if (kvm_state->hdr.vmx.flags & KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE) {
                vmx->nested.has_preemption_timer_deadline = true;
                vmx->nested.preemption_timer_deadline =