123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- /* SPDX-License-Identifier: GPL-2.0 */
- #ifndef _X86_SGX_H
- #define _X86_SGX_H
- #include <linux/bitops.h>
- #include <linux/err.h>
- #include <linux/io.h>
- #include <linux/rwsem.h>
- #include <linux/types.h>
- #include <asm/asm.h>
- #include <asm/sgx.h>
- #undef pr_fmt
- #define pr_fmt(fmt) "sgx: " fmt
- #define EREMOVE_ERROR_MESSAGE \
- "EREMOVE returned %d (0x%x) and an EPC page was leaked. SGX may become unusable. " \
- "Refer to Documentation/x86/sgx.rst for more information."
- #define SGX_MAX_EPC_SECTIONS 8
- #define SGX_EEXTEND_BLOCK_SIZE 256
- #define SGX_NR_TO_SCAN 16
- #define SGX_NR_LOW_PAGES 32
- #define SGX_NR_HIGH_PAGES 64
- /* Pages, which are being tracked by the page reclaimer. */
- #define SGX_EPC_PAGE_RECLAIMER_TRACKED BIT(0)
- /* Pages on free list */
- #define SGX_EPC_PAGE_IS_FREE BIT(1)
- struct sgx_epc_page {
- unsigned int section;
- u16 flags;
- u16 poison;
- struct sgx_encl_page *owner;
- struct list_head list;
- };
- /*
- * Contains the tracking data for NUMA nodes having EPC pages. Most importantly,
- * the free page list local to the node is stored here.
- */
- struct sgx_numa_node {
- struct list_head free_page_list;
- struct list_head sgx_poison_page_list;
- unsigned long size;
- spinlock_t lock;
- };
- /*
- * The firmware can define multiple chunks of EPC to the different areas of the
- * physical memory e.g. for memory areas of the each node. This structure is
- * used to store EPC pages for one EPC section and virtual memory area where
- * the pages have been mapped.
- */
- struct sgx_epc_section {
- unsigned long phys_addr;
- void *virt_addr;
- struct sgx_epc_page *pages;
- struct sgx_numa_node *node;
- };
- extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
- static inline unsigned long sgx_get_epc_phys_addr(struct sgx_epc_page *page)
- {
- struct sgx_epc_section *section = &sgx_epc_sections[page->section];
- unsigned long index;
- index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
- return section->phys_addr + index * PAGE_SIZE;
- }
- static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
- {
- struct sgx_epc_section *section = &sgx_epc_sections[page->section];
- unsigned long index;
- index = ((unsigned long)page - (unsigned long)section->pages) / sizeof(*page);
- return section->virt_addr + index * PAGE_SIZE;
- }
- struct sgx_epc_page *__sgx_alloc_epc_page(void);
- void sgx_free_epc_page(struct sgx_epc_page *page);
- void sgx_reclaim_direct(void);
- void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
- int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
- struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
- void sgx_ipi_cb(void *info);
- #ifdef CONFIG_X86_SGX_KVM
- int __init sgx_vepc_init(void);
- #else
- static inline int __init sgx_vepc_init(void)
- {
- return -ENODEV;
- }
- #endif
- void sgx_update_lepubkeyhash(u64 *lepubkeyhash);
- #endif /* _X86_SGX_H */
|