Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/kernel/cpu/sgx/sgx.h
26516 views
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
109