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 <asm/sgx.h> 12 13 #undef pr_fmt 14 #define pr_fmt(fmt) "sgx: " fmt 15 16 #define EREMOVE_ERROR_MESSAGE \ 17 "EREMOVE returned %d (0x%x) and an EPC page was leaked. SGX may become unusable. " \ 18 "Refer to Documentation/x86/sgx.rst for more information." 19 20 #define SGX_MAX_EPC_SECTIONS 8 21 #define SGX_EEXTEND_BLOCK_SIZE 256 22 #define SGX_NR_TO_SCAN 16 23 #define SGX_NR_LOW_PAGES 32 24 #define SGX_NR_HIGH_PAGES 64 25 26 /* Pages, which are being tracked by the page reclaimer. */ 27 #define SGX_EPC_PAGE_RECLAIMER_TRACKED BIT(0) 28 29 struct sgx_epc_page { 30 unsigned int section; 31 unsigned int flags; 32 struct sgx_encl_page *owner; 33 struct list_head list; 34 }; 35 36 /* 37 * Contains the tracking data for NUMA nodes having EPC pages. Most importantly, 38 * the free page list local to the node is stored here. 39 */ 40 struct sgx_numa_node { 41 struct list_head free_page_list; 42 spinlock_t lock; 43 }; 44 45 /* 46 * The firmware can define multiple chunks of EPC to the different areas of the 47 * physical memory e.g. for memory areas of the each node. This structure is 48 * used to store EPC pages for one EPC section and virtual memory area where 49 * the pages have been mapped. 50 */ 51 struct sgx_epc_section { 52 unsigned long phys_addr; 53 void *virt_addr; 54 struct sgx_epc_page *pages; 55 struct sgx_numa_node *node; 56 }; 57 58 extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS]; 59 sgx_get_epc_phys_addr(struct sgx_epc_page * page)60static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page) 61 { 62 struct sgx_epc_section *section = &sgx_epc_sections[page->section]; 63 unsigned long index; 64 65 index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); 66 67 return section->phys_addr + index * PAGE_SIZE; 68 } 69 sgx_get_epc_virt_addr(struct sgx_epc_page * page)70static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page) 71 { 72 struct sgx_epc_section *section = &sgx_epc_sections[page->section]; 73 unsigned long index; 74 75 index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); 76 77 return section->virt_addr + index * PAGE_SIZE; 78 } 79 80 struct sgx_epc_page *__sgx_alloc_epc_page(void); 81 void sgx_free_epc_page(struct sgx_epc_page *page); 82 83 void sgx_mark_page_reclaimable(struct sgx_epc_page *page); 84 int sgx_unmark_page_reclaimable(struct sgx_epc_page *page); 85 struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim); 86 87 #ifdef CONFIG_X86_SGX_KVM 88 int __init sgx_vepc_init(void); 89 #else sgx_vepc_init(void)90static inline int __init sgx_vepc_init(void) 91 { 92 return -ENODEV; 93 } 94 #endif 95 96 void sgx_update_lepubkeyhash(u64 *lepubkeyhash); 97 98 #endif /* _X86_SGX_H */ 99