* This is used during huge page splitting to build the SPTEs that make up the
  * new page table.
  */
-u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, int huge_level,
+u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, union kvm_mmu_page_role role,
                              int index)
 {
        u64 child_spte;
-       int child_level;
 
        if (WARN_ON_ONCE(!is_shadow_present_pte(huge_spte)))
                return 0;
                return 0;
 
        child_spte = huge_spte;
-       child_level = huge_level - 1;
 
        /*
         * The child_spte already has the base address of the huge page being
         * split. So we just have to OR in the offset to the page at the next
         * lower level for the given index.
         */
-       child_spte |= (index * KVM_PAGES_PER_HPAGE(child_level)) << PAGE_SHIFT;
+       child_spte |= (index * KVM_PAGES_PER_HPAGE(role.level)) << PAGE_SHIFT;
 
-       if (child_level == PG_LEVEL_4K) {
+       if (role.level == PG_LEVEL_4K) {
                child_spte &= ~PT_PAGE_SIZE_MASK;
 
                /*
-                * When splitting to a 4K page, mark the page executable as the
-                * NX hugepage mitigation no longer applies.
+                * When splitting to a 4K page where execution is allowed, mark
+                * the page executable as the NX hugepage mitigation no longer
+                * applies.
                 */
-               if (is_nx_huge_page_enabled(kvm))
+               if ((role.access & ACC_EXEC_MASK) && is_nx_huge_page_enabled(kvm))
                        child_spte = make_spte_executable(child_spte);
        }
 
 
               unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn,
               u64 old_spte, bool prefetch, bool can_unsync,
               bool host_writable, u64 *new_spte);
-u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, int huge_level,
-                             int index);
+u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte,
+                             union kvm_mmu_page_role role, int index);
 u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled);
 u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access);
 u64 mark_spte_for_access_track(u64 spte);
 
         * not been linked in yet and thus is not reachable from any other CPU.
         */
        for (i = 0; i < SPTE_ENT_PER_PAGE; i++)
-               sp->spt[i] = make_huge_page_split_spte(kvm, huge_spte, level, i);
+               sp->spt[i] = make_huge_page_split_spte(kvm, huge_spte, sp->role, i);
 
        /*
         * Replace the huge spte with a pointer to the populated lower level