/* We should be here with a valid MFN. */
ASSERT(!mfn_eq(mfn, INVALID_MFN));
- /* We don't allow replacing any valid entry. */
+ /*
+ * We don't allow replacing any valid entry.
+ *
+ * Note that the function xen_pt_update() relies on this
+ * assumption and will skip the TLB flush. The function will need
+ * to be updated if the check is relaxed.
+ */
if ( lpae_is_valid(entry) )
{
if ( lpae_is_mapping(entry, level) )
}
/*
- * Flush the TLBs even in case of failure because we may have
+ * The TLBs flush can be safely skipped when a mapping is inserted
+ * as we don't allow mapping replacement (see xen_pt_check_entry()).
+ *
+ * For all the other cases, the TLBs will be flushed unconditionally
+ * even if the mapping has failed. This is because we may have
* partially modified the PT. This will prevent any unexpected
* behavior afterwards.
*/
- flush_xen_tlb_range_va(virt, PAGE_SIZE * nr_mfns);
+ if ( !((flags & _PAGE_PRESENT) && !mfn_eq(mfn, INVALID_MFN)) )
+ flush_xen_tlb_range_va(virt, PAGE_SIZE * nr_mfns);
spin_unlock(&xen_pt_lock);