Skip to content

Commit

Permalink
shim: Flush the memory region from i-cache before execution
Browse files Browse the repository at this point in the history
We've seen crashes in early GRUB code on an ARM Cortex-A72-based
platform that point at seemingly harmless instructions. Flushing
the i-cache of those instructions prior to executing has been
shown to avoid the problem, which has parallels with this story:
  https://www.mail-archive.com/[email protected]/msg06203.html

Add a cache flushing utility function and provide an implementation
using a GCC intrinsic. This will need to be extended to support other
compilers. Note that this intrinsic is a no-op for x86 platforms.

This fixes issue #498.

Signed-off-by: dann frazier <[email protected]>
  • Loading branch information
dann frazier authored and vathpela committed Oct 4, 2022
1 parent 14d6339 commit 5c537b3
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,11 @@
*/
#define unreachable() __builtin_unreachable()

#if defined(__GNUC__)
#define cache_invalidate(begin, end) __builtin___clear_cache(begin, end)
#else /* __GNUC__ */
#error shim has no cache_invalidate() implementation for this compiler
#endif /* __GNUC__ */

#endif /* !COMPILER_H_ */
// vim:fenc=utf-8:tw=75:et
3 changes: 3 additions & 0 deletions pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,9 @@ handle_image (void *data, unsigned int datasize,

CopyMem(buffer, data, context.SizeOfHeaders);

/* Flush the instruction cache for the region holding the image */
cache_invalidate(buffer, buffer + context.ImageSize);

*entry_point = ImageAddress(buffer, context.ImageSize, context.EntryPoint);
if (!*entry_point) {
perror(L"Entry point is invalid\n");
Expand Down

0 comments on commit 5c537b3

Please sign in to comment.