arch/x86/zefi: Fix entry-nop hack for EFI entry

commit 5e9c583c24 ("arch/x86_64: Terrible, awful hackery to
bootstrap entry") introduced a terrible trick which begins execution
at the bottom of .locore with a jump, which then gets replaced with
NOP instructions for the benefit of 16 bit real mode startup of the
other CPUs later on.

But I forgot that EFI enters in 64 bit code natively, and so never
hits that path.  And moving it to the 64 bit setup code doesn't work,
because at that point when we are NOT loaded from EFI, we already have
the Zephyr page tables in place that disallow writes to .locore.

So do it in the EFI loader, which while sort of a weird place, has the
benefit of being in C instead of assembly.

Really all this code needs to go away.  A proper x86 entry
architecture would enter somewhere in the main blob, and .locore
should be a tiny stub we copy in at runtime.

Fixes #36107

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2021-06-11 15:37:56 -07:00 committed by Anas Nashif
commit b651aa9f7d

View file

@ -92,6 +92,20 @@ uintptr_t __abi efi_entry(void *img_handle, struct efi_system_table *sys_tab)
for (int j = 0; j < bytes; j++) { for (int j = 0; j < bytes; j++) {
dst[j] = src[j]; dst[j] = src[j];
} }
/* Page-aligned blocks below 1M are the .locore
* section, which has a jump in its first bytes for
* the benefit of 32 bit entry. Those have to be
* written over with NOP instructions. (See comment
* about OUTRAGEOUS HACK in locore.S) before Zephyr
* starts, because the very first thing it does is
* install its own page table that disallows writes.
*/
if (((long)dst & 0xfff) == 0 && dst < (uint8_t *)0x100000L) {
for (int i = 0; i < 8; i++) {
dst[i] = 0x90; /* 0x90 == 1-byte NOP */
}
}
} }
unsigned char *code = (void *)zefi_entry; unsigned char *code = (void *)zefi_entry;