Re: [PATCH 0/2] relocator/x86: fix multiboot2 Xen boot failure on GRUB 2.14

Leo Sandoval via Grub-devel <[email protected]> Thu, 14 May 2026 10:51:52 -0600
Newsgroups org.gnu.grub-devel
Message-ID <CACF7NTjPsu_xA0OfmQT0NqMdbjnMTT4u0AEWqn2Lw41Nb3rAzA@mail.gmail.com>
--===============3456224657962107283==
Content-Type: multipart/alternative; boundary="00000000000064357b0651c9ea7f"

--00000000000064357b0651c9ea7f
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Thanks for your series Jiaqing

We no longer accept contributions from the mailing list; we recently
switched to GitLab. Please create an account, verify it and propose an MR.
Detailed instructions are at

https://gitlab.freedesktop.org/gnu-grub/grub/-/blob/master/CONTRIBUTING

Leo

On Wed, May 13, 2026 at 10:12=E2=80=AFAM Jiaqing Zhao <[email protected]=
> wrote:

> Booting Xen via multiboot2 on x86_64 EFI is currently broken in two
> independent ways introduced by recent hardening work in the relocator
> path. This series fixes both issues.
>
> The first regression comes from commit d72208423dca ("kern/dl: Use
> correct segment in grub_dl_set_mem_attrs()"), which now correctly
> applies read-only attributes according to ELF section flags to .text
> sections of loaded modules. The x86 relocator stubs are, however,
> patched in place at runtime. With the new attributes in effect the
> runtime patch faults with #PF due to a write to a read-only page.
> Patch 1 moves those stubs to a dedicated .text.relocator section flagged
> "awx" (writable, executable) so the assembler emits expected ELF section
> flags for that usage.
>
> Fail log:
> kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes fo=
r
> section 1 at 0x7b3b7000, segement flags 0x6
> kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x5, clear_attrs 0=
x2
> kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes fo=
r
> section 3 at 0x7b3be000, segement flags 0x2
> kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x4, clear_attrs 0=
x3
> kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes fo=
r
> section 4 at 0x7b3bf000, segement flags 0x3
> kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x6, clear_attrs 0=
x1
> kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes fo=
r
> section 5 at 0x7b3c0000, segement flags 0x3
> kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x6, clear_attrs 0=
x1
> kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes fo=
r
> section 6 at 0x7b3c1000, segement flags 0x2
> kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x4, clear_attrs 0=
x3
> kern/dl.c:grub_dl_flush_cache:606:modules: flushing 0xb000 bytes at
> 0x7b3b7000
> kern/dl.c:grub_dl_load_core_noinit:798:modules: module name: relocator
> kern/dl.c:grub_dl_load_core_noinit:799:modules: init function: 0x0
>
> !!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID - 00000000 !!=
!!
> ExceptionData - 0000000000000003  I:0 R:0 U:0 W:1 P:1 PK:0 SS:0 SGX:0
> RIP  - 000000007B3BD1C4, CS  - 0000000000000038, RFLAGS - 000000000021024=
6
> RAX  - 0000000036D76289, RCX - 000000007FEC7ED8, RDX - 000000007B3B7BCA
> RBX  - 0000000000000000, RSP - 000000007FEC8290, RBP - 000000007FEC82D0
> RSI  - 0000000000000048, RDI - 0000000000003000
> R8   - 0000000000000000, R9  - 0000000000000020, R10 - 000000007DFC5CB0
> R11  - 00000000003E8000, R12 - 000000007E126F98, R13 - 000000007DF0AF20
> R14  - 000000007DF0AF28, R15 - 000000007DF0AF30
> DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
> GS   - 0000000000000030, SS  - 0000000000000030
> CR0  - 0000000080010033, CR2 - 000000007B3B7BCA, CR3 - 000000007FC01000
> CR4  - 0000000000000668, CR8 - 0000000000000000
> DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
> DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
> GDTR - 000000007F9D4000 0000000000000057, LDTR - 0000000000000000
> IDTR - 000000007F520018 0000000000000FFF,   TR - 0000000000000048
> FXSAVE_STATE - 000000007F9D3460
> !!!! Find image based on IP(0x7B3BD1C4) (No PDB)
> (ImageBase=3D0000000078E59000, EntryPoint=3D0000000079EC3A48) !!!!
>
> The second regression comes from commit 6898fcf74d13 ("relocator: Switch
> to own page table while moving chunks"), which builds a GRUB-owned page
> table covering [0, max_ram_size) and switches CR3 to it before moving
> chunks, to avoid clobbering firmware-owned page tables. Unfortunately,
> payloads such as Xen continue to access memory above max_ram_size after
> the switch, particularly for EFI runtime services and MMIO regions
> mapped high by the firmware, and those mappings are absent from GRUB's
> preamble page table,which again ends in #PF. Patch 2 generates the
> preamble PML4 based on the firmware's PML4 before overwriting entries
> for [0, max_ram_size), so high mappings remain reachable across the CR3
> switch.
>
> Fail log:
> lib/relocator.c:grub_relocator_prepare_relocs:1553:relocator: Relocs
> allocated
> at 0x100000
> lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk
> 0x3000->0x3000, 0x48
> lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk
> 0x2000->0x2000, 0x7a2
> lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk
> 0x27fa000->0x27fa000, 0x26c2226
> lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk
> 0x1780000->0x1780000, 0x1079988
> lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk
> 0x1000->0x1000, 0x18
> lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk
> 0x7da00000->0x7da00000, 0x400000
> lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chun=
k
> 0x1000->0x1000, 0x18
> lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chun=
k
> 0x2000->0x2000, 0x7a2
> lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chun=
k
> 0x3000->0x3000, 0x48
> lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chun=
k
> 0x1780000->0x1780000, 0x1079988
> lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chun=
k
> 0x27fa000->0x27fa000, 0x26c2226
> lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chun=
k
> 0x7da00000->0x7da00000, 0x400000
> !!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID - 00000000 !!=
!!
> ExceptionData - 0000000000000002  I:0 R:0 U:0 W:1 P:0 PK:0 SS:0 SGX:0
> RIP  - 000000007F517A02, CS  - 0000000000000038, RFLAGS - 000000000021024=
6
> RAX  - 0000000000000000, RCX - 0000000000000001, RDX - 000000007F5186E0
> RBX  - 0000387000000402, RSP - 000000007FEC7F90, RBP - 000000007FEC8010
> RSI  - 0000000000000000, RDI - 0000000000000001
> R8   - 000000007FEC80CC, R9  - 0000387000000402, R10 - 0000000000000000
> R11  - 0000000000000000, R12 - 000000007FEC80CC, R13 - 0000000000000001
> R14  - 0000000000000000, R15 - 0000000000000001
> DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
> GS   - 0000000000000030, SS  - 0000000000000030
> CR0  - 0000000080010033, CR2 - 0000387000000402, CR3 - 0000000000101000
> CR4  - 0000000000000668, CR8 - 0000000000000000
> DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
> DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
> GDTR - 000000007F9D4000 0000000000000057, LDTR - 0000000000000000
> IDTR - 000000007F520018 0000000000000FFF,   TR - 0000000000000048
> FXSAVE_STATE - 000000007F9D3460
> !!!! Find image based on IP(0x7F517A02)
> edk2/Build/OvmfX64/DEBUG_GCC/X64/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe/DEBUG/Cpu=
Io2Dxe.dll
> (ImageBase=3D000000007F516000, EntryPoint=3D000000007F517BE3) !!!!
>
> With both patches applied, multiboot2 Xen boot on x86_64 EFI works
> again, and the existing low-memory chunk-move protection is preserved.
>
> Jiaqing Zhao (2):
>   relocator/x86: place runtime-patched stubs in writable section
>   relocator/x86: inherit firmware PML4 in preamble page table
>
>  grub-core/lib/i386/relocator16.S        | 5 ++++-
>  grub-core/lib/i386/relocator32.S        | 3 +++
>  grub-core/lib/i386/relocator64.S        | 3 +++
>  grub-core/lib/i386/relocator_asm.S      | 3 +++
>  grub-core/lib/i386/relocator_common_c.c | 8 ++++++++
>  grub-core/lib/x86_64/relocator_asm.S    | 3 +++
>  6 files changed, 24 insertions(+), 1 deletion(-)
>
> --
> 2.53.0
>
>

--00000000000064357b0651c9ea7f
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thanks for your series Jiaqing</div><div><br><div>We =
no longer accept contributions from the=C2=A0mailing list; we recently swit=
ched to GitLab. Please create an account, verify it and propose an MR. Deta=
iled instructions are at</div><div><br></div><div><a href=3D"https://gitlab=
.freedesktop.org/gnu-grub/grub/-/blob/master/CONTRIBUTING">https://gitlab.f=
reedesktop.org/gnu-grub/grub/-/blob/master/CONTRIBUTING</a></div></div><div=
><br></div><div>Leo</div></div><br><div class=3D"gmail_quote gmail_quote_co=
ntainer"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, May 13, 2026 at 10:1=
2=E2=80=AFAM Jiaqing Zhao &lt;<a href=3D"mailto:[email protected]">Zhao.=
[email protected]</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pad=
ding-left:1ex">Booting Xen via multiboot2 on x86_64 EFI is currently broken=
 in two<br>
independent ways introduced by recent hardening work in the relocator<br>
path. This series fixes both issues.<br>
<br>
The first regression comes from commit d72208423dca (&quot;kern/dl: Use<br>
correct segment in grub_dl_set_mem_attrs()&quot;), which now correctly<br>
applies read-only attributes according to ELF section flags to .text<br>
sections of loaded modules. The x86 relocator stubs are, however,<br>
patched in place at runtime. With the new attributes in effect the<br>
runtime patch faults with #PF due to a write to a read-only page.<br>
Patch 1 moves those stubs to a dedicated .text.relocator section flagged<br=
>
&quot;awx&quot; (writable, executable) so the assembler emits expected ELF =
section<br>
flags for that usage.<br>
<br>
Fail log:<br>
kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes for<=
br>
section 1 at 0x7b3b7000, segement flags 0x6<br>
kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x5, clear_attrs 0x2=
<br>
kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes for<=
br>
section 3 at 0x7b3be000, segement flags 0x2<br>
kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x4, clear_attrs 0x3=
<br>
kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes for<=
br>
section 4 at 0x7b3bf000, segement flags 0x3<br>
kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x6, clear_attrs 0x1=
<br>
kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes for<=
br>
section 5 at 0x7b3c0000, segement flags 0x3<br>
kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x6, clear_attrs 0x1=
<br>
kern/dl.c:grub_dl_set_mem_attrs:684:modules: setting memory attributes for<=
br>
section 6 at 0x7b3c1000, segement flags 0x2<br>
kern/dl.c:grub_dl_set_mem_attrs:699:modules: set_attrs 0x4, clear_attrs 0x3=
<br>
kern/dl.c:grub_dl_flush_cache:606:modules: flushing 0xb000 bytes at 0x7b3b7=
000<br>
kern/dl.c:grub_dl_load_core_noinit:798:modules: module name: relocator<br>
kern/dl.c:grub_dl_load_core_noinit:799:modules: init function: 0x0<br>
<br>
!!!! X64 Exception Type - 0E(#PF - Page-Fault)=C2=A0 CPU Apic ID - 00000000=
 !!!!<br>
ExceptionData - 0000000000000003=C2=A0 I:0 R:0 U:0 W:1 P:1 PK:0 SS:0 SGX:0<=
br>
RIP=C2=A0 - 000000007B3BD1C4, CS=C2=A0 - 0000000000000038, RFLAGS - 0000000=
000210246<br>
RAX=C2=A0 - 0000000036D76289, RCX - 000000007FEC7ED8, RDX - 000000007B3B7BC=
A<br>
RBX=C2=A0 - 0000000000000000, RSP - 000000007FEC8290, RBP - 000000007FEC82D=
0<br>
RSI=C2=A0 - 0000000000000048, RDI - 0000000000003000<br>
R8=C2=A0 =C2=A0- 0000000000000000, R9=C2=A0 - 0000000000000020, R10 - 00000=
0007DFC5CB0<br>
R11=C2=A0 - 00000000003E8000, R12 - 000000007E126F98, R13 - 000000007DF0AF2=
0<br>
R14=C2=A0 - 000000007DF0AF28, R15 - 000000007DF0AF30<br>
DS=C2=A0 =C2=A0- 0000000000000030, ES=C2=A0 - 0000000000000030, FS=C2=A0 - =
0000000000000030<br>
GS=C2=A0 =C2=A0- 0000000000000030, SS=C2=A0 - 0000000000000030<br>
CR0=C2=A0 - 0000000080010033, CR2 - 000000007B3B7BCA, CR3 - 000000007FC0100=
0<br>
CR4=C2=A0 - 0000000000000668, CR8 - 0000000000000000<br>
DR0=C2=A0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 000000000000000=
0<br>
DR3=C2=A0 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 000000000000040=
0<br>
GDTR - 000000007F9D4000 0000000000000057, LDTR - 0000000000000000<br>
IDTR - 000000007F520018 0000000000000FFF,=C2=A0 =C2=A0TR - 0000000000000048=
<br>
FXSAVE_STATE - 000000007F9D3460<br>
!!!! Find image based on IP(0x7B3BD1C4) (No PDB)=C2=A0 (ImageBase=3D0000000=
078E59000, EntryPoint=3D0000000079EC3A48) !!!!<br>
<br>
The second regression comes from commit 6898fcf74d13 (&quot;relocator: Swit=
ch<br>
to own page table while moving chunks&quot;), which builds a GRUB-owned pag=
e<br>
table covering [0, max_ram_size) and switches CR3 to it before moving<br>
chunks, to avoid clobbering firmware-owned page tables. Unfortunately,<br>
payloads such as Xen continue to access memory above max_ram_size after<br>
the switch, particularly for EFI runtime services and MMIO regions<br>
mapped high by the firmware, and those mappings are absent from GRUB&#39;s<=
br>
preamble page table,which again ends in #PF. Patch 2 generates the<br>
preamble PML4 based on the firmware&#39;s PML4 before overwriting entries<b=
r>
for [0, max_ram_size), so high mappings remain reachable across the CR3<br>
switch.<br>
<br>
Fail log:<br>
lib/relocator.c:grub_relocator_prepare_relocs:1553:relocator: Relocs alloca=
ted<br>
at 0x100000<br>
lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk<br>
0x3000-&gt;0x3000, 0x48<br>
lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk<br>
0x2000-&gt;0x2000, 0x7a2<br>
lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk<br>
0x27fa000-&gt;0x27fa000, 0x26c2226<br>
lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk<br>
0x1780000-&gt;0x1780000, 0x1079988<br>
lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk<br>
0x1000-&gt;0x1000, 0x18<br>
lib/relocator.c:grub_relocator_prepare_relocs:1566:relocator: chunk<br>
0x7da00000-&gt;0x7da00000, 0x400000<br>
lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chunk<=
br>
0x1000-&gt;0x1000, 0x18<br>
lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chunk<=
br>
0x2000-&gt;0x2000, 0x7a2<br>
lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chunk<=
br>
0x3000-&gt;0x3000, 0x48<br>
lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chunk<=
br>
0x1780000-&gt;0x1780000, 0x1079988<br>
lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chunk<=
br>
0x27fa000-&gt;0x27fa000, 0x26c2226<br>
lib/relocator.c:grub_relocator_prepare_relocs:1613:relocator: sorted chunk<=
br>
0x7da00000-&gt;0x7da00000, 0x400000<br>
!!!! X64 Exception Type - 0E(#PF - Page-Fault)=C2=A0 CPU Apic ID - 00000000=
 !!!!<br>
ExceptionData - 0000000000000002=C2=A0 I:0 R:0 U:0 W:1 P:0 PK:0 SS:0 SGX:0<=
br>
RIP=C2=A0 - 000000007F517A02, CS=C2=A0 - 0000000000000038, RFLAGS - 0000000=
000210246<br>
RAX=C2=A0 - 0000000000000000, RCX - 0000000000000001, RDX - 000000007F5186E=
0<br>
RBX=C2=A0 - 0000387000000402, RSP - 000000007FEC7F90, RBP - 000000007FEC801=
0<br>
RSI=C2=A0 - 0000000000000000, RDI - 0000000000000001<br>
R8=C2=A0 =C2=A0- 000000007FEC80CC, R9=C2=A0 - 0000387000000402, R10 - 00000=
00000000000<br>
R11=C2=A0 - 0000000000000000, R12 - 000000007FEC80CC, R13 - 000000000000000=
1<br>
R14=C2=A0 - 0000000000000000, R15 - 0000000000000001<br>
DS=C2=A0 =C2=A0- 0000000000000030, ES=C2=A0 - 0000000000000030, FS=C2=A0 - =
0000000000000030<br>
GS=C2=A0 =C2=A0- 0000000000000030, SS=C2=A0 - 0000000000000030<br>
CR0=C2=A0 - 0000000080010033, CR2 - 0000387000000402, CR3 - 000000000010100=
0<br>
CR4=C2=A0 - 0000000000000668, CR8 - 0000000000000000<br>
DR0=C2=A0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 000000000000000=
0<br>
DR3=C2=A0 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 000000000000040=
0<br>
GDTR - 000000007F9D4000 0000000000000057, LDTR - 0000000000000000<br>
IDTR - 000000007F520018 0000000000000FFF,=C2=A0 =C2=A0TR - 0000000000000048=
<br>
FXSAVE_STATE - 000000007F9D3460<br>
!!!! Find image based on IP(0x7F517A02) edk2/Build/OvmfX64/DEBUG_GCC/X64/Ue=
fiCpuPkg/CpuIo2Dxe/CpuIo2Dxe/DEBUG/CpuIo2Dxe.dll (ImageBase=3D000000007F516=
000, EntryPoint=3D000000007F517BE3) !!!!<br>
<br>
With both patches applied, multiboot2 Xen boot on x86_64 EFI works<br>
again, and the existing low-memory chunk-move protection is preserved.<br>
<br>
Jiaqing Zhao (2):<br>
=C2=A0 relocator/x86: place runtime-patched stubs in writable section<br>
=C2=A0 relocator/x86: inherit firmware PML4 in preamble page table<br>
<br>
=C2=A0grub-core/lib/i386/relocator16.S=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 5 ++++-=
<br>
=C2=A0grub-core/lib/i386/relocator32.S=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 3 +++<b=
r>
=C2=A0grub-core/lib/i386/relocator64.S=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 3 +++<b=
r>
=C2=A0grub-core/lib/i386/relocator_asm.S=C2=A0 =C2=A0 =C2=A0 | 3 +++<br>
=C2=A0grub-core/lib/i386/relocator_common_c.c | 8 ++++++++<br>
=C2=A0grub-core/lib/x86_64/relocator_asm.S=C2=A0 =C2=A0 | 3 +++<br>
=C2=A06 files changed, 24 insertions(+), 1 deletion(-)<br>
<br>
-- <br>
2.53.0<br>
<br>
</blockquote></div>

--00000000000064357b0651c9ea7f--



--===============3456224657962107283==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KR3J1Yi1kZXZl
bCBtYWlsaW5nIGxpc3QKR3J1Yi1kZXZlbEBnbnUub3JnCmh0dHBzOi8vbGlzdHMuZ251Lm9yZy9t
YWlsbWFuL2xpc3RpbmZvL2dydWItZGV2ZWwK

--===============3456224657962107283==--