xref: /openbmc/linux/arch/x86/kernel/cpu/sgx/sgx.h (revision ff61f079)
1e7e05452SSean Christopherson /* SPDX-License-Identifier: GPL-2.0 */
2e7e05452SSean Christopherson #ifndef _X86_SGX_H
3e7e05452SSean Christopherson #define _X86_SGX_H
4e7e05452SSean Christopherson 
5e7e05452SSean Christopherson #include <linux/bitops.h>
6e7e05452SSean Christopherson #include <linux/err.h>
7e7e05452SSean Christopherson #include <linux/io.h>
8e7e05452SSean Christopherson #include <linux/rwsem.h>
9e7e05452SSean Christopherson #include <linux/types.h>
10e7e05452SSean Christopherson #include <asm/asm.h>
118ca52cc3SSean Christopherson #include <asm/sgx.h>
12e7e05452SSean Christopherson 
13e7e05452SSean Christopherson #undef pr_fmt
14e7e05452SSean Christopherson #define pr_fmt(fmt) "sgx: " fmt
15e7e05452SSean Christopherson 
16b0c7459bSKai Huang #define EREMOVE_ERROR_MESSAGE \
17b0c7459bSKai Huang 	"EREMOVE returned %d (0x%x) and an EPC page was leaked. SGX may become unusable. " \
18*ff61f079SJonathan Corbet 	"Refer to Documentation/arch/x86/sgx.rst for more information."
19b0c7459bSKai Huang 
20e7e05452SSean Christopherson #define SGX_MAX_EPC_SECTIONS		8
21c6d26d37SJarkko Sakkinen #define SGX_EEXTEND_BLOCK_SIZE		256
221728ab54SJarkko Sakkinen #define SGX_NR_TO_SCAN			16
231728ab54SJarkko Sakkinen #define SGX_NR_LOW_PAGES		32
241728ab54SJarkko Sakkinen #define SGX_NR_HIGH_PAGES		64
251728ab54SJarkko Sakkinen 
261728ab54SJarkko Sakkinen /* Pages, which are being tracked by the page reclaimer. */
271728ab54SJarkko Sakkinen #define SGX_EPC_PAGE_RECLAIMER_TRACKED	BIT(0)
28e7e05452SSean Christopherson 
29d6d261bdSTony Luck /* Pages on free list */
30d6d261bdSTony Luck #define SGX_EPC_PAGE_IS_FREE		BIT(1)
31d6d261bdSTony Luck 
32e7e05452SSean Christopherson struct sgx_epc_page {
33e7e05452SSean Christopherson 	unsigned int section;
34992801aeSTony Luck 	u16 flags;
35992801aeSTony Luck 	u16 poison;
361728ab54SJarkko Sakkinen 	struct sgx_encl_page *owner;
37e7e05452SSean Christopherson 	struct list_head list;
38e7e05452SSean Christopherson };
39e7e05452SSean Christopherson 
40e7e05452SSean Christopherson /*
41901ddbb9SJarkko Sakkinen  * Contains the tracking data for NUMA nodes having EPC pages. Most importantly,
42901ddbb9SJarkko Sakkinen  * the free page list local to the node is stored here.
43901ddbb9SJarkko Sakkinen  */
44901ddbb9SJarkko Sakkinen struct sgx_numa_node {
45901ddbb9SJarkko Sakkinen 	struct list_head free_page_list;
46992801aeSTony Luck 	struct list_head sgx_poison_page_list;
4750468e43SJarkko Sakkinen 	unsigned long size;
48901ddbb9SJarkko Sakkinen 	spinlock_t lock;
49901ddbb9SJarkko Sakkinen };
50901ddbb9SJarkko Sakkinen 
51901ddbb9SJarkko Sakkinen /*
52e7e05452SSean Christopherson  * The firmware can define multiple chunks of EPC to the different areas of the
53e7e05452SSean Christopherson  * physical memory e.g. for memory areas of the each node. This structure is
54e7e05452SSean Christopherson  * used to store EPC pages for one EPC section and virtual memory area where
55e7e05452SSean Christopherson  * the pages have been mapped.
56e7e05452SSean Christopherson  */
57e7e05452SSean Christopherson struct sgx_epc_section {
58e7e05452SSean Christopherson 	unsigned long phys_addr;
59e7e05452SSean Christopherson 	void *virt_addr;
60e7e05452SSean Christopherson 	struct sgx_epc_page *pages;
61901ddbb9SJarkko Sakkinen 	struct sgx_numa_node *node;
62e7e05452SSean Christopherson };
63e7e05452SSean Christopherson 
64e7e05452SSean Christopherson extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
65e7e05452SSean Christopherson 
sgx_get_epc_phys_addr(struct sgx_epc_page * page)66e7e05452SSean Christopherson static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page)
67e7e05452SSean Christopherson {
68e7e05452SSean Christopherson 	struct sgx_epc_section *section = &sgx_epc_sections[page->section];
69e7e05452SSean Christopherson 	unsigned long index;
70e7e05452SSean Christopherson 
71e7e05452SSean Christopherson 	index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
72e7e05452SSean Christopherson 
73e7e05452SSean Christopherson 	return section->phys_addr + index * PAGE_SIZE;
74e7e05452SSean Christopherson }
75e7e05452SSean Christopherson 
sgx_get_epc_virt_addr(struct sgx_epc_page * page)76e7e05452SSean Christopherson static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
77e7e05452SSean Christopherson {
78e7e05452SSean Christopherson 	struct sgx_epc_section *section = &sgx_epc_sections[page->section];
79e7e05452SSean Christopherson 	unsigned long index;
80e7e05452SSean Christopherson 
81e7e05452SSean Christopherson 	index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
82e7e05452SSean Christopherson 
83e7e05452SSean Christopherson 	return section->virt_addr + index * PAGE_SIZE;
84e7e05452SSean Christopherson }
85e7e05452SSean Christopherson 
86d2285493SJarkko Sakkinen struct sgx_epc_page *__sgx_alloc_epc_page(void);
87d2285493SJarkko Sakkinen void sgx_free_epc_page(struct sgx_epc_page *page);
88d2285493SJarkko Sakkinen 
89a0506b3bSReinette Chatre void sgx_reclaim_direct(void);
901728ab54SJarkko Sakkinen void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
911728ab54SJarkko Sakkinen int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
921728ab54SJarkko Sakkinen struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
931728ab54SJarkko Sakkinen 
94c7c6a8a6SReinette Chatre void sgx_ipi_cb(void *info);
95c7c6a8a6SReinette Chatre 
96540745ddSSean Christopherson #ifdef CONFIG_X86_SGX_KVM
97540745ddSSean Christopherson int __init sgx_vepc_init(void);
98540745ddSSean Christopherson #else
sgx_vepc_init(void)99540745ddSSean Christopherson static inline int __init sgx_vepc_init(void)
100540745ddSSean Christopherson {
101540745ddSSean Christopherson 	return -ENODEV;
102540745ddSSean Christopherson }
103540745ddSSean Christopherson #endif
104540745ddSSean Christopherson 
10573916b6aSKai Huang void sgx_update_lepubkeyhash(u64 *lepubkeyhash);
10673916b6aSKai Huang 
107e7e05452SSean Christopherson #endif /* _X86_SGX_H */
108