mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.3 KiB
86 lines
2.3 KiB
/* 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 "arch.h" |
|
|
|
#undef pr_fmt |
|
#define pr_fmt(fmt) "sgx: " fmt |
|
|
|
#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) |
|
|
|
struct sgx_epc_page { |
|
unsigned int section; |
|
unsigned int flags; |
|
struct sgx_encl_page *owner; |
|
struct list_head list; |
|
}; |
|
|
|
/* |
|
* 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. |
|
* |
|
* 'lock' must be held before accessing 'page_list' or 'free_cnt'. |
|
*/ |
|
struct sgx_epc_section { |
|
unsigned long phys_addr; |
|
void *virt_addr; |
|
struct sgx_epc_page *pages; |
|
|
|
spinlock_t lock; |
|
struct list_head page_list; |
|
unsigned long free_cnt; |
|
|
|
/* |
|
* Pages which need EREMOVE run on them before they can be |
|
* used. Only safe to be accessed in ksgxd and init code. |
|
* Not protected by locks. |
|
*/ |
|
struct list_head init_laundry_list; |
|
}; |
|
|
|
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_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); |
|
|
|
#endif /* _X86_SGX_H */
|
|
|