Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
xen.31758
64f71f50-Arm-handle-cache-flush-at-top.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 64f71f50-Arm-handle-cache-flush-at-top.patch of Package xen.31758
# Commit 9a216e92de9f9011097e4f1fb55ff67ba0a21704 # Date 2023-09-05 14:30:08 +0200 # Author Stefano Stabellini <stefano.stabellini@amd.com> # Committer Jan Beulich <jbeulich@suse.com> xen/arm: page: Handle cache flush of an element at the top of the address space The region that needs to be cleaned/invalidated may be at the top of the address space. This means that 'end' (i.e. 'p + size') will be 0 and therefore nothing will be cleaned/invalidated as the check in the loop will always be false. On Arm64, we only support we only support up to 48-bit Virtual address space. So this is not a concern there. However, for 32-bit, the mapcache is using the last 2GB of the address space. Therefore we may not clean/invalidate properly some pages. This could lead to memory corruption or data leakage (the scrubbed value may still sit in the cache when the guest could read directly the memory and therefore read the old content). Rework invalidate_dcache_va_range(), clean_dcache_va_range(), clean_and_invalidate_dcache_va_range() to handle a cache flush with an element at the top of the address space. This is CVE-2023-34321 / XSA-437. Reported-by: Julien Grall <jgrall@amazon.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com> Signed-off-by: Julien Grall <jgrall@amazon.com> Acked-by: Bertrand Marquis <bertrand.marquis@arm.com> --- a/xen/include/asm-arm/page.h +++ b/xen/include/asm-arm/page.h @@ -152,26 +152,25 @@ static inline size_t read_dcache_line_by static inline int invalidate_dcache_va_range(const void *p, unsigned long size) { - const void *end = p + size; size_t cacheline_mask = dcache_line_bytes - 1; dsb(sy); /* So the CPU issues all writes to the range */ if ( (uintptr_t)p & cacheline_mask ) { + size -= dcache_line_bytes - ((uintptr_t)p & cacheline_mask); p = (void *)((uintptr_t)p & ~cacheline_mask); asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p)); p += dcache_line_bytes; } - if ( (uintptr_t)end & cacheline_mask ) - { - end = (void *)((uintptr_t)end & ~cacheline_mask); - asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (end)); - } - for ( ; p < end; p += dcache_line_bytes ) + for ( ; size >= dcache_line_bytes; + p += dcache_line_bytes, size -= dcache_line_bytes ) asm volatile (__invalidate_dcache_one(0) : : "r" (p)); + if ( size > 0 ) + asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p)); + dsb(sy); /* So we know the flushes happen before continuing */ return 0; @@ -179,10 +178,14 @@ static inline int invalidate_dcache_va_r static inline int clean_dcache_va_range(const void *p, unsigned long size) { - const void *end = p + size; + size_t cacheline_mask = dcache_line_bytes - 1; + dsb(sy); /* So the CPU issues all writes to the range */ - p = (void *)((uintptr_t)p & ~(dcache_line_bytes - 1)); - for ( ; p < end; p += dcache_line_bytes ) + size += (uintptr_t)p & cacheline_mask; + size = (size + cacheline_mask) & ~cacheline_mask; + p = (void *)((uintptr_t)p & ~cacheline_mask); + for ( ; size >= dcache_line_bytes; + p += dcache_line_bytes, size -= dcache_line_bytes ) asm volatile (__clean_dcache_one(0) : : "r" (p)); dsb(sy); /* So we know the flushes happen before continuing */ /* ARM callers assume that dcache_* functions cannot fail. */ @@ -192,10 +195,14 @@ static inline int clean_dcache_va_range( static inline int clean_and_invalidate_dcache_va_range (const void *p, unsigned long size) { - const void *end = p + size; + size_t cacheline_mask = dcache_line_bytes - 1; + dsb(sy); /* So the CPU issues all writes to the range */ - p = (void *)((uintptr_t)p & ~(dcache_line_bytes - 1)); - for ( ; p < end; p += dcache_line_bytes ) + size += (uintptr_t)p & cacheline_mask; + size = (size + cacheline_mask) & ~cacheline_mask; + p = (void *)((uintptr_t)p & ~cacheline_mask); + for ( ; size >= dcache_line_bytes; + p += dcache_line_bytes, size -= dcache_line_bytes ) asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p)); dsb(sy); /* So we know the flushes happen before continuing */ /* ARM callers assume that dcache_* functions cannot fail. */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor