ne_enclave
list_add(&ne_mem_region->mem_region_list_entry, &ne_enclave->mem_regions_list);
slot_add_mem_req.slot_uid = ne_enclave->slot_uid;
ne_enclave->mem_size += slot_add_mem_req.size;
ne_enclave->nr_mem_regions++;
static int ne_start_enclave_ioctl(struct ne_enclave *ne_enclave,
if (!ne_enclave->nr_mem_regions) {
if (ne_enclave->mem_size < NE_MIN_ENCLAVE_MEM_SIZE) {
if (!ne_enclave->nr_vcpus) {
for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++)
for_each_cpu(cpu, ne_enclave->threads_per_core[i])
if (!cpumask_test_cpu(cpu, ne_enclave->vcpu_ids)) {
enclave_start_req.slot_uid = ne_enclave->slot_uid;
ne_enclave->state = NE_STATE_RUNNING;
struct ne_enclave *ne_enclave = file->private_data;
mutex_lock(&ne_enclave->enclave_info_mutex);
if (ne_enclave->state != NE_STATE_INIT) {
mutex_unlock(&ne_enclave->enclave_info_mutex);
if (vcpu_id >= (ne_enclave->nr_parent_vm_cores *
ne_enclave->nr_threads_per_core)) {
mutex_unlock(&ne_enclave->enclave_info_mutex);
rc = ne_get_cpu_from_cpu_pool(ne_enclave, &vcpu_id);
mutex_unlock(&ne_enclave->enclave_info_mutex);
rc = ne_check_cpu_in_cpu_pool(ne_enclave, vcpu_id);
mutex_unlock(&ne_enclave->enclave_info_mutex);
rc = ne_add_vcpu_ioctl(ne_enclave, vcpu_id);
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_lock(&ne_enclave->enclave_info_mutex);
if (ne_enclave->state != NE_STATE_INIT) {
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_lock(&ne_enclave->enclave_info_mutex);
if (ne_enclave->state != NE_STATE_INIT) {
mutex_unlock(&ne_enclave->enclave_info_mutex);
rc = ne_set_user_memory_region_ioctl(ne_enclave, mem_region);
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_lock(&ne_enclave->enclave_info_mutex);
if (ne_enclave->state != NE_STATE_INIT) {
mutex_unlock(&ne_enclave->enclave_info_mutex);
rc = ne_start_enclave_ioctl(ne_enclave, &enclave_start_info);
mutex_unlock(&ne_enclave->enclave_info_mutex);
mutex_unlock(&ne_enclave->enclave_info_mutex);
static void ne_enclave_remove_all_mem_region_entries(struct ne_enclave *ne_enclave)
&ne_enclave->mem_regions_list,
static void ne_enclave_remove_all_vcpu_id_entries(struct ne_enclave *ne_enclave)
for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++) {
for_each_cpu(cpu, ne_enclave->threads_per_core[i])
free_cpumask_var(ne_enclave->threads_per_core[i]);
kfree(ne_enclave->threads_per_core);
free_cpumask_var(ne_enclave->vcpu_ids);
static void ne_pci_dev_remove_enclave_entry(struct ne_enclave *ne_enclave,
struct ne_enclave *ne_enclave_entry = NULL;
struct ne_enclave *ne_enclave_entry_tmp = NULL;
if (ne_enclave_entry->slot_uid == ne_enclave->slot_uid) {
struct ne_enclave *ne_enclave = file->private_data;
if (!ne_enclave)
if (!ne_enclave->slot_uid)
mutex_lock(&ne_enclave->enclave_info_mutex);
if (ne_enclave->state != NE_STATE_INIT && ne_enclave->state != NE_STATE_STOPPED) {
enclave_stop_request.slot_uid = ne_enclave->slot_uid;
slot_free_req.slot_uid = ne_enclave->slot_uid;
ne_pci_dev_remove_enclave_entry(ne_enclave, ne_pci_dev);
ne_enclave_remove_all_mem_region_entries(ne_enclave);
ne_enclave_remove_all_vcpu_id_entries(ne_enclave);
mutex_unlock(&ne_enclave->enclave_info_mutex);
kfree(ne_enclave);
mutex_unlock(&ne_enclave->enclave_info_mutex);
struct ne_enclave *ne_enclave = file->private_data;
poll_wait(file, &ne_enclave->eventq, wait);
if (ne_enclave->has_event)
struct ne_enclave *ne_enclave = NULL;
ne_enclave = kzalloc_obj(*ne_enclave);
if (!ne_enclave)
ne_enclave->nr_parent_vm_cores = ne_cpu_pool.nr_parent_vm_cores;
ne_enclave->nr_threads_per_core = ne_cpu_pool.nr_threads_per_core;
ne_enclave->numa_node = ne_cpu_pool.numa_node;
ne_enclave->threads_per_core = kzalloc_objs(*ne_enclave->threads_per_core,
ne_enclave->nr_parent_vm_cores);
if (!ne_enclave->threads_per_core) {
for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++)
if (!zalloc_cpumask_var(&ne_enclave->threads_per_core[i], GFP_KERNEL)) {
if (!zalloc_cpumask_var(&ne_enclave->vcpu_ids, GFP_KERNEL)) {
enclave_file = anon_inode_getfile("ne-vm", &ne_enclave_fops, ne_enclave, O_RDWR);
init_waitqueue_head(&ne_enclave->eventq);
ne_enclave->has_event = false;
mutex_init(&ne_enclave->enclave_info_mutex);
ne_enclave->max_mem_regions = cmd_reply.mem_regions;
INIT_LIST_HEAD(&ne_enclave->mem_regions_list);
ne_enclave->mm = current->mm;
ne_enclave->slot_uid = cmd_reply.slot_uid;
ne_enclave->state = NE_STATE_INIT;
list_add(&ne_enclave->enclave_list_entry, &ne_pci_dev->enclaves_list);
if (copy_to_user(slot_uid, &ne_enclave->slot_uid, sizeof(ne_enclave->slot_uid))) {
free_cpumask_var(ne_enclave->vcpu_ids);
for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++)
free_cpumask_var(ne_enclave->threads_per_core[i]);
kfree(ne_enclave->threads_per_core);
kfree(ne_enclave);
static bool ne_donated_cpu(struct ne_enclave *ne_enclave, unsigned int cpu)
if (cpumask_test_cpu(cpu, ne_enclave->vcpu_ids))
static int ne_set_enclave_threads_per_core(struct ne_enclave *ne_enclave,
if (core_id >= ne_enclave->nr_parent_vm_cores) {
cpumask_set_cpu(cpu, ne_enclave->threads_per_core[core_id]);
static int ne_get_cpu_from_cpu_pool(struct ne_enclave *ne_enclave, u32 *vcpu_id)
for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++)
for_each_cpu(cpu, ne_enclave->threads_per_core[i])
if (!ne_donated_cpu(ne_enclave, cpu)) {
rc = ne_set_enclave_threads_per_core(ne_enclave, core_id, *vcpu_id);
*vcpu_id = cpumask_any(ne_enclave->threads_per_core[core_id]);
static int ne_check_cpu_in_cpu_pool(struct ne_enclave *ne_enclave, u32 vcpu_id)
if (ne_donated_cpu(ne_enclave, vcpu_id)) {
for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++)
if (cpumask_test_cpu(vcpu_id, ne_enclave->threads_per_core[i]))
rc = ne_set_enclave_threads_per_core(ne_enclave, core_id, vcpu_id);
static int ne_add_vcpu_ioctl(struct ne_enclave *ne_enclave, u32 vcpu_id)
if (ne_enclave->mm != current->mm)
slot_add_vcpu_req.slot_uid = ne_enclave->slot_uid;
cpumask_set_cpu(vcpu_id, ne_enclave->vcpu_ids);
ne_enclave->nr_vcpus++;
static int ne_sanity_check_user_mem_region(struct ne_enclave *ne_enclave,
if (ne_enclave->mm != current->mm)
list_for_each_entry(ne_mem_region, &ne_enclave->mem_regions_list,
static int ne_sanity_check_user_mem_region_page(struct ne_enclave *ne_enclave,
if (ne_enclave->numa_node != page_to_nid(mem_region_page)) {
ne_enclave->numa_node);
static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave,
rc = ne_sanity_check_user_mem_region(ne_enclave, mem_region);
rc = ne_sanity_check_user_mem_region_page(ne_enclave, ne_mem_region->pages[i]);
if ((ne_enclave->nr_mem_regions + phys_contig_mem_regions.num) >
ne_enclave->max_mem_regions) {
ne_enclave->max_mem_regions);
struct ne_enclave *ne_enclave = NULL;
list_for_each_entry(ne_enclave, &ne_pci_dev->enclaves_list, enclave_list_entry) {
mutex_lock(&ne_enclave->enclave_info_mutex);
if (ne_enclave->state != NE_STATE_RUNNING)
slot_info_req.slot_uid = ne_enclave->slot_uid;
if (ne_enclave->state != cmd_reply.state) {
ne_enclave->state = cmd_reply.state;
ne_enclave->has_event = true;
wake_up_interruptible(&ne_enclave->eventq);
mutex_unlock(&ne_enclave->enclave_info_mutex);