efi/x86: Don't depend on firmware GDT layout
authorArvind Sankar <nivedita@alum.mit.edu>
Sun, 2 Feb 2020 17:13:48 +0000 (12:13 -0500)
committerArd Biesheuvel <ardb@kernel.org>
Sat, 22 Feb 2020 22:37:37 +0000 (23:37 +0100)
commit90ff226281e1083988a42cfc51f89d91734cc55e
tree2e72c2efa77491117d20eb0d4705faa35acc4013
parent67a6af7ad1d161dbc9c139e868d5549e632923f7
efi/x86: Don't depend on firmware GDT layout

When booting in mixed mode, the firmware's GDT is still installed at
handover entry in efi32_stub_entry. We save the GDTR for later use in
__efi64_thunk but we are assuming that descriptor 2 (__KERNEL_CS) is a
valid 32-bit code segment descriptor and that descriptor 3
(__KERNEL_DS/__BOOT_DS) is a valid data segment descriptor.

This happens to be true for OVMF (it actually uses descriptor 1 for data
segments, but descriptor 3 is also setup as data), but we shouldn't
depend on this being the case.

Fix this by saving the code and data selectors in addition to the GDTR
in efi32_stub_entry, and restoring them in __efi64_thunk before calling
the firmware. The UEFI specification guarantees that selectors will be
flat, so using the DS selector for all the segment registers should be
enough.

We also need to install our own GDT before initializing segment
registers in startup_32, so move the GDT load up to the beginning of the
function.

[ardb: mention mixed mode in the commit log]

Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200202171353.3736319-3-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/x86/boot/compressed/efi_thunk_64.S
arch/x86/boot/compressed/head_64.S