forked from 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.
120 lines
3.0 KiB
120 lines
3.0 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
/** |
|
* Copyright(c) 2016-20 Intel Corporation. |
|
* |
|
* Contains the software defined data structures for enclaves. |
|
*/ |
|
#ifndef _X86_ENCL_H |
|
#define _X86_ENCL_H |
|
|
|
#include <linux/cpumask.h> |
|
#include <linux/kref.h> |
|
#include <linux/list.h> |
|
#include <linux/mm_types.h> |
|
#include <linux/mmu_notifier.h> |
|
#include <linux/mutex.h> |
|
#include <linux/notifier.h> |
|
#include <linux/srcu.h> |
|
#include <linux/workqueue.h> |
|
#include <linux/xarray.h> |
|
#include "sgx.h" |
|
|
|
/* 'desc' bits holding the offset in the VA (version array) page. */ |
|
#define SGX_ENCL_PAGE_VA_OFFSET_MASK GENMASK_ULL(11, 3) |
|
|
|
/* 'desc' bit marking that the page is being reclaimed. */ |
|
#define SGX_ENCL_PAGE_BEING_RECLAIMED BIT(3) |
|
|
|
struct sgx_encl_page { |
|
unsigned long desc; |
|
unsigned long vm_max_prot_bits; |
|
struct sgx_epc_page *epc_page; |
|
struct sgx_encl *encl; |
|
struct sgx_va_page *va_page; |
|
}; |
|
|
|
enum sgx_encl_flags { |
|
SGX_ENCL_IOCTL = BIT(0), |
|
SGX_ENCL_DEBUG = BIT(1), |
|
SGX_ENCL_CREATED = BIT(2), |
|
SGX_ENCL_INITIALIZED = BIT(3), |
|
}; |
|
|
|
struct sgx_encl_mm { |
|
struct sgx_encl *encl; |
|
struct mm_struct *mm; |
|
struct list_head list; |
|
struct mmu_notifier mmu_notifier; |
|
}; |
|
|
|
struct sgx_encl { |
|
unsigned long base; |
|
unsigned long size; |
|
unsigned long flags; |
|
unsigned int page_cnt; |
|
unsigned int secs_child_cnt; |
|
struct mutex lock; |
|
struct xarray page_array; |
|
struct sgx_encl_page secs; |
|
unsigned long attributes; |
|
unsigned long attributes_mask; |
|
|
|
cpumask_t cpumask; |
|
struct file *backing; |
|
struct kref refcount; |
|
struct list_head va_pages; |
|
unsigned long mm_list_version; |
|
struct list_head mm_list; |
|
spinlock_t mm_lock; |
|
struct srcu_struct srcu; |
|
}; |
|
|
|
#define SGX_VA_SLOT_COUNT 512 |
|
|
|
struct sgx_va_page { |
|
struct sgx_epc_page *epc_page; |
|
DECLARE_BITMAP(slots, SGX_VA_SLOT_COUNT); |
|
struct list_head list; |
|
}; |
|
|
|
struct sgx_backing { |
|
pgoff_t page_index; |
|
struct page *contents; |
|
struct page *pcmd; |
|
unsigned long pcmd_offset; |
|
}; |
|
|
|
extern const struct vm_operations_struct sgx_vm_ops; |
|
|
|
static inline int sgx_encl_find(struct mm_struct *mm, unsigned long addr, |
|
struct vm_area_struct **vma) |
|
{ |
|
struct vm_area_struct *result; |
|
|
|
result = vma_lookup(mm, addr); |
|
if (!result || result->vm_ops != &sgx_vm_ops) |
|
return -EINVAL; |
|
|
|
*vma = result; |
|
|
|
return 0; |
|
} |
|
|
|
int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start, |
|
unsigned long end, unsigned long vm_flags); |
|
|
|
void sgx_encl_release(struct kref *ref); |
|
int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); |
|
int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, |
|
struct sgx_backing *backing); |
|
void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write); |
|
int sgx_encl_test_and_clear_young(struct mm_struct *mm, |
|
struct sgx_encl_page *page); |
|
|
|
struct sgx_epc_page *sgx_alloc_va_page(void); |
|
unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page); |
|
void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset); |
|
bool sgx_va_page_full(struct sgx_va_page *va_page); |
|
void sgx_encl_free_epc_page(struct sgx_epc_page *page); |
|
|
|
#endif /* _X86_ENCL_H */
|
|
|