KVM: Move INVPCID type check from vmx and svm to the common kvm_handle_invpcid()
authorVipin Sharma <vipinsh@google.com>
Tue, 9 Nov 2021 17:44:26 +0000 (17:44 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 11 Nov 2021 15:56:24 +0000 (10:56 -0500)
Handle #GP on INVPCID due to an invalid type in the common switch
statement instead of relying on the callers (VMX and SVM) to manually
validate the type.

Unlike INVVPID and INVEPT, INVPCID is not explicitly documented to check
the type before reading the operand from memory, so deferring the
type validity check until after that point is architecturally allowed.

Signed-off-by: Vipin Sharma <vipinsh@google.com>
Reviewed-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20211109174426.2350547-3-vipinsh@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/svm.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c

index 21bb81710e0f64485a0455040e0b51728ee05d62..ccbf96876ec6e027e608a73291acd45cca131d15 100644 (file)
@@ -3119,11 +3119,6 @@ static int invpcid_interception(struct kvm_vcpu *vcpu)
        type = svm->vmcb->control.exit_info_2;
        gva = svm->vmcb->control.exit_info_1;
 
-       if (type > 3) {
-               kvm_inject_gp(vcpu, 0);
-               return 1;
-       }
-
        return kvm_handle_invpcid(vcpu, type, gva);
 }
 
index 2abcbbb43124e581c8775cdb208e41f928e13183..3b09ac93c86e4edb17375b9d25421fcb9219f454 100644 (file)
@@ -5454,11 +5454,6 @@ static int handle_invpcid(struct kvm_vcpu *vcpu)
        gpr_index = vmx_get_instr_info_reg2(vmx_instruction_info);
        type = kvm_register_read(vcpu, gpr_index);
 
-       if (type > 3) {
-               kvm_inject_gp(vcpu, 0);
-               return 1;
-       }
-
        /* According to the Intel instruction reference, the memory operand
         * is read even if it isn't needed (e.g., for type==all)
         */
index 3a22aa207c734edd39d17b541b75de875e670853..375ef23f698bec5833e74e7c317809517f1940bb 100644 (file)
@@ -12510,7 +12510,8 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva)
                return kvm_skip_emulated_instruction(vcpu);
 
        default:
-               BUG(); /* We have already checked above that type <= 3 */
+               kvm_inject_gp(vcpu, 0);
+               return 1;
        }
 }
 EXPORT_SYMBOL_GPL(kvm_handle_invpcid);