1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/export.h> 4 #include <linux/mm.h> 5 #include <asm/pgtable.h> 6 #include <asm/mem_encrypt.h> 7 8 static pgprot_t protection_map[16] __ro_after_init = { 9 [VM_NONE] = PAGE_NONE, 10 [VM_READ] = PAGE_READONLY, 11 [VM_WRITE] = PAGE_COPY, 12 [VM_WRITE | VM_READ] = PAGE_COPY, 13 [VM_EXEC] = PAGE_READONLY_EXEC, 14 [VM_EXEC | VM_READ] = PAGE_READONLY_EXEC, 15 [VM_EXEC | VM_WRITE] = PAGE_COPY_EXEC, 16 [VM_EXEC | VM_WRITE | VM_READ] = PAGE_COPY_EXEC, 17 [VM_SHARED] = PAGE_NONE, 18 [VM_SHARED | VM_READ] = PAGE_READONLY, 19 [VM_SHARED | VM_WRITE] = PAGE_SHARED, 20 [VM_SHARED | VM_WRITE | VM_READ] = PAGE_SHARED, 21 [VM_SHARED | VM_EXEC] = PAGE_READONLY_EXEC, 22 [VM_SHARED | VM_EXEC | VM_READ] = PAGE_READONLY_EXEC, 23 [VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_SHARED_EXEC, 24 [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED_EXEC 25 }; 26 27 void add_encrypt_protection_map(void) 28 { 29 unsigned int i; 30 31 for (i = 0; i < ARRAY_SIZE(protection_map); i++) 32 protection_map[i] = pgprot_encrypted(protection_map[i]); 33 } 34 35 pgprot_t vm_get_page_prot(unsigned long vm_flags) 36 { 37 unsigned long val = pgprot_val(protection_map[vm_flags & 38 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]); 39 40 #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS 41 /* 42 * Take the 4 protection key bits out of the vma->vm_flags value and 43 * turn them in to the bits that we can put in to a pte. 44 * 45 * Only override these if Protection Keys are available (which is only 46 * on 64-bit). 47 */ 48 if (vm_flags & VM_PKEY_BIT0) 49 val |= _PAGE_PKEY_BIT0; 50 if (vm_flags & VM_PKEY_BIT1) 51 val |= _PAGE_PKEY_BIT1; 52 if (vm_flags & VM_PKEY_BIT2) 53 val |= _PAGE_PKEY_BIT2; 54 if (vm_flags & VM_PKEY_BIT3) 55 val |= _PAGE_PKEY_BIT3; 56 #endif 57 58 val = __sme_set(val); 59 if (val & _PAGE_PRESENT) 60 val &= __supported_pte_mask; 61 return __pgprot(val); 62 } 63 EXPORT_SYMBOL(vm_get_page_prot); 64