Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _X86_SGX_H
0003 #define _X86_SGX_H
0004 
0005 #include <linux/bitops.h>
0006 #include <linux/err.h>
0007 #include <linux/io.h>
0008 #include <linux/rwsem.h>
0009 #include <linux/types.h>
0010 #include <asm/asm.h>
0011 #include <asm/sgx.h>
0012 
0013 #undef pr_fmt
0014 #define pr_fmt(fmt) "sgx: " fmt
0015 
0016 #define EREMOVE_ERROR_MESSAGE \
0017     "EREMOVE returned %d (0x%x) and an EPC page was leaked. SGX may become unusable. " \
0018     "Refer to Documentation/x86/sgx.rst for more information."
0019 
0020 #define SGX_MAX_EPC_SECTIONS        8
0021 #define SGX_EEXTEND_BLOCK_SIZE      256
0022 #define SGX_NR_TO_SCAN          16
0023 #define SGX_NR_LOW_PAGES        32
0024 #define SGX_NR_HIGH_PAGES       64
0025 
0026 /* Pages, which are being tracked by the page reclaimer. */
0027 #define SGX_EPC_PAGE_RECLAIMER_TRACKED  BIT(0)
0028 
0029 /* Pages on free list */
0030 #define SGX_EPC_PAGE_IS_FREE        BIT(1)
0031 
0032 struct sgx_epc_page {
0033     unsigned int section;
0034     u16 flags;
0035     u16 poison;
0036     struct sgx_encl_page *owner;
0037     struct list_head list;
0038 };
0039 
0040 /*
0041  * Contains the tracking data for NUMA nodes having EPC pages. Most importantly,
0042  * the free page list local to the node is stored here.
0043  */
0044 struct sgx_numa_node {
0045     struct list_head free_page_list;
0046     struct list_head sgx_poison_page_list;
0047     unsigned long size;
0048     spinlock_t lock;
0049 };
0050 
0051 /*
0052  * The firmware can define multiple chunks of EPC to the different areas of the
0053  * physical memory e.g. for memory areas of the each node. This structure is
0054  * used to store EPC pages for one EPC section and virtual memory area where
0055  * the pages have been mapped.
0056  */
0057 struct sgx_epc_section {
0058     unsigned long phys_addr;
0059     void *virt_addr;
0060     struct sgx_epc_page *pages;
0061     struct sgx_numa_node *node;
0062 };
0063 
0064 extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
0065 
0066 static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page)
0067 {
0068     struct sgx_epc_section *section = &sgx_epc_sections[page->section];
0069     unsigned long index;
0070 
0071     index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
0072 
0073     return section->phys_addr + index * PAGE_SIZE;
0074 }
0075 
0076 static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
0077 {
0078     struct sgx_epc_section *section = &sgx_epc_sections[page->section];
0079     unsigned long index;
0080 
0081     index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
0082 
0083     return section->virt_addr + index * PAGE_SIZE;
0084 }
0085 
0086 struct sgx_epc_page *__sgx_alloc_epc_page(void);
0087 void sgx_free_epc_page(struct sgx_epc_page *page);
0088 
0089 void sgx_reclaim_direct(void);
0090 void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
0091 int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
0092 struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
0093 
0094 void sgx_ipi_cb(void *info);
0095 
0096 #ifdef CONFIG_X86_SGX_KVM
0097 int __init sgx_vepc_init(void);
0098 #else
0099 static inline int __init sgx_vepc_init(void)
0100 {
0101     return -ENODEV;
0102 }
0103 #endif
0104 
0105 void sgx_update_lepubkeyhash(u64 *lepubkeyhash);
0106 
0107 #endif /* _X86_SGX_H */