sgx.h (2779B)
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/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 32struct 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 */ 44struct 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 */ 57struct 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 64extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS]; 65 66static 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 76static 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 86struct sgx_epc_page *__sgx_alloc_epc_page(void); 87void sgx_free_epc_page(struct sgx_epc_page *page); 88 89void sgx_mark_page_reclaimable(struct sgx_epc_page *page); 90int sgx_unmark_page_reclaimable(struct sgx_epc_page *page); 91struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim); 92 93#ifdef CONFIG_X86_SGX_KVM 94int __init sgx_vepc_init(void); 95#else 96static inline int __init sgx_vepc_init(void) 97{ 98 return -ENODEV; 99} 100#endif 101 102void sgx_update_lepubkeyhash(u64 *lepubkeyhash); 103 104#endif /* _X86_SGX_H */