Kernel/MM: Synchronize executable memory after handling an inode fault

ARM requires an explicit cache flush when modifying executable memory:
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/caches-and-self-modifying-code

__builtin___clear_cache compiles to a no-op if no explicit flushing is
needed (like on x86):
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005f_005f_005fclear_005fcache
This commit is contained in:
Sönke Holz 2024-12-22 17:20:07 +01:00
parent 1d29f02274
commit d73a8fe750

View file

@ -623,6 +623,17 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region, bool m
InterruptDisabler disabler;
u8* dest_ptr = MM.quickmap_page(*new_physical_page);
memcpy(dest_ptr, page_buffer, PAGE_SIZE);
if (is_executable()) {
// Some architectures require an explicit synchronization operation after writing to memory that will be executed.
// This is required even if no instructions were previously fetched from that (physical) memory location,
// because some systems have an I-cache that is not coherent with the D-cache,
// resulting in the I-cache being filled with old values if the contents of the D-cache aren't written back yet.
// __builtin___clear_cache is a no-op on architectures where this isn't needed, like on x86.
__builtin___clear_cache(reinterpret_cast<char*>(dest_ptr), reinterpret_cast<char*>(dest_ptr + PAGE_SIZE));
}
MM.unquickmap_page();
}