max_order(curr_d)) )
return;
- /*
- * With MEMF_no_tlbflush set, alloc_heap_pages() will ignore
- * TLB-flushes. After VM creation, this is a security issue (it can
- * make pages accessible to guest B, when guest A may still have a
- * cached mapping to them). So we do this only during domain creation,
- * when the domain itself has not yet been unpaused for the first
- * time.
- */
if ( unlikely(!d->creation_finished) )
+ {
+ /*
+ * With MEMF_no_tlbflush set, alloc_heap_pages() will ignore
+ * TLB-flushes. After VM creation, this is a security issue (it can
+ * make pages accessible to guest B, when guest A may still have a
+ * cached mapping to them). So we do this only during domain creation,
+ * when the domain itself has not yet been unpaused for the first
+ * time.
+ */
a->memflags |= MEMF_no_tlbflush;
+ /*
+ * With MEMF_no_icache_flush, alloc_heap_pages() will skip
+ * performing icache flushes. We do it only before domain
+ * creation as once the domain is running there is a danger of
+ * executing instructions from stale caches if icache flush is
+ * delayed.
+ */
+ a->memflags |= MEMF_no_icache_flush;
+ }
for ( i = a->nr_done; i < a->nr_extents; i++ )
{
}
mfn = gpfn;
- page = mfn_to_page(mfn);
}
else
{
out:
if ( need_tlbflush )
filtered_flush_tlb_mask(tlbflush_timestamp);
+
+ if ( a->memflags & MEMF_no_icache_flush )
+ invalidate_icache();
+
a->nr_done = i;
}
/* Ensure cache and RAM are consistent for platforms where the
* guest can control its own visibility of/through the cache.
*/
- flush_page_to_ram(page_to_mfn(&pg[i]), true);
+ flush_page_to_ram(page_to_mfn(&pg[i]), !(memflags & MEMF_no_icache_flush));
}
spin_unlock(&heap_lock);
#define MEMF_no_owner (1U<<_MEMF_no_owner)
#define _MEMF_no_tlbflush 6
#define MEMF_no_tlbflush (1U<<_MEMF_no_tlbflush)
+#define _MEMF_no_icache_flush 7
+#define MEMF_no_icache_flush (1U<<_MEMF_no_icache_flush)
#define _MEMF_node 8
#define MEMF_node_mask ((1U << (8 * sizeof(nodeid_t))) - 1)
#define MEMF_node(n) ((((n) + 1) & MEMF_node_mask) << _MEMF_node)