This is the same as commit 
147277540bbc ("kvm: svm: Add support for
additional SVM NPF error codes", 2016-11-23), but for Intel processors.
In this case, the exit qualification field's bit 8 says whether the
EPT violation occurred while translating the guest's final physical
address or rather while translating the guest page tables.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
 #define PFERR_GUEST_PAGE_MASK (1ULL << PFERR_GUEST_PAGE_BIT)
 
 #define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK |       \
-                                PFERR_USER_MASK |              \
                                 PFERR_WRITE_MASK |             \
                                 PFERR_PRESENT_MASK)
 
 
         * This can occur when using nested virtualization with nested
         * paging in both guests. If true, we simply unprotect the page
         * and resume the guest.
-        *
-        * Note: AMD only (since it supports the PFERR_GUEST_PAGE_MASK used
-        *       in PFERR_NEXT_GUEST_PAGE)
         */
        if (vcpu->arch.mmu.direct_map &&
-               error_code == PFERR_NESTED_GUEST_PAGE) {
+           (error_code & PFERR_NESTED_GUEST_PAGE) == PFERR_NESTED_GUEST_PAGE) {
                kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(cr2));
                return 1;
        }
 
 {
        unsigned long exit_qualification;
        gpa_t gpa;
-       u32 error_code;
+       u64 error_code;
 
        exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 
                        EPT_VIOLATION_EXECUTABLE))
                      ? PFERR_PRESENT_MASK : 0;
 
+       error_code |= (exit_qualification & 0x100) != 0 ?
+              PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK;
+
        vcpu->arch.gpa_available = true;
        vcpu->arch.exit_qualification = exit_qualification;