Skip to content

Commit bd47c99

Browse files
andraprsgregkh
authored andcommitted
nitro_enclaves: Init misc device providing the ioctl interface
The Nitro Enclaves driver provides an ioctl interface to the user space for enclave lifetime management e.g. enclave creation / termination and setting enclave resources such as memory and CPU. This ioctl interface is mapped to a Nitro Enclaves misc device. Changelog v9 -> v10 * Update commit message to include the changelog before the SoB tag(s). v8 -> v9 * Use the ne_devs data structure to get the refs for the NE misc device in the NE PCI device driver logic. v7 -> v8 * Add define for the CID of the primary / parent VM. * Update the NE PCI driver shutdown logic to include misc device deregister. v6 -> v7 * Set the NE PCI device the parent of the NE misc device to be able to use it in the ioctl logic. * Update the naming and add more comments to make more clear the logic of handling full CPU cores and dedicating them to the enclave. v5 -> v6 * Remove the ioctl to query API version. * Update documentation to kernel-doc format. v4 -> v5 * Update the size of the NE CPU pool string from 4096 to 512 chars. v3 -> v4 * Use dev_err instead of custom NE log pattern. * Remove the NE CPU pool init during kernel module loading, as the CPU pool is now setup at runtime, via a sysfs file for the kernel parameter. * Add minimum enclave memory size definition. v2 -> v3 * Remove the GPL additional wording as SPDX-License-Identifier is already in place. * Remove the WARN_ON calls. * Remove linux/bug and linux/kvm_host includes that are not needed. * Remove "ratelimited" from the logs that are not in the ioctl call paths. * Remove file ops that do nothing for now - open and release. v1 -> v2 * Add log pattern for NE. * Update goto labels to match their purpose. * Update ne_cpu_pool data structure to include the global mutex. * Update NE misc device mode to 0660. * Check if the CPU siblings are included in the NE CPU pool, as full CPU cores are given for the enclave(s). Reviewed-by: Alexander Graf <[email protected]> Signed-off-by: Andra Paraschiv <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e5d616d commit bd47c99

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*/
5+
6+
/**
7+
* DOC: Enclave lifetime management driver for Nitro Enclaves (NE).
8+
* Nitro is a hypervisor that has been developed by Amazon.
9+
*/
10+
11+
#include <linux/anon_inodes.h>
12+
#include <linux/capability.h>
13+
#include <linux/cpu.h>
14+
#include <linux/device.h>
15+
#include <linux/file.h>
16+
#include <linux/hugetlb.h>
17+
#include <linux/limits.h>
18+
#include <linux/list.h>
19+
#include <linux/miscdevice.h>
20+
#include <linux/mm.h>
21+
#include <linux/mman.h>
22+
#include <linux/module.h>
23+
#include <linux/mutex.h>
24+
#include <linux/nitro_enclaves.h>
25+
#include <linux/pci.h>
26+
#include <linux/poll.h>
27+
#include <linux/slab.h>
28+
#include <linux/types.h>
29+
#include <uapi/linux/vm_sockets.h>
30+
31+
#include "ne_misc_dev.h"
32+
#include "ne_pci_dev.h"
33+
34+
/**
35+
* NE_CPUS_SIZE - Size for max 128 CPUs, for now, in a cpu-list string, comma
36+
* separated. The NE CPU pool includes CPUs from a single NUMA
37+
* node.
38+
*/
39+
#define NE_CPUS_SIZE (512)
40+
41+
/**
42+
* NE_EIF_LOAD_OFFSET - The offset where to copy the Enclave Image Format (EIF)
43+
* image in enclave memory.
44+
*/
45+
#define NE_EIF_LOAD_OFFSET (8 * 1024UL * 1024UL)
46+
47+
/**
48+
* NE_MIN_ENCLAVE_MEM_SIZE - The minimum memory size an enclave can be launched
49+
* with.
50+
*/
51+
#define NE_MIN_ENCLAVE_MEM_SIZE (64 * 1024UL * 1024UL)
52+
53+
/**
54+
* NE_MIN_MEM_REGION_SIZE - The minimum size of an enclave memory region.
55+
*/
56+
#define NE_MIN_MEM_REGION_SIZE (2 * 1024UL * 1024UL)
57+
58+
/**
59+
* NE_PARENT_VM_CID - The CID for the vsock device of the primary / parent VM.
60+
*/
61+
#define NE_PARENT_VM_CID (3)
62+
63+
static const struct file_operations ne_fops = {
64+
.owner = THIS_MODULE,
65+
.llseek = noop_llseek,
66+
};
67+
68+
static struct miscdevice ne_misc_dev = {
69+
.minor = MISC_DYNAMIC_MINOR,
70+
.name = "nitro_enclaves",
71+
.fops = &ne_fops,
72+
.mode = 0660,
73+
};
74+
75+
struct ne_devs ne_devs = {
76+
.ne_misc_dev = &ne_misc_dev,
77+
};
78+
79+
/*
80+
* TODO: Update logic to create new sysfs entries instead of using
81+
* a kernel parameter e.g. if multiple sysfs files needed.
82+
*/
83+
static const struct kernel_param_ops ne_cpu_pool_ops = {
84+
.get = param_get_string,
85+
};
86+
87+
static char ne_cpus[NE_CPUS_SIZE];
88+
static struct kparam_string ne_cpus_arg = {
89+
.maxlen = sizeof(ne_cpus),
90+
.string = ne_cpus,
91+
};
92+
93+
module_param_cb(ne_cpus, &ne_cpu_pool_ops, &ne_cpus_arg, 0644);
94+
/* https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html#cpu-lists */
95+
MODULE_PARM_DESC(ne_cpus, "<cpu-list> - CPU pool used for Nitro Enclaves");
96+
97+
/**
98+
* struct ne_cpu_pool - CPU pool used for Nitro Enclaves.
99+
* @avail_threads_per_core: Available full CPU cores to be dedicated to
100+
* enclave(s). The cpumasks from the array, indexed
101+
* by core id, contain all the threads from the
102+
* available cores, that are not set for created
103+
* enclave(s). The full CPU cores are part of the
104+
* NE CPU pool.
105+
* @mutex: Mutex for the access to the NE CPU pool.
106+
* @nr_parent_vm_cores : The size of the available threads per core array.
107+
* The total number of CPU cores available on the
108+
* primary / parent VM.
109+
* @nr_threads_per_core: The number of threads that a full CPU core has.
110+
* @numa_node: NUMA node of the CPUs in the pool.
111+
*/
112+
struct ne_cpu_pool {
113+
cpumask_var_t *avail_threads_per_core;
114+
struct mutex mutex;
115+
unsigned int nr_parent_vm_cores;
116+
unsigned int nr_threads_per_core;
117+
int numa_node;
118+
};
119+
120+
static struct ne_cpu_pool ne_cpu_pool;
121+
122+
static int __init ne_init(void)
123+
{
124+
mutex_init(&ne_cpu_pool.mutex);
125+
126+
return pci_register_driver(&ne_pci_driver);
127+
}
128+
129+
static void __exit ne_exit(void)
130+
{
131+
pci_unregister_driver(&ne_pci_driver);
132+
}
133+
134+
module_init(ne_init);
135+
module_exit(ne_exit);
136+
137+
MODULE_AUTHOR("Amazon.com, Inc. or its affiliates");
138+
MODULE_DESCRIPTION("Nitro Enclaves Driver");
139+
MODULE_LICENSE("GPL v2");

drivers/virt/nitro_enclaves/ne_pci_dev.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,18 @@ static int ne_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
523523

524524
ne_devs.ne_pci_dev = ne_pci_dev;
525525

526+
rc = misc_register(ne_devs.ne_misc_dev);
527+
if (rc < 0) {
528+
dev_err(&pdev->dev, "Error in misc dev register [rc=%d]\n", rc);
529+
530+
goto disable_ne_pci_dev;
531+
}
532+
526533
return 0;
527534

535+
disable_ne_pci_dev:
536+
ne_devs.ne_pci_dev = NULL;
537+
ne_pci_dev_disable(pdev);
528538
teardown_msix:
529539
ne_teardown_msix(pdev);
530540
iounmap_pci_bar:
@@ -550,6 +560,8 @@ static void ne_pci_remove(struct pci_dev *pdev)
550560
{
551561
struct ne_pci_dev *ne_pci_dev = pci_get_drvdata(pdev);
552562

563+
misc_deregister(ne_devs.ne_misc_dev);
564+
553565
ne_devs.ne_pci_dev = NULL;
554566

555567
ne_pci_dev_disable(pdev);
@@ -580,6 +592,8 @@ static void ne_pci_shutdown(struct pci_dev *pdev)
580592
if (!ne_pci_dev)
581593
return;
582594

595+
misc_deregister(ne_devs.ne_misc_dev);
596+
583597
ne_devs.ne_pci_dev = NULL;
584598

585599
ne_pci_dev_disable(pdev);

0 commit comments

Comments
 (0)