• Sean Christopherson's avatar
    KVM: nVMX: Inject #GP, not #UD, if "generic" VMXON CR0/CR4 check fails · 9cc40932
    Sean Christopherson authored
    Inject #GP for if VMXON is attempting with a CR0/CR4 that fails the
    generic "is CRx valid" check, but passes the CR4.VMXE check, and do the
    generic checks _after_ handling the post-VMXON VM-Fail.
    
    The CR4.VMXE check, and all other #UD cases, are special pre-conditions
    that are enforced prior to pivoting on the current VMX mode, i.e. occur
    before interception if VMXON is attempted in VMX non-root mode.
    
    All other CR0/CR4 checks generate #GP and effectively have lower priority
    than the post-VMXON check.
    
    Per the SDM:
    
        IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or ...
            THEN #UD;
        ELSIF not in VMX operation
            THEN
                IF (CPL > 0) or (in A20M mode) or
                (the values of CR0 and CR4 are not supported in VMX operation)
                    THEN #GP(0);
        ELSIF in VMX non-root operation
            THEN VMexit;
        ELSIF CPL > 0
            THEN #GP(0);
        ELSE VMfail("VMXON executed in VMX root operation");
        FI;
    
    which, if re-written without ELSIF, yields:
    
        IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or ...
            THEN #UD
    
        IF in VMX non-root operation
            THEN VMexit;
    
        IF CPL > 0
            THEN #GP(0)
    
        IF in VMX operation
            THEN VMfail("VMXON executed in VMX root operation");
    
        IF (in A20M mode) or
           (the values of CR0 and CR4 are not supported in VMX operation)
                    THEN #GP(0);
    
    Note, KVM unconditionally forwards VMXON VM-Exits that occur in L2 to L1,
    i.e. there is no need to check the vCPU is not in VMX non-root mode.  Add
    a comment to explain why unconditionally forwarding such exits is
    functionally correct.
    Reported-by: default avatarEric Li <ercli@ucdavis.edu>
    Fixes: c7d855c2 ("KVM: nVMX: Inject #UD if VMXON is attempted with incompatible CR0/CR4")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Link: https://lore.kernel.org/r/20221006001956.329314-1-seanjc@google.com
    9cc40932
nested.c 218 KB