From: Jan Beulich <jbeulich@suse.com>
To: Alejandro Vallejo <alejandro.vallejo@cloud.com>,
Frediano Ziglio <frediano.ziglio@cloud.com>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Roger Pau Monné" <roger.pau@citrix.com>,
Xen-devel <xen-devel@lists.xenproject.org>
Subject: Re: [PATCH 5/5] x86: Rollback relocation in case of EFI multiboot
Date: Thu, 8 Aug 2024 12:36:38 +0200 [thread overview]
Message-ID: <68a1b0cf-24a4-49a2-a398-6fa56a6bcdc3@suse.com> (raw)
In-Reply-To: <20240807134819.8987-6-alejandro.vallejo@cloud.com>
On 07.08.2024 15:48, Alejandro Vallejo wrote:
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -352,6 +352,7 @@ __efi64_mb2_start:
> and $~15,%rsp
>
> /* Save Multiboot2 magic on the stack. */
> + shlq $32, %rax
As indicated for the earlier patch: No insn suffixes please when they're
not actually needed to clarify operand size. (Or else at the very least
be consistent and have suffixes everywhere. Comment applies throughout
the patch.)
Additionally there's some trickery going on here which absolutely needs
commenting, at least lightly. Aiui ...
> push %rax
>
> /* Save EFI ImageHandle on the stack. */
> @@ -382,11 +383,24 @@ __efi64_mb2_start:
> /* Just pop an item from the stack. */
> pop %rax
>
> - /* Restore Multiboot2 magic. */
> - pop %rax
... you eliminate this in favor of ...
> + /* Prepare stack for relocation call */
> + subq $16, %rsp
... using the low half of that stack slot here for the last function
argument, then POPing %eax entirely elsewhere, in trampoline_efi_setup.
> + lea l2_bootmap(%rip), %ecx
> + movl %ecx, 16(%rsp)
> + lea l3_bootmap(%rip), %ecx
> + movl %ecx, 12(%rsp)
> + lea __base_relocs_end(%rip), %ecx
> + movl %ecx, 8(%rsp)
> + lea __base_relocs_start(%rip), %ecx
> + movl %ecx, 4(%rsp)
> + lea __image_base__(%rip),%rsi
Nit: Consistently blanks after commas please in new code.
> + movl %esi, (%rsp)
Since a 32-bit value suffices, why a 64-bit LEA above?
> + movabsq $__XEN_VIRT_START, %rcx
> + subq %rsi, %rcx
> + push %rcx
>
> - /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
> - lea trampoline_setup(%rip),%r15
> + /* Jump to trampoline_efi_setup after switching CPU to x86_32 mode. */
> + lea trampoline_efi_setup(%rip),%r15
>
> x86_32_switch:
> mov %r15,%rdi
All of the changes here are benign to the existing MB2/EFI code path just
because __base_relocs_start[] is empty there, aiui. That could certainly
do with making explicit in the description. Initially I meant to indicate
that apparently you're breaking that path.
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -23,7 +23,9 @@ asm (
> " .text \n"
> " .globl _start \n"
> "_start: \n"
> - " jmp reloc \n"
> + " cmpb $0, %al \n"
> + " je reloc \n"
While minor here, I think we should generally prefer TEST (and then JZ)
over CMP when checking for 0. I wonder though whether we really want to
go with this kind of multiplexing. A new reloc-pe.c may be a cleaner
approach. This may then (possibly later) also allow to (more easily)
exclude this code when linking xen-syms.
> @@ -375,6 +377,65 @@ void *__stdcall reloc(uint32_t magic, uint32_t in, uint32_t trampoline,
> }
> }
>
> +struct pe_base_relocs {
> + u32 rva;
> + u32 size;
> + u16 entries[];
uint<N>_t please in new code (but see also at the bottom).
> +};
> +
> +#define PE_BASE_RELOC_ABS 0
> +#define PE_BASE_RELOC_HIGHLOW 3
> +#define PE_BASE_RELOC_DIR64 10
> +
> +void __stdcall reloc_pe_back(long long delta,
> + uint32_t xen_phys_start,
> + const struct pe_base_relocs *__base_relocs_start,
> + const struct pe_base_relocs *__base_relocs_end,
> + char *l3_bootmap, char *l2_bootmap)
You only ever use the last two when cast to unsigned long. What's wrong
with declaring them as unsigned long right away? xen_phys_start may also
want to have unsigned long type.
> +{
> + const struct pe_base_relocs *base_relocs;
> +
> + for ( base_relocs = __base_relocs_start; base_relocs < __base_relocs_end; )
> + {
> + unsigned int i = 0, n;
> +
> + n = (base_relocs->size - sizeof(*base_relocs)) /
> + sizeof(*base_relocs->entries);
> +
> + /*
> + * Relevant l{2,3}_bootmap entries get initialized explicitly in
> + * efi_arch_memory_setup(), so we must not apply relocations there.
> + * l2_directmap's first slot, otoh, should be handled normally, as
> + * efi_arch_memory_setup() won't touch it (xen_phys_start should
> + * never be zero).
> + */
> + if ( xen_phys_start + base_relocs->rva == (unsigned long)l3_bootmap ||
> + xen_phys_start + base_relocs->rva == (unsigned long)l2_bootmap )
> + i = n;
> +
> + for ( ; i < n; ++i )
> + {
> + unsigned long addr = xen_phys_start + base_relocs->rva +
> + (base_relocs->entries[i] & 0xfff);
> +
> + switch ( base_relocs->entries[i] >> 12 )
> + {
> + case PE_BASE_RELOC_ABS:
> + break;
> + case PE_BASE_RELOC_HIGHLOW:
> + if ( delta )
> + *(u32 *)addr += delta;
> + break;
> + case PE_BASE_RELOC_DIR64:
> + if ( delta )
> + *(u64 *)addr += delta;
> + break;
> + }
Except for the dropped default case (which imo needs to be there, just
that you can't use blexit() here), the body of the function looks like
a plain copy of efi_arch_relocate_image(). We want to avoid such
(source) duplication, and rather put the logic in e.g. a header
included by both parties.
Jan
prev parent reply other threads:[~2024-08-08 10:36 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-07 13:48 [PATCH 0/5] Improve support for EFI multiboot loading Alejandro Vallejo
2024-08-07 13:48 ` [PATCH 1/5] x86: Put trampoline in .init.data section Alejandro Vallejo
2024-08-08 7:34 ` Jan Beulich
[not found] ` <CACHz=Zh7wK58mbB762fnevHEKW9qhp-NRJ6buNe1b-qLxP0qPg@mail.gmail.com>
[not found] ` <b9b40658-ff13-4240-98a2-4811411e31b6@suse.com>
2024-08-08 13:05 ` Frediano Ziglio
2024-08-19 14:16 ` Frediano Ziglio
2024-08-19 14:29 ` Jan Beulich
2024-08-19 15:30 ` Frediano Ziglio
2024-08-19 15:50 ` Jan Beulich
2024-08-27 14:56 ` Frediano Ziglio
2024-08-27 15:55 ` Jan Beulich
2024-08-07 13:48 ` [PATCH 2/5] x86: Fix early output messages in case of EFI Alejandro Vallejo
2024-08-08 7:49 ` Jan Beulich
[not found] ` <CACHz=ZjYdBcB_S1tpXpuRQDKGAKY=SrgTEy8_0Wyq_q+bOBfHg@mail.gmail.com>
2024-08-08 9:29 ` Jan Beulich
[not found] ` <CACHz=ZgRK2DMHmiAVsBo1WJVBxbnTka3-CcpgopKB-6gWs5ZSw@mail.gmail.com>
2024-08-08 12:58 ` Jan Beulich
2024-08-08 13:17 ` Frediano Ziglio
2024-08-08 14:04 ` Jan Beulich
2024-08-07 13:48 ` [PATCH 3/5] x86: Set xen_phys_start and trampoline_xen_phys_start earlier Alejandro Vallejo
2024-08-08 8:25 ` Jan Beulich
2024-08-09 12:48 ` Frediano Ziglio
2024-08-09 12:59 ` Jan Beulich
2024-08-09 13:50 ` Frediano Ziglio
2024-08-09 14:02 ` Jan Beulich
2024-08-09 14:34 ` Frediano Ziglio
2024-08-12 8:41 ` Jan Beulich
2024-08-12 12:42 ` Frediano Ziglio
2024-08-07 13:48 ` [PATCH 4/5] x86: Force proper gdt_boot_base setting Alejandro Vallejo
2024-08-08 9:58 ` Jan Beulich
2024-08-07 13:48 ` [PATCH 5/5] x86: Rollback relocation in case of EFI multiboot Alejandro Vallejo
2024-08-08 10:36 ` Jan Beulich [this message]
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=68a1b0cf-24a4-49a2-a398-6fa56a6bcdc3@suse.com \
--to=jbeulich@suse.com \
--cc=alejandro.vallejo@cloud.com \
--cc=andrew.cooper3@citrix.com \
--cc=frediano.ziglio@cloud.com \
--cc=roger.pau@citrix.com \
--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.