x86: support cache-writeback in flush_area_local() et al

The majority of the present callers really aren't after invalidating
cache contents, but only after writeback. Make this available by simply
extending the FLUSH_CACHE handling accordingly. No feature checks are
required here: cache_writeback() falls back to cache_flush() as
necessary, while WBNOINVD degenerates to WBINVD on older hardware.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
Jan Beulich committed 2025-05-14 10:58:02 +02:00
1 parent bbaea9878b
commit aa3f897a20
2 files changed
+16 -7

No files matched your search

+9 -6
View File
@@ -232,7 +232,7 @@ unsigned int flush_area_local(const void *va, unsigned int flags)
if ( flags & FLUSH_HVM_ASID_CORE )
hvm_flush_guest_tlbs();
if ( flags & FLUSH_CACHE )
if ( flags & (FLUSH_CACHE | FLUSH_CACHE_WRITEBACK) )
{
const struct cpuinfo_x86 *c = &current_cpu_data;
unsigned long sz = 0;
@@ -245,13 +245,16 @@ unsigned int flush_area_local(const void *va, unsigned int flags)
c->x86_clflush_size && c->x86_cache_size && sz &&
((sz >> 10) < c->x86_cache_size) )
{
cache_flush(va, sz);
flags &= ~FLUSH_CACHE;
if ( flags & FLUSH_CACHE )
cache_flush(va, sz);
else
cache_writeback(va, sz);
flags &= ~(FLUSH_CACHE | FLUSH_CACHE_WRITEBACK);
}
else
{
else if ( flags & FLUSH_CACHE )
wbinvd();
}
else
wbnoinvd();
}
if ( flags & FLUSH_ROOT_PGTBL )
+7 -1
View File
@@ -135,6 +135,8 @@ void switch_cr3_cr4(unsigned long cr3, unsigned long cr4);
#else
# define FLUSH_NO_ASSIST 0
#endif
/* Write back data cache contents */
#define FLUSH_CACHE_WRITEBACK 0x10000
/* Flush local TLBs/caches. */
unsigned int flush_area_local(const void *va, unsigned int flags);
@@ -195,7 +197,11 @@ static inline int clean_and_invalidate_dcache_va_range(const void *p,
}
static inline int clean_dcache_va_range(const void *p, unsigned long size)
{
return clean_and_invalidate_dcache_va_range(p, size);
unsigned int order = get_order_from_bytes(size);
/* sub-page granularity support needs to be added if necessary */
flush_area_local(p, FLUSH_CACHE_WRITEBACK | FLUSH_ORDER(order));
return 0;
}
unsigned int guest_flush_tlb_flags(const struct domain *d);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.