1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _X86_SGX_H 3 #define _X86_SGX_H 4 5 #include <linux/bitops.h> 6 #include <linux/err.h> 7 #include <linux/io.h> 8 #include <linux/rwsem.h> 9 #include <linux/types.h> 10 #include <asm/asm.h> 11 #include "arch.h" 12 13 #undef pr_fmt 14 #define pr_fmt(fmt) "sgx: " fmt 15 16 #define SGX_MAX_EPC_SECTIONS 8 17 #define SGX_EEXTEND_BLOCK_SIZE 256 18 #define SGX_NR_TO_SCAN 16 19 #define SGX_NR_LOW_PAGES 32 20 #define SGX_NR_HIGH_PAGES 64 21 22 /* Pages, which are being tracked by the page reclaimer. */ 23 #define SGX_EPC_PAGE_RECLAIMER_TRACKED BIT(0) 24 25 struct sgx_epc_page { 26 unsigned int section; 27 unsigned int flags; 28 struct sgx_encl_page *owner; 29 struct list_head list; 30 }; 31 32 /* 33 * The firmware can define multiple chunks of EPC to the different areas of the 34 * physical memory e.g. for memory areas of the each node. This structure is 35 * used to store EPC pages for one EPC section and virtual memory area where 36 * the pages have been mapped. 37 * 38 * 'lock' must be held before accessing 'page_list' or 'free_cnt'. 39 */ 40 struct sgx_epc_section { 41 unsigned long phys_addr; 42 void *virt_addr; 43 struct sgx_epc_page *pages; 44 45 spinlock_t lock; 46 struct list_head page_list; 47 unsigned long free_cnt; 48 49 /* 50 * Pages which need EREMOVE run on them before they can be 51 * used. Only safe to be accessed in ksgxd and init code. 52 * Not protected by locks. 53 */ 54 struct list_head init_laundry_list; 55 }; 56 57 extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS]; 58 59 static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page) 60 { 61 struct sgx_epc_section *section = &sgx_epc_sections[page->section]; 62 unsigned long index; 63 64 index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); 65 66 return section->phys_addr + index * PAGE_SIZE; 67 } 68 69 static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page) 70 { 71 struct sgx_epc_section *section = &sgx_epc_sections[page->section]; 72 unsigned long index; 73 74 index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); 75 76 return section->virt_addr + index * PAGE_SIZE; 77 } 78 79 struct sgx_epc_page *__sgx_alloc_epc_page(void); 80 void sgx_free_epc_page(struct sgx_epc_page *page); 81 82 void sgx_mark_page_reclaimable(struct sgx_epc_page *page); 83 int sgx_unmark_page_reclaimable(struct sgx_epc_page *page); 84 struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim); 85 86 #endif /* _X86_SGX_H */ 87