All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ross Lagerwall <ross.lagerwall@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: "Ross Lagerwall" <ross.lagerwall@citrix.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"George Dunlap" <george.dunlap@citrix.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Julien Grall" <julien@xen.org>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Wei Liu" <wl@xen.org>, "Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH 2/4] x86: Add support for building a multiboot2 PE binary
Date: Wed, 13 Mar 2024 15:04:37 +0000	[thread overview]
Message-ID: <20240313150439.791213-3-ross.lagerwall@citrix.com> (raw)
In-Reply-To: <20240313150439.791213-1-ross.lagerwall@citrix.com>

Add a new config option, CONFIG_MULTIBOOT_PE, that when set changes
xen.gz to be a compressed PE binary instead of a compressed ELF binary.
This requires use with a multiboot2 loader that supports the PE load
type.

Using this option allows the binary to be signed and verified by Shim.
This means the same xen.gz can then be used for BIOS boot, UEFI Boot and
UEFI boot with Secure Boot verification (all with the convenience of
GRUB2 as a bootloader).

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
---
 xen/Makefile             |  1 +
 xen/arch/x86/Kconfig     |  6 +++++
 xen/arch/x86/Makefile    | 48 ++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/head.S | 33 +++++++++++++++++++++++++++
 4 files changed, 88 insertions(+)

diff --git a/xen/Makefile b/xen/Makefile
index 21832d640225..c9461c9778cc 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -581,6 +581,7 @@ _clean:
 		-o -name ".*.cmd" -o -name "lib.a" \) -exec rm -f {} \;
 	rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET)-syms $(TARGET)-syms.map
 	rm -f $(TARGET).efi $(TARGET).efi.map $(TARGET).efi.elf $(TARGET).efi.stripped
+	rm -f $(TARGET).elf $(TARGET).map
 	rm -f asm-offsets.s arch/*/include/asm/asm-offsets.h
 	rm -f .banner .allconfig.tmp include/xen/compile.h
 	rm -rf $(objtree)/arch/*/include/generated
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 1acdffc51c22..2d8f6e687e58 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -348,6 +348,12 @@ config REQUIRE_NX
 	  was unavailable. However, if enabled, Xen will no longer boot on
 	  any CPU which is lacking NX support.
 
+config MULTIBOOT_PE
+	bool "Build the multiboot binary as PE"
+	help
+	  Build the multiboot xen.gz binary as a PE binary rather than ELF.
+	  This allows it to be signed and verified when using Secure Boot
+	  with Shim and a bootloader.
 endmenu
 
 source "common/Kconfig"
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 26d87405297b..e26b1cb35036 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -123,6 +123,53 @@ syms-warn-dup-$(CONFIG_ENFORCE_UNIQUE_SYMBOLS) := --error-dup
 
 orphan-handling-$(call ld-option,--orphan-handling=warn) += --orphan-handling=warn
 
+ifeq ($(CONFIG_MULTIBOOT_PE),y)
+ifneq ($(XEN_BUILD_PE),y)
+$(TARGET): FORCE
+	rm -f $@
+	echo 'PE build not supported'
+else
+$(TARGET): VIRT_BASE = 0x$(shell $(NM) $(obj)/efi/relocs-dummy.o | sed -n 's, A VIRT_START$$,,p')
+$(TARGET): $(objtree)/prelink.o $(note_file) $(obj)/efi.lds \
+           $(obj)/efi/relocs-dummy.o $(obj)/efi/set-coff-flags $(TARGET)-syms $(efi-y)
+ifeq ($(CONFIG_DEBUG_INFO),y)
+	$(if $(filter --strip-debug,$(EFI_LDFLAGS)),echo,:) "Will strip debug info from $(@F)"
+endif
+	$(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) --disable-reloc-section \
+	      -T $(obj)/efi.lds -N $< $(relocs-dummy) \
+	      $(objtree)/common/symbols-dummy.o $(note_file_option) \
+	      -o $(dot-target).$(VIRT_BASE).0
+	$(NM) -pa --format=sysv $(dot-target).$(VIRT_BASE).0 \
+		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
+		> $(dot-target).0s.S
+	$(MAKE) $(build)=$(@D) .$(@F).0s.o
+	$(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) --disable-reloc-section \
+	      -T $(obj)/efi.lds -N $< $(dot-target).0s.o $(note_file_option) \
+	      -o $(dot-target).$(VIRT_BASE).1
+	$(NM) -pa --format=sysv $(dot-target).$(VIRT_BASE).1 \
+		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
+		> $(dot-target).1s.S
+	$(MAKE) $(build)=$(@D) .$(@F).1s.o
+	$(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) --disable-reloc-section \
+	      -T $(obj)/efi.lds -N $< $(dot-target).1s.o $(orphan-handling-y) \
+	      $(note_file_option) -o $@.tmp
+	od -t x4 -N 8192 $@.tmp  | grep 1badb002 > /dev/null || \
+		{ echo "No Multiboot1 header found" >&2; false; }
+	od -t x4 -N 32768 $@.tmp | grep e85250d6 > /dev/null || \
+		{ echo "No Multiboot2 header found" >&2; false; }
+	mv $@.tmp $(TARGET)
+	$(NM) -pa --format=sysv $@ \
+		| $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \
+		> $@.map
+ifeq ($(CONFIG_DEBUG_INFO),y)
+	$(if $(filter --strip-debug,$(EFI_LDFLAGS)),:$(space))$(OBJCOPY) -O elf64-x86-64 $@ $@.elf
+endif
+	rm -f $(dot-target).[0-9]* $(@D)/..$(@F).[0-9]*
+ifeq ($(CONFIG_XEN_IBT),y)
+	$(SHELL) $(srctree)/tools/check-endbr.sh $@
+endif
+endif
+else
 $(TARGET): TMP = $(dot-target).elf32
 $(TARGET): $(TARGET)-syms $(efi-y) $(obj)/boot/mkelf32
 	$(obj)/boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TMP) $(XEN_IMG_OFFSET) \
@@ -132,6 +179,7 @@ $(TARGET): $(TARGET)-syms $(efi-y) $(obj)/boot/mkelf32
 	od -t x4 -N 32768 $(TMP) | grep e85250d6 > /dev/null || \
 		{ echo "No Multiboot2 header found" >&2; false; }
 	mv $(TMP) $(TARGET)
+endif
 
 CFLAGS-$(XEN_BUILD_EFI) += -DXEN_BUILD_EFI
 
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 015023915a72..84dc8b76b61d 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -44,6 +44,25 @@
 .Lmb2ht_init_end\@:
         .endm
 
+        .macro mb2ht_qargs arg:req, args:vararg
+        .quad \arg
+        .ifnb \args
+        mb2ht_args \args
+        .endif
+        .endm
+
+        .macro mb2ht_qinit type:req, req:req, args:vararg
+        .balign MULTIBOOT2_TAG_ALIGN, 0xc2 /* Avoid padding with long nops. */
+.Lmb2ht_init_start\@:
+        .short \type
+        .short \req
+        .long .Lmb2ht_init_end\@ - .Lmb2ht_init_start\@
+        .ifnb \args
+        mb2ht_qargs \args
+        .endif
+.Lmb2ht_init_end\@:
+        .endm
+
 ENTRY(start)
         jmp     __start
 
@@ -90,8 +109,14 @@ multiboot2_header:
                    0x200000, /* Load address alignment (2 MiB). */ \
                    MULTIBOOT2_LOAD_PREFERENCE_HIGH
 
+        /* Load type */
+#ifdef CONFIG_MULTIBOOT_PE
+        mb2ht_init MB2_HT(LOAD_TYPE), MB2_HT(OPTIONAL), \
+                   MULTIBOOT2_LOAD_TYPE_PE
+#else
         mb2ht_init MB2_HT(LOAD_TYPE), MB2_HT(OPTIONAL), \
                    MULTIBOOT2_LOAD_TYPE_ELF
+#endif
 
         /* Console flags tag. */
         mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \
@@ -107,8 +132,16 @@ multiboot2_header:
         mb2ht_init MB2_HT(EFI_BS), MB2_HT(OPTIONAL)
 
         /* EFI64 Multiboot2 entry point. */
+#ifdef CONFIG_MULTIBOOT_PE
+        mb2ht_qinit MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
+                   __efi64_mb2_start
+
+        mb2ht_qinit MB2_HT(ENTRY_ADDRESS), MB2_HT(OPTIONAL), \
+                   start
+#else
         mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
                    sym_offs(__efi64_mb2_start)
+#endif
 
         /* Multiboot2 header end tag. */
         mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
-- 
2.43.0



  parent reply	other threads:[~2024-03-13 15:03 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-13 15:04 [PATCH 0/4] x86: Multiboot PE support Ross Lagerwall
2024-03-13 15:04 ` [PATCH 1/4] multiboot2: Advertise the load type Ross Lagerwall
2024-03-13 15:04 ` Ross Lagerwall [this message]
2024-03-13 15:04 ` [PATCH 3/4] x86: Hand-edit coff flags to remove RELOCS_STRIPPED flag Ross Lagerwall
2024-03-13 15:04 ` [PATCH 4/4] x86: Call Shim Verify in the multiboot2 path Ross Lagerwall

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=20240313150439.791213-3-ross.lagerwall@citrix.com \
    --to=ross.lagerwall@citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=george.dunlap@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=julien@xen.org \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=wl@xen.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.