Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linuxefi: Invalidate i-cache before starting the kernel #107

Merged
merged 1 commit into from
Oct 4, 2022

Conversation

dannf
Copy link
Contributor

@dannf dannf commented Aug 25, 2022

We need to flush the memory range of the code we are about to execute
from the instruction cache before we can safely execute it. Not doing
so appears to be the source of rare synchronous exceptions a user
is seeing on a Cortex-A72-based platform while executing the Linux EFI
stub. Notably they seem to correlate with an instruction on a cache
line boundary.

Signed-off-by: dann frazier dann.frazier@canonical.com

@dannf
Copy link
Contributor Author

dannf commented Aug 25, 2022

Related: rhboot/shim#504

Copy link
Member

@frozencemetery frozencemetery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch. In the shim case, we only flush on aa64, while this seems to always be flushing. Is there a particular reason for that, or was it just easier?

@dannf
Copy link
Contributor Author

dannf commented Aug 30, 2022

Thanks for the patch. In the shim case, we only flush on aa64, while this seems to always be flushing. Is there a particular reason for that, or was it just easier?

Well noticed. In GRUB, grub_arch_sync_caches() is a no-op on x86. A google search tells me that x86 automatically invalidates cached instructions when those addresses are written. Does shim support arches other than x86 & aarch64?

Hm.. gcc appears to optimize out calls to __builtin___clear_cache() on x86. Maybe we just skip the arch guard altogether in shim to future proof it?

@jlinton
Copy link

jlinton commented Sep 7, 2022

Just stumbled on this, and it makes sense. The grub_cmd_linux() is just loading the kernel as normal data, I don't see anything in that path that is going to force the I-D cache to be coherent (most older Arm machines aren't I/D coherent), so anything that has been prefetched or is stale in the icache will remain there before the code is executed. Alternatively, one could just do this on arm64, path, or maybe we should start considering switching to back to using the bootservices as upstream grub is still doing (AFAIK after looking at it). X86/etc should not have this issue.

We need to flush the memory range of the code we are about to execute
from the instruction cache before we can safely execute it. Not doing
so appears to be the source of rare synchronous exceptions a user
is seeing on a Cortex-A72-based platform while executing the Linux EFI
stub. Notably they seem to correlate with an instruction on a cache
line boundary.

Signed-off-by: dann frazier <dann.frazier@canonical.com>
@frozencemetery frozencemetery merged commit 4e9020a into rhboot:fedora-38 Oct 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants