All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Vallejo <alejandro.vallejo@cloud.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Alejandro Vallejo" <alejandro.vallejo@cloud.com>,
	"Frediano Ziglio" <frediano.ziglio@cloud.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH 5/5] x86: Rollback relocation in case of EFI multiboot
Date: Wed,  7 Aug 2024 14:48:19 +0100	[thread overview]
Message-ID: <20240807134819.8987-6-alejandro.vallejo@cloud.com> (raw)
In-Reply-To: <20240807134819.8987-1-alejandro.vallejo@cloud.com>

In case EFI not multiboot rolling back relocation is done in
efi_arch_post_exit_boot, called by efi_start however this is
not done in multiboot code path.
Do it also for this path to make it work correctly.

Signed-off-by: Frediano Ziglio <frediano.ziglio@cloud.com>
---
 xen/arch/x86/boot/head.S  | 29 +++++++++++++++---
 xen/arch/x86/boot/reloc.c | 63 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index abfa3d82f7..75ac74a589 100644
--- 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
         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
+        /* Prepare stack for relocation call */
+        subq    $16, %rsp
+        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
+        movl    %esi, (%rsp)
+        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
@@ -557,6 +571,12 @@ __start:
         and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
         jmp     .Lmb2_tsize
 
+trampoline_efi_setup:
+        movb    $1, %al
+        call    reloc
+        pop     %eax
+        jmp     trampoline_setup
+
 trampoline_bios_setup:
         /*
          * Called on legacy BIOS platforms only.
@@ -627,6 +647,7 @@ trampoline_setup:
         push    %ecx                /* Bottom-most low-memory stack address. */
         push    %ebx                /* Multiboot / PVH information address. */
         push    %eax                /* Magic number. */
+        movb    $0, %al
         call    reloc
 #ifdef CONFIG_PVH_GUEST
         cmpb    $0, sym_esi(pvh_boot)
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index 4033557481..3aa97a99d0 100644
--- 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"
+    "    jmp  reloc_pe_back            \n"
     );
 
 #include "defs.h"
@@ -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[];
+};
+
+#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)
+{
+    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;
+            }
+        }
+        base_relocs = (const void *)(base_relocs->entries + i + (i & 1));
+    }
+}
+
 /*
  * Local variables:
  * mode: C
-- 
2.45.2



  parent reply	other threads:[~2024-08-07 13:48 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 ` Alejandro Vallejo [this message]
2024-08-08 10:36   ` [PATCH 5/5] x86: Rollback relocation in case of EFI multiboot Jan Beulich

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=20240807134819.8987-6-alejandro.vallejo@cloud.com \
    --to=alejandro.vallejo@cloud.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=frediano.ziglio@cloud.com \
    --cc=jbeulich@suse.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.