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