xref: /openbmc/linux/arch/x86/kernel/cpu/sgx/sgx.h (revision d6d261bded8a57aed4faa12d08a5b193418d3aa4)
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 /* Pages on free list */
30 #define SGX_EPC_PAGE_IS_FREE		BIT(1)
31 
32 struct sgx_epc_page {
33 	unsigned int section;
34 	unsigned int flags;
35 	struct sgx_encl_page *owner;
36 	struct list_head list;
37 };
38 
39 /*
40  * Contains the tracking data for NUMA nodes having EPC pages. Most importantly,
41  * the free page list local to the node is stored here.
42  */
43 struct sgx_numa_node {
44 	struct list_head free_page_list;
45 	spinlock_t lock;
46 };
47 
48 /*
49  * The firmware can define multiple chunks of EPC to the different areas of the
50  * physical memory e.g. for memory areas of the each node. This structure is
51  * used to store EPC pages for one EPC section and virtual memory area where
52  * the pages have been mapped.
53  */
54 struct sgx_epc_section {
55 	unsigned long phys_addr;
56 	void *virt_addr;
57 	struct sgx_epc_page *pages;
58 	struct sgx_numa_node *node;
59 };
60 
61 extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
62 
63 static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page)
64 {
65 	struct sgx_epc_section *section = &sgx_epc_sections[page->section];
66 	unsigned long index;
67 
68 	index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
69 
70 	return section->phys_addr + index * PAGE_SIZE;
71 }
72 
73 static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
74 {
75 	struct sgx_epc_section *section = &sgx_epc_sections[page->section];
76 	unsigned long index;
77 
78 	index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
79 
80 	return section->virt_addr + index * PAGE_SIZE;
81 }
82 
83 struct sgx_epc_page *__sgx_alloc_epc_page(void);
84 void sgx_free_epc_page(struct sgx_epc_page *page);
85 
86 void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
87 int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
88 struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
89 
90 #ifdef CONFIG_X86_SGX_KVM
91 int __init sgx_vepc_init(void);
92 #else
93 static inline int __init sgx_vepc_init(void)
94 {
95 	return -ENODEV;
96 }
97 #endif
98 
99 void sgx_update_lepubkeyhash(u64 *lepubkeyhash);
100 
101 #endif /* _X86_SGX_H */
102