diff options
Diffstat (limited to 'arch/arm/kernel/efi.c')
-rw-r--r-- | arch/arm/kernel/efi.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index ff8a9d8acfac..9f43ba012d10 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c | |||
@@ -11,6 +11,41 @@ | |||
11 | #include <asm/mach/map.h> | 11 | #include <asm/mach/map.h> |
12 | #include <asm/mmu_context.h> | 12 | #include <asm/mmu_context.h> |
13 | 13 | ||
14 | static int __init set_permissions(pte_t *ptep, pgtable_t token, | ||
15 | unsigned long addr, void *data) | ||
16 | { | ||
17 | efi_memory_desc_t *md = data; | ||
18 | pte_t pte = *ptep; | ||
19 | |||
20 | if (md->attribute & EFI_MEMORY_RO) | ||
21 | pte = set_pte_bit(pte, __pgprot(L_PTE_RDONLY)); | ||
22 | if (md->attribute & EFI_MEMORY_XP) | ||
23 | pte = set_pte_bit(pte, __pgprot(L_PTE_XN)); | ||
24 | set_pte_ext(ptep, pte, PTE_EXT_NG); | ||
25 | return 0; | ||
26 | } | ||
27 | |||
28 | int __init efi_set_mapping_permissions(struct mm_struct *mm, | ||
29 | efi_memory_desc_t *md) | ||
30 | { | ||
31 | unsigned long base, size; | ||
32 | |||
33 | base = md->virt_addr; | ||
34 | size = md->num_pages << EFI_PAGE_SHIFT; | ||
35 | |||
36 | /* | ||
37 | * We can only use apply_to_page_range() if we can guarantee that the | ||
38 | * entire region was mapped using pages. This should be the case if the | ||
39 | * region does not cover any naturally aligned SECTION_SIZE sized | ||
40 | * blocks. | ||
41 | */ | ||
42 | if (round_down(base + size, SECTION_SIZE) < | ||
43 | round_up(base, SECTION_SIZE) + SECTION_SIZE) | ||
44 | return apply_to_page_range(mm, base, size, set_permissions, md); | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
14 | int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) | 49 | int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) |
15 | { | 50 | { |
16 | struct map_desc desc = { | 51 | struct map_desc desc = { |
@@ -34,5 +69,11 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) | |||
34 | desc.type = MT_DEVICE; | 69 | desc.type = MT_DEVICE; |
35 | 70 | ||
36 | create_mapping_late(mm, &desc, true); | 71 | create_mapping_late(mm, &desc, true); |
72 | |||
73 | /* | ||
74 | * If stricter permissions were specified, apply them now. | ||
75 | */ | ||
76 | if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP)) | ||
77 | return efi_set_mapping_permissions(mm, md); | ||
37 | return 0; | 78 | return 0; |
38 | } | 79 | } |