Linux Audio

Check our new training course

In-person Linux kernel drivers training

Jun 16-20, 2025
Register
Loading...
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/**
  3 * Copyright(c) 2016-20 Intel Corporation.
  4 *
  5 * Contains the software defined data structures for enclaves.
  6 */
  7#ifndef _X86_ENCL_H
  8#define _X86_ENCL_H
  9
 10#include <linux/cpumask.h>
 11#include <linux/kref.h>
 12#include <linux/list.h>
 13#include <linux/mm_types.h>
 14#include <linux/mmu_notifier.h>
 15#include <linux/mutex.h>
 16#include <linux/notifier.h>
 17#include <linux/srcu.h>
 18#include <linux/workqueue.h>
 19#include <linux/xarray.h>
 20#include "sgx.h"
 21
 22/* 'desc' bits holding the offset in the VA (version array) page. */
 23#define SGX_ENCL_PAGE_VA_OFFSET_MASK	GENMASK_ULL(11, 3)
 24
 25/* 'desc' bit marking that the page is being reclaimed. */
 26#define SGX_ENCL_PAGE_BEING_RECLAIMED	BIT(3)
 27
 28struct sgx_encl_page {
 29	unsigned long desc;
 30	unsigned long vm_max_prot_bits:8;
 31	enum sgx_page_type type:16;
 32	struct sgx_epc_page *epc_page;
 33	struct sgx_encl *encl;
 34	struct sgx_va_page *va_page;
 35};
 36
 37enum sgx_encl_flags {
 38	SGX_ENCL_IOCTL		= BIT(0),
 39	SGX_ENCL_DEBUG		= BIT(1),
 40	SGX_ENCL_CREATED	= BIT(2),
 41	SGX_ENCL_INITIALIZED	= BIT(3),
 42};
 43
 44struct sgx_encl_mm {
 45	struct sgx_encl *encl;
 46	struct mm_struct *mm;
 47	struct list_head list;
 48	struct mmu_notifier mmu_notifier;
 49};
 50
 51struct sgx_encl {
 52	unsigned long base;
 53	unsigned long size;
 54	unsigned long flags;
 55	unsigned int page_cnt;
 56	unsigned int secs_child_cnt;
 57	struct mutex lock;
 58	struct xarray page_array;
 59	struct sgx_encl_page secs;
 60	unsigned long attributes;
 61	unsigned long attributes_mask;
 62
 63	cpumask_t cpumask;
 64	struct file *backing;
 65	struct kref refcount;
 66	struct list_head va_pages;
 67	unsigned long mm_list_version;
 68	struct list_head mm_list;
 69	spinlock_t mm_lock;
 70	struct srcu_struct srcu;
 71};
 72
 73#define SGX_VA_SLOT_COUNT 512
 74
 75struct sgx_va_page {
 76	struct sgx_epc_page *epc_page;
 77	DECLARE_BITMAP(slots, SGX_VA_SLOT_COUNT);
 78	struct list_head list;
 79};
 80
 81struct sgx_backing {
 82	struct page *contents;
 83	struct page *pcmd;
 84	unsigned long pcmd_offset;
 85};
 86
 87extern const struct vm_operations_struct sgx_vm_ops;
 88
 89static inline int sgx_encl_find(struct mm_struct *mm, unsigned long addr,
 90				struct vm_area_struct **vma)
 91{
 92	struct vm_area_struct *result;
 93
 94	result = vma_lookup(mm, addr);
 95	if (!result || result->vm_ops != &sgx_vm_ops)
 96		return -EINVAL;
 97
 98	*vma = result;
 99
100	return 0;
101}
102
103int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start,
104		     unsigned long end, unsigned long vm_flags);
105
106bool current_is_ksgxd(void);
107void sgx_encl_release(struct kref *ref);
108int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm);
109const cpumask_t *sgx_encl_cpumask(struct sgx_encl *encl);
110int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index,
111			   struct sgx_backing *backing);
112void sgx_encl_put_backing(struct sgx_backing *backing);
113int sgx_encl_test_and_clear_young(struct mm_struct *mm,
114				  struct sgx_encl_page *page);
115struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl,
116					  unsigned long offset,
117					  u64 secinfo_flags);
118void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr);
119struct sgx_epc_page *sgx_alloc_va_page(bool reclaim);
120unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page);
121void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset);
122bool sgx_va_page_full(struct sgx_va_page *va_page);
123void sgx_encl_free_epc_page(struct sgx_epc_page *page);
124struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
125					 unsigned long addr);
126struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim);
127void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page);
128
129#endif /* _X86_ENCL_H */