0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/efi.h>
0013 #include <linux/libfdt.h>
0014 #include <asm/efi.h>
0015
0016 #include "efistub.h"
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #define EFI_RT_VIRTUAL_BASE SZ_512M
0039 #define EFI_RT_VIRTUAL_SIZE SZ_512M
0040
0041 #ifdef CONFIG_ARM64
0042 # define EFI_RT_VIRTUAL_LIMIT DEFAULT_MAP_WINDOW_64
0043 #elif defined(CONFIG_RISCV)
0044 # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE_MIN
0045 #else
0046 # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE
0047 #endif
0048
0049 static u64 virtmap_base = EFI_RT_VIRTUAL_BASE;
0050 static bool flat_va_mapping;
0051
0052 const efi_system_table_t *efi_system_table;
0053
0054 static struct screen_info *setup_graphics(void)
0055 {
0056 efi_guid_t gop_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
0057 efi_status_t status;
0058 unsigned long size;
0059 void **gop_handle = NULL;
0060 struct screen_info *si = NULL;
0061
0062 size = 0;
0063 status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL,
0064 &gop_proto, NULL, &size, gop_handle);
0065 if (status == EFI_BUFFER_TOO_SMALL) {
0066 si = alloc_screen_info();
0067 if (!si)
0068 return NULL;
0069 status = efi_setup_gop(si, &gop_proto, size);
0070 if (status != EFI_SUCCESS) {
0071 free_screen_info(si);
0072 return NULL;
0073 }
0074 }
0075 return si;
0076 }
0077
0078 static void install_memreserve_table(void)
0079 {
0080 struct linux_efi_memreserve *rsv;
0081 efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
0082 efi_status_t status;
0083
0084 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
0085 (void **)&rsv);
0086 if (status != EFI_SUCCESS) {
0087 efi_err("Failed to allocate memreserve entry!\n");
0088 return;
0089 }
0090
0091 rsv->next = 0;
0092 rsv->size = 0;
0093 atomic_set(&rsv->count, 0);
0094
0095 status = efi_bs_call(install_configuration_table,
0096 &memreserve_table_guid, rsv);
0097 if (status != EFI_SUCCESS)
0098 efi_err("Failed to install memreserve config table!\n");
0099 }
0100
0101 static u32 get_supported_rt_services(void)
0102 {
0103 const efi_rt_properties_table_t *rt_prop_table;
0104 u32 supported = EFI_RT_SUPPORTED_ALL;
0105
0106 rt_prop_table = get_efi_config_table(EFI_RT_PROPERTIES_TABLE_GUID);
0107 if (rt_prop_table)
0108 supported &= rt_prop_table->runtime_services_supported;
0109
0110 return supported;
0111 }
0112
0113
0114
0115
0116
0117
0118
0119 efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
0120 efi_system_table_t *sys_table_arg)
0121 {
0122 efi_loaded_image_t *image;
0123 efi_status_t status;
0124 unsigned long image_addr;
0125 unsigned long image_size = 0;
0126
0127 unsigned long initrd_addr = 0;
0128 unsigned long initrd_size = 0;
0129 unsigned long fdt_addr = 0;
0130 unsigned long fdt_size = 0;
0131 char *cmdline_ptr = NULL;
0132 int cmdline_size = 0;
0133 efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
0134 unsigned long reserve_addr = 0;
0135 unsigned long reserve_size = 0;
0136 enum efi_secureboot_mode secure_boot;
0137 struct screen_info *si;
0138 efi_properties_table_t *prop_tbl;
0139
0140 efi_system_table = sys_table_arg;
0141
0142
0143 if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
0144 status = EFI_INVALID_PARAMETER;
0145 goto fail;
0146 }
0147
0148 status = check_platform_features();
0149 if (status != EFI_SUCCESS)
0150 goto fail;
0151
0152
0153
0154
0155
0156
0157 status = efi_system_table->boottime->handle_protocol(handle,
0158 &loaded_image_proto, (void *)&image);
0159 if (status != EFI_SUCCESS) {
0160 efi_err("Failed to get loaded image protocol\n");
0161 goto fail;
0162 }
0163
0164
0165
0166
0167
0168
0169 cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
0170 if (!cmdline_ptr) {
0171 efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
0172 status = EFI_OUT_OF_RESOURCES;
0173 goto fail;
0174 }
0175
0176 if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
0177 IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
0178 cmdline_size == 0) {
0179 status = efi_parse_options(CONFIG_CMDLINE);
0180 if (status != EFI_SUCCESS) {
0181 efi_err("Failed to parse options\n");
0182 goto fail_free_cmdline;
0183 }
0184 }
0185
0186 if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) {
0187 status = efi_parse_options(cmdline_ptr);
0188 if (status != EFI_SUCCESS) {
0189 efi_err("Failed to parse options\n");
0190 goto fail_free_cmdline;
0191 }
0192 }
0193
0194 efi_info("Booting Linux Kernel...\n");
0195
0196 si = setup_graphics();
0197
0198 status = handle_kernel_image(&image_addr, &image_size,
0199 &reserve_addr,
0200 &reserve_size,
0201 image, handle);
0202 if (status != EFI_SUCCESS) {
0203 efi_err("Failed to relocate kernel\n");
0204 goto fail_free_screeninfo;
0205 }
0206
0207 efi_retrieve_tpm2_eventlog();
0208
0209
0210 efi_enable_reset_attack_mitigation();
0211
0212 secure_boot = efi_get_secureboot();
0213
0214
0215
0216
0217
0218
0219 if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) ||
0220 secure_boot != efi_secureboot_mode_disabled) {
0221 if (strstr(cmdline_ptr, "dtb="))
0222 efi_err("Ignoring DTB from command line.\n");
0223 } else {
0224 status = efi_load_dtb(image, &fdt_addr, &fdt_size);
0225
0226 if (status != EFI_SUCCESS) {
0227 efi_err("Failed to load device tree!\n");
0228 goto fail_free_image;
0229 }
0230 }
0231
0232 if (fdt_addr) {
0233 efi_info("Using DTB from command line\n");
0234 } else {
0235
0236 fdt_addr = (uintptr_t)get_fdt(&fdt_size);
0237 if (fdt_addr)
0238 efi_info("Using DTB from configuration table\n");
0239 }
0240
0241 if (!fdt_addr)
0242 efi_info("Generating empty DTB\n");
0243
0244 efi_load_initrd(image, &initrd_addr, &initrd_size, ULONG_MAX,
0245 efi_get_max_initrd_addr(image_addr));
0246
0247 efi_random_get_seed();
0248
0249
0250
0251
0252
0253
0254
0255
0256 prop_tbl = get_efi_config_table(EFI_PROPERTIES_TABLE_GUID);
0257 flat_va_mapping = prop_tbl &&
0258 (prop_tbl->memory_protection_attribute &
0259 EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
0260
0261
0262 efi_novamap |= !(get_supported_rt_services() &
0263 EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP);
0264
0265
0266 if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) {
0267
0268
0269
0270
0271
0272
0273 static const u64 headroom = EFI_RT_VIRTUAL_LIMIT -
0274 EFI_RT_VIRTUAL_BASE -
0275 EFI_RT_VIRTUAL_SIZE;
0276 u32 rnd;
0277
0278 status = efi_get_random_bytes(sizeof(rnd), (u8 *)&rnd);
0279 if (status == EFI_SUCCESS) {
0280 virtmap_base = EFI_RT_VIRTUAL_BASE +
0281 (((headroom >> 21) * rnd) >> (32 - 21));
0282 }
0283 }
0284
0285 install_memreserve_table();
0286
0287 status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr,
0288 initrd_addr, initrd_size,
0289 cmdline_ptr, fdt_addr, fdt_size);
0290 if (status != EFI_SUCCESS)
0291 goto fail_free_initrd;
0292
0293 if (IS_ENABLED(CONFIG_ARM))
0294 efi_handle_post_ebs_state();
0295
0296 efi_enter_kernel(image_addr, fdt_addr, fdt_totalsize((void *)fdt_addr));
0297
0298
0299 fail_free_initrd:
0300 efi_err("Failed to update FDT and exit boot services\n");
0301
0302 efi_free(initrd_size, initrd_addr);
0303 efi_free(fdt_size, fdt_addr);
0304
0305 fail_free_image:
0306 efi_free(image_size, image_addr);
0307 efi_free(reserve_size, reserve_addr);
0308 fail_free_screeninfo:
0309 free_screen_info(si);
0310 fail_free_cmdline:
0311 efi_bs_call(free_pool, cmdline_ptr);
0312 fail:
0313 return status;
0314 }
0315
0316
0317
0318
0319
0320
0321
0322
0323 void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
0324 unsigned long desc_size, efi_memory_desc_t *runtime_map,
0325 int *count)
0326 {
0327 u64 efi_virt_base = virtmap_base;
0328 efi_memory_desc_t *in, *out = runtime_map;
0329 int l;
0330
0331 for (l = 0; l < map_size; l += desc_size) {
0332 u64 paddr, size;
0333
0334 in = (void *)memory_map + l;
0335 if (!(in->attribute & EFI_MEMORY_RUNTIME))
0336 continue;
0337
0338 paddr = in->phys_addr;
0339 size = in->num_pages * EFI_PAGE_SIZE;
0340
0341 in->virt_addr = in->phys_addr;
0342 if (efi_novamap) {
0343 continue;
0344 }
0345
0346
0347
0348
0349
0350
0351 if (!flat_va_mapping) {
0352
0353 paddr = round_down(in->phys_addr, SZ_64K);
0354 size += in->phys_addr - paddr;
0355
0356
0357
0358
0359
0360
0361
0362 if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M)
0363 efi_virt_base = round_up(efi_virt_base, SZ_2M);
0364 else
0365 efi_virt_base = round_up(efi_virt_base, SZ_64K);
0366
0367 in->virt_addr += efi_virt_base - paddr;
0368 efi_virt_base += size;
0369 }
0370
0371 memcpy(out, in, desc_size);
0372 out = (void *)out + desc_size;
0373 ++*count;
0374 }
0375 }