Skip to content

Commit 040f882

Browse files
committed
x86/efi: EFI stub DRTM launch support for Secure Launch
This support allows the DRTM launch to be initiated after an EFI stub launch of the Linux kernel is done. This is accomplished by providing a handler to jump to when a Secure Launch is in progress. This has to be called after the EFI stub does Exit Boot Services. Signed-off-by: Ross Philipson <ross.philipson@oracle.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
1 parent f609048 commit 040f882

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

drivers/firmware/efi/libstub/efistub.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
135135
*hi = upper_32_bits(data);
136136
}
137137

138+
static inline
139+
void efi_set_u64_form(u32 lo, u32 hi, u64 *data)
140+
{
141+
u64 upper = hi;
142+
143+
*data = lo | upper << 32;
144+
}
145+
138146
/*
139147
* Allocation types for calls to boottime->allocate_pages.
140148
*/

drivers/firmware/efi/libstub/x86-stub.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/efi.h>
1010
#include <linux/pci.h>
1111
#include <linux/stddef.h>
12+
#include <linux/slr_table.h>
13+
#include <linux/slaunch.h>
1214

1315
#include <asm/efi.h>
1416
#include <asm/e820/types.h>
@@ -795,6 +797,101 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry,
795797
kernel_inittext_size);
796798
}
797799

800+
#if (IS_ENABLED(CONFIG_SECURE_LAUNCH))
801+
802+
static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
803+
struct boot_params *boot_params)
804+
{
805+
struct slr_entry_intel_info *txt_info;
806+
struct slr_entry_policy *policy;
807+
bool updated = false;
808+
int i;
809+
810+
txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
811+
if (!txt_info)
812+
return false;
813+
814+
txt_info->boot_params_addr = (u64)boot_params;
815+
816+
policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
817+
if (!policy)
818+
return false;
819+
820+
for (i = 0; i < policy->nr_entries; i++) {
821+
if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
822+
policy->policy_entries[i].entity = (u64)boot_params;
823+
updated = true;
824+
break;
825+
}
826+
}
827+
828+
/*
829+
* If this is a PE entry into EFI stub the mocked up boot params will
830+
* be missing some of the setup header data needed for the second stage
831+
* of the Secure Launch boot.
832+
*/
833+
if (image) {
834+
struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
835+
offsetof(struct boot_params, hdr));
836+
u64 cmdline_ptr;
837+
838+
boot_params->hdr.setup_sects = hdr->setup_sects;
839+
boot_params->hdr.syssize = hdr->syssize;
840+
boot_params->hdr.version = hdr->version;
841+
boot_params->hdr.loadflags = hdr->loadflags;
842+
boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
843+
boot_params->hdr.min_alignment = hdr->min_alignment;
844+
boot_params->hdr.xloadflags = hdr->xloadflags;
845+
boot_params->hdr.init_size = hdr->init_size;
846+
boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
847+
efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
848+
&cmdline_ptr);
849+
boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
850+
}
851+
852+
return updated;
853+
}
854+
855+
static void efi_secure_launch(struct boot_params *boot_params)
856+
{
857+
struct slr_entry_dl_info *dlinfo;
858+
efi_guid_t guid = SLR_TABLE_GUID;
859+
dl_handler_func handler_callback;
860+
struct slr_table *slrt;
861+
862+
/*
863+
* The presence of this table indicated a Secure Launch
864+
* is being requested.
865+
*/
866+
slrt = (struct slr_table *)get_efi_config_table(guid);
867+
if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
868+
return;
869+
870+
/*
871+
* Since the EFI stub library creates its own boot_params on entry, the
872+
* SLRT and TXT heap have to be updated with this version.
873+
*/
874+
if (!efi_secure_launch_update_boot_params(slrt, boot_params))
875+
return;
876+
877+
/* Jump through DL stub to initiate Secure Launch */
878+
dlinfo = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
879+
880+
handler_callback = (dl_handler_func)dlinfo->dl_handler;
881+
882+
handler_callback(&dlinfo->bl_context);
883+
884+
unreachable();
885+
}
886+
887+
#else
888+
889+
static void efi_secure_launch(struct boot_params *boot_params)
890+
{
891+
}
892+
893+
#endif /* IS_ENABLED(CONFIG_SECURE_LAUNCH) */
894+
798895
static void __noreturn enter_kernel(unsigned long kernel_addr,
799896
struct boot_params *boot_params)
800897
{
@@ -929,6 +1026,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
9291026
goto fail;
9301027
}
9311028

1029+
/* If a Secure Launch is in progress, this never returns */
1030+
efi_secure_launch(boot_params);
1031+
9321032
/*
9331033
* Call the SEV init code while still running with the firmware's
9341034
* GDT/IDT, so #VC exceptions will be handled by EFI.

0 commit comments

Comments
 (0)