1e7e05452SSean Christopherson /* SPDX-License-Identifier: GPL-2.0 */ 2e7e05452SSean Christopherson #ifndef _X86_SGX_H 3e7e05452SSean Christopherson #define _X86_SGX_H 4e7e05452SSean Christopherson 5e7e05452SSean Christopherson #include <linux/bitops.h> 6e7e05452SSean Christopherson #include <linux/err.h> 7e7e05452SSean Christopherson #include <linux/io.h> 8e7e05452SSean Christopherson #include <linux/rwsem.h> 9e7e05452SSean Christopherson #include <linux/types.h> 10e7e05452SSean Christopherson #include <asm/asm.h> 11e7e05452SSean Christopherson #include "arch.h" 12e7e05452SSean Christopherson 13e7e05452SSean Christopherson #undef pr_fmt 14e7e05452SSean Christopherson #define pr_fmt(fmt) "sgx: " fmt 15e7e05452SSean Christopherson 16e7e05452SSean Christopherson #define SGX_MAX_EPC_SECTIONS 8 17*c6d26d37SJarkko Sakkinen #define SGX_EEXTEND_BLOCK_SIZE 256 18e7e05452SSean Christopherson 19e7e05452SSean Christopherson struct sgx_epc_page { 20e7e05452SSean Christopherson unsigned int section; 21e7e05452SSean Christopherson struct list_head list; 22e7e05452SSean Christopherson }; 23e7e05452SSean Christopherson 24e7e05452SSean Christopherson /* 25e7e05452SSean Christopherson * The firmware can define multiple chunks of EPC to the different areas of the 26e7e05452SSean Christopherson * physical memory e.g. for memory areas of the each node. This structure is 27e7e05452SSean Christopherson * used to store EPC pages for one EPC section and virtual memory area where 28e7e05452SSean Christopherson * the pages have been mapped. 29e7e05452SSean Christopherson */ 30e7e05452SSean Christopherson struct sgx_epc_section { 31e7e05452SSean Christopherson unsigned long phys_addr; 32e7e05452SSean Christopherson void *virt_addr; 33e7e05452SSean Christopherson struct list_head page_list; 34e7e05452SSean Christopherson struct list_head laundry_list; 35e7e05452SSean Christopherson struct sgx_epc_page *pages; 36e7e05452SSean Christopherson spinlock_t lock; 37e7e05452SSean Christopherson }; 38e7e05452SSean Christopherson 39e7e05452SSean Christopherson extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS]; 40e7e05452SSean Christopherson 41e7e05452SSean Christopherson static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page) 42e7e05452SSean Christopherson { 43e7e05452SSean Christopherson struct sgx_epc_section *section = &sgx_epc_sections[page->section]; 44e7e05452SSean Christopherson unsigned long index; 45e7e05452SSean Christopherson 46e7e05452SSean Christopherson index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); 47e7e05452SSean Christopherson 48e7e05452SSean Christopherson return section->phys_addr + index * PAGE_SIZE; 49e7e05452SSean Christopherson } 50e7e05452SSean Christopherson 51e7e05452SSean Christopherson static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page) 52e7e05452SSean Christopherson { 53e7e05452SSean Christopherson struct sgx_epc_section *section = &sgx_epc_sections[page->section]; 54e7e05452SSean Christopherson unsigned long index; 55e7e05452SSean Christopherson 56e7e05452SSean Christopherson index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page); 57e7e05452SSean Christopherson 58e7e05452SSean Christopherson return section->virt_addr + index * PAGE_SIZE; 59e7e05452SSean Christopherson } 60e7e05452SSean Christopherson 61d2285493SJarkko Sakkinen struct sgx_epc_page *__sgx_alloc_epc_page(void); 62d2285493SJarkko Sakkinen void sgx_free_epc_page(struct sgx_epc_page *page); 63d2285493SJarkko Sakkinen 64e7e05452SSean Christopherson #endif /* _X86_SGX_H */ 65