1 /* 2 * Extensible Firmware Interface 3 * 4 * Based on Extensible Firmware Interface Specification version 2.4 5 * 6 * Copyright (C) 2013, 2014 Linaro Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 */ 13 14 #include <linux/dmi.h> 15 #include <linux/efi.h> 16 #include <linux/init.h> 17 18 #include <asm/efi.h> 19 20 /* 21 * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be 22 * executable, everything else can be mapped with the XN bits 23 * set. Also take the new (optional) RO/XP bits into account. 24 */ 25 static __init pteval_t create_mapping_protection(efi_memory_desc_t *md) 26 { 27 u64 attr = md->attribute; 28 u32 type = md->type; 29 30 if (type == EFI_MEMORY_MAPPED_IO) 31 return PROT_DEVICE_nGnRE; 32 33 if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr), 34 "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?")) 35 /* 36 * If the region is not aligned to the page size of the OS, we 37 * can not use strict permissions, since that would also affect 38 * the mapping attributes of the adjacent regions. 39 */ 40 return pgprot_val(PAGE_KERNEL_EXEC); 41 42 /* R-- */ 43 if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == 44 (EFI_MEMORY_XP | EFI_MEMORY_RO)) 45 return pgprot_val(PAGE_KERNEL_RO); 46 47 /* R-X */ 48 if (attr & EFI_MEMORY_RO) 49 return pgprot_val(PAGE_KERNEL_ROX); 50 51 /* RW- */ 52 if (attr & EFI_MEMORY_XP || type != EFI_RUNTIME_SERVICES_CODE) 53 return pgprot_val(PAGE_KERNEL); 54 55 /* RWX */ 56 return pgprot_val(PAGE_KERNEL_EXEC); 57 } 58 59 /* we will fill this structure from the stub, so don't put it in .bss */ 60 struct screen_info screen_info __section(.data); 61 62 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) 63 { 64 pteval_t prot_val = create_mapping_protection(md); 65 66 create_pgd_mapping(mm, md->phys_addr, md->virt_addr, 67 md->num_pages << EFI_PAGE_SHIFT, 68 __pgprot(prot_val | PTE_NG)); 69 return 0; 70 } 71 72 static int __init arm64_dmi_init(void) 73 { 74 /* 75 * On arm64, DMI depends on UEFI, and dmi_scan_machine() needs to 76 * be called early because dmi_id_init(), which is an arch_initcall 77 * itself, depends on dmi_scan_machine() having been called already. 78 */ 79 dmi_scan_machine(); 80 if (dmi_available) 81 dmi_set_dump_stack_arch_desc(); 82 return 0; 83 } 84 core_initcall(arm64_dmi_init); 85 86 /* 87 * UpdateCapsule() depends on the system being shutdown via 88 * ResetSystem(). 89 */ 90 bool efi_poweroff_required(void) 91 { 92 return efi_enabled(EFI_RUNTIME_SERVICES); 93 } 94