| 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(vm_flags_t 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 |  | 
|---|