On February 21, 2024 12:17:30 PM PST, ross.philip...@oracle.com wrote:
>On 2/15/24 1:01 AM, Ard Biesheuvel wrote:
>> On Wed, 14 Feb 2024 at 23:32, Ross Philipson <ross.philip...@oracle.com> 
>> wrote:
>>> 
>>> 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.philip...@oracle.com>
>>> ---
>>>   drivers/firmware/efi/libstub/x86-stub.c | 55 +++++++++++++++++++++++++
>>>   1 file changed, 55 insertions(+)
>>> 
>>> diff --git a/drivers/firmware/efi/libstub/x86-stub.c 
>>> b/drivers/firmware/efi/libstub/x86-stub.c
>>> index 0d510c9a06a4..4df2cf539194 100644
>>> --- a/drivers/firmware/efi/libstub/x86-stub.c
>>> +++ b/drivers/firmware/efi/libstub/x86-stub.c
>>> @@ -9,6 +9,7 @@
>>>   #include <linux/efi.h>
>>>   #include <linux/pci.h>
>>>   #include <linux/stddef.h>
>>> +#include <linux/slr_table.h>
>>> 
>>>   #include <asm/efi.h>
>>>   #include <asm/e820/types.h>
>>> @@ -810,6 +811,57 @@ static efi_status_t efi_decompress_kernel(unsigned 
>>> long *kernel_entry)
>>>          return EFI_SUCCESS;
>>>   }
>>> 
>>> +static void efi_secure_launch(struct boot_params *boot_params)
>>> +{
>>> +       struct slr_entry_uefi_config *uefi_config;
>>> +       struct slr_uefi_cfg_entry *uefi_entry;
>>> +       struct slr_entry_dl_info *dlinfo;
>>> +       efi_guid_t guid = SLR_TABLE_GUID;
>>> +       struct slr_table *slrt;
>>> +       u64 memmap_hi;
>>> +       void *table;
>>> +       u8 buf[64] = {0};
>>> +
>> 
>> If you add a flex array to slr_entry_uefi_config as I suggested in
>> response to the other patch, we could simplify this substantially
>
>I feel like there is some reason why we did not use flex arrays. We were 
>talking and we seem to remember we used to use them and someone asked us to 
>remove them. We are still looking into it. But if we can go back to them, I 
>will take all the changes you recommended here.
>
>Thanks
>Ross
>
>> 
>> static struct slr_entry_uefi_config cfg = {
>>          .hdr.tag        = SLR_ENTRY_UEFI_CONFIG,
>>          .hdr.size       = sizeof(cfg),
>>          .revision       = SLR_UEFI_CONFIG_REVISION,
>>          .nr_entries     = 1,
>>          .entries[0]     = {
>>                  .pcr    = 18,
>>                  .evt_info = "Measured UEFI memory map",
>>          },
>> };
>> 
>> cfg.entries[0].cfg  = boot_params->efi_info.efi_memmap |
>>                        (u64)boot_params->efi_info.efi_memmap_hi << 32;
>> cfg.entries[0].size = boot_params->efi_info.efi_memmap_size;
>> 
>> 
>> 
>>> +       table = get_efi_config_table(guid);
>>> +
>>> +       /*
>>> +        * The presence of this table indicated a Secure Launch
>>> +        * is being requested.
>>> +        */
>>> +       if (!table)
>>> +               return;
>>> +
>>> +       slrt = (struct slr_table *)table;
>>> +
>>> +       if (slrt->magic != SLR_TABLE_MAGIC)
>>> +               return;
>>> +
>> 
>> slrt = (struct slr_table *)get_efi_config_table(guid);
>> if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
>>          return;
>> 
>>> +       /* Add config information to measure the UEFI memory map */
>>> +       uefi_config = (struct slr_entry_uefi_config *)buf;
>>> +       uefi_config->hdr.tag = SLR_ENTRY_UEFI_CONFIG;
>>> +       uefi_config->hdr.size = sizeof(*uefi_config) + sizeof(*uefi_entry);
>>> +       uefi_config->revision = SLR_UEFI_CONFIG_REVISION;
>>> +       uefi_config->nr_entries = 1;
>>> +       uefi_entry = (struct slr_uefi_cfg_entry *)(buf + 
>>> sizeof(*uefi_config));
>>> +       uefi_entry->pcr = 18;
>>> +       uefi_entry->cfg = boot_params->efi_info.efi_memmap;
>>> +       memmap_hi = boot_params->efi_info.efi_memmap_hi;
>>> +       uefi_entry->cfg |= memmap_hi << 32;
>>> +       uefi_entry->size = boot_params->efi_info.efi_memmap_size;
>>> +       memcpy(&uefi_entry->evt_info[0], "Measured UEFI memory map",
>>> +               strlen("Measured UEFI memory map"));
>>> +
>> 
>> Drop all of this
>> 
>>> +       if (slr_add_entry(slrt, (struct slr_entry_hdr *)uefi_config))
>> 
>> if (slr_add_entry(slrt, &uefi_config.hdr))
>> 
>> 
>>> +               return;
>>> +
>>> +       /* Jump through DL stub to initiate Secure Launch */
>>> +       dlinfo = (struct slr_entry_dl_info *)
>>> +               slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
>>> +
>>> +       asm volatile ("jmp *%%rax"
>>> +                     : : "a" (dlinfo->dl_handler), "D" 
>>> (&dlinfo->bl_context));
>> 
>> Fix the prototype and just do
>> 
>> dlinfo->dl_handler(&dlinfo->bl_context);
>> unreachable();
>> 
>> 
>> So in summary, this becomes
>> 
>> static void efi_secure_launch(struct boot_params *boot_params)
>> {
>>          static struct slr_entry_uefi_config cfg = {
>>                  .hdr.tag        = SLR_ENTRY_UEFI_CONFIG,
>>                  .hdr.size       = sizeof(cfg),
>>                  .revision       = SLR_UEFI_CONFIG_REVISION,
>>                  .nr_entries     = 1,
>>                  .entries[0]     = {
>>                          .pcr    = 18,
>>                          .evt_info = "Measured UEFI memory map",
>>                  },
>>          };
>>          struct slr_entry_dl_info *dlinfo;
>>          efi_guid_t guid = SLR_TABLE_GUID;
>>          struct slr_table *slrt;
>> 
>>          /*
>>           * The presence of this table indicated a Secure Launch
>>           * is being requested.
>>           */
>>          slrt = (struct slr_table *)get_efi_config_table(guid);
>>          if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
>>                  return;
>> 
>>          cfg.entries[0].cfg  = boot_params->efi_info.efi_memmap |
>>                                (u64)boot_params->efi_info.efi_memmap_hi << 
>> 32;
>>          cfg.entries[0].size = boot_params->efi_info.efi_memmap_size;
>> 
>>          if (slr_add_entry(slrt, &cfg.hdr))
>>                  return;
>> 
>>          /* Jump through DL stub to initiate Secure Launch */
>>          dlinfo = (struct slr_entry_dl_info *)
>>                   slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
>> 
>>          dlinfo->dl_handler(&dlinfo->bl_context);
>> 
>>          unreachable();
>> }
>> 
>> 
>>> +}
>>> +
>>>   static void __noreturn enter_kernel(unsigned long kernel_addr,
>>>                                      struct boot_params *boot_params)
>>>   {
>>> @@ -934,6 +986,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
>>>                  goto fail;
>>>          }
>>> 
>>> +       /* If a Secure Launch is in progress, this never returns */
>> 
>> if (IS_ENABLED(CONFIG_SECURE_LAUNCH))
>> 
>>> +       efi_secure_launch(boot_params);
>>> +
>>>          /*
>>>           * Call the SEV init code while still running with the firmware's
>>>           * GDT/IDT, so #VC exceptions will be handled by EFI.
>>> --
>>> 2.39.3
>>> 
>> 
>

Linux kernel code doesn't use VLAs because of the limited stack size, and VLAs 
or alloca() makes stack size tracking impossible. Although this technically 
speaking runs in a different environment, it is easier to enforce the 
constraint globally.

Reply via email to