Path: blob/master/drivers/firmware/efi/libstub/x86-stub.c
29537 views
// SPDX-License-Identifier: GPL-2.0-only12/* -----------------------------------------------------------------------3*4* Copyright 2011 Intel Corporation; author Matt Fleming5*6* ----------------------------------------------------------------------- */78#include <linux/efi.h>9#include <linux/pci.h>10#include <linux/stddef.h>1112#include <asm/efi.h>13#include <asm/e820/types.h>14#include <asm/setup.h>15#include <asm/desc.h>16#include <asm/boot.h>17#include <asm/kaslr.h>18#include <asm/sev.h>1920#include "efistub.h"21#include "x86-stub.h"2223extern char _bss[], _ebss[];2425const efi_system_table_t *efi_system_table;26const efi_dxe_services_table_t *efi_dxe_table;27static efi_loaded_image_t *image = NULL;28static efi_memory_attribute_protocol_t *memattr;2930typedef union sev_memory_acceptance_protocol sev_memory_acceptance_protocol_t;31union sev_memory_acceptance_protocol {32struct {33efi_status_t (__efiapi * allow_unaccepted_memory)(34sev_memory_acceptance_protocol_t *);35};36struct {37u32 allow_unaccepted_memory;38} mixed_mode;39};4041static efi_status_t42preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)43{44struct pci_setup_rom *rom __free(efi_pool) = NULL;45efi_status_t status;46unsigned long size;47uint64_t romsize;48void *romimage;4950/*51* Some firmware images contain EFI function pointers at the place where52* the romimage and romsize fields are supposed to be. Typically the EFI53* code is mapped at high addresses, translating to an unrealistically54* large romsize. The UEFI spec limits the size of option ROMs to 1655* MiB so we reject any ROMs over 16 MiB in size to catch this.56*/57romimage = efi_table_attr(pci, romimage);58romsize = efi_table_attr(pci, romsize);59if (!romimage || !romsize || romsize > SZ_16M)60return EFI_INVALID_PARAMETER;6162size = romsize + sizeof(*rom);6364status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,65(void **)&rom);66if (status != EFI_SUCCESS) {67efi_err("Failed to allocate memory for 'rom'\n");68return status;69}7071memset(rom, 0, sizeof(*rom));7273rom->data.type = SETUP_PCI;74rom->data.len = size - sizeof(struct setup_data);75rom->data.next = 0;76rom->pcilen = romsize;7778status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,79PCI_VENDOR_ID, 1, &rom->vendor);8081if (status != EFI_SUCCESS) {82efi_err("Failed to read rom->vendor\n");83return status;84}8586status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,87PCI_DEVICE_ID, 1, &rom->devid);8889if (status != EFI_SUCCESS) {90efi_err("Failed to read rom->devid\n");91return status;92}9394status = efi_call_proto(pci, get_location, &rom->segment, &rom->bus,95&rom->device, &rom->function);9697if (status != EFI_SUCCESS)98return status;99100memcpy(rom->romdata, romimage, romsize);101*__rom = no_free_ptr(rom);102return EFI_SUCCESS;103}104105/*106* There's no way to return an informative status from this function,107* because any analysis (and printing of error messages) needs to be108* done directly at the EFI function call-site.109*110* For example, EFI_INVALID_PARAMETER could indicate a bug or maybe we111* just didn't find any PCI devices, but there's no way to tell outside112* the context of the call.113*/114static void setup_efi_pci(struct boot_params *params)115{116efi_status_t status;117efi_handle_t *pci_handle __free(efi_pool) = NULL;118efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;119struct setup_data *data;120unsigned long num;121efi_handle_t h;122123status = efi_bs_call(locate_handle_buffer, EFI_LOCATE_BY_PROTOCOL,124&pci_proto, NULL, &num, &pci_handle);125if (status != EFI_SUCCESS)126return;127128data = (struct setup_data *)(unsigned long)params->hdr.setup_data;129130while (data && data->next)131data = (struct setup_data *)(unsigned long)data->next;132133for_each_efi_handle(h, pci_handle, num) {134efi_pci_io_protocol_t *pci = NULL;135struct pci_setup_rom *rom;136137status = efi_bs_call(handle_protocol, h, &pci_proto,138(void **)&pci);139if (status != EFI_SUCCESS || !pci)140continue;141142status = preserve_pci_rom_image(pci, &rom);143if (status != EFI_SUCCESS)144continue;145146if (data)147data->next = (unsigned long)rom;148else149params->hdr.setup_data = (unsigned long)rom;150151data = (struct setup_data *)rom;152}153}154155static void retrieve_apple_device_properties(struct boot_params *boot_params)156{157efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;158struct setup_data *data, *new;159efi_status_t status;160u32 size = 0;161apple_properties_protocol_t *p;162163status = efi_bs_call(locate_protocol, &guid, NULL, (void **)&p);164if (status != EFI_SUCCESS)165return;166167if (efi_table_attr(p, version) != 0x10000) {168efi_err("Unsupported properties proto version\n");169return;170}171172efi_call_proto(p, get_all, NULL, &size);173if (!size)174return;175176do {177status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,178size + sizeof(struct setup_data),179(void **)&new);180if (status != EFI_SUCCESS) {181efi_err("Failed to allocate memory for 'properties'\n");182return;183}184185status = efi_call_proto(p, get_all, new->data, &size);186187if (status == EFI_BUFFER_TOO_SMALL)188efi_bs_call(free_pool, new);189} while (status == EFI_BUFFER_TOO_SMALL);190191new->type = SETUP_APPLE_PROPERTIES;192new->len = size;193new->next = 0;194195data = (struct setup_data *)(unsigned long)boot_params->hdr.setup_data;196if (!data) {197boot_params->hdr.setup_data = (unsigned long)new;198} else {199while (data->next)200data = (struct setup_data *)(unsigned long)data->next;201data->next = (unsigned long)new;202}203}204205static bool apple_match_product_name(void)206{207static const char type1_product_matches[][15] = {208"MacBookPro11,3",209"MacBookPro11,5",210"MacBookPro13,3",211"MacBookPro14,3",212"MacBookPro15,1",213"MacBookPro15,3",214"MacBookPro16,1",215"MacBookPro16,4",216};217const struct efi_smbios_type1_record *record;218const u8 *product;219220record = (struct efi_smbios_type1_record *)efi_get_smbios_record(1);221if (!record)222return false;223224product = efi_get_smbios_string(record, product_name);225if (!product)226return false;227228for (int i = 0; i < ARRAY_SIZE(type1_product_matches); i++) {229if (!strcmp(product, type1_product_matches[i]))230return true;231}232233return false;234}235236static void apple_set_os(void)237{238struct {239unsigned long version;240efi_status_t (__efiapi *set_os_version)(const char *);241efi_status_t (__efiapi *set_os_vendor)(const char *);242} *set_os;243efi_status_t status;244245if (!efi_is_64bit() || !apple_match_product_name())246return;247248status = efi_bs_call(locate_protocol, &APPLE_SET_OS_PROTOCOL_GUID, NULL,249(void **)&set_os);250if (status != EFI_SUCCESS)251return;252253if (set_os->version >= 2) {254status = set_os->set_os_vendor("Apple Inc.");255if (status != EFI_SUCCESS)256efi_err("Failed to set OS vendor via apple_set_os\n");257}258259if (set_os->version > 0) {260/* The version being set doesn't seem to matter */261status = set_os->set_os_version("Mac OS X 10.9");262if (status != EFI_SUCCESS)263efi_err("Failed to set OS version via apple_set_os\n");264}265}266267efi_status_t efi_adjust_memory_range_protection(unsigned long start,268unsigned long size)269{270efi_status_t status;271efi_gcd_memory_space_desc_t desc;272unsigned long end, next;273unsigned long rounded_start, rounded_end;274unsigned long unprotect_start, unprotect_size;275276rounded_start = rounddown(start, EFI_PAGE_SIZE);277rounded_end = roundup(start + size, EFI_PAGE_SIZE);278279if (memattr != NULL) {280status = efi_call_proto(memattr, set_memory_attributes,281rounded_start,282rounded_end - rounded_start,283EFI_MEMORY_RO);284if (status != EFI_SUCCESS) {285efi_warn("Failed to set EFI_MEMORY_RO attribute\n");286return status;287}288289status = efi_call_proto(memattr, clear_memory_attributes,290rounded_start,291rounded_end - rounded_start,292EFI_MEMORY_XP);293if (status != EFI_SUCCESS)294efi_warn("Failed to clear EFI_MEMORY_XP attribute\n");295return status;296}297298if (efi_dxe_table == NULL)299return EFI_SUCCESS;300301/*302* Don't modify memory region attributes, if they are303* already suitable, to lower the possibility to304* encounter firmware bugs.305*/306307for (end = start + size; start < end; start = next) {308309status = efi_dxe_call(get_memory_space_descriptor, start, &desc);310311if (status != EFI_SUCCESS)312break;313314next = desc.base_address + desc.length;315316/*317* Only system memory and more reliable memory are suitable for318* trampoline/kernel image placement. So only those memory types319* may need to have attributes modified.320*/321322if ((desc.gcd_memory_type != EfiGcdMemoryTypeSystemMemory &&323desc.gcd_memory_type != EfiGcdMemoryTypeMoreReliable) ||324(desc.attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0)325continue;326327unprotect_start = max(rounded_start, (unsigned long)desc.base_address);328unprotect_size = min(rounded_end, next) - unprotect_start;329330status = efi_dxe_call(set_memory_space_attributes,331unprotect_start, unprotect_size,332EFI_MEMORY_WB);333334if (status != EFI_SUCCESS) {335efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %lx\n",336unprotect_start,337unprotect_start + unprotect_size,338status);339break;340}341}342return EFI_SUCCESS;343}344345static void setup_unaccepted_memory(void)346{347efi_guid_t mem_acceptance_proto = OVMF_SEV_MEMORY_ACCEPTANCE_PROTOCOL_GUID;348sev_memory_acceptance_protocol_t *proto;349efi_status_t status;350351if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))352return;353354/*355* Enable unaccepted memory before calling exit boot services in order356* for the UEFI to not accept all memory on EBS.357*/358status = efi_bs_call(locate_protocol, &mem_acceptance_proto, NULL,359(void **)&proto);360if (status != EFI_SUCCESS)361return;362363status = efi_call_proto(proto, allow_unaccepted_memory);364if (status != EFI_SUCCESS)365efi_err("Memory acceptance protocol failed\n");366}367368static efi_char16_t *efistub_fw_vendor(void)369{370unsigned long vendor = efi_table_attr(efi_system_table, fw_vendor);371372return (efi_char16_t *)vendor;373}374375static const efi_char16_t apple[] = L"Apple";376377static void setup_quirks(struct boot_params *boot_params)378{379if (!memcmp(efistub_fw_vendor(), apple, sizeof(apple))) {380if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))381retrieve_apple_device_properties(boot_params);382383apple_set_os();384}385}386387static void setup_graphics(struct boot_params *boot_params)388{389struct screen_info *si = memset(&boot_params->screen_info, 0, sizeof(*si));390391efi_setup_gop(si);392}393394static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status)395{396efi_bs_call(exit, handle, status, 0, NULL);397for(;;)398asm("hlt");399}400401/*402* Because the x86 boot code expects to be passed a boot_params we403* need to create one ourselves (usually the bootloader would create404* one for us).405*/406static efi_status_t efi_allocate_bootparams(efi_handle_t handle,407struct boot_params **bp)408{409efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;410struct boot_params *boot_params;411struct setup_header *hdr;412efi_status_t status;413unsigned long alloc;414char *cmdline_ptr;415416status = efi_bs_call(handle_protocol, handle, &proto, (void **)&image);417if (status != EFI_SUCCESS) {418efi_err("Failed to get handle for LOADED_IMAGE_PROTOCOL\n");419return status;420}421422status = efi_allocate_pages(PARAM_SIZE, &alloc, ULONG_MAX);423if (status != EFI_SUCCESS)424return status;425426boot_params = memset((void *)alloc, 0x0, PARAM_SIZE);427hdr = &boot_params->hdr;428429/* Assign the setup_header fields that the kernel actually cares about */430hdr->root_flags = 1;431hdr->vid_mode = 0xffff;432433hdr->type_of_loader = 0x21;434hdr->initrd_addr_max = INT_MAX;435436/* Convert unicode cmdline to ascii */437cmdline_ptr = efi_convert_cmdline(image);438if (!cmdline_ptr) {439efi_free(PARAM_SIZE, alloc);440return EFI_OUT_OF_RESOURCES;441}442443efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr,444&boot_params->ext_cmd_line_ptr);445446*bp = boot_params;447return EFI_SUCCESS;448}449450static void add_e820ext(struct boot_params *params,451struct setup_data *e820ext, u32 nr_entries)452{453struct setup_data *data;454455e820ext->type = SETUP_E820_EXT;456e820ext->len = nr_entries * sizeof(struct boot_e820_entry);457e820ext->next = 0;458459data = (struct setup_data *)(unsigned long)params->hdr.setup_data;460461while (data && data->next)462data = (struct setup_data *)(unsigned long)data->next;463464if (data)465data->next = (unsigned long)e820ext;466else467params->hdr.setup_data = (unsigned long)e820ext;468}469470static efi_status_t471setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_size)472{473struct boot_e820_entry *entry = params->e820_table;474struct efi_info *efi = ¶ms->efi_info;475struct boot_e820_entry *prev = NULL;476u32 nr_entries;477u32 nr_desc;478int i;479480nr_entries = 0;481nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;482483for (i = 0; i < nr_desc; i++) {484efi_memory_desc_t *d;485unsigned int e820_type = 0;486unsigned long m = efi->efi_memmap;487488#ifdef CONFIG_X86_64489m |= (u64)efi->efi_memmap_hi << 32;490#endif491492d = efi_memdesc_ptr(m, efi->efi_memdesc_size, i);493switch (d->type) {494case EFI_RESERVED_TYPE:495case EFI_RUNTIME_SERVICES_CODE:496case EFI_RUNTIME_SERVICES_DATA:497case EFI_MEMORY_MAPPED_IO:498case EFI_MEMORY_MAPPED_IO_PORT_SPACE:499case EFI_PAL_CODE:500e820_type = E820_TYPE_RESERVED;501break;502503case EFI_UNUSABLE_MEMORY:504e820_type = E820_TYPE_UNUSABLE;505break;506507case EFI_ACPI_RECLAIM_MEMORY:508e820_type = E820_TYPE_ACPI;509break;510511case EFI_LOADER_CODE:512case EFI_LOADER_DATA:513case EFI_BOOT_SERVICES_CODE:514case EFI_BOOT_SERVICES_DATA:515case EFI_CONVENTIONAL_MEMORY:516if (efi_soft_reserve_enabled() &&517(d->attribute & EFI_MEMORY_SP))518e820_type = E820_TYPE_SOFT_RESERVED;519else520e820_type = E820_TYPE_RAM;521break;522523case EFI_ACPI_MEMORY_NVS:524e820_type = E820_TYPE_NVS;525break;526527case EFI_PERSISTENT_MEMORY:528e820_type = E820_TYPE_PMEM;529break;530531case EFI_UNACCEPTED_MEMORY:532if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))533continue;534e820_type = E820_TYPE_RAM;535process_unaccepted_memory(d->phys_addr,536d->phys_addr + PAGE_SIZE * d->num_pages);537break;538default:539continue;540}541542/* Merge adjacent mappings */543if (prev && prev->type == e820_type &&544(prev->addr + prev->size) == d->phys_addr) {545prev->size += d->num_pages << 12;546continue;547}548549if (nr_entries == ARRAY_SIZE(params->e820_table)) {550u32 need = (nr_desc - i) * sizeof(struct e820_entry) +551sizeof(struct setup_data);552553if (!e820ext || e820ext_size < need)554return EFI_BUFFER_TOO_SMALL;555556/* boot_params map full, switch to e820 extended */557entry = (struct boot_e820_entry *)e820ext->data;558}559560entry->addr = d->phys_addr;561entry->size = d->num_pages << PAGE_SHIFT;562entry->type = e820_type;563prev = entry++;564nr_entries++;565}566567if (nr_entries > ARRAY_SIZE(params->e820_table)) {568u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_table);569570add_e820ext(params, e820ext, nr_e820ext);571nr_entries -= nr_e820ext;572}573574params->e820_entries = (u8)nr_entries;575576return EFI_SUCCESS;577}578579static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,580u32 *e820ext_size)581{582efi_status_t status;583unsigned long size;584585size = sizeof(struct setup_data) +586sizeof(struct e820_entry) * nr_desc;587588if (*e820ext) {589efi_bs_call(free_pool, *e820ext);590*e820ext = NULL;591*e820ext_size = 0;592}593594status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,595(void **)e820ext);596if (status == EFI_SUCCESS)597*e820ext_size = size;598599return status;600}601602static efi_status_t allocate_e820(struct boot_params *params,603struct setup_data **e820ext,604u32 *e820ext_size)605{606struct efi_boot_memmap *map __free(efi_pool) = NULL;607efi_status_t status;608__u32 nr_desc;609610status = efi_get_memory_map(&map, false);611if (status != EFI_SUCCESS)612return status;613614nr_desc = map->map_size / map->desc_size;615if (nr_desc > ARRAY_SIZE(params->e820_table) - EFI_MMAP_NR_SLACK_SLOTS) {616u32 nr_e820ext = nr_desc - ARRAY_SIZE(params->e820_table) +617EFI_MMAP_NR_SLACK_SLOTS;618619status = alloc_e820ext(nr_e820ext, e820ext, e820ext_size);620if (status != EFI_SUCCESS)621return status;622}623624if (IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))625return allocate_unaccepted_bitmap(nr_desc, map);626627return EFI_SUCCESS;628}629630struct exit_boot_struct {631struct boot_params *boot_params;632struct efi_info *efi;633};634635static efi_status_t exit_boot_func(struct efi_boot_memmap *map,636void *priv)637{638const char *signature;639struct exit_boot_struct *p = priv;640641signature = efi_is_64bit() ? EFI64_LOADER_SIGNATURE642: EFI32_LOADER_SIGNATURE;643memcpy(&p->efi->efi_loader_signature, signature, sizeof(__u32));644645efi_set_u64_split((unsigned long)efi_system_table,646&p->efi->efi_systab, &p->efi->efi_systab_hi);647p->efi->efi_memdesc_size = map->desc_size;648p->efi->efi_memdesc_version = map->desc_ver;649efi_set_u64_split((unsigned long)map->map,650&p->efi->efi_memmap, &p->efi->efi_memmap_hi);651p->efi->efi_memmap_size = map->map_size;652653return EFI_SUCCESS;654}655656static efi_status_t exit_boot(struct boot_params *boot_params, void *handle)657{658struct setup_data *e820ext = NULL;659__u32 e820ext_size = 0;660efi_status_t status;661struct exit_boot_struct priv;662663priv.boot_params = boot_params;664priv.efi = &boot_params->efi_info;665666status = allocate_e820(boot_params, &e820ext, &e820ext_size);667if (status != EFI_SUCCESS)668return status;669670/* Might as well exit boot services now */671status = efi_exit_boot_services(handle, &priv, exit_boot_func);672if (status != EFI_SUCCESS)673return status;674675/* Historic? */676boot_params->alt_mem_k = 32 * 1024;677678status = setup_e820(boot_params, e820ext, e820ext_size);679if (status != EFI_SUCCESS)680return status;681682return EFI_SUCCESS;683}684685static bool have_unsupported_snp_features(void)686{687u64 unsupported;688689unsupported = snp_get_unsupported_features(sev_get_status());690if (unsupported) {691efi_err("Unsupported SEV-SNP features detected: 0x%llx\n",692unsupported);693return true;694}695return false;696}697698static void efi_get_seed(void *seed, int size)699{700efi_get_random_bytes(size, seed);701702/*703* This only updates seed[0] when running on 32-bit, but in that case,704* seed[1] is not used anyway, as there is no virtual KASLR on 32-bit.705*/706*(unsigned long *)seed ^= kaslr_get_random_long("EFI");707}708709static void error(char *str)710{711efi_warn("Decompression failed: %s\n", str);712}713714static const char *cmdline_memmap_override;715716static efi_status_t parse_options(const char *cmdline)717{718static const char opts[][14] = {719"mem=", "memmap=", "hugepages="720};721722for (int i = 0; i < ARRAY_SIZE(opts); i++) {723const char *p = strstr(cmdline, opts[i]);724725if (p == cmdline || (p > cmdline && isspace(p[-1]))) {726cmdline_memmap_override = opts[i];727break;728}729}730731return efi_parse_options(cmdline);732}733734static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry,735struct boot_params *boot_params)736{737unsigned long virt_addr = LOAD_PHYSICAL_ADDR;738unsigned long addr, alloc_size, entry;739efi_status_t status;740u32 seed[2] = {};741742boot_params_ptr = boot_params;743744/* determine the required size of the allocation */745alloc_size = ALIGN(max_t(unsigned long, output_len, kernel_total_size),746MIN_KERNEL_ALIGN);747748if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {749u64 range = KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR - kernel_total_size;750static const efi_char16_t ami[] = L"American Megatrends";751752efi_get_seed(seed, sizeof(seed));753754virt_addr += (range * seed[1]) >> 32;755virt_addr &= ~(CONFIG_PHYSICAL_ALIGN - 1);756757/*758* Older Dell systems with AMI UEFI firmware v2.0 may hang759* while decompressing the kernel if physical address760* randomization is enabled.761*762* https://bugzilla.kernel.org/show_bug.cgi?id=218173763*/764if (efi_system_table->hdr.revision <= EFI_2_00_SYSTEM_TABLE_REVISION &&765!memcmp(efistub_fw_vendor(), ami, sizeof(ami))) {766efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n");767seed[0] = 0;768} else if (cmdline_memmap_override) {769efi_info("%s detected on the kernel command line - disabling physical KASLR\n",770cmdline_memmap_override);771seed[0] = 0;772}773774boot_params->hdr.loadflags |= KASLR_FLAG;775}776777status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr,778seed[0], EFI_LOADER_CODE,779LOAD_PHYSICAL_ADDR,780EFI_X86_KERNEL_ALLOC_LIMIT);781if (status != EFI_SUCCESS)782return status;783784entry = decompress_kernel((void *)addr, virt_addr, error);785if (entry == ULONG_MAX) {786efi_free(alloc_size, addr);787return EFI_LOAD_ERROR;788}789790*kernel_entry = addr + entry;791792return efi_adjust_memory_range_protection(addr, kernel_text_size) ?:793efi_adjust_memory_range_protection(addr + kernel_inittext_offset,794kernel_inittext_size);795}796797static void __noreturn enter_kernel(unsigned long kernel_addr,798struct boot_params *boot_params)799{800/* enter decompressed kernel with boot_params pointer in RSI/ESI */801asm("jmp *%0"::"r"(kernel_addr), "S"(boot_params));802803unreachable();804}805806/*807* On success, this routine will jump to the relocated image directly and never808* return. On failure, it will exit to the firmware via efi_exit() instead of809* returning.810*/811void __noreturn efi_stub_entry(efi_handle_t handle,812efi_system_table_t *sys_table_arg,813struct boot_params *boot_params)814815{816efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;817const struct linux_efi_initrd *initrd = NULL;818unsigned long kernel_entry;819struct setup_header *hdr;820efi_status_t status;821822efi_system_table = sys_table_arg;823/* Check if we were booted by the EFI firmware */824if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)825efi_exit(handle, EFI_INVALID_PARAMETER);826827if (!IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL) || !boot_params) {828status = efi_allocate_bootparams(handle, &boot_params);829if (status != EFI_SUCCESS)830efi_exit(handle, status);831}832833hdr = &boot_params->hdr;834835if (have_unsupported_snp_features())836efi_exit(handle, EFI_UNSUPPORTED);837838if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) {839efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID);840if (efi_dxe_table &&841efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) {842efi_warn("Ignoring DXE services table: invalid signature\n");843efi_dxe_table = NULL;844}845}846847/* grab the memory attributes protocol if it exists */848efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr);849850status = efi_setup_5level_paging();851if (status != EFI_SUCCESS) {852efi_err("efi_setup_5level_paging() failed!\n");853goto fail;854}855856#ifdef CONFIG_CMDLINE_BOOL857status = parse_options(CONFIG_CMDLINE);858if (status != EFI_SUCCESS) {859efi_err("Failed to parse options\n");860goto fail;861}862#endif863if (!IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {864unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr |865((u64)boot_params->ext_cmd_line_ptr << 32));866status = parse_options((char *)cmdline_paddr);867if (status != EFI_SUCCESS) {868efi_err("Failed to parse options\n");869goto fail;870}871}872873if (efi_mem_encrypt > 0)874hdr->xloadflags |= XLF_MEM_ENCRYPTION;875876status = efi_decompress_kernel(&kernel_entry, boot_params);877if (status != EFI_SUCCESS) {878efi_err("Failed to decompress kernel\n");879goto fail;880}881882/*883* At this point, an initrd may already have been loaded by the884* bootloader and passed via bootparams. We permit an initrd loaded885* from the LINUX_EFI_INITRD_MEDIA_GUID device path to supersede it.886*887* If the device path is not present, any command-line initrd=888* arguments will be processed only if image is not NULL, which will be889* the case only if we were loaded via the PE entry point.890*/891status = efi_load_initrd(image, hdr->initrd_addr_max, ULONG_MAX,892&initrd);893if (status != EFI_SUCCESS)894goto fail;895if (initrd && initrd->size > 0) {896efi_set_u64_split(initrd->base, &hdr->ramdisk_image,897&boot_params->ext_ramdisk_image);898efi_set_u64_split(initrd->size, &hdr->ramdisk_size,899&boot_params->ext_ramdisk_size);900}901902903/*904* If the boot loader gave us a value for secure_boot then we use that,905* otherwise we ask the BIOS.906*/907if (boot_params->secure_boot == efi_secureboot_mode_unset)908boot_params->secure_boot = efi_get_secureboot();909910/* Ask the firmware to clear memory on unclean shutdown */911efi_enable_reset_attack_mitigation();912913efi_random_get_seed();914915efi_retrieve_eventlog();916917setup_graphics(boot_params);918919setup_efi_pci(boot_params);920921setup_quirks(boot_params);922923setup_unaccepted_memory();924925status = exit_boot(boot_params, handle);926if (status != EFI_SUCCESS) {927efi_err("exit_boot() failed!\n");928goto fail;929}930931/*932* Call the SEV init code while still running with the firmware's933* GDT/IDT, so #VC exceptions will be handled by EFI.934*/935sev_enable(boot_params);936937efi_5level_switch();938939enter_kernel(kernel_entry, boot_params);940fail:941efi_err("efi_stub_entry() failed!\n");942943efi_exit(handle, status);944}945946efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,947efi_system_table_t *sys_table_arg)948{949efi_stub_entry(handle, sys_table_arg, NULL);950}951952#ifdef CONFIG_EFI_HANDOVER_PROTOCOL953void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,954struct boot_params *boot_params)955{956memset(_bss, 0, _ebss - _bss);957efi_stub_entry(handle, sys_table_arg, boot_params);958}959960#ifndef CONFIG_EFI_MIXED961extern __alias(efi_handover_entry)962void efi32_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,963struct boot_params *boot_params);964965extern __alias(efi_handover_entry)966void efi64_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,967struct boot_params *boot_params);968#endif969#endif970971972