diff options
Diffstat (limited to 'arch/arm64/kernel/efi.c')
-rw-r--r-- | arch/arm64/kernel/efi.c | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index b6abc852f2a1..78f52488f9ff 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -17,22 +17,51 @@ | |||
17 | 17 | ||
18 | #include <asm/efi.h> | 18 | #include <asm/efi.h> |
19 | 19 | ||
20 | int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) | 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) | ||
21 | { | 26 | { |
22 | pteval_t prot_val; | 27 | u64 attr = md->attribute; |
28 | u32 type = md->type; | ||
23 | 29 | ||
24 | /* | 30 | if (type == EFI_MEMORY_MAPPED_IO) |
25 | * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be | 31 | return PROT_DEVICE_nGnRE; |
26 | * executable, everything else can be mapped with the XN bits | 32 | |
27 | * set. | 33 | if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr), |
28 | */ | 34 | "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?")) |
29 | if ((md->attribute & EFI_MEMORY_WB) == 0) | 35 | /* |
30 | prot_val = PROT_DEVICE_nGnRE; | 36 | * If the region is not aligned to the page size of the OS, we |
31 | else if (md->type == EFI_RUNTIME_SERVICES_CODE || | 37 | * can not use strict permissions, since that would also affect |
32 | !PAGE_ALIGNED(md->phys_addr)) | 38 | * the mapping attributes of the adjacent regions. |
33 | prot_val = pgprot_val(PAGE_KERNEL_EXEC); | 39 | */ |
34 | else | 40 | return pgprot_val(PAGE_KERNEL_EXEC); |
35 | prot_val = pgprot_val(PAGE_KERNEL); | 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); | ||
36 | 65 | ||
37 | create_pgd_mapping(mm, md->phys_addr, md->virt_addr, | 66 | create_pgd_mapping(mm, md->phys_addr, md->virt_addr, |
38 | md->num_pages << EFI_PAGE_SHIFT, | 67 | md->num_pages << EFI_PAGE_SHIFT, |