return &slot->arch.lpage_info[level - 2][idx];
}
+static bool kvm_gfn_is_lpage_allowed(struct kvm *kvm,
+ const struct kvm_memory_slot *slot,
+ gfn_t gfn, int level)
+{
+ const struct kvm_memory_slot *other_slot;
+
+ BUILD_BUG_ON(KVM_MAX_NR_ADDRESS_SPACES > 2);
+
+ if (lpage_info_slot(gfn, slot, level)->disallow_lpage)
+ return false;
+
+ if (kvm_arch_nr_memslot_as_ids(kvm) > 1) {
+ other_slot = __gfn_to_memslot(__kvm_memslots(kvm, slot->as_id ^ 1), gfn);
+ if (other_slot && lpage_info_slot(gfn, other_slot, level)->disallow_lpage)
+ return false;
+ }
+
+ return true;
+}
+
/*
* The most significant bit in disallow_lpage tracks whether or not memory
* attributes are mixed, i.e. not identical for all gfns at the current level.
* write-protected (see above), thus if the gfn can be mapped with a
* hugepage and isn't write-tracked, it can't have a shadow page.
*/
- if (!lpage_info_slot(gfn, slot, PG_LEVEL_2M)->disallow_lpage)
+ if (kvm_gfn_is_lpage_allowed(kvm, slot, gfn, PG_LEVEL_2M))
return 0;
/*