1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /** 3 * Copyright(c) 2016-20 Intel Corporation. 4 * 5 * Contains the software defined data structures for enclaves. 6 */ 7 #ifndef _X86_ENCL_H 8 #define _X86_ENCL_H 9 10 #include <linux/cpumask.h> 11 #include <linux/kref.h> 12 #include <linux/list.h> 13 #include <linux/mm_types.h> 14 #include <linux/mmu_notifier.h> 15 #include <linux/mutex.h> 16 #include <linux/notifier.h> 17 #include <linux/srcu.h> 18 #include <linux/workqueue.h> 19 #include <linux/xarray.h> 20 #include "sgx.h" 21 22 /* 'desc' bits holding the offset in the VA (version array) page. */ 23 #define SGX_ENCL_PAGE_VA_OFFSET_MASK GENMASK_ULL(11, 3) 24 25 /* 'desc' bit marking that the page is being reclaimed. */ 26 #define SGX_ENCL_PAGE_BEING_RECLAIMED BIT(3) 27 28 struct sgx_encl_page { 29 unsigned long desc; 30 unsigned long vm_max_prot_bits; 31 struct sgx_epc_page *epc_page; 32 struct sgx_encl *encl; 33 struct sgx_va_page *va_page; 34 }; 35 36 enum sgx_encl_flags { 37 SGX_ENCL_IOCTL = BIT(0), 38 SGX_ENCL_DEBUG = BIT(1), 39 SGX_ENCL_CREATED = BIT(2), 40 SGX_ENCL_INITIALIZED = BIT(3), 41 }; 42 43 struct sgx_encl_mm { 44 struct sgx_encl *encl; 45 struct mm_struct *mm; 46 struct list_head list; 47 struct mmu_notifier mmu_notifier; 48 }; 49 50 struct sgx_encl { 51 unsigned long base; 52 unsigned long size; 53 unsigned long flags; 54 unsigned int page_cnt; 55 unsigned int secs_child_cnt; 56 struct mutex lock; 57 struct xarray page_array; 58 struct sgx_encl_page secs; 59 unsigned long attributes; 60 unsigned long attributes_mask; 61 62 cpumask_t cpumask; 63 struct file *backing; 64 struct kref refcount; 65 struct list_head va_pages; 66 unsigned long mm_list_version; 67 struct list_head mm_list; 68 spinlock_t mm_lock; 69 struct srcu_struct srcu; 70 }; 71 72 #define SGX_VA_SLOT_COUNT 512 73 74 struct sgx_va_page { 75 struct sgx_epc_page *epc_page; 76 DECLARE_BITMAP(slots, SGX_VA_SLOT_COUNT); 77 struct list_head list; 78 }; 79 80 struct sgx_backing { 81 pgoff_t page_index; 82 struct page *contents; 83 struct page *pcmd; 84 unsigned long pcmd_offset; 85 }; 86 87 extern const struct vm_operations_struct sgx_vm_ops; 88 89 static inline int sgx_encl_find(struct mm_struct *mm, unsigned long addr, 90 struct vm_area_struct **vma) 91 { 92 struct vm_area_struct *result; 93 94 result = find_vma(mm, addr); 95 if (!result || result->vm_ops != &sgx_vm_ops || addr < result->vm_start) 96 return -EINVAL; 97 98 *vma = result; 99 100 return 0; 101 } 102 103 int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start, 104 unsigned long end, unsigned long vm_flags); 105 106 void sgx_encl_release(struct kref *ref); 107 int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); 108 int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, 109 struct sgx_backing *backing); 110 void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write); 111 int sgx_encl_test_and_clear_young(struct mm_struct *mm, 112 struct sgx_encl_page *page); 113 114 struct sgx_epc_page *sgx_alloc_va_page(void); 115 unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page); 116 void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset); 117 bool sgx_va_page_full(struct sgx_va_page *va_page); 118 119 #endif /* _X86_ENCL_H */ 120