1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 3 * Copyright (C) 2020 Western Digital Corporat 4 * Adapted from arch/arm64/kernel/efi.c 5 */ 6 7 #include <linux/efi.h> 8 #include <linux/init.h> 9 10 #include <asm/efi.h> 11 #include <asm/pgtable.h> 12 #include <asm/pgtable-bits.h> 13 14 /* 15 * Only regions of type EFI_RUNTIME_SERVICES_C 16 * executable, everything else can be mapped w 17 * set. Also take the new (optional) RO/XP bit 18 */ 19 static __init pgprot_t efimem_to_pgprot_map(ef 20 { 21 u64 attr = md->attribute; 22 u32 type = md->type; 23 24 if (type == EFI_MEMORY_MAPPED_IO) 25 return PAGE_KERNEL; 26 27 /* R-- */ 28 if ((attr & (EFI_MEMORY_XP | EFI_MEMOR 29 (EFI_MEMORY_XP | EFI_MEMORY_RO)) 30 return PAGE_KERNEL_READ; 31 32 /* R-X */ 33 if (attr & EFI_MEMORY_RO) 34 return PAGE_KERNEL_READ_EXEC; 35 36 /* RW- */ 37 if (((attr & (EFI_MEMORY_RP | EFI_MEMO 38 EFI_MEMORY_XP) || 39 type != EFI_RUNTIME_SERVICES_CODE) 40 return PAGE_KERNEL; 41 42 /* RWX */ 43 return PAGE_KERNEL_EXEC; 44 } 45 46 int __init efi_create_mapping(struct mm_struct 47 { 48 pgprot_t prot = __pgprot(pgprot_val(ef 49 ~(_PAGE_GLOBAL 50 int i; 51 52 /* RISC-V maps one page at a time */ 53 for (i = 0; i < md->num_pages; i++) 54 create_pgd_mapping(mm->pgd, md 55 md->phys_ad 56 PAGE_SIZE, 57 return 0; 58 } 59 60 static int __init set_permissions(pte_t *ptep, 61 { 62 efi_memory_desc_t *md = data; 63 pte_t pte = ptep_get(ptep); 64 unsigned long val; 65 66 if (md->attribute & EFI_MEMORY_RO) { 67 val = pte_val(pte) & ~_PAGE_WR 68 val |= _PAGE_READ; 69 pte = __pte(val); 70 } 71 if (md->attribute & EFI_MEMORY_XP) { 72 val = pte_val(pte) & ~_PAGE_EX 73 pte = __pte(val); 74 } 75 set_pte(ptep, pte); 76 77 return 0; 78 } 79 80 int __init efi_set_mapping_permissions(struct 81 efi_mem 82 bool ig 83 { 84 BUG_ON(md->type != EFI_RUNTIME_SERVICE 85 md->type != EFI_RUNTIME_SERVICE 86 87 /* 88 * Calling apply_to_page_range() is on 89 * guaranteed to be mapped down to pag 90 * for regions that have been mapped u 91 * (and this is checked by the generic 92 * routines), there is no need to chec 93 */ 94 return apply_to_page_range(mm, md->vir 95 md->num_pag 96 set_permiss 97 } 98
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.