xref: /openbmc/linux/arch/x86/kernel/cpu/sgx/sgx.h (revision 0d3b051a)
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 "arch.h"
12 
13 #undef pr_fmt
14 #define pr_fmt(fmt) "sgx: " fmt
15 
16 #define SGX_MAX_EPC_SECTIONS		8
17 #define SGX_EEXTEND_BLOCK_SIZE		256
18 #define SGX_NR_TO_SCAN			16
19 #define SGX_NR_LOW_PAGES		32
20 #define SGX_NR_HIGH_PAGES		64
21 
22 /* Pages, which are being tracked by the page reclaimer. */
23 #define SGX_EPC_PAGE_RECLAIMER_TRACKED	BIT(0)
24 
25 struct sgx_epc_page {
26 	unsigned int section;
27 	unsigned int flags;
28 	struct sgx_encl_page *owner;
29 	struct list_head list;
30 };
31 
32 /*
33  * The firmware can define multiple chunks of EPC to the different areas of the
34  * physical memory e.g. for memory areas of the each node. This structure is
35  * used to store EPC pages for one EPC section and virtual memory area where
36  * the pages have been mapped.
37  *
38  * 'lock' must be held before accessing 'page_list' or 'free_cnt'.
39  */
40 struct sgx_epc_section {
41 	unsigned long phys_addr;
42 	void *virt_addr;
43 	struct sgx_epc_page *pages;
44 
45 	spinlock_t lock;
46 	struct list_head page_list;
47 	unsigned long free_cnt;
48 
49 	/*
50 	 * Pages which need EREMOVE run on them before they can be
51 	 * used.  Only safe to be accessed in ksgxd and init code.
52 	 * Not protected by locks.
53 	 */
54 	struct list_head init_laundry_list;
55 };
56 
57 extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
58 
59 static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page)
60 {
61 	struct sgx_epc_section *section = &sgx_epc_sections[page->section];
62 	unsigned long index;
63 
64 	index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
65 
66 	return section->phys_addr + index * PAGE_SIZE;
67 }
68 
69 static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
70 {
71 	struct sgx_epc_section *section = &sgx_epc_sections[page->section];
72 	unsigned long index;
73 
74 	index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
75 
76 	return section->virt_addr + index * PAGE_SIZE;
77 }
78 
79 struct sgx_epc_page *__sgx_alloc_epc_page(void);
80 void sgx_free_epc_page(struct sgx_epc_page *page);
81 
82 void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
83 int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
84 struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
85 
86 #endif /* _X86_SGX_H */
87