From: Jason Gunthorpe <jgg@nvidia.com>
To: Alexandre Ghiti <alex@ghiti.fr>,
Albert Ou <aou@eecs.berkeley.edu>,
Ard Biesheuvel <ardb@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Catalin Marinas <catalin.marinas@arm.com>,
Jonathan Corbet <corbet@lwn.net>, David Sterba <dsterba@suse.com>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-doc@vger.kernel.org, linux-efi@vger.kernel.org,
linux-riscv@lists.infradead.org,
Mark Rutland <mark.rutland@arm.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Paul Walmsley <pjw@kernel.org>,
Randy Dunlap <rdunlap@infradead.org>,
Simon Glass <sjg@chromium.org>,
Shuah Khan <skhan@linuxfoundation.org>,
Nick Terrell <terrelln@fb.com>, Will Deacon <will@kernel.org>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>,
Conor Dooley <conor.dooley@microchip.com>,
linux-integrity@vger.kernel.org,
Palmer Dabbelt <palmer@rivosinc.com>,
patches@lists.linux.dev,
Ross Philipson <ross.philipson@gmail.com>,
Sami Tolvanen <samitolvanen@google.com>,
Song Shuai <songshuaishuai@tinylab.org>
Subject: [PATCH 08/16] efi/libstub: Add generic arch callbacks for DRTM
Date: Thu, 24 Sep 2026 10:53:11 -0300 [thread overview]
Message-ID: <8-v1-27d06b313981+8b-arm64_drtm_jgg@nvidia.com> (raw)
In-Reply-To: <0-v1-27d06b313981+8b-arm64_drtm_jgg@nvidia.com>
If the architecture supports an EFI stub launched version of DRTM, it
can select the kconfig and provide the hooks under its architecture
build.
Have the common code parse a drtm=enforce|auto|off kernel command line
parameter to set the boot behavior. Support commas in the args list since
there will be more options here down the road.
efi_drtm_prepare() is called before doing any decompression or image
relocation. It should figure out if DRTM is supported, policy-permitted,
and how much memory efi_drtm_get_extra_size() should return.
The image handling is revised to allocate extra_size at the end of
the normal image. The architecture can use this to store any
information needed for the DRTM flow. It is always contiguous with
Image, which is a requirement of ARM's specification.
efi_drtm_prepare_launch() is called while still in EFI boot services after
Image is fully prepared in its final location.
efi_drtm_launch() is called after exiting boot services and must
jump into the kernel through the DRTM flow. If it returns, then the
normal launch is tried (auto mode).
The extra_size is allocated directly after the Image. Handle the
trivial zboot flow now, and vmlinux in the following patch.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
.../admin-guide/kernel-parameters.txt | 12 +++++++
drivers/firmware/efi/Kconfig | 30 ++++++++++++++++
drivers/firmware/efi/libstub/efi-stub-entry.c | 4 +++
.../firmware/efi/libstub/efi-stub-helper.c | 34 ++++++++++++++++++
drivers/firmware/efi/libstub/efistub.h | 36 +++++++++++++++++++
drivers/firmware/efi/libstub/fdt.c | 8 ++++-
drivers/firmware/efi/libstub/zboot.c | 19 +++++++---
7 files changed, 137 insertions(+), 6 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 68647ff4bdd24b..a576e06bd43584 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1373,6 +1373,18 @@ Kernel parameters
data set with no connector name will be used for
any connectors not explicitly specified.
+ drtm= [EFI,EARLY]
+ Format: { "off" | "auto" | "enforce" }
+ Control the EFI stub Dynamic Root of Trust for
+ Measurement (DRTM) launch policy.
+ off: do not attempt a DRTM launch.
+ auto: attempt a DRTM launch when supported, but fall
+ back to a normal boot if preparation or launch fails.
+ enforce: require a DRTM launch and refuse to fall back
+ to a normal boot if preparation or launch fails.
+ The default is selected by the EFI_STUB_DRTM_DEFAULT_*
+ configuration options.
+
dscc4.setup= [NET]
dt_cpu_ftrs= [PPC,EARLY]
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3d6fb3ca2806ca..f77fa1ae716843 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -75,6 +75,36 @@ config EFI_GENERIC_STUB
config EFI_STUB_IMAGE_INFO
bool
+config EFI_STUB_DRTM
+ bool
+
+choice
+ prompt "Default DRTM launch policy"
+ depends on EFI_STUB_DRTM
+ default EFI_STUB_DRTM_DEFAULT_OFF
+ help
+ Select the DRTM policy used when no drtm= option is present on the
+ kernel command line. The command-line option overrides this default.
+
+config EFI_STUB_DRTM_DEFAULT_OFF
+ bool "Off"
+ help
+ Do not attempt a DRTM launch unless it is requested explicitly.
+
+config EFI_STUB_DRTM_DEFAULT_AUTO
+ bool "Automatic with fallback"
+ help
+ Attempt a DRTM launch when the firmware supports it, but fall back to
+ normal boot if preparation or a returnable launch attempt fails.
+
+config EFI_STUB_DRTM_DEFAULT_ENFORCE
+ bool "Enforce"
+ help
+ Require a DRTM launch and refuse normal-boot fallback if preparation
+ or a returnable launch attempt fails.
+
+endchoice
+
config EFI_ZBOOT
bool "Enable the generic EFI decompressor"
depends on EFI_GENERIC_STUB && !ARM
diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c
index 83fade2b0d3b84..5b356c4be78975 100644
--- a/drivers/firmware/efi/libstub/efi-stub-entry.c
+++ b/drivers/firmware/efi/libstub/efi-stub-entry.c
@@ -67,6 +67,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
if (status != EFI_SUCCESS)
return status;
+ status = efi_drtm_prepare();
+ if (status != EFI_SUCCESS)
+ return status;
+
efi_info("Booting Linux Kernel...\n");
status = handle_kernel_image(&image_addr, &image_size,
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index f27f2e1f001997..2dd4a5ac916000 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -27,6 +27,37 @@ static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
int efi_mem_encrypt;
+#ifdef CONFIG_EFI_STUB_DRTM
+enum efi_drtm_policy efi_drtm_policy =
+ IS_ENABLED(CONFIG_EFI_STUB_DRTM_DEFAULT_ENFORCE) ? EFI_DRTM_ENFORCE :
+ IS_ENABLED(CONFIG_EFI_STUB_DRTM_DEFAULT_AUTO) ? EFI_DRTM_AUTO :
+ EFI_DRTM_OFF;
+
+static void efi_drtm_parse_options(char *options)
+{
+ char *keyword;
+
+ while (options) {
+ keyword = options;
+ while (*options && *options != ',')
+ options++;
+ if (*options)
+ *options++ = '\0';
+ else
+ options = NULL;
+
+ if (!strcmp(keyword, "off"))
+ efi_drtm_policy = EFI_DRTM_OFF;
+ else if (!strcmp(keyword, "auto"))
+ efi_drtm_policy = EFI_DRTM_AUTO;
+ else if (!strcmp(keyword, "enforce"))
+ efi_drtm_policy = EFI_DRTM_ENFORCE;
+ }
+}
+#else
+static void efi_drtm_parse_options(char *options) {}
+#endif
+
bool __pure __efi_soft_reserve_enabled(void)
{
return !efi_nosoftreserve;
@@ -89,6 +120,9 @@ efi_status_t efi_parse_options(char const *cmdline)
efi_mem_encrypt = 1;
else if (parse_option_str(val, "off"))
efi_mem_encrypt = -1;
+ } else if (IS_ENABLED(CONFIG_EFI_STUB_DRTM) &&
+ !strcmp(param, "drtm") && val) {
+ efi_drtm_parse_options(val);
} else if (!strcmp(param, "efi") && val) {
efi_nochunk = parse_option_str(val, "nochunk");
efi_novamap |= parse_option_str(val, "novamap");
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index da01d6005a62af..f3a6aefdc052ca 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1078,6 +1078,42 @@ efi_status_t check_platform_features(void);
void *get_efi_config_table(efi_guid_t guid);
+enum efi_drtm_policy {
+ EFI_DRTM_OFF,
+ EFI_DRTM_AUTO,
+ EFI_DRTM_ENFORCE,
+};
+
+#ifdef CONFIG_EFI_STUB_DRTM
+extern enum efi_drtm_policy efi_drtm_policy;
+efi_status_t efi_drtm_prepare(void);
+unsigned long efi_drtm_get_extra_size(void);
+efi_status_t efi_drtm_prepare_launch(unsigned long image_base,
+ unsigned long fdt_addr);
+void efi_drtm_launch(void);
+#else
+enum {efi_drtm_policy = EFI_DRTM_OFF};
+static inline efi_status_t efi_drtm_prepare(void)
+{
+ return EFI_SUCCESS;
+}
+
+static inline unsigned long efi_drtm_get_extra_size(void)
+{
+ return 0;
+}
+
+static inline efi_status_t
+efi_drtm_prepare_launch(unsigned long image_base, unsigned long fdt_addr)
+{
+ return EFI_SUCCESS;
+}
+
+static inline void efi_drtm_launch(void)
+{
+}
+#endif
+
/* NOTE: These functions do not print a trailing newline after the string */
void efi_char16_puts(efi_char16_t *);
void efi_puts(const char *str);
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 5b2dd709d7b151..15bb331f2dc56c 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -223,6 +223,7 @@ static
efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
efi_loaded_image_t *image,
unsigned long *new_fdt_addr,
+ unsigned long kernel_addr,
char *cmdline_ptr)
{
unsigned long desc_size;
@@ -289,6 +290,10 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
goto fail_free_new_fdt;
}
+ status = efi_drtm_prepare_launch(kernel_addr, *new_fdt_addr);
+ if (status != EFI_SUCCESS)
+ goto fail_free_new_fdt;
+
priv.new_fdt_addr = (void *)*new_fdt_addr;
status = efi_exit_boot_services(handle, &priv, exit_boot_func);
@@ -350,7 +355,7 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
efi_status_t status;
status = allocate_new_fdt_and_exit_boot(handle, image, &fdt_addr,
- cmdline_ptr);
+ kernel_addr, cmdline_ptr);
if (status != EFI_SUCCESS) {
efi_err("Failed to update FDT and exit boot services\n");
return status;
@@ -359,6 +364,7 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
if (IS_ENABLED(CONFIG_ARM))
efi_handle_post_ebs_state();
+ efi_drtm_launch();
efi_enter_kernel(kernel_addr, fdt_addr, fdt_totalsize((void *)fdt_addr));
/* not reached */
}
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 960a542881d875..6ca231ad593b20 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -35,7 +35,7 @@ asmlinkage efi_status_t __efiapi
efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
{
char *cmdline_ptr __free(efi_pool) = NULL;
- unsigned long image_base, alloc_size;
+ unsigned long image_base, image_size, alloc_size;
efi_loaded_image_t *image;
efi_status_t status;
@@ -52,12 +52,17 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
if (status != EFI_SUCCESS)
return status;
- efi_info("Decompressing Linux Kernel...\n");
-
- status = efi_zboot_decompress_init(&alloc_size);
+ status = efi_drtm_prepare();
if (status != EFI_SUCCESS)
return status;
+ efi_info("Decompressing Linux Kernel...\n");
+
+ status = efi_zboot_decompress_init(&image_size);
+ if (status != EFI_SUCCESS)
+ return status;
+ alloc_size = image_size + efi_drtm_get_extra_size();
+
// If the architecture has a preferred address for the image,
// try that first.
image_base = alloc_preferred_address(alloc_size);
@@ -92,8 +97,12 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
}
// Decompress the payload into the newly allocated buffer
- status = efi_zboot_decompress((void *)image_base, alloc_size);
+ status = efi_zboot_decompress((void *)image_base, image_size);
if (status == EFI_SUCCESS) {
+ /*
+ * Have to sync the entire allocation because the sync also
+ * remaps and changes the permissions.
+ */
efi_cache_sync_image(image_base, alloc_size);
status =
efi_stub_common(handle, image, image_base, cmdline_ptr);
--
2.43.0
next prev parent reply other threads:[~2026-09-24 13:53 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 13:53 [PATCH 00/16] arm64: DRTM, boot portion Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 01/16] efi/libstub: Fix error unwind freeing fdt in allocate_new_fdt_and_exit_boot() Jason Gunthorpe
2026-09-24 22:42 ` Jonathan Cameron
2026-09-24 23:44 ` Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 02/16] efi/riscv: libstub: Don't set image_size in handle_kernel_image() Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 03/16] efi/libstub: Free cmdline_ptr in efi_pe_entry Jason Gunthorpe
2026-09-24 22:49 ` Jonathan Cameron
2026-09-25 12:59 ` Jason Gunthorpe
2026-09-25 13:20 ` Ard Biesheuvel
2026-09-24 13:53 ` [PATCH 04/16] vmlinux.lds: Move DATA_LE32() from arm64 to the common linker script Jason Gunthorpe
2026-09-24 22:53 ` Jonathan Cameron
2026-09-24 23:50 ` Jason Gunthorpe
2026-09-25 13:30 ` Ard Biesheuvel
2026-09-24 13:53 ` [PATCH 05/16] efi/libstub: Add a general way to get symbols from the vmlinux into zboot Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 06/16] arm64/efi: Use CONFIG_EFI_STUB_IMAGE_INFO for code_size Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 07/16] efi/zboot: Lift efi_cache_sync_image() from efi_zboot_decompress() Jason Gunthorpe
2026-09-24 22:57 ` Jonathan Cameron
2026-09-24 23:53 ` Jason Gunthorpe
2026-09-24 13:53 ` Jason Gunthorpe [this message]
2026-09-24 13:53 ` [PATCH 09/16] efi/libstub: Have efi_kaslr_relocate_kernel() handle extra_size Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 10/16] efi: Add a __efi_data_handoff section annotation Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 11/16] efi/libstub: Put the stub's writable data in unique sections for DRTM Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 12/16] arm64: drtm: Add macro definitions for DEN0113 Jason Gunthorpe
2026-09-25 0:29 ` Jonathan Cameron
2026-09-26 18:27 ` Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 13/16] arm64: drtm: Update the linker script for EFI_STUB_DRTM Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 14/16] arm64: drtm: Add drtm_entry point to head.S Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 15/16] arm64: drtm: Call UNPROTECT_MEMORY Jason Gunthorpe
2026-09-24 13:53 ` [PATCH 16/16] efi/arm64: Implement ARM64 DRTM in the stub Jason Gunthorpe
2026-09-25 18:37 ` Jonathan Cameron
2026-09-26 18:45 ` Jason Gunthorpe
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=8-v1-27d06b313981+8b-arm64_drtm_jgg@nvidia.com \
--to=jgg@nvidia.com \
--cc=alex@ghiti.fr \
--cc=alexghiti@rivosinc.com \
--cc=aou@eecs.berkeley.edu \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=catalin.marinas@arm.com \
--cc=conor.dooley@microchip.com \
--cc=corbet@lwn.net \
--cc=dsterba@suse.com \
--cc=ilias.apalodimas@linaro.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=palmer@dabbelt.com \
--cc=palmer@rivosinc.com \
--cc=patches@lists.linux.dev \
--cc=pjw@kernel.org \
--cc=rdunlap@infradead.org \
--cc=ross.philipson@gmail.com \
--cc=samitolvanen@google.com \
--cc=sjg@chromium.org \
--cc=skhan@linuxfoundation.org \
--cc=songshuaishuai@tinylab.org \
--cc=terrelln@fb.com \
--cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox