From: Jiri Kosina <[email protected]>

old_memmap's efi_call_phys_prolog() calls set_pgd() with swapper PGD that
has PAGE_USER set, which makes PTI set NX on it, and therefore EFI can't
execute it's code.

Fix that by forcefully clearing _PAGE_NX from the PGD (this can't be done
by the pgprot API).

_PAGE_NX will be automatically reintroduced in efi_call_phys_epilog(), as
_set_pgd() will again notice that this is _PAGE_USER, and set _PAGE_NX on
it.

Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Pavel Tatashin <[email protected]>
---
 arch/x86/platform/efi/efi_64.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 18dfaad71c99..12118bae3caf 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -90,6 +90,12 @@ pgd_t * __init efi_call_phys_prolog(void)
                save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
                vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
                set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), 
*pgd_offset_k(vaddress));
+               /*
+                * pgprot API doesn't clear it for PGD
+                *
+                * Will be brought back automatically in _epilog()
+                */
+               pgd_offset_k(pgd * PGDIR_SIZE)->pgd &= ~_PAGE_NX;
        }
 out:
        __flush_tlb_all();
-- 
2.16.2

Reply via email to