1105698Srwatson/* SPDX-License-Identifier: GPL-2.0 */ 2105698Srwatson/** 3119314Srwatson * Copyright(c) 2016-20 Intel Corporation. 4105698Srwatson * 5105698Srwatson * Contains the software defined data structures for enclaves. 6105698Srwatson */ 7105698Srwatson#ifndef _X86_ENCL_H 8106436Srwatson#define _X86_ENCL_H 9106436Srwatson 10106436Srwatson#include <linux/cpumask.h> 11106436Srwatson#include <linux/kref.h> 12105698Srwatson#include <linux/list.h> 13105698Srwatson#include <linux/mm_types.h> 14105698Srwatson#include <linux/mmu_notifier.h> 15105698Srwatson#include <linux/mutex.h> 16105698Srwatson#include <linux/notifier.h> 17105698Srwatson#include <linux/srcu.h> 18105698Srwatson#include <linux/workqueue.h> 19105698Srwatson#include <linux/xarray.h> 20105698Srwatson#include "sgx.h" 21105698Srwatson 22105698Srwatson/* 'desc' bits holding the offset in the VA (version array) page. */ 23105698Srwatson#define SGX_ENCL_PAGE_VA_OFFSET_MASK GENMASK_ULL(11, 3) 24105698Srwatson 25105698Srwatson/* 'desc' bit marking that the page is being reclaimed. */ 26105698Srwatson#define SGX_ENCL_PAGE_BEING_RECLAIMED BIT(3) 27105698Srwatson 28105698Srwatsonstruct sgx_encl_page { 29105698Srwatson unsigned long desc; 30105698Srwatson unsigned long vm_max_prot_bits:8; 31105698Srwatson enum sgx_page_type type:16; 32105698Srwatson struct sgx_epc_page *epc_page; 33105698Srwatson struct sgx_encl *encl; 34105698Srwatson struct sgx_va_page *va_page; 35176901Srwatson}; 36176901Srwatson 37176901Srwatsonenum sgx_encl_flags { 38105698Srwatson SGX_ENCL_IOCTL = BIT(0), 39105698Srwatson SGX_ENCL_DEBUG = BIT(1), 40105698Srwatson SGX_ENCL_CREATED = BIT(2), 41105698Srwatson SGX_ENCL_INITIALIZED = BIT(3), 42105698Srwatson}; 43105698Srwatson 44106053Swollmanstruct sgx_encl_mm { 45105698Srwatson struct sgx_encl *encl; 46105698Srwatson struct mm_struct *mm; 47105698Srwatson struct list_head list; 48124174Snectar struct mmu_notifier mmu_notifier; 49105698Srwatson}; 50105698Srwatson 51105698Srwatsonstruct sgx_encl { 52105698Srwatson unsigned long base; 53105698Srwatson unsigned long size; 54119314Srwatson unsigned long flags; 55119314Srwatson unsigned int page_cnt; 56119314Srwatson unsigned int secs_child_cnt; 57119314Srwatson struct mutex lock; 58119314Srwatson struct xarray page_array; 59119314Srwatson struct sgx_encl_page secs; 60122868Srwatson unsigned long attributes; 61119314Srwatson unsigned long attributes_mask; 62119314Srwatson 63119314Srwatson cpumask_t cpumask; 64119314Srwatson struct file *backing; 65119314Srwatson struct kref refcount; 66105698Srwatson struct list_head va_pages; 67105698Srwatson unsigned long mm_list_version; 68105698Srwatson struct list_head mm_list; 69105698Srwatson spinlock_t mm_lock; 70119314Srwatson struct srcu_struct srcu; 71105698Srwatson}; 72119314Srwatson 73119314Srwatson#define SGX_VA_SLOT_COUNT 512 74119314Srwatson 75119314Srwatsonstruct sgx_va_page { 76119314Srwatson struct sgx_epc_page *epc_page; 77105698Srwatson DECLARE_BITMAP(slots, SGX_VA_SLOT_COUNT); 78105698Srwatson struct list_head list; 79105698Srwatson}; 80105698Srwatson 81105698Srwatsonstruct sgx_backing { 82105698Srwatson struct page *contents; 83105698Srwatson struct page *pcmd; 84105698Srwatson unsigned long pcmd_offset; 85105698Srwatson}; 86105698Srwatson 87105698Srwatsonextern const struct vm_operations_struct sgx_vm_ops; 88105698Srwatson 89105698Srwatsonstatic inline int sgx_encl_find(struct mm_struct *mm, unsigned long addr, 90119314Srwatson struct vm_area_struct **vma) 91105698Srwatson{ 92119314Srwatson struct vm_area_struct *result; 93119314Srwatson 94119314Srwatson result = vma_lookup(mm, addr); 95119314Srwatson if (!result || result->vm_ops != &sgx_vm_ops) 96119314Srwatson return -EINVAL; 97119314Srwatson 98119314Srwatson *vma = result; 99119314Srwatson 100119314Srwatson return 0; 101119314Srwatson} 102119314Srwatson 103119314Srwatsonint sgx_encl_may_map(struct sgx_encl *encl, unsigned long start, 104119314Srwatson unsigned long end, unsigned long vm_flags); 105119314Srwatson 106119314Srwatsonbool current_is_ksgxd(void); 107119314Srwatsonvoid sgx_encl_release(struct kref *ref); 108119314Srwatsonint sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); 109119314Srwatsonconst cpumask_t *sgx_encl_cpumask(struct sgx_encl *encl); 110119314Srwatsonint sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, 111119314Srwatson struct sgx_backing *backing); 112119314Srwatsonvoid sgx_encl_put_backing(struct sgx_backing *backing); 113119314Srwatsonint sgx_encl_test_and_clear_young(struct mm_struct *mm, 114119314Srwatson struct sgx_encl_page *page); 115119314Srwatsonstruct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl, 116119314Srwatson unsigned long offset, 117119314Srwatson u64 secinfo_flags); 118119314Srwatsonvoid sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr); 119119314Srwatsonstruct sgx_epc_page *sgx_alloc_va_page(bool reclaim); 120119314Srwatsonunsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page); 121119314Srwatsonvoid sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset); 122119314Srwatsonbool sgx_va_page_full(struct sgx_va_page *va_page); 123119314Srwatsonvoid sgx_encl_free_epc_page(struct sgx_epc_page *page); 124119314Srwatsonstruct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl, 125119314Srwatson unsigned long addr); 126119314Srwatsonstruct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim); 127119314Srwatsonvoid sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page); 128119314Srwatson 129119314Srwatson#endif /* _X86_ENCL_H */ 130119314Srwatson