xref: /openbmc/linux/arch/x86/kernel/cpu/sgx/sgx.h (revision e7e0545299d8cb0fd6fe3ba50401b7f5c3937362)
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