On 06.05.2025 10:31, Roger Pau Monne wrote: > @@ -2606,6 +2619,36 @@ unsigned int domain_max_paddr_bits(const struct domain > *d) > return bits; > } > > +void vcpu_flush_cache(struct vcpu *curr) > +{ > + ASSERT(curr == current); > + ASSERT(cache_flush_permitted(curr->domain)); > + > + flush_mask(curr->arch.dirty_cache, FLUSH_CACHE); > + cpumask_clear(curr->arch.dirty_cache);
While here re-ordering of the two operations would be merely for (kind of) doc purposes, ... > + __cpumask_set_cpu(smp_processor_id(), curr->arch.dirty_cache); > +} > + > +void domain_flush_cache(const struct domain *d) > +{ > + const struct vcpu *v; > + cpumask_t *mask = this_cpu(scratch_cpumask); > + > + ASSERT(cache_flush_permitted(d)); > + > + cpumask_clear(mask); > + for_each_vcpu( d, v ) > + cpumask_or(mask, mask, v->arch.dirty_cache); > + > + flush_mask(mask, FLUSH_CACHE); > + /* > + * Clearing the mask of vCPUs in the domain would be racy unless all > vCPUs > + * are paused, so just leave them as-is, at the cost of possibly doing > + * redundant flushes in later calls. It's still better than doing a > + * host-wide cache flush. > + */ ... wouldn't clearing before flushing avoid the raciness here? > +} Also imo both functions are a better fit in mm.c. Jan