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