All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: Daniel Kiper <daniel.kiper@oracle.com>
Cc: Juergen Gross <JGross@suse.com>,
	sstabellini@kernel.org, konrad.wilk@oracle.com,
	andrew.cooper3@citrix.com, cardoe@cardoe.com,
	pgnet.dev@gmail.com, ning.sun@intel.com, julien.grall@arm.com,
	xen-devel@lists.xenproject.org, qiaowei.ren@intel.com,
	gang.wei@intel.com, fu.wei@linaro.org
Subject: Re: [PATCH v12 05/10] x86: add multiboot2 protocol support for EFI platforms
Date: Fri, 20 Jan 2017 05:40:55 -0700	[thread overview]
Message-ID: <588213670200007800132307@prv-mh.provo.novell.com> (raw)
In-Reply-To: <20170120114323.GJ23864@olila.local.net-space.pl>

>>> On 20.01.17 at 12:43, <daniel.kiper@oracle.com> wrote:
> On Fri, Jan 20, 2017 at 02:46:47AM -0700, Jan Beulich wrote:
>> >>> On 20.01.17 at 02:34, <daniel.kiper@oracle.com> wrote:
>> > @@ -100,20 +107,48 @@ multiboot2_header_start:
>> >  gdt_boot_descr:
>> >          .word   6*8-1
>> >          .long   sym_phys(trampoline_gdt)
>> > +        .long   0 /* Needed for 64-bit lgdt */
>> > +
>> > +        .align 4
>> > +vga_text_buffer:
>> > +        .long   0xb8000
>> > +
>> > +efi_platform:
>> > +        .byte   0
>>
>> You mean to modify these fields, but you add them to a r/o section.
> 
> Yep. So, I think that we should move them to .init.data. Is it OK for you?

That's what I'm asking for, yes.

>> > +.Lefi_multiboot2_proto:
>> > +        /* Zero EFI SystemTable and EFI ImageHandle addresses. */
>> > +        xor     %esi,%esi
>> > +        xor     %edi,%edi
>> > +
>> > +        /* Skip Multiboot2 information fixed part. */
>> > +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%ecx
>>
>> In an earlier reply to Andrew's inquiry regarding the possible
>> truncation here you said that grub can be made obey to such a
>> load restriction. None of the tags added here or in patch 2
>> appear to have such an effect, so would you please clarify how
>> the address restriction is being enforced?
> 
> GRUB2 itself does allocations for all multiboot2 stuff always below 4 GiB.
> So, there is no need for extra tags.
> 
> Additionally, multiboot2 spec says this:
> 
> The bootloader must not load any part of the kernel, the modules, the Multiboot2
> information structure, etc. higher than 4 GiB - 1. This requirement is put in
> force because most of currently specified tags supports 32-bit addresses only.
> Additionally, some kernels, even if they run on EFI 64-bit platform, still
> execute some parts of its initialization code in 32-bit mode.

Okay, that's good enough for now, even if it escapes me how that's
supposed to work on systems without any memory below 4Gb.

>> > +        /* Are EFI boot services available? */
>> > +        cmpb    $0,efi_platform(%rip)
>> > +        jnz     0f
>> > +
>> > +        /* Jump to .Lmb2_no_bs after switching CPU to x86_32 mode. */
>> > +        lea     .Lmb2_no_bs(%rip),%edi
>> > +        jmp     x86_32_switch
>> > +0:
>>
>> I realize you need to avoid clobbering %rdi in the non-error case,
>> but the register choice seems sub-optimal: If you used a register
>> which you can clobber here (e.g. %edx as it seems, using %edi in
>> its place at x86_32_switch and cs32_switch), you could simplify
>> this to
>>
>>     cmpb ...
>>     lea ...
>>     je x86_32_switch
>>
>> at once avoiding all the numeric labels here.
> 
> If you do not care that it will be always loaded then OK.

That's okay, of course. The main thing is that we should prefer the
one branch variant over the two branches one.

> However, I think
> that %r15d is a bit better here because if we need to add another argument
> to efi_multiboot2() and we use %edx then we must change code in more places.
> Of course we should do "mov %r15d,%edi" after x86_32_switch label then.

As long as all affected code lives outside of the trampoline, using
any of the high 8 registers is certainly fine here.

>> > +2:
>> > +        push    %rax
>> > +        push    %rdi
>> > +
>> > +        /*
>> > +         * Initialize BSS (no nasty surprises!).
>> > +         * It must be done earlier than in BIOS case
>> > +         * because efi_multiboot2() touches it.
>> > +         */
>> > +        lea     __bss_start(%rip),%edi
>> > +        lea     __bss_end(%rip),%ecx
>> > +        sub     %edi,%ecx
>> > +        shr     $3,%ecx
>> > +        xor     %eax,%eax
>> > +        rep stosq
>> > +
>> > +        pop     %rdi
>> > +
>> > +        /*
>> > +         * efi_multiboot2() is called according to System V AMD64 ABI:
>> > +         *   - IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable,
>> > +         *   - OUT: %rax - highest allocated memory address below 1 MiB;
>> > +         *                 memory below this address is used for trampoline
>> > +         *                 stack, trampoline itself and as a storage for
>> > +         *                 mbi struct created in reloc().
>> > +         *
>> > +         * MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag is not provided
>> > +         * on EFI platforms. Hence, it could not be used like
>> > +         * on legacy BIOS platforms.
>> > +         */
>> > +        call    efi_multiboot2
>>
>> Now that we had a need for commit f6b7fedc89 ("x86/EFI: meet
>> further spec requirements for runtime calls") I'm worried about stack
>> alignment here. Does GrUB call or jmp to our entry point (and is that
>> firmly specified to be the case)? Perhaps it would be a good idea to
>> align the stack earlier on in any case. Or if not (and if alignment at
>> this call is ABI conforming), a comment should be left here to warn
>> people of future modifications to the amount of items pushed onto /
>> popped off the stack.
> 
> Multiboot2 spec requires that stack, among others, is passed to loaded
> image according to UEFI spec. Though, IIRC, there are no extra stack checks
> there. Maybe we should add something to GRUB2 if it does not exists.

That would imply they do a call (and not a jmp), which would make
the present code correct afaict. As said, imo there should still be a
warning added here, for anyone wanting to modify the stack layout.

>> > --- a/xen/arch/x86/efi/efi-boot.h
>> > +++ b/xen/arch/x86/efi/efi-boot.h
>> > @@ -100,6 +100,9 @@ static void __init relocate_trampoline(unsigned long phys)
>> >  {
>> >      const s32 *trampoline_ptr;
>> >
>> > +    if ( !efi_enabled(EFI_LOADER) || trampoline_phys )
>> > +        return;
>> > +
>> >      trampoline_phys = phys;
>> >      /* Apply relocations to trampoline. */
>> >      for ( trampoline_ptr = __trampoline_rel_start;
>> > @@ -210,12 +213,10 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>> >
>> >  static void __init efi_arch_pre_exit_boot(void)
>> >  {
>> > -    if ( !trampoline_phys )
>> > -    {
>> > -        if ( !cfg.addr )
>> > -            blexit(L"No memory for trampoline");
>> > -        relocate_trampoline(cfg.addr);
>> > -    }
>> > +    if ( !cfg.addr )
>> > +        blexit(L"No memory for trampoline");
>> > +
>> > +    relocate_trampoline(cfg.addr);
>> >  }
>>
>> Why can't this function be left untouched, and the change to
>> relocate_trampoline() above also be reduced or even be removed
>> altogether?
> 
> There is pretty good chance that efi_arch_pre_exit_boot() can be left
> untouched though relocate_trampoline() needs at least
> 
> if ( !efi_enabled(EFI_LOADER) )
>     return;

Right, hence the "reduced".

>> > +    SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
>> > +
>> > +    StdErr = SystemTable->StdErr ? SystemTable->StdErr : SystemTable->ConOut;
>> > +
>> > +    /*
>> > +     * Print error message and halt the system.
>> > +     *
>> > +     * We have to open code MS x64 calling convention
>> > +     * in assembly because here this convention may
>> > +     * not be directly supported by C compiler.
>> > +     */
>> > +    asm volatile(
>> > +    "    call *%2                     \n"
>> > +    "0:  hlt                          \n"
>> > +    "    jmp  0b                      \n"
>> > +       : "+c" (StdErr), "+d" (err) : "g" (StdErr->OutputString)
>>
>> The "g" really wants to be "rm": While the kind of expression doesn't
>> really allow for an immediate, you still shouldn't give wrong examples
>> of constraints (with the * now properly added to the call operand, it
>> doesn't allow for an immediate anymore).
> 
> I was considering that change once but I was not sure. Though if you
> think that it make sense I will do that.

Yes please.

>> > --- a/xen/include/asm-x86/config.h
>> > +++ b/xen/include/asm-x86/config.h
>> > @@ -73,6 +73,11 @@
>> >  #define STACK_ORDER 3
>> >  #define STACK_SIZE  (PAGE_SIZE << STACK_ORDER)
>> >
>> > +#define MB_TRAMPOLINE_STACK_SIZE        PAGE_SIZE
>> > +#define MB_TRAMPOLINE_SIZE              (KB(64) - MB_TRAMPOLINE_STACK_SIZE)
>>
>> What's the reason for the MB_ prefixes here? The trampoline is
>> always the same size, isn't it? Nor am I convinced we really need
> 
> Please take a look at efi_arch_memory_setup(). Amount of memory allocated
> for trampoline and other stuff depends on boot loader type. So, when I use
> "MB_" I would like underline that this is relevant for multiboot protocols.
> Though I think that we can use the same size for all protocols. However,
> I would not like to touch native EFI loader case.

You already don't touch it, and I see no reason why this should
change. Yet this is orthogonal to the naming of the constants here.
As said, the trampoline itself is always the same, and the stack
portion of it is simply unused in the native EFI loader case. Plus
MB_TRAMPOLINE_SIZE is in no way the size of the trampoline in the
first place. Perhaps TRAMPOLINE_SPACE (and then covering both
parts)?

>> two defines - except in the link time assertion you always use
>> the sum of the two.
>>
>> > +#define MBI_SIZE                        (2 * PAGE_SIZE)
>>
>> On top of Doug's question - if it is needed at all, what does this
> 
> Please look around reloc() call in xen/arch/x86/boot/head.S. You quickly
> realize that there is following memory layout from top to bottom:
> 
>         +------------------+
>         | TRAMPOLINE_STACK |
>         +------------------+
>         |    TRAMPOLINE    |
>         +------------------+
>         |    mbi struct    |
>         +------------------+
> 
>> match up with, i.e. how come this is 2 pages (and not 1 or 3)?
> 
> Just thought that 8 KiB will be sufficient for Xen/modules arguments,
> memory map and other minor things.

Even with a couple of dozen modules passed? But the primary
question was left unanswered anyway: Does this need placing in
the low megabyte at all? And even if it does, especially if you
limit it to 8k, I don't see why it wouldn't fit inside the 64k
trampoline area.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  reply	other threads:[~2017-01-20 12:40 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-20  1:34 [PATCH v12 00/10] x86: multiboot2 protocol support Daniel Kiper
2017-01-20  1:34 ` [PATCH v12 01/10] x86/boot: implement early command line parser in C Daniel Kiper
2017-01-20 16:37   ` Doug Goldstein
2017-01-20 16:41     ` Doug Goldstein
2017-01-20  1:34 ` [PATCH v12 02/10] x86: add multiboot2 protocol support Daniel Kiper
2017-01-20 16:52   ` Andrew Cooper
2017-01-20 17:24     ` Daniel Kiper
2017-01-20 18:07       ` Andrew Cooper
2017-01-20 19:01   ` Doug Goldstein
2017-01-20  1:34 ` [PATCH v12 03/10] efi: build xen.gz with EFI code Daniel Kiper
2017-01-20  1:34 ` [PATCH v12 04/10] efi: create new early memory allocator Daniel Kiper
2017-01-20  1:34 ` [PATCH v12 05/10] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
2017-01-20  4:37   ` Doug Goldstein
2017-01-20  9:46   ` Jan Beulich
2017-01-20 11:43     ` Daniel Kiper
2017-01-20 12:40       ` Jan Beulich [this message]
2017-01-20 13:46         ` Daniel Kiper
2017-01-20 14:10           ` Jan Beulich
2017-01-20 14:43             ` Daniel Kiper
2017-01-20 15:23               ` Jan Beulich
2017-01-20 19:04   ` Doug Goldstein
2017-01-20 19:05     ` Andrew Cooper
2017-01-20 19:34   ` Doug Goldstein
2017-01-20 21:42     ` Daniel Kiper
2017-01-20  1:34 ` [PATCH v12 06/10] x86: change default load address from 1 MiB to 2 MiB Daniel Kiper
2017-01-20  4:06   ` Doug Goldstein
2017-01-20  8:49     ` Jan Beulich
2017-01-20 10:29       ` Daniel Kiper
2017-01-20  1:34 ` [PATCH v12 07/10] x86/setup: use XEN_IMG_OFFSET instead of Daniel Kiper
2017-01-20  4:07   ` Doug Goldstein
2017-01-20  1:34 ` [PATCH v12 08/10] x86: make Xen early boot code relocatable Daniel Kiper
2017-01-20  1:34 ` [PATCH v12 09/10] x86/boot: rename sym_phys() to sym_offs() Daniel Kiper
2017-01-20  4:08   ` Doug Goldstein
2017-01-20  1:34 ` [PATCH v12 10/10] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
2017-01-20  4:08   ` Doug Goldstein
2017-01-20 16:22 ` [PATCH v12 00/10] x86: multiboot2 protocol support Doug Goldstein
2017-01-20 17:21   ` Daniel Kiper
2017-01-20 18:53     ` Doug Goldstein
2017-01-20 19:28     ` Doug Goldstein
2017-01-20 19:42 ` Doug Goldstein
2017-01-20 19:52   ` Doug Goldstein
2017-01-20 20:01   ` Konrad Rzeszutek Wilk
2017-01-20 21:54   ` Daniel Kiper
2017-01-23 13:08     ` Daniel Kiper
2017-01-23 14:28       ` Konrad Rzeszutek Wilk
2017-01-23 16:03         ` Doug Goldstein
2017-01-23 18:12           ` Daniel Kiper
2017-01-23 15:35       ` Doug Goldstein
2017-01-23 15:45         ` Daniel Kiper
2017-01-23 16:07           ` Doug Goldstein
2017-01-23 18:16             ` Daniel Kiper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=588213670200007800132307@prv-mh.provo.novell.com \
    --to=jbeulich@suse.com \
    --cc=JGross@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=cardoe@cardoe.com \
    --cc=daniel.kiper@oracle.com \
    --cc=fu.wei@linaro.org \
    --cc=gang.wei@intel.com \
    --cc=julien.grall@arm.com \
    --cc=konrad.wilk@oracle.com \
    --cc=ning.sun@intel.com \
    --cc=pgnet.dev@gmail.com \
    --cc=qiaowei.ren@intel.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.