return false;
 }
 
+static bool
+check_hugepage_cache_consistency(struct kvm_vcpu *vcpu, gfn_t gfn, int level)
+{
+       int page_num = KVM_PAGES_PER_HPAGE(level);
+
+       gfn &= ~(page_num - 1);
+
+       return kvm_mtrr_check_gfn_range_consistency(vcpu, gfn, page_num);
+}
+
 static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code,
                          bool prefault)
 {
        if (r)
                return r;
 
-       force_pt_level = mapping_level_dirty_bitmap(vcpu, gfn);
+       if (mapping_level_dirty_bitmap(vcpu, gfn) ||
+           !check_hugepage_cache_consistency(vcpu, gfn, PT_DIRECTORY_LEVEL))
+               force_pt_level = 1;
+       else
+               force_pt_level = 0;
+
        if (likely(!force_pt_level)) {
                level = mapping_level(vcpu, gfn);
+               if (level > PT_DIRECTORY_LEVEL &&
+                   !check_hugepage_cache_consistency(vcpu, gfn, level))
+                       level = PT_DIRECTORY_LEVEL;
                gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
        } else
                level = PT_PAGE_TABLE_LEVEL;
 
        return type;
 }
 EXPORT_SYMBOL_GPL(kvm_mtrr_get_guest_memory_type);
+
+bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
+                                         int page_num)
+{
+       struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
+       struct mtrr_iter iter;
+       u64 start, end;
+       int type = -1;
+
+       start = gfn_to_gpa(gfn);
+       end = gfn_to_gpa(gfn + page_num);
+       mtrr_for_each_mem_type(&iter, mtrr_state, start, end) {
+               if (type == -1) {
+                       type = iter.mem_type;
+                       continue;
+               }
+
+               if (type != iter.mem_type)
+                       return false;
+       }
+
+       if (!iter.partial_map)
+               return true;
+
+       if (type == -1)
+               return true;
+
+       return type == mtrr_default_type(mtrr_state);
+}
 
 bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
+                                         int page_num);
 
 #define KVM_SUPPORTED_XCR0     (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \
                                | XSTATE_BNDREGS | XSTATE_BNDCSR \