|
9 | 9 | #include <linux/efi.h> |
10 | 10 | #include <linux/pci.h> |
11 | 11 | #include <linux/stddef.h> |
| 12 | +#include <linux/slr_table.h> |
| 13 | +#include <linux/slaunch.h> |
12 | 14 |
|
13 | 15 | #include <asm/efi.h> |
14 | 16 | #include <asm/e820/types.h> |
@@ -795,6 +797,101 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry, |
795 | 797 | kernel_inittext_size); |
796 | 798 | } |
797 | 799 |
|
| 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 | + |
798 | 895 | static void __noreturn enter_kernel(unsigned long kernel_addr, |
799 | 896 | struct boot_params *boot_params) |
800 | 897 | { |
@@ -929,6 +1026,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle, |
929 | 1026 | goto fail; |
930 | 1027 | } |
931 | 1028 |
|
| 1029 | + /* If a Secure Launch is in progress, this never returns */ |
| 1030 | + efi_secure_launch(boot_params); |
| 1031 | + |
932 | 1032 | /* |
933 | 1033 | * Call the SEV init code while still running with the firmware's |
934 | 1034 | * GDT/IDT, so #VC exceptions will be handled by EFI. |
|
0 commit comments