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