lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <8bc0a2a5-a486-4a4d-83e6-45b6c00685ea@amd.com>
Date: Mon, 7 Apr 2025 15:11:32 +0530
From: "Aithal, Srikanth" <sraithal@....com>
To: Ard Biesheuvel <ardb@...nel.org>
Cc: linux-kernel@...r.kernel.org, Ingo Molnar <mingo@...nel.org>,
 David Woodhouse <dwmw@...zon.co.uk>, "H. Peter Anvin" <hpa@...or.com>,
 Kees Cook <keescook@...omium.org>, x86@...nel.org
Subject: Re: [tip: x86/boot] x86/boot: Move the EFI mixed mode startup code
 back under arch/x86, into startup/

On 4/7/2025 2:00 PM, Ard Biesheuvel wrote:
> On Mon, 7 Apr 2025 at 10:38, Aithal, Srikanth <sraithal@....com> wrote:
>>
>> Hello,
>>
>> This commit breaks the build of next-20250407. The kernel config is
>> attached here.
>>
>> Build error:
>>
>> arch/x86/boot/startup/efi-mixed.o: warning: objtool:
>> efi32_stub_entry+0x0: unannotated intra-function call
>> make[3]: *** [scripts/Makefile.build:335:
>> arch/x86/boot/startup/efi-mixed.o] Error 255
>> make[3]: *** Deleting file 'arch/x86/boot/startup/efi-mixed.o'
>> make[3]: *** Waiting for unfinished jobs....
>> make[2]: *** [scripts/Makefile.build:461: arch/x86/boot/startup] Error 2
>> make[2]: *** Waiting for unfinished jobs....
>> make[1]: *** [/home/VT_BUILD/linux/Makefile:2006: .] Error 2
>> make: *** [Makefile:248: __sub-make] Error 2
>>
>>
> 
> Apologies for the breakage.
> 
> Does it help to add the following to arch/x86/boot/startup/Makefile:
> 
> OBJECT_FILES_NON_STANDARD := y
> 
> ?

yes, this fixes the issue.

Reported-by: Srikanth Aithal <sraithal@....com>
Tested-by: Srikanth Aithal <sraithal@....com>

> 
>>
>> Thanks,
>> Srikanth Aithal <sraithal@....com>
>>
>>
>> On 4/7/2025 12:03 AM, tip-bot2 for Ard Biesheuvel wrote:
>>> The following commit has been merged into the x86/boot branch of tip:
>>>
>>> Commit-ID:     4f2d1bbc2c92a32fd612e6c3b51832d5c1c3678e
>>> Gitweb:        https://git.kernel.org/tip/4f2d1bbc2c92a32fd612e6c3b51832d5c1c3678e
>>> Author:        Ard Biesheuvel <ardb@...nel.org>
>>> AuthorDate:    Tue, 01 Apr 2025 15:34:20 +02:00
>>> Committer:     Ingo Molnar <mingo@...nel.org>
>>> CommitterDate: Sun, 06 Apr 2025 20:15:14 +02:00
>>>
>>> x86/boot: Move the EFI mixed mode startup code back under arch/x86, into startup/
>>>
>>> Linus expressed a strong preference for arch-specific asm code (i.e.,
>>> virtually all of it) to reside under arch/ rather than anywhere else.
>>>
>>> So move the EFI mixed mode startup code back, and put it under
>>> arch/x86/boot/startup/ where all shared x86 startup code is going to
>>> live.
>>>
>>> Suggested-by: Linus Torvalds <torvalds@...ux-foundation.org>
>>> Signed-off-by: Ard Biesheuvel <ardb@...nel.org>
>>> Signed-off-by: Ingo Molnar <mingo@...nel.org>
>>> Cc: David Woodhouse <dwmw@...zon.co.uk>
>>> Cc: H. Peter Anvin <hpa@...or.com>
>>> Cc: Kees Cook <keescook@...omium.org>
>>> Link: https://lore.kernel.org/r/20250401133416.1436741-11-ardb+git@google.com
>>> ---
>>>    arch/x86/boot/startup/Makefile           |   3 +-
>>>    arch/x86/boot/startup/efi-mixed.S        | 253 ++++++++++++++++++++++-
>>>    drivers/firmware/efi/libstub/Makefile    |   1 +-
>>>    drivers/firmware/efi/libstub/x86-mixed.S | 253 +----------------------
>>>    4 files changed, 256 insertions(+), 254 deletions(-)
>>>    create mode 100644 arch/x86/boot/startup/efi-mixed.S
>>>    delete mode 100644 drivers/firmware/efi/libstub/x86-mixed.S
>>>
>>> diff --git a/arch/x86/boot/startup/Makefile b/arch/x86/boot/startup/Makefile
>>> index 03519ef..73946a3 100644
>>> --- a/arch/x86/boot/startup/Makefile
>>> +++ b/arch/x86/boot/startup/Makefile
>>> @@ -1,3 +1,6 @@
>>>    # SPDX-License-Identifier: GPL-2.0
>>>
>>> +KBUILD_AFLAGS                += -D__DISABLE_EXPORTS
>>> +
>>>    lib-$(CONFIG_X86_64)                += la57toggle.o
>>> +lib-$(CONFIG_EFI_MIXED)              += efi-mixed.o
>>> diff --git a/arch/x86/boot/startup/efi-mixed.S b/arch/x86/boot/startup/efi-mixed.S
>>> new file mode 100644
>>> index 0000000..e04ed99
>>> --- /dev/null
>>> +++ b/arch/x86/boot/startup/efi-mixed.S
>>> @@ -0,0 +1,253 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/*
>>> + * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming
>>> + *
>>> + * Early support for invoking 32-bit EFI services from a 64-bit kernel.
>>> + *
>>> + * Because this thunking occurs before ExitBootServices() we have to
>>> + * restore the firmware's 32-bit GDT and IDT before we make EFI service
>>> + * calls.
>>> + *
>>> + * On the plus side, we don't have to worry about mangling 64-bit
>>> + * addresses into 32-bits because we're executing with an identity
>>> + * mapped pagetable and haven't transitioned to 64-bit virtual addresses
>>> + * yet.
>>> + */
>>> +
>>> +#include <linux/linkage.h>
>>> +#include <asm/desc_defs.h>
>>> +#include <asm/msr.h>
>>> +#include <asm/page_types.h>
>>> +#include <asm/pgtable_types.h>
>>> +#include <asm/processor-flags.h>
>>> +#include <asm/segment.h>
>>> +
>>> +     .text
>>> +     .code32
>>> +#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> +SYM_FUNC_START(efi32_stub_entry)
>>> +     call    1f
>>> +1:   popl    %ecx
>>> +
>>> +     /* Clear BSS */
>>> +     xorl    %eax, %eax
>>> +     leal    (_bss - 1b)(%ecx), %edi
>>> +     leal    (_ebss - 1b)(%ecx), %ecx
>>> +     subl    %edi, %ecx
>>> +     shrl    $2, %ecx
>>> +     cld
>>> +     rep     stosl
>>> +
>>> +     add     $0x4, %esp              /* Discard return address */
>>> +     movl    8(%esp), %ebx           /* struct boot_params pointer */
>>> +     jmp     efi32_startup
>>> +SYM_FUNC_END(efi32_stub_entry)
>>> +#endif
>>> +
>>> +/*
>>> + * Called using a far call from __efi64_thunk() below, using the x86_64 SysV
>>> + * ABI (except for R8/R9 which are inaccessible to 32-bit code - EAX/EBX are
>>> + * used instead).  EBP+16 points to the arguments passed via the stack.
>>> + *
>>> + * The first argument (EDI) is a pointer to the boot service or protocol, to
>>> + * which the remaining arguments are passed, each truncated to 32 bits.
>>> + */
>>> +SYM_FUNC_START_LOCAL(efi_enter32)
>>> +     /*
>>> +      * Convert x86-64 SysV ABI params to i386 ABI
>>> +      */
>>> +     pushl   32(%ebp)        /* Up to 3 args passed via the stack */
>>> +     pushl   24(%ebp)
>>> +     pushl   16(%ebp)
>>> +     pushl   %ebx            /* R9 */
>>> +     pushl   %eax            /* R8 */
>>> +     pushl   %ecx
>>> +     pushl   %edx
>>> +     pushl   %esi
>>> +
>>> +     /* Disable paging */
>>> +     movl    %cr0, %eax
>>> +     btrl    $X86_CR0_PG_BIT, %eax
>>> +     movl    %eax, %cr0
>>> +
>>> +     /* Disable long mode via EFER */
>>> +     movl    $MSR_EFER, %ecx
>>> +     rdmsr
>>> +     btrl    $_EFER_LME, %eax
>>> +     wrmsr
>>> +
>>> +     call    *%edi
>>> +
>>> +     /* We must preserve return value */
>>> +     movl    %eax, %edi
>>> +
>>> +     call    efi32_enable_long_mode
>>> +
>>> +     addl    $32, %esp
>>> +     movl    %edi, %eax
>>> +     lret
>>> +SYM_FUNC_END(efi_enter32)
>>> +
>>> +     .code64
>>> +SYM_FUNC_START(__efi64_thunk)
>>> +     push    %rbp
>>> +     movl    %esp, %ebp
>>> +     push    %rbx
>>> +
>>> +     /* Move args #5 and #6 into 32-bit accessible registers */
>>> +     movl    %r8d, %eax
>>> +     movl    %r9d, %ebx
>>> +
>>> +     lcalll  *efi32_call(%rip)
>>> +
>>> +     pop     %rbx
>>> +     pop     %rbp
>>> +     RET
>>> +SYM_FUNC_END(__efi64_thunk)
>>> +
>>> +     .code32
>>> +SYM_FUNC_START_LOCAL(efi32_enable_long_mode)
>>> +     movl    %cr4, %eax
>>> +     btsl    $(X86_CR4_PAE_BIT), %eax
>>> +     movl    %eax, %cr4
>>> +
>>> +     movl    $MSR_EFER, %ecx
>>> +     rdmsr
>>> +     btsl    $_EFER_LME, %eax
>>> +     wrmsr
>>> +
>>> +     /* Disable interrupts - the firmware's IDT does not work in long mode */
>>> +     cli
>>> +
>>> +     /* Enable paging */
>>> +     movl    %cr0, %eax
>>> +     btsl    $X86_CR0_PG_BIT, %eax
>>> +     movl    %eax, %cr0
>>> +     ret
>>> +SYM_FUNC_END(efi32_enable_long_mode)
>>> +
>>> +/*
>>> + * This is the common EFI stub entry point for mixed mode. It sets up the GDT
>>> + * and page tables needed for 64-bit execution, after which it calls the
>>> + * common 64-bit EFI entrypoint efi_stub_entry().
>>> + *
>>> + * Arguments:        0(%esp) image handle
>>> + *           4(%esp) EFI system table pointer
>>> + *           %ebx    struct boot_params pointer (or NULL)
>>> + *
>>> + * Since this is the point of no return for ordinary execution, no registers
>>> + * are considered live except for the function parameters. [Note that the EFI
>>> + * stub may still exit and return to the firmware using the Exit() EFI boot
>>> + * service.]
>>> + */
>>> +SYM_FUNC_START_LOCAL(efi32_startup)
>>> +     movl    %esp, %ebp
>>> +
>>> +     subl    $8, %esp
>>> +     sgdtl   (%esp)                  /* Save GDT descriptor to the stack */
>>> +     movl    2(%esp), %esi           /* Existing GDT pointer */
>>> +     movzwl  (%esp), %ecx            /* Existing GDT limit */
>>> +     inc     %ecx                    /* Existing GDT size */
>>> +     andl    $~7, %ecx               /* Ensure size is multiple of 8 */
>>> +
>>> +     subl    %ecx, %esp              /* Allocate new GDT */
>>> +     andl    $~15, %esp              /* Realign the stack */
>>> +     movl    %esp, %edi              /* New GDT address */
>>> +     leal    7(%ecx), %eax           /* New GDT limit */
>>> +     pushw   %cx                     /* Push 64-bit CS (for LJMP below) */
>>> +     pushl   %edi                    /* Push new GDT address */
>>> +     pushw   %ax                     /* Push new GDT limit */
>>> +
>>> +     /* Copy GDT to the stack and add a 64-bit code segment at the end */
>>> +     movl    $GDT_ENTRY(DESC_CODE64, 0, 0xfffff) & 0xffffffff, (%edi,%ecx)
>>> +     movl    $GDT_ENTRY(DESC_CODE64, 0, 0xfffff) >> 32, 4(%edi,%ecx)
>>> +     shrl    $2, %ecx
>>> +     cld
>>> +     rep     movsl                   /* Copy the firmware GDT */
>>> +     lgdtl   (%esp)                  /* Switch to the new GDT */
>>> +
>>> +     call    1f
>>> +1:   pop     %edi
>>> +
>>> +     /* Record mixed mode entry */
>>> +     movb    $0x0, (efi_is64 - 1b)(%edi)
>>> +
>>> +     /* Set up indirect far call to re-enter 32-bit mode */
>>> +     leal    (efi32_call - 1b)(%edi), %eax
>>> +     addl    %eax, (%eax)
>>> +     movw    %cs, 4(%eax)
>>> +
>>> +     /* Disable paging */
>>> +     movl    %cr0, %eax
>>> +     btrl    $X86_CR0_PG_BIT, %eax
>>> +     movl    %eax, %cr0
>>> +
>>> +     /* Set up 1:1 mapping */
>>> +     leal    (pte - 1b)(%edi), %eax
>>> +     movl    $_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE, %ecx
>>> +     leal    (_PAGE_PRESENT | _PAGE_RW)(%eax), %edx
>>> +2:   movl    %ecx, (%eax)
>>> +     addl    $8, %eax
>>> +     addl    $PMD_SIZE, %ecx
>>> +     jnc     2b
>>> +
>>> +     movl    $PAGE_SIZE, %ecx
>>> +     .irpc   l, 0123
>>> +     movl    %edx, \l * 8(%eax)
>>> +     addl    %ecx, %edx
>>> +     .endr
>>> +     addl    %ecx, %eax
>>> +     movl    %edx, (%eax)
>>> +     movl    %eax, %cr3
>>> +
>>> +     call    efi32_enable_long_mode
>>> +
>>> +     /* Set up far jump to 64-bit mode (CS is already on the stack) */
>>> +     leal    (efi_stub_entry - 1b)(%edi), %eax
>>> +     movl    %eax, 2(%esp)
>>> +
>>> +     movl    0(%ebp), %edi
>>> +     movl    4(%ebp), %esi
>>> +     movl    %ebx, %edx
>>> +     ljmpl   *2(%esp)
>>> +SYM_FUNC_END(efi32_startup)
>>> +
>>> +/*
>>> + * efi_status_t efi32_pe_entry(efi_handle_t image_handle,
>>> + *                          efi_system_table_32_t *sys_table)
>>> + */
>>> +SYM_FUNC_START(efi32_pe_entry)
>>> +     pushl   %ebx                            // save callee-save registers
>>> +
>>> +     /* Check whether the CPU supports long mode */
>>> +     movl    $0x80000001, %eax               // assume extended info support
>>> +     cpuid
>>> +     btl     $29, %edx                       // check long mode bit
>>> +     jnc     1f
>>> +     leal    8(%esp), %esp                   // preserve stack alignment
>>> +     xor     %ebx, %ebx                      // no struct boot_params pointer
>>> +     jmp     efi32_startup                   // only ESP and EBX remain live
>>> +1:   movl    $0x80000003, %eax               // EFI_UNSUPPORTED
>>> +     popl    %ebx
>>> +     RET
>>> +SYM_FUNC_END(efi32_pe_entry)
>>> +
>>> +#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> +     .org    efi32_stub_entry + 0x200
>>> +     .code64
>>> +SYM_FUNC_START_NOALIGN(efi64_stub_entry)
>>> +     jmp     efi_handover_entry
>>> +SYM_FUNC_END(efi64_stub_entry)
>>> +#endif
>>> +
>>> +     .data
>>> +     .balign 8
>>> +SYM_DATA_START_LOCAL(efi32_call)
>>> +     .long   efi_enter32 - .
>>> +     .word   0x0
>>> +SYM_DATA_END(efi32_call)
>>> +SYM_DATA(efi_is64, .byte 1)
>>> +
>>> +     .bss
>>> +     .balign PAGE_SIZE
>>> +SYM_DATA_LOCAL(pte, .fill 6 * PAGE_SIZE, 1, 0)
>>> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
>>> index d23a1b9..2f17339 100644
>>> --- a/drivers/firmware/efi/libstub/Makefile
>>> +++ b/drivers/firmware/efi/libstub/Makefile
>>> @@ -85,7 +85,6 @@ lib-$(CONFIG_EFI_GENERIC_STUB)      += efi-stub.o string.o intrinsics.o systable.o \
>>>    lib-$(CONFIG_ARM)           += arm32-stub.o
>>>    lib-$(CONFIG_ARM64)         += kaslr.o arm64.o arm64-stub.o smbios.o
>>>    lib-$(CONFIG_X86)           += x86-stub.o smbios.o
>>> -lib-$(CONFIG_EFI_MIXED)              += x86-mixed.o
>>>    lib-$(CONFIG_X86_64)                += x86-5lvl.o
>>>    lib-$(CONFIG_RISCV)         += kaslr.o riscv.o riscv-stub.o
>>>    lib-$(CONFIG_LOONGARCH)             += loongarch.o loongarch-stub.o
>>> diff --git a/drivers/firmware/efi/libstub/x86-mixed.S b/drivers/firmware/efi/libstub/x86-mixed.S
>>> deleted file mode 100644
>>> index e04ed99..0000000
>>> --- a/drivers/firmware/efi/libstub/x86-mixed.S
>>> +++ /dev/null
>>> @@ -1,253 +0,0 @@
>>> -/* SPDX-License-Identifier: GPL-2.0 */
>>> -/*
>>> - * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming
>>> - *
>>> - * Early support for invoking 32-bit EFI services from a 64-bit kernel.
>>> - *
>>> - * Because this thunking occurs before ExitBootServices() we have to
>>> - * restore the firmware's 32-bit GDT and IDT before we make EFI service
>>> - * calls.
>>> - *
>>> - * On the plus side, we don't have to worry about mangling 64-bit
>>> - * addresses into 32-bits because we're executing with an identity
>>> - * mapped pagetable and haven't transitioned to 64-bit virtual addresses
>>> - * yet.
>>> - */
>>> -
>>> -#include <linux/linkage.h>
>>> -#include <asm/desc_defs.h>
>>> -#include <asm/msr.h>
>>> -#include <asm/page_types.h>
>>> -#include <asm/pgtable_types.h>
>>> -#include <asm/processor-flags.h>
>>> -#include <asm/segment.h>
>>> -
>>> -     .text
>>> -     .code32
>>> -#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> -SYM_FUNC_START(efi32_stub_entry)
>>> -     call    1f
>>> -1:   popl    %ecx
>>> -
>>> -     /* Clear BSS */
>>> -     xorl    %eax, %eax
>>> -     leal    (_bss - 1b)(%ecx), %edi
>>> -     leal    (_ebss - 1b)(%ecx), %ecx
>>> -     subl    %edi, %ecx
>>> -     shrl    $2, %ecx
>>> -     cld
>>> -     rep     stosl
>>> -
>>> -     add     $0x4, %esp              /* Discard return address */
>>> -     movl    8(%esp), %ebx           /* struct boot_params pointer */
>>> -     jmp     efi32_startup
>>> -SYM_FUNC_END(efi32_stub_entry)
>>> -#endif
>>> -
>>> -/*
>>> - * Called using a far call from __efi64_thunk() below, using the x86_64 SysV
>>> - * ABI (except for R8/R9 which are inaccessible to 32-bit code - EAX/EBX are
>>> - * used instead).  EBP+16 points to the arguments passed via the stack.
>>> - *
>>> - * The first argument (EDI) is a pointer to the boot service or protocol, to
>>> - * which the remaining arguments are passed, each truncated to 32 bits.
>>> - */
>>> -SYM_FUNC_START_LOCAL(efi_enter32)
>>> -     /*
>>> -      * Convert x86-64 SysV ABI params to i386 ABI
>>> -      */
>>> -     pushl   32(%ebp)        /* Up to 3 args passed via the stack */
>>> -     pushl   24(%ebp)
>>> -     pushl   16(%ebp)
>>> -     pushl   %ebx            /* R9 */
>>> -     pushl   %eax            /* R8 */
>>> -     pushl   %ecx
>>> -     pushl   %edx
>>> -     pushl   %esi
>>> -
>>> -     /* Disable paging */
>>> -     movl    %cr0, %eax
>>> -     btrl    $X86_CR0_PG_BIT, %eax
>>> -     movl    %eax, %cr0
>>> -
>>> -     /* Disable long mode via EFER */
>>> -     movl    $MSR_EFER, %ecx
>>> -     rdmsr
>>> -     btrl    $_EFER_LME, %eax
>>> -     wrmsr
>>> -
>>> -     call    *%edi
>>> -
>>> -     /* We must preserve return value */
>>> -     movl    %eax, %edi
>>> -
>>> -     call    efi32_enable_long_mode
>>> -
>>> -     addl    $32, %esp
>>> -     movl    %edi, %eax
>>> -     lret
>>> -SYM_FUNC_END(efi_enter32)
>>> -
>>> -     .code64
>>> -SYM_FUNC_START(__efi64_thunk)
>>> -     push    %rbp
>>> -     movl    %esp, %ebp
>>> -     push    %rbx
>>> -
>>> -     /* Move args #5 and #6 into 32-bit accessible registers */
>>> -     movl    %r8d, %eax
>>> -     movl    %r9d, %ebx
>>> -
>>> -     lcalll  *efi32_call(%rip)
>>> -
>>> -     pop     %rbx
>>> -     pop     %rbp
>>> -     RET
>>> -SYM_FUNC_END(__efi64_thunk)
>>> -
>>> -     .code32
>>> -SYM_FUNC_START_LOCAL(efi32_enable_long_mode)
>>> -     movl    %cr4, %eax
>>> -     btsl    $(X86_CR4_PAE_BIT), %eax
>>> -     movl    %eax, %cr4
>>> -
>>> -     movl    $MSR_EFER, %ecx
>>> -     rdmsr
>>> -     btsl    $_EFER_LME, %eax
>>> -     wrmsr
>>> -
>>> -     /* Disable interrupts - the firmware's IDT does not work in long mode */
>>> -     cli
>>> -
>>> -     /* Enable paging */
>>> -     movl    %cr0, %eax
>>> -     btsl    $X86_CR0_PG_BIT, %eax
>>> -     movl    %eax, %cr0
>>> -     ret
>>> -SYM_FUNC_END(efi32_enable_long_mode)
>>> -
>>> -/*
>>> - * This is the common EFI stub entry point for mixed mode. It sets up the GDT
>>> - * and page tables needed for 64-bit execution, after which it calls the
>>> - * common 64-bit EFI entrypoint efi_stub_entry().
>>> - *
>>> - * Arguments:        0(%esp) image handle
>>> - *           4(%esp) EFI system table pointer
>>> - *           %ebx    struct boot_params pointer (or NULL)
>>> - *
>>> - * Since this is the point of no return for ordinary execution, no registers
>>> - * are considered live except for the function parameters. [Note that the EFI
>>> - * stub may still exit and return to the firmware using the Exit() EFI boot
>>> - * service.]
>>> - */
>>> -SYM_FUNC_START_LOCAL(efi32_startup)
>>> -     movl    %esp, %ebp
>>> -
>>> -     subl    $8, %esp
>>> -     sgdtl   (%esp)                  /* Save GDT descriptor to the stack */
>>> -     movl    2(%esp), %esi           /* Existing GDT pointer */
>>> -     movzwl  (%esp), %ecx            /* Existing GDT limit */
>>> -     inc     %ecx                    /* Existing GDT size */
>>> -     andl    $~7, %ecx               /* Ensure size is multiple of 8 */
>>> -
>>> -     subl    %ecx, %esp              /* Allocate new GDT */
>>> -     andl    $~15, %esp              /* Realign the stack */
>>> -     movl    %esp, %edi              /* New GDT address */
>>> -     leal    7(%ecx), %eax           /* New GDT limit */
>>> -     pushw   %cx                     /* Push 64-bit CS (for LJMP below) */
>>> -     pushl   %edi                    /* Push new GDT address */
>>> -     pushw   %ax                     /* Push new GDT limit */
>>> -
>>> -     /* Copy GDT to the stack and add a 64-bit code segment at the end */
>>> -     movl    $GDT_ENTRY(DESC_CODE64, 0, 0xfffff) & 0xffffffff, (%edi,%ecx)
>>> -     movl    $GDT_ENTRY(DESC_CODE64, 0, 0xfffff) >> 32, 4(%edi,%ecx)
>>> -     shrl    $2, %ecx
>>> -     cld
>>> -     rep     movsl                   /* Copy the firmware GDT */
>>> -     lgdtl   (%esp)                  /* Switch to the new GDT */
>>> -
>>> -     call    1f
>>> -1:   pop     %edi
>>> -
>>> -     /* Record mixed mode entry */
>>> -     movb    $0x0, (efi_is64 - 1b)(%edi)
>>> -
>>> -     /* Set up indirect far call to re-enter 32-bit mode */
>>> -     leal    (efi32_call - 1b)(%edi), %eax
>>> -     addl    %eax, (%eax)
>>> -     movw    %cs, 4(%eax)
>>> -
>>> -     /* Disable paging */
>>> -     movl    %cr0, %eax
>>> -     btrl    $X86_CR0_PG_BIT, %eax
>>> -     movl    %eax, %cr0
>>> -
>>> -     /* Set up 1:1 mapping */
>>> -     leal    (pte - 1b)(%edi), %eax
>>> -     movl    $_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE, %ecx
>>> -     leal    (_PAGE_PRESENT | _PAGE_RW)(%eax), %edx
>>> -2:   movl    %ecx, (%eax)
>>> -     addl    $8, %eax
>>> -     addl    $PMD_SIZE, %ecx
>>> -     jnc     2b
>>> -
>>> -     movl    $PAGE_SIZE, %ecx
>>> -     .irpc   l, 0123
>>> -     movl    %edx, \l * 8(%eax)
>>> -     addl    %ecx, %edx
>>> -     .endr
>>> -     addl    %ecx, %eax
>>> -     movl    %edx, (%eax)
>>> -     movl    %eax, %cr3
>>> -
>>> -     call    efi32_enable_long_mode
>>> -
>>> -     /* Set up far jump to 64-bit mode (CS is already on the stack) */
>>> -     leal    (efi_stub_entry - 1b)(%edi), %eax
>>> -     movl    %eax, 2(%esp)
>>> -
>>> -     movl    0(%ebp), %edi
>>> -     movl    4(%ebp), %esi
>>> -     movl    %ebx, %edx
>>> -     ljmpl   *2(%esp)
>>> -SYM_FUNC_END(efi32_startup)
>>> -
>>> -/*
>>> - * efi_status_t efi32_pe_entry(efi_handle_t image_handle,
>>> - *                          efi_system_table_32_t *sys_table)
>>> - */
>>> -SYM_FUNC_START(efi32_pe_entry)
>>> -     pushl   %ebx                            // save callee-save registers
>>> -
>>> -     /* Check whether the CPU supports long mode */
>>> -     movl    $0x80000001, %eax               // assume extended info support
>>> -     cpuid
>>> -     btl     $29, %edx                       // check long mode bit
>>> -     jnc     1f
>>> -     leal    8(%esp), %esp                   // preserve stack alignment
>>> -     xor     %ebx, %ebx                      // no struct boot_params pointer
>>> -     jmp     efi32_startup                   // only ESP and EBX remain live
>>> -1:   movl    $0x80000003, %eax               // EFI_UNSUPPORTED
>>> -     popl    %ebx
>>> -     RET
>>> -SYM_FUNC_END(efi32_pe_entry)
>>> -
>>> -#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> -     .org    efi32_stub_entry + 0x200
>>> -     .code64
>>> -SYM_FUNC_START_NOALIGN(efi64_stub_entry)
>>> -     jmp     efi_handover_entry
>>> -SYM_FUNC_END(efi64_stub_entry)
>>> -#endif
>>> -
>>> -     .data
>>> -     .balign 8
>>> -SYM_DATA_START_LOCAL(efi32_call)
>>> -     .long   efi_enter32 - .
>>> -     .word   0x0
>>> -SYM_DATA_END(efi32_call)
>>> -SYM_DATA(efi_is64, .byte 1)
>>> -
>>> -     .bss
>>> -     .balign PAGE_SIZE
>>> -SYM_DATA_LOCAL(pte, .fill 6 * PAGE_SIZE, 1, 0)


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ