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:8; 31 enum sgx_page_type type:16; 32 struct sgx_epc_page *epc_page; 33 struct sgx_encl *encl; 34 struct sgx_va_page *va_page; 35 }; 36 37 enum sgx_encl_flags { 38 SGX_ENCL_IOCTL = BIT(0), 39 SGX_ENCL_DEBUG = BIT(1), 40 SGX_ENCL_CREATED = BIT(2), 41 SGX_ENCL_INITIALIZED = BIT(3), 42 }; 43 44 struct sgx_encl_mm { 45 struct sgx_encl *encl; 46 struct mm_struct *mm; 47 struct list_head list; 48 struct mmu_notifier mmu_notifier; 49 }; 50 51 struct sgx_encl { 52 unsigned long base; 53 unsigned long size; 54 unsigned long flags; 55 unsigned int page_cnt; 56 unsigned int secs_child_cnt; 57 struct mutex lock; 58 struct xarray page_array; 59 struct sgx_encl_page secs; 60 unsigned long attributes; 61 unsigned long attributes_mask; 62 63 cpumask_t cpumask; 64 struct file *backing; 65 struct kref refcount; 66 struct list_head va_pages; 67 unsigned long mm_list_version; 68 struct list_head mm_list; 69 spinlock_t mm_lock; 70 struct srcu_struct srcu; 71 }; 72 73 #define SGX_VA_SLOT_COUNT 512 74 75 struct sgx_va_page { 76 struct sgx_epc_page *epc_page; 77 DECLARE_BITMAP(slots, SGX_VA_SLOT_COUNT); 78 struct list_head list; 79 }; 80 81 struct sgx_backing { 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 = vma_lookup(mm, addr); 95 if (!result || result->vm_ops != &sgx_vm_ops) 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 bool current_is_ksgxd(void); 107 void sgx_encl_release(struct kref *ref); 108 int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); 109 const cpumask_t *sgx_encl_cpumask(struct sgx_encl *encl); 110 int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, 111 struct sgx_backing *backing); 112 int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, 113 struct sgx_backing *backing); 114 void sgx_encl_put_backing(struct sgx_backing *backing); 115 int sgx_encl_test_and_clear_young(struct mm_struct *mm, 116 struct sgx_encl_page *page); 117 struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl, 118 unsigned long offset, 119 u64 secinfo_flags); 120 void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr); 121 struct sgx_epc_page *sgx_alloc_va_page(bool reclaim); 122 unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page); 123 void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset); 124 bool sgx_va_page_full(struct sgx_va_page *va_page); 125 void sgx_encl_free_epc_page(struct sgx_epc_page *page); 126 struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl, 127 unsigned long addr); 128 struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim); 129 void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page); 130 131 #endif /* _X86_ENCL_H */ 132