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