/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _X86_SGX_H #define _X86_SGX_H #include #include #include #include #include #include #include "arch.h" #undef pr_fmt #define pr_fmt(fmt) "sgx: " fmt #define SGX_MAX_EPC_SECTIONS 8 #define SGX_EEXTEND_BLOCK_SIZE 256 #define SGX_NR_TO_SCAN 16 #define SGX_NR_LOW_PAGES 32 #define SGX_NR_HIGH_PAGES 64 /* Pages, which are being tracked by the page reclaimer. */ #define SGX_EPC_PAGE_RECLAIMER_TRACKED BIT(0) struct sgx_epc_page { unsigned int section; unsigned int flags; struct sgx_encl_page *owner; struct list_head list; }; /* * The firmware can define multiple chunks of EPC to the different areas of the * physical memory e.g. for memory areas of the each node. This structure is * used to store EPC pages for one EPC section and virtual memory area where * the pages have been mapped. * * 'lock' must be held before accessing 'page_list' or 'free_cnt'. */ struct sgx_epc_section { unsigned long phys_addr; void *virt_addr; struct sgx_epc_page *pages; spinlock_t lock; struct list_head page_list; unsigned long free_cnt; /* * Pages which need EREMOVE run on them before they can be * used. Only safe to be accessed in ksgxd and init code. * Not protected by locks. */ struct list_head init_laundry_list; }; extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS]; static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page) { struct sgx_epc_section *section = &sgx_epc_sections[page->section]; unsigned long index; index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); return section->phys_addr + index * PAGE_SIZE; } static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page) { struct sgx_epc_section *section = &sgx_epc_sections[page->section]; unsigned long index; index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); return section->virt_addr + index * PAGE_SIZE; } struct sgx_epc_page *__sgx_alloc_epc_page(void); void sgx_free_epc_page(struct sgx_epc_page *page); void sgx_mark_page_reclaimable(struct sgx_epc_page *page); int sgx_unmark_page_reclaimable(struct sgx_epc_page *page); struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim); #endif /* _X86_SGX_H */