• Joerg Roedel's avatar
    x86/efi: Load fixmap GDT in efi_call_phys_epilog() · eeb89e2b
    Joerg Roedel authored
    When PTI is enabled on x86-32 the kernel uses the GDT mapped in the fixmap
    for the simple reason that this address is also mapped for user-space.
    
    The efi_call_phys_prolog()/efi_call_phys_epilog() wrappers change the GDT
    to call EFI runtime services and switch back to the kernel GDT when they
    return. But the switch-back uses the writable GDT, not the fixmap GDT.
    
    When that happened and and the CPU returns to user-space it switches to the
    user %cr3 and tries to restore user segment registers. This fails because
    the writable GDT is not mapped in the user page-table, and without a GDT
    the fault handlers also can't be launched. The result is a triple fault and
    reboot of the machine.
    
    Fix that by restoring the GDT back to the fixmap GDT which is also mapped
    in the user page-table.
    
    Fixes: 7757d607 x86/pti: ('Allow CONFIG_PAGE_TABLE_ISOLATION for x86_32')
    Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
    Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
    Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
    Cc: Michal Hocko <mhocko@suse.com>
    Cc: Andi Kleen <ak@linux.intel.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Cc: Pavel Machek <pavel@ucw.cz>
    Cc: hpa@zytor.com
    Cc: linux-efi@vger.kernel.org
    Link: https://lkml.kernel.org/r/1535702738-10971-1-git-send-email-joro@8bytes.org
    eeb89e2b
efi_32.c 2.27 KB