On 24/09/2024 11:28 am, Frediano Ziglio wrote:
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 80bba6ff21..6d8eec554b 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -253,36 +244,30 @@ __efi64_mb2_start:
>          shr     $3, %ecx
>          xor     %eax, %eax
>          rep stosq
> -        mov     %edx, %eax
>  
> -        /* Check for Multiboot2 bootloader. */
> -        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> -        je      .Lefi_multiboot2_proto
> -
> -        /* Jump to .Lnot_multiboot after switching CPU to x86_32 mode. */
> -        lea     .Lnot_multiboot(%rip), %r15
> -        jmp     x86_32_switch
> +        /* Save Multiboot2 magic on the stack. */
> +        push    %rdx
>  
> -.Lefi_multiboot2_proto:
> -        /* Zero EFI SystemTable, EFI ImageHandle addresses and cmdline. */
> -        xor     %esi,%esi
> -        xor     %edi,%edi
> -        xor     %edx,%edx
> +        /* Save Multiboot2 pointer on the stack, keep the stack aligned. */
> +        push    %rbx

I'd merge these two pushes, so

    /* Spill MB2 magic.  Spill the pointer too, to keep the stack
aligned. */
    push %rdx
    push %rbx

and ...

>  
> -        /* Skip Multiboot2 information fixed part. */
> -        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%ecx
> -        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        /*
> +         * efi_parse_mbi2() is called according to System V AMD64 ABI:
> +         *   - IN:  %edi - Multiboot2 magic, %rsi - Multiboot2 pointer.

%rsi below %edi please, for readability.

> +         *   - OUT: %rax - error string.
> +         */
> +        mov     %edx, %edi
> +        mov     %rbx, %rsi
> +        call    efi_parse_mbi2
> +        lea     .Ldirect_error(%rip), %r15
> +        test    %rax, %rax
> +        jnz     x86_32_switch
>  
> -.Lefi_mb2_tsize:
> -        /* Check Multiboot2 information total size. */
> -        mov     %ecx,%r8d
> -        sub     %ebx,%r8d
> -        cmp     %r8d,MB2_fixed_total_size(%rbx)
> -        jbe     .Lrun_bs
> +        /* Restore Multiboot2 pointer. */
> +        pop     %rbx
>  
> -        /* Are EFI boot services available? */
> -        cmpl    $MULTIBOOT2_TAG_TYPE_EFI_BS,MB2_tag_type(%rcx)
> -        jne     .Lefi_mb2_st
> +        /* Restore Multiboot2 magic. */
> +        pop     %rax

... merge these pops too.  (It's a shame the pushes/pops implement a
%edx -> %eax swap for magic, but it's for BSS clearing purposes.)

> diff --git a/xen/arch/x86/efi/parse-mbi2.c b/xen/arch/x86/efi/parse-mbi2.c
> new file mode 100644
> index 0000000000..6038f35b16
> --- /dev/null
> +++ b/xen/arch/x86/efi/parse-mbi2.c
> @@ -0,0 +1,58 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <xen/efi.h>
> +#include <xen/init.h>
> +#include <xen/multiboot2.h>
> +#include <asm/asm_defns.h>
> +#include <asm/efibind.h>
> +#include <efi/efidef.h>
> +#include <efi/eficapsule.h>
> +#include <efi/eficon.h>
> +#include <efi/efidevp.h>
> +#include <efi/efiapi.h>
> +
> +void __init efi_multiboot2(EFI_HANDLE ImageHandle,
> +                           EFI_SYSTEM_TABLE *SystemTable,
> +                           const char *cmdline);

This wants to be in a header file seen by all references.  I see you
you've fixed up an error in the stub clearly caused by the absence of a
shared header.

> +
> +const char * asmlinkage __init
> +efi_parse_mbi2(uint32_t magic, const multiboot2_fixed_t *mbi)
> +{
> +    const multiboot2_tag_t *tag;
> +    EFI_HANDLE ImageHandle = NULL;
> +    EFI_SYSTEM_TABLE *SystemTable = NULL;
> +    const char *cmdline = NULL;
> +    bool have_bs = false;
> +
> +    if ( magic != MULTIBOOT2_BOOTLOADER_MAGIC )
> +        return "ERR: Not a Multiboot2 bootloader!";
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = _p(ROUNDUP((unsigned long)(mbi + 1), MULTIBOOT2_TAG_ALIGN));
> +
> +    for ( ; (const void *)tag - (const void *)mbi < mbi->total_size
> +            && tag->type != MULTIBOOT2_TAG_TYPE_END;
> +          tag = _p(ROUNDUP((unsigned long)((const void *)tag + tag->size),
> +                   MULTIBOOT2_TAG_ALIGN)) )
> +    {
> +        if ( tag->type == MULTIBOOT2_TAG_TYPE_EFI_BS )
> +            have_bs = true;
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_EFI64 )
> +            SystemTable = _p(((const multiboot2_tag_efi64_t *)tag)->pointer);
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_EFI64_IH )
> +            ImageHandle = _p(((const multiboot2_tag_efi64_ih_t 
> *)tag)->pointer);
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_CMDLINE )
> +            cmdline = ((const multiboot2_tag_string_t *)tag)->string;

switch ( tag->type ) please.  It's more lines, but more legible.

Otherwise, LGTM.  Definitely nice to move this out of asm.

~Andrew

Reply via email to